Skip to content

Commit 867fc89

Browse files
committed
Improve spotlight cone visualization
1 parent 71736c7 commit 867fc89

File tree

1 file changed

+24
-4
lines changed
  • ContentEditor.App/EngineObjects/Components

1 file changed

+24
-4
lines changed

ContentEditor.App/EngineObjects/Components/Light.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)