feat: dynamic point light on a physics ball — falls and illuminates
- LightBall entity: sphere mesh + DynamicSphere physics + Light.Point - Renderer reads light position from Transform (not static Light.Position) so the light moves with the physics body - Light intensity 20, range 30, warm color (1.0, 0.9, 0.7) - Ball falls from y=15, bounces on floor, light follows it - Renderer: prefers Light+Transform pair for dynamic position, falls back to Light only
This commit is contained in:
@@ -268,6 +268,13 @@ class Program
|
|||||||
.Set(new Transform(new Vector3(0, 8, 0), Quaternion.Identity, Vector3.One))
|
.Set(new Transform(new Vector3(0, 8, 0), Quaternion.Identity, Vector3.One))
|
||||||
.Set(Light.Point(new Vector3(0, 8, 0), new Vector3(1.0f, 0.9f, 0.7f), intensity: 15.0f, range: 25.0f));
|
.Set(Light.Point(new Vector3(0, 8, 0), new Vector3(1.0f, 0.9f, 0.7f), intensity: 15.0f, range: 25.0f));
|
||||||
|
|
||||||
|
var lightSphere = ProceduralMesh.CreateSphere(0.5f, 24, 12, new Vector3(1.0f, 0.9f, 0.7f));
|
||||||
|
world.Entity("LightBall")
|
||||||
|
.Set(new Transform(new Vector3(0, 15, 0), Quaternion.Identity, Vector3.One))
|
||||||
|
.Set(lightSphere)
|
||||||
|
.Set(RigidBody.DynamicSphere(0.5f, mass: 0.5f))
|
||||||
|
.Set(Light.Point(new Vector3(0, 15, 0), new Vector3(1.0f, 0.9f, 0.7f), intensity: 20.0f, range: 30.0f));
|
||||||
|
|
||||||
var entityCount = 0;
|
var entityCount = 0;
|
||||||
world.Each((Entity e, ref Transform _) => entityCount++);
|
world.Each((Entity e, ref Transform _) => entityCount++);
|
||||||
Console.WriteLine($"[Scene] {entityCount} entities: torus knot + 4 dynamic cubes + 3 dynamic spheres + static floor + grid");
|
Console.WriteLine($"[Scene] {entityCount} entities: torus knot + 4 dynamic cubes + 3 dynamic spheres + static floor + grid");
|
||||||
|
|||||||
@@ -77,17 +77,28 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
|
|||||||
vp = Matrix4x4.CreateLookAt(new Vector3(0, 0, -6), Vector3.Zero, Vector3.UnitY) * proj;
|
vp = Matrix4x4.CreateLookAt(new Vector3(0, 0, -6), Vector3.Zero, Vector3.UnitY) * proj;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect point light from ECS (first point light found)
|
// Collect point light from ECS — prefer light attached to a moving entity
|
||||||
var lightPos = new Vector4(0, 5, 0, 0);
|
var lightPos = new Vector4(0, 5, 0, 0);
|
||||||
var lightColor = new Vector4(1, 1, 1, 0);
|
var lightColor = new Vector4(1, 1, 1, 0);
|
||||||
world.Each((Entity e, ref Light l) =>
|
world.Each((Entity e, ref Light l, ref Transform lt) =>
|
||||||
{
|
{
|
||||||
if (l.IsPoint && lightPos.W == 0)
|
if (l.IsPoint && lightPos.W == 0)
|
||||||
{
|
{
|
||||||
lightPos = new Vector4(l.Position, l.Intensity);
|
lightPos = new Vector4(lt.Position, l.Intensity);
|
||||||
lightColor = new Vector4(l.Color, l.Range);
|
lightColor = new Vector4(l.Color, l.Range);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (lightPos.W == 0)
|
||||||
|
{
|
||||||
|
world.Each((Entity e, ref Light l) =>
|
||||||
|
{
|
||||||
|
if (l.IsPoint && lightPos.W == 0)
|
||||||
|
{
|
||||||
|
lightPos = new Vector4(l.Position, l.Intensity);
|
||||||
|
lightColor = new Vector4(l.Color, l.Range);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Pack UBO: mat4 vp (64 bytes) + vec4 lightPos (16) + vec4 lightColor (16) = 96 bytes
|
// Pack UBO: mat4 vp (64 bytes) + vec4 lightPos (16) + vec4 lightColor (16) = 96 bytes
|
||||||
var uboData = stackalloc byte[128];
|
var uboData = stackalloc byte[128];
|
||||||
|
|||||||
Reference in New Issue
Block a user