Materials

This commit is contained in:
Crizomb 2025-09-26 04:33:09 +02:00
parent c0c129db88
commit f5d4a5cb7e
5 changed files with 113 additions and 106 deletions

View file

@ -1,11 +0,0 @@
package main
type Color interface {
GetColor(Vector3) Vector3
}
var RED = Vector3{255, 0, 0}
var GREEN = Vector3{0, 255, 0}
var BLUE = Vector3{0, 0, 255}
var WHITE = Vector3{255, 255, 255}
var GREY = Vector3{127, 127, 127}

62
material.go Normal file
View file

@ -0,0 +1,62 @@
package main
type Color interface {
GetColor(Vector3) Vector3
}
// Ambre je te copie
type Material struct {
diffuseColor Color
diffuseFac float64
specularColor Color
specularFac float64
specularExp float64
reflectanceFac float64
reflectanceTint Color
refractFac float64
refractIndice float64
}
func DefaultMaterial(diffuseColor Color) Material {
return Material{
diffuseColor: diffuseColor,
diffuseFac: 1.0,
specularColor: Vector3{1.0, 1.0, 1.0},
specularFac: 0.5,
specularExp: 32.0,
reflectanceFac: 0.0,
reflectanceTint: Vector3{1.0, 1.0, 1.0},
refractFac: 0.0,
refractIndice: 1.0,
}
}
func MixMat(mat1 Material, mat2 Material, t float64, p Vector3) Material {
return Material{
mat1.diffuseColor.GetColor(p).Scale(1 - t).Add((mat2.diffuseColor.GetColor(p)).Scale(t)),
(mat1.diffuseFac*(1-t) + mat2.diffuseFac) * t,
mat1.specularColor.GetColor(p).Scale(1 - t).Add((mat2.specularColor.GetColor(p)).Scale(t)),
(mat1.specularFac*(1-t) + mat2.specularFac) * t,
(mat1.specularExp*(1-t) + mat2.specularExp) * t,
(mat1.reflectanceFac*(1-t) + mat2.reflectanceFac) * t,
mat1.reflectanceTint.GetColor(p).Scale(1 - t).Add((mat2.reflectanceTint.GetColor(p)).Scale(t)),
(mat1.refractFac*(1-t) + mat2.refractFac) * t,
(mat1.refractIndice*(1-t) + mat2.refractIndice) * t,
}
}
// Colors
var RED = Vector3{255, 0, 0}
var GREEN = Vector3{0, 255, 0}
var BLUE = Vector3{0, 0, 255}
var WHITE = Vector3{255, 255, 255}
var GREY = Vector3{127, 127, 127}
// Materials
var RED_MAT = DefaultMaterial(RED)
var GREEN_MAT = DefaultMaterial(GREEN)
var BLUE_MAT = DefaultMaterial(BLUE)
var WHITE_MAT = DefaultMaterial(WHITE)
var GREY_MAT = DefaultMaterial(GREY)

View file

@ -2,33 +2,33 @@ package main
// Sphere // Sphere
type Sphere struct { type Sphere struct {
center Vector3 center Vector3
radius float64 radius float64
color Color material Material
} }
func (s Sphere) Distance(p Vector3) (float64, Color) { func (s Sphere) Distance(p Vector3) (float64, Material) {
return p.Sub(s.center).Length() - s.radius, s.color return p.Sub(s.center).Length() - s.radius, s.material
} }
// Box // Box
type Box struct { type Box struct {
center Vector3 center Vector3
dimensions Vector3 dimensions Vector3
color Color material Material
} }
func (s Box) Distance(p Vector3) (float64, Color) { func (s Box) Distance(p Vector3) (float64, Material) {
q := p.Sub(s.center).Abs().Sub(s.dimensions) q := p.Sub(s.center).Abs().Sub(s.dimensions)
return q.Max(0.0).Length() + min(max(q.X, max(q.Y, q.Z)), 0.0), s.color return q.Max(0.0).Length() + min(max(q.X, max(q.Y, q.Z)), 0.0), s.material
} }
type Plane struct { type Plane struct {
normal Vector3 normal Vector3
height float64 height float64
color Color material Material
} }
func (s Plane) Distance(p Vector3) (float64, Color) { func (s Plane) Distance(p Vector3) (float64, Material) {
return p.Dot(s.normal) + s.height, s.color return p.Dot(s.normal) - s.height, s.material
} }

