Add lighting
This commit is contained in:
@@ -45,6 +45,10 @@ type grot3dConfig struct {
|
||||
MaxAngleY float64 `json:"maxAngleY"` // Maximum rotation angle for Y axis (degrees)
|
||||
MinAngleZ float64 `json:"minAngleZ"` // Minimum rotation angle for Z axis (degrees)
|
||||
MaxAngleZ float64 `json:"maxAngleZ"` // Maximum rotation angle for Z axis (degrees)
|
||||
LightX float64 `json:"lightX"` // Light direction X component
|
||||
LightY float64 `json:"lightY"` // Light direction Y component
|
||||
LightZ float64 `json:"lightZ"` // Light direction Z component
|
||||
AmbientLight float64 `json:"ambientLight"` // Ambient light level (0-1)
|
||||
ViewWidth float64 `json:"viewWidth"` // SVG viewBox width
|
||||
ViewHeight float64 `json:"viewHeight"` // SVG viewBox height
|
||||
Perspective float64 `json:"perspective"` // Perspective distance (larger = less perspective)
|
||||
@@ -80,6 +84,7 @@ type triangleWithDepth struct {
|
||||
depth float64
|
||||
visible bool
|
||||
idx0, idx1, idx2 int
|
||||
normal point3d
|
||||
}
|
||||
|
||||
func (s *grot3dSim) GetState() simulationState {
|
||||
@@ -358,6 +363,7 @@ func (s *grot3dSim) generateSVG() string {
|
||||
idx0: idx0,
|
||||
idx1: idx1,
|
||||
idx2: idx2,
|
||||
normal: normal,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -389,14 +395,22 @@ func (s *grot3dSim) generateSVG() string {
|
||||
continue
|
||||
}
|
||||
|
||||
// Use depth for shading (closer = lighter)
|
||||
intensity := 0.5 + (tri.depth+150)/300*0.5
|
||||
if intensity < 0.5 {
|
||||
intensity = 0.5
|
||||
}
|
||||
if intensity > 1.0 {
|
||||
intensity = 1.0
|
||||
// Calculate lighting intensity
|
||||
// Normalize light direction
|
||||
lightDir := point3d{x: s.cfg.LightX, y: s.cfg.LightY, z: s.cfg.LightZ}
|
||||
lightMag := math.Sqrt(lightDir.x*lightDir.x + lightDir.y*lightDir.y + lightDir.z*lightDir.z)
|
||||
if lightMag > 0 {
|
||||
lightDir.x /= lightMag
|
||||
lightDir.y /= lightMag
|
||||
lightDir.z /= lightMag
|
||||
}
|
||||
|
||||
// Diffuse lighting (Lambert) - dot product of normal and light direction
|
||||
diffuse := math.Max(0, -(tri.normal.x*lightDir.x + tri.normal.y*lightDir.y + tri.normal.z*lightDir.z))
|
||||
|
||||
// Combine ambient and diffuse
|
||||
intensity := s.cfg.AmbientLight + (1.0-s.cfg.AmbientLight)*diffuse
|
||||
intensity = math.Max(0, math.Min(1, intensity))
|
||||
|
||||
// Get centroid UV
|
||||
uv0 := s.uvs[tri.idx0]
|
||||
@@ -494,6 +508,10 @@ func newGrot3dSimInfo() simulationInfo {
|
||||
data.NewField("maxAngleY", nil, []float64{45}),
|
||||
data.NewField("minAngleZ", nil, []float64{0}),
|
||||
data.NewField("maxAngleZ", nil, []float64{0}),
|
||||
data.NewField("lightX", nil, []float64{-1}),
|
||||
data.NewField("lightY", nil, []float64{-1}),
|
||||
data.NewField("lightZ", nil, []float64{1}),
|
||||
data.NewField("ambientLight", nil, []float64{0.3}),
|
||||
data.NewField("viewWidth", nil, []float64{800}),
|
||||
data.NewField("viewHeight", nil, []float64{800}),
|
||||
data.NewField("perspective", nil, []float64{1000}),
|
||||
@@ -512,6 +530,10 @@ func newGrot3dSimInfo() simulationInfo {
|
||||
MaxAngleY: 45,
|
||||
MinAngleZ: 0,
|
||||
MaxAngleZ: 0,
|
||||
LightX: -1,
|
||||
LightY: -1,
|
||||
LightZ: -1,
|
||||
AmbientLight: 0.3,
|
||||
ViewWidth: 800,
|
||||
ViewHeight: 800,
|
||||
Perspective: 1000,
|
||||
|
||||
Reference in New Issue
Block a user