diff --git a/color.go b/color.go deleted file mode 100644 index 81e01ea..0000000 --- a/color.go +++ /dev/null @@ -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} diff --git a/material.go b/material.go new file mode 100644 index 0000000..966fc07 --- /dev/null +++ b/material.go @@ -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) diff --git a/primitives_sdf.go b/primitives_sdf.go index 4b78ee5..de9c14d 100644 --- a/primitives_sdf.go +++ b/primitives_sdf.go @@ -2,33 +2,33 @@ package main // Sphere type Sphere struct { - center Vector3 - radius float64 - color Color + center Vector3 + radius float64 + material Material } -func (s Sphere) Distance(p Vector3) (float64, Color) { - return p.Sub(s.center).Length() - s.radius, s.color +func (s Sphere) Distance(p Vector3) (float64, Material) { + return p.Sub(s.center).Length() - s.radius, s.material } // Box type Box struct { center 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) - 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 { - normal Vector3 - height float64 - color Color + normal Vector3 + height float64 + material Material } -func (s Plane) Distance(p Vector3) (float64, Color) { - return p.Dot(s.normal) + s.height, s.color +func (s Plane) Distance(p Vector3) (float64, Material) { + return p.Dot(s.normal) - s.height, s.material } diff --git a/ray_marching.go b/ray_marching.go index c589f53..888a5ec 100644 --- a/ray_marching.go +++ b/ray_marching.go @@ -1,5 +1,9 @@ package main +// RIGHT : x +// FORWARD : Y +// UP : Z + import ( "math" @@ -13,12 +17,10 @@ const WIDTH = 500 const HEIGHT = 500 const PI = math.Pi -// var sphere Sphere = Sphere{Vector3{0, 0, 100}, 10, RED} -// var plane Plane = Plane{Vector3{0, 1, 0}, -10, GREY} -// var scene UnionSDF = UnionSDF{sphere, plane} +var sphere Sphere = Sphere{Vector3{0, 100, 10}, 10, RED_MAT} +var plane Plane = Plane{Vector3{0, 0, 1}, -10, GREY_MAT} +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} // radius, theta, phi @@ -28,11 +30,11 @@ var screenPhysicalSize float64 = 5 func rayMarch(origin Vector3, direction Vector3) (bool, Vector3) { p := origin for range MAX_STEP { - dist, color := scene.Distance(p) + dist, mat := scene.Distance(p) // fmt.Println(dist) if dist < EPS { // fmt.Println("hit") - return true, color.GetColor(p) + return true, mat.diffuseColor.GetColor(p) } if dist > MAX_DIST { break @@ -58,7 +60,7 @@ func genImage() *rl.Image { sx := screenPhysicalSize * (float64(pixel_x)/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() // fmt.Println(origin, direction) @@ -88,42 +90,3 @@ func main() { 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() -// } -// } diff --git a/sdf.go b/sdf.go index 89f51d5..1603f6b 100644 --- a/sdf.go +++ b/sdf.go @@ -3,7 +3,7 @@ package main import "math" type SDF interface { - Distance(Vector3) (float64, Color) + Distance(Vector3) (float64, Material) } func DistanceOnly(sdf SDF, p Vector3) float64 { @@ -25,7 +25,7 @@ type TranslatedSDF struct { 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)) } @@ -35,7 +35,7 @@ type RotatedSDF struct { 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) return s.primitive.Distance(rotated_p) } @@ -45,7 +45,7 @@ type ScaledSDF struct { 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)) return dist * s.scale, color } @@ -55,7 +55,7 @@ type RepeatSDF struct { cellSize Vector3 } -func (s RepeatSDF) Distance(p Vector3) (float64, Color) { +func (s RepeatSDF) Distance(p Vector3) (float64, Material) { x, y, z := p.Unpack() sx, sy, sz := s.cellSize.Unpack() round := math.RoundToEven @@ -68,7 +68,7 @@ type UnionSDF struct { primitive2 SDF } -func (s UnionSDF) Distance(p Vector3) (float64, Color) { +func (s UnionSDF) Distance(p Vector3) (float64, Material) { d1, color1 := s.primitive1.Distance(p) d2, color2 := s.primitive2.Distance(p) d := math.Min(d1, d2) @@ -85,7 +85,7 @@ type SubstractionSDF struct { primitive2 SDF } -func (s SubstractionSDF) Distance(p Vector3) (float64, Color) { +func (s SubstractionSDF) Distance(p Vector3) (float64, Material) { d1, color1 := s.primitive1.Distance(p) d2, _ := s.primitive2.Distance(p) @@ -98,15 +98,14 @@ type IntersectionSDF struct { primitive2 SDF } -func (s IntersectionSDF) Distance(p Vector3) (float64, Color) { +func (s IntersectionSDF) Distance(p Vector3) (float64, Material) { - d1, color1 := s.primitive1.Distance(p) - d2, color2 := s.primitive2.Distance(p) - c1 := color1.GetColor(p) - c2 := color2.GetColor(p) + d1, mat1 := s.primitive1.Distance(p) + d2, mat2 := s.primitive2.Distance(p) 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 { @@ -115,17 +114,15 @@ type SmoothUnionSDF struct { k float64 } -func (s SmoothUnionSDF) Distance(p Vector3) (float64, Color) { +func (s SmoothUnionSDF) Distance(p Vector3) (float64, Material) { k := 4 * s.k - d1, color1 := s.primitive1.Distance(p) - d2, color2 := s.primitive2.Distance(p) - c1 := color1.GetColor(p) - c2 := color2.GetColor(p) + d1, mat1 := s.primitive1.Distance(p) + d2, mat2 := s.primitive2.Distance(p) h := math.Max(k-math.Abs(d1-d2), 0.0) d := math.Min(d1, d2) - h*h*0.25/k t := SmoothStep(d2-d1, -k, k) - color := Mix(c1, c2, t) - return d, color + mat := MixMat(mat1, mat2, t, p) + return d, mat } type SmoothSubstractionSDF struct { @@ -134,17 +131,15 @@ type SmoothSubstractionSDF struct { k float64 } -func (s SmoothSubstractionSDF) Distance(p Vector3) (float64, Color) { +func (s SmoothSubstractionSDF) Distance(p Vector3) (float64, Material) { k := 4 * s.k - d1, color1 := s.primitive1.Distance(p) - d2, color2 := s.primitive2.Distance(p) - c1 := color1.GetColor(p) - c2 := color2.GetColor(p) + d1, mat1 := s.primitive1.Distance(p) + d2, mat2 := s.primitive2.Distance(p) h := math.Max(k-math.Abs(-d1-d2), 0.0) d := math.Max(-d1, d2) + h*h*0.25/k t := SmoothStep(d2-d1, -k, k) - color := Mix(c1, c2, t) - return d, color + mat := MixMat(mat1, mat2, t, p) + return d, mat } type SmoothIntersectionSDF struct { @@ -153,14 +148,12 @@ type SmoothIntersectionSDF struct { k float64 } -func (s SmoothIntersectionSDF) Distance(p Vector3) (float64, Color) { +func (s SmoothIntersectionSDF) Distance(p Vector3) (float64, Material) { k := 4 * s.k - d1, color1 := s.primitive1.Distance(p) - d2, color2 := s.primitive2.Distance(p) - c1 := color1.GetColor(p) - c2 := color2.GetColor(p) + d1, mat1 := s.primitive1.Distance(p) + d2, mat2 := s.primitive2.Distance(p) d := math.Max(k-math.Abs(d1-d2), 0.0) t := SmoothStep(d2-d1, -k, k) - color := Mix(c1, c2, t) - return d, color + mat := MixMat(mat1, mat2, t, p) + return d, mat }