feat: materials, floor grid, specular lighting, orbit camera
- Add Material component with Albedo, Roughness, Metallic. - MeshRenderer reads Material and tints vertex color; falls back to default. - Add Blinn-Phong specular using camera position pushed via push constants. - Add floor plane and grid mesh in Program.cs. - Add OrbitCameraController with right-mouse orbit and mouse-wheel zoom. - Forward SDL events to InputMapping from Sdl3Window.PumpEvents. - Update main loop to update camera and aspect ratio on resize. - Recompile SPIR-V shaders. - Update CORTEX_ENGINE_ARCHITECTURE.md with Material, lighting, and orbit camera.
This commit is contained in:
@@ -38,6 +38,8 @@ public sealed unsafe class MeshRenderer : IDisposable
|
||||
public float Pad2;
|
||||
public Vector3 AmbientColor;
|
||||
public float Pad3;
|
||||
public Vector3 CameraPosition;
|
||||
public float Pad4;
|
||||
}
|
||||
|
||||
private sealed class MeshBuffers : IDisposable
|
||||
@@ -201,19 +203,19 @@ public sealed unsafe class MeshRenderer : IDisposable
|
||||
_buffers[e] = buffers;
|
||||
}
|
||||
|
||||
var bytes = BuildMeshVertices(mesh, transform);
|
||||
var material = e.Has<Material>() ? e.Get<Material>() : Material.Default;
|
||||
var bytes = BuildMeshVertices(mesh, transform, material);
|
||||
buffers.VertexBuffer.Update(bytes);
|
||||
|
||||
var model = transform.GetMatrix();
|
||||
var mvp = Matrix4x4.Multiply(Matrix4x4.Multiply(model, view), proj);
|
||||
var mvpT = Matrix4x4.Transpose(mvp);
|
||||
var mvp = Matrix4x4.Transpose(Matrix4x4.Multiply(view, proj));
|
||||
|
||||
var push = new PushConstants
|
||||
{
|
||||
Mvp = mvpT,
|
||||
Mvp = mvp,
|
||||
LightDirection = new Vector3(0.5f, -1.0f, -0.5f),
|
||||
LightColor = new Vector3(1.0f, 0.95f, 0.8f),
|
||||
AmbientColor = new Vector3(0.15f, 0.15f, 0.2f)
|
||||
AmbientColor = new Vector3(0.15f, 0.15f, 0.2f),
|
||||
CameraPosition = camera.Position
|
||||
};
|
||||
|
||||
var pushSize = (uint)sizeof(PushConstants);
|
||||
@@ -306,7 +308,7 @@ public sealed unsafe class MeshRenderer : IDisposable
|
||||
new IndexBuffer(_context, indexBytes, (uint)mesh.Indices.Length));
|
||||
}
|
||||
|
||||
private byte[] BuildMeshVertices(Mesh mesh, Transform transform)
|
||||
private byte[] BuildMeshVertices(Mesh mesh, Transform transform, Material material)
|
||||
{
|
||||
var matrix = transform.GetMatrix();
|
||||
var bytes = new byte[mesh.Vertices.Length * 9 * sizeof(float)];
|
||||
@@ -316,14 +318,15 @@ public sealed unsafe class MeshRenderer : IDisposable
|
||||
for (var i = 0; i < mesh.Vertices.Length; i++)
|
||||
{
|
||||
var v = mesh.Vertices[i];
|
||||
var transformed = Vector3.Transform(v.Position, matrix);
|
||||
var worldPos = Vector3.Transform(v.Position, matrix);
|
||||
var normal = transform.TransformNormal(v.Normal);
|
||||
dst[i * 9 + 0] = transformed.X;
|
||||
dst[i * 9 + 1] = transformed.Y;
|
||||
dst[i * 9 + 2] = transformed.Z;
|
||||
dst[i * 9 + 3] = v.Color.X;
|
||||
dst[i * 9 + 4] = v.Color.Y;
|
||||
dst[i * 9 + 5] = v.Color.Z;
|
||||
var color = v.Color * material.Albedo;
|
||||
dst[i * 9 + 0] = worldPos.X;
|
||||
dst[i * 9 + 1] = worldPos.Y;
|
||||
dst[i * 9 + 2] = worldPos.Z;
|
||||
dst[i * 9 + 3] = color.X;
|
||||
dst[i * 9 + 4] = color.Y;
|
||||
dst[i * 9 + 5] = color.Z;
|
||||
dst[i * 9 + 6] = normal.X;
|
||||
dst[i * 9 + 7] = normal.Y;
|
||||
dst[i * 9 + 8] = normal.Z;
|
||||
|
||||
@@ -15,17 +15,24 @@ layout(push_constant) uniform PushConstants
|
||||
float pad2;
|
||||
vec3 ambientColor;
|
||||
float pad3;
|
||||
vec3 cameraPosition;
|
||||
float pad4;
|
||||
} push;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 normal = normalize(fragNormal);
|
||||
vec3 lightDir = normalize(-push.lightDirection);
|
||||
vec3 viewDir = normalize(push.cameraPosition - fragWorldPos);
|
||||
vec3 halfDir = normalize(lightDir + viewDir);
|
||||
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
float spec = pow(max(dot(normal, halfDir), 0.0), 64.0) * 0.5;
|
||||
|
||||
vec3 diffuse = push.lightColor * diff;
|
||||
vec3 specular = push.lightColor * spec;
|
||||
vec3 ambient = push.ambientColor;
|
||||
|
||||
vec3 result = (ambient + diffuse) * fragColor;
|
||||
vec3 result = (ambient + diffuse + specular) * fragColor;
|
||||
outColor = vec4(result, 1.0);
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -17,6 +17,8 @@ layout(push_constant) uniform PushConstants
|
||||
float pad2;
|
||||
vec3 ambientColor;
|
||||
float pad3;
|
||||
vec3 cameraPosition;
|
||||
float pad4;
|
||||
} push;
|
||||
|
||||
void main()
|
||||
|
||||
@@ -59,7 +59,7 @@ public sealed unsafe class VulkanPipeline : IDisposable
|
||||
{
|
||||
StageFlags = ShaderStageFlags.VertexBit | ShaderStageFlags.FragmentBit,
|
||||
Offset = 0,
|
||||
Size = (uint)(28 * sizeof(float))
|
||||
Size = (uint)(32 * sizeof(float))
|
||||
};
|
||||
|
||||
var createInfo = new PipelineLayoutCreateInfo
|
||||
|
||||
Reference in New Issue
Block a user