@@ -13,12 +13,18 @@ public abstract class Light(GameObject gameObject, RszInstance data) : Component
1313 public bool IsEnabled => AppConfig . Instance . RenderLights . Get ( ) ;
1414
1515 protected Material ? _defaultLightGizmoMaterial ;
16+ protected Material ? _defaultLightGizmoMaterialInner ;
1617
1718 protected Material CreateLightMaterial ( RenderContext ctx ) => _defaultLightGizmoMaterial = ctx . GetMaterialBuilder ( BuiltInMaterials . MonoColor , "light" )
1819 . Color ( "_MainColor" , Colors . Lights )
1920 . Float ( "_FadeMaxDistance" , 250 )
2021 . Blend ( ) ;
2122
23+ protected Material CreateLightMaterialInner ( RenderContext ctx ) => _defaultLightGizmoMaterialInner = ctx . GetMaterialBuilder ( BuiltInMaterials . MonoColor , "light_inner" )
24+ . Color ( "_MainColor" , Colors . Lights with { W = Colors . Lights . W * 0.5f } )
25+ . Float ( "_FadeMaxDistance" , 250 )
26+ . Blend ( ) ;
27+
2228 public abstract GizmoContainer ? Update ( GizmoContainer ? gizmo ) ;
2329
2430 internal override void OnActivate ( )
@@ -41,16 +47,30 @@ public class SpotLight(GameObject gameObject, RszInstance data) : Light(gameObje
4147 public override GizmoContainer ? Update ( GizmoContainer ? gizmo )
4248 {
4349 gizmo ??= new GizmoContainer ( Scene ! , this ) ;
44- gizmo . PushMaterial ( _defaultLightGizmoMaterial ??= CreateLightMaterial ( Scene ! . RenderContext ) ) ;
4550
4651 var fwd = Transform . Forward ;
4752 var radius = RszFieldCache . SpotLight . Radius . GetOrDefault ( Data , 0.03f ) ;
4853 var range = RszFieldCache . SpotLight . ReferenceEffectiveRange . GetOrDefault ( Data , 10 ) ;
49- var spread = RszFieldCache . SpotLight . Spread . GetOrDefault ( Data , 50 ) ;
54+ var cone = RszFieldCache . SpotLight . Cone . GetOrDefault ( Data , 50 ) ;
55+ var spread = Math . Min ( cone , RszFieldCache . SpotLight . Spread . GetOrDefault ( Data , 50 ) ) ;
56+ // note: I assume spread and cone are for inner and outer cone respectively
57+ // inner being full intensity and then gradually 0 intensity until cone angle
58+
59+ // note2: the angle/distance calculation is probably wrong, very visibly when cone approaches 90
60+ // we're offsetting a circle instead of making an arc
61+
62+ if ( Math . Abs ( cone - 90f ) < 0.1f ) cone = 89.9f ;
5063
5164 var origin = Transform . Position ;
52- var endRadius = MathF . Tan ( spread / 180f * MathF . PI ) * range ;
53- gizmo . Add ( new Cone ( origin + fwd * radius , 0.001f , origin + fwd * range , endRadius ) ) ;
65+ var endRadiusCone = MathF . Tan ( cone / 180f * MathF . PI ) * range ;
66+ var endRadiusSpread = MathF . Tan ( spread / 180f * MathF . PI ) * range ;
67+
68+ gizmo . PushMaterial ( _defaultLightGizmoMaterial ??= CreateLightMaterial ( Scene ! . RenderContext ) ) ;
69+ gizmo . Add ( new Cone ( origin + fwd * radius , 0.001f , origin + fwd * range * Math . Sign ( endRadiusCone ) , Math . Abs ( endRadiusCone ) ) ) ;
70+ gizmo . PopMaterial ( ) ;
71+
72+ gizmo . PushMaterial ( _defaultLightGizmoMaterialInner ??= CreateLightMaterialInner ( Scene ! . RenderContext ) ) ;
73+ gizmo . Add ( new Cone ( origin + fwd * radius , 0.001f , origin + fwd * range * Math . Sign ( endRadiusSpread ) , Math . Abs ( endRadiusSpread ) ) ) ;
5474 gizmo . PopMaterial ( ) ;
5575 return gizmo ;
5676 }
0 commit comments