View file

@ -1,5 +1,9 @@
package main package main
// RIGHT : x
// FORWARD : Y
// UP : Z
import ( import (
"math" "math"
@ -13,12 +17,10 @@ const WIDTH = 500
const HEIGHT = 500 const HEIGHT = 500
const PI = math.Pi const PI = math.Pi
// var sphere Sphere = Sphere{Vector3{0, 0, 100}, 10, RED} var sphere Sphere = Sphere{Vector3{0, 100, 10}, 10, RED_MAT}
// var plane Plane = Plane{Vector3{0, 1, 0}, -10, GREY} var plane Plane = Plane{Vector3{0, 0, 1}, -10, GREY_MAT}
// var scene UnionSDF = UnionSDF{sphere, plane} var scene UnionSDF = UnionSDF{sphere, plane}
// x right, y forward, z up
var scene Sphere = Sphere{Vector3{0, 100, 0}, 5, RED}
var cameraPos Vector3 = Vector3{0, -10, 0} var cameraPos Vector3 = Vector3{0, -10, 0}
// radius, theta, phi // radius, theta, phi
@ -28,11 +30,11 @@ var screenPhysicalSize float64 = 5
func rayMarch(origin Vector3, direction Vector3) (bool, Vector3) { func rayMarch(origin Vector3, direction Vector3) (bool, Vector3) {
p := origin p := origin
for range MAX_STEP { for range MAX_STEP {
dist, color := scene.Distance(p) dist, mat := scene.Distance(p)
// fmt.Println(dist) // fmt.Println(dist)
if dist < EPS { if dist < EPS {
// fmt.Println("hit") // fmt.Println("hit")
return true, color.GetColor(p) return true, mat.diffuseColor.GetColor(p)
} }
if dist > MAX_DIST { if dist > MAX_DIST {
break break
@ -58,7 +60,7 @@ func genImage() *rl.Image {
sx := screenPhysicalSize * (float64(pixel_x)/WIDTH - 0.5) sx := screenPhysicalSize * (float64(pixel_x)/WIDTH - 0.5)
sy := screenPhysicalSize * (float64(pixel_y)/WIDTH - 0.5) sy := screenPhysicalSize * (float64(pixel_y)/WIDTH - 0.5)
origin := screenCenter.Add(theta_vec.Scale(-sx)).Add(phi_vec.Scale(-sy)) origin := screenCenter.Add(phi_vec.Scale(-sx)).Add(theta_vec.Scale(sy))
direction := (origin.Sub(cameraPos)).Normalized() direction := (origin.Sub(cameraPos)).Normalized()
// fmt.Println(origin, direction) // fmt.Println(origin, direction)
@ -88,42 +90,3 @@ func main() {
rl.EndDrawing() rl.EndDrawing()
} }
} }
// func main() {
// screenWidth := int32(800)
// screenHeight := int32(450)
// rl.InitWindow(screenWidth, screenHeight, "Bouncing Ball in Go - raylib")
// defer rl.CloseWindow()
// rl.SetTargetFPS(60)
// // Ball properties
// ballRadius := float32(20)
// ballPos := rl.NewVector2(float32(screenWidth)/2.0, float32(screenHeight)/2.0)
// ballSpeed := rl.NewVector2(4, 3)
// ballColor := rl.Red
// for !rl.WindowShouldClose() {
// // Update
// ballPos.X += ballSpeed.X
// ballPos.Y += ballSpeed.Y
// // Bounce on edges
// if ballPos.X >= float32(screenWidth)-ballRadius || ballPos.X <= ballRadius {
// ballSpeed.X *= -1
// }
// if ballPos.Y >= float32(screenHeight)-ballRadius || ballPos.Y <= ballRadius {
// ballSpeed.Y *= -1
// }
// // Draw
// rl.BeginDrawing()
// rl.ClearBackground(rl.RayWhite)
// rl.DrawText("Bouncing Ball Example", 10, 10, 20, rl.DarkGray)
// rl.DrawCircleV(ballPos, ballRadius, ballColor)
// rl.EndDrawing()
// }
// }

63
sdf.go
View file

@ -3,7 +3,7 @@ package main
import "math" import "math"
type SDF interface { type SDF interface {
Distance(Vector3) (float64, Color) Distance(Vector3) (float64, Material)
} }
func DistanceOnly(sdf SDF, p Vector3) float64 { func DistanceOnly(sdf SDF, p Vector3) float64 {
@ -25,7 +25,7 @@ type TranslatedSDF struct {
translate Vector3 translate Vector3
} }
func (s TranslatedSDF) Distance(p Vector3) (float64, Color) { func (s TranslatedSDF) Distance(p Vector3) (float64, Material) {
return s.primitive.Distance(p.Sub(s.translate)) return s.primitive.Distance(p.Sub(s.translate))
} }
@ -35,7 +35,7 @@ type RotatedSDF struct {
angle float64 angle float64
} }
func (s RotatedSDF) Distance(p Vector3) (float64, Color) { func (s RotatedSDF) Distance(p Vector3) (float64, Material) {
rotated_p := Rotate(p, s.rotVector, s.angle) rotated_p := Rotate(p, s.rotVector, s.angle)
return s.primitive.Distance(rotated_p) return s.primitive.Distance(rotated_p)
} }
@ -45,7 +45,7 @@ type ScaledSDF struct {
scale float64 scale float64
} }
func (s ScaledSDF) Distance(p Vector3) (float64, Color) { func (s ScaledSDF) Distance(p Vector3) (float64, Material) {
dist, color := s.primitive.Distance(p.Scale(1 / s.scale)) dist, color := s.primitive.Distance(p.Scale(1 / s.scale))
return dist * s.scale, color return dist * s.scale, color
} }
@ -55,7 +55,7 @@ type RepeatSDF struct {
cellSize Vector3 cellSize Vector3
} }
func (s RepeatSDF) Distance(p Vector3) (float64, Color) { func (s RepeatSDF) Distance(p Vector3) (float64, Material) {
x, y, z := p.Unpack() x, y, z := p.Unpack()
sx, sy, sz := s.cellSize.Unpack() sx, sy, sz := s.cellSize.Unpack()
round := math.RoundToEven round := math.RoundToEven
@ -68,7 +68,7 @@ type UnionSDF struct {
primitive2 SDF primitive2 SDF
} }
func (s UnionSDF) Distance(p Vector3) (float64, Color) { func (s UnionSDF) Distance(p Vector3) (float64, Material) {
d1, color1 := s.primitive1.Distance(p) d1, color1 := s.primitive1.Distance(p)
d2, color2 := s.primitive2.Distance(p) d2, color2 := s.primitive2.Distance(p)
d := math.Min(d1, d2) d := math.Min(d1, d2)
@ -85,7 +85,7 @@ type SubstractionSDF struct {
primitive2 SDF primitive2 SDF
} }
func (s SubstractionSDF) Distance(p Vector3) (float64, Color) { func (s SubstractionSDF) Distance(p Vector3) (float64, Material) {
d1, color1 := s.primitive1.Distance(p) d1, color1 := s.primitive1.Distance(p)
d2, _ := s.primitive2.Distance(p) d2, _ := s.primitive2.Distance(p)
@ -98,15 +98,14 @@ type IntersectionSDF struct {
primitive2 SDF primitive2 SDF
} }
func (s IntersectionSDF) Distance(p Vector3) (float64, Color) { func (s IntersectionSDF) Distance(p Vector3) (float64, Material) {
d1, color1 := s.primitive1.Distance(p) d1, mat1 := s.primitive1.Distance(p)
d2, color2 := s.primitive2.Distance(p) d2, mat2 := s.primitive2.Distance(p)
c1 := color1.GetColor(p)
c2 := color2.GetColor(p)
d := math.Max(d1, d2) d := math.Max(d1, d2)
color := c1.Add(c2).Scale(0.5)
return d, color mat := MixMat(mat1, mat2, 0.5, p)
return d, mat
} }
type SmoothUnionSDF struct { type SmoothUnionSDF struct {
@ -115,17 +114,15 @@ type SmoothUnionSDF struct {
k float64 k float64
} }
func (s SmoothUnionSDF) Distance(p Vector3) (float64, Color) { func (s SmoothUnionSDF) Distance(p Vector3) (float64, Material) {
k := 4 * s.k k := 4 * s.k
d1, color1 := s.primitive1.Distance(p) d1, mat1 := s.primitive1.Distance(p)
d2, color2 := s.primitive2.Distance(p) d2, mat2 := s.primitive2.Distance(p)
c1 := color1.GetColor(p)
c2 := color2.GetColor(p)
h := math.Max(k-math.Abs(d1-d2), 0.0) h := math.Max(k-math.Abs(d1-d2), 0.0)
d := math.Min(d1, d2) - h*h*0.25/k d := math.Min(d1, d2) - h*h*0.25/k
t := SmoothStep(d2-d1, -k, k) t := SmoothStep(d2-d1, -k, k)
color := Mix(c1, c2, t) mat := MixMat(mat1, mat2, t, p)
return d, color return d, mat
} }
type SmoothSubstractionSDF struct { type SmoothSubstractionSDF struct {
@ -134,17 +131,15 @@ type SmoothSubstractionSDF struct {
k float64 k float64
} }
func (s SmoothSubstractionSDF) Distance(p Vector3) (float64, Color) { func (s SmoothSubstractionSDF) Distance(p Vector3) (float64, Material) {
k := 4 * s.k k := 4 * s.k
d1, color1 := s.primitive1.Distance(p) d1, mat1 := s.primitive1.Distance(p)
d2, color2 := s.primitive2.Distance(p) d2, mat2 := s.primitive2.Distance(p)
c1 := color1.GetColor(p)
c2 := color2.GetColor(p)
h := math.Max(k-math.Abs(-d1-d2), 0.0) h := math.Max(k-math.Abs(-d1-d2), 0.0)
d := math.Max(-d1, d2) + h*h*0.25/k d := math.Max(-d1, d2) + h*h*0.25/k
t := SmoothStep(d2-d1, -k, k) t := SmoothStep(d2-d1, -k, k)
color := Mix(c1, c2, t) mat := MixMat(mat1, mat2, t, p)
return d, color return d, mat
} }
type SmoothIntersectionSDF struct { type SmoothIntersectionSDF struct {
@ -153,14 +148,12 @@ type SmoothIntersectionSDF struct {
k float64 k float64
} }
func (s SmoothIntersectionSDF) Distance(p Vector3) (float64, Color) { func (s SmoothIntersectionSDF) Distance(p Vector3) (float64, Material) {
k := 4 * s.k k := 4 * s.k
d1, color1 := s.primitive1.Distance(p) d1, mat1 := s.primitive1.Distance(p)
d2, color2 := s.primitive2.Distance(p) d2, mat2 := s.primitive2.Distance(p)
c1 := color1.GetColor(p)
c2 := color2.GetColor(p)
d := math.Max(k-math.Abs(d1-d2), 0.0) d := math.Max(k-math.Abs(d1-d2), 0.0)
t := SmoothStep(d2-d1, -k, k) t := SmoothStep(d2-d1, -k, k)
color := Mix(c1, c2, t) mat := MixMat(mat1, mat2, t, p)
return d, color return d, mat
} }