diff --git a/samples/03_model_render/model_loader.cpp b/samples/03_model_render/model_loader.cpp index 7748c33..93ee771 100644 --- a/samples/03_model_render/model_loader.cpp +++ b/samples/03_model_render/model_loader.cpp @@ -679,7 +679,7 @@ Nodes::Add(const mat4 &transform, const i32 parent) m_Dirty = true; const u32 index = Count(); m_Transforms.push_back(transform); - m_GlobalTransforms.push_back(transform); + m_GlobalTransforms.emplace_back(transform); const u32 parentVal = (parent < 0 ? ROOT_BIT : parent & PARENT_MASK) | DIRTY_BIT; m_Parents_.push_back(parentVal); @@ -726,7 +726,7 @@ Nodes::GetGlobalTransformByteSize() const return m_GlobalTransforms.size() * sizeof m_GlobalTransforms[0]; } -const mat4 * +const Nodes::Transform * Nodes::GetGlobalTransformPtr() const { return m_GlobalTransforms.data(); @@ -763,7 +763,7 @@ Nodes::Update() if (isDirty || isParentDirty) { // Update w.r.t parent if either local or parent transforms updated. - *globalTransformIter = m_GlobalTransforms[parentIdx] * *transformIter; + *globalTransformIter = m_GlobalTransforms[parentIdx].m_GlobalTransforms * *transformIter; m_Parents_[parentIdx] |= DIRTY_BIT; // Set dirty to propagate the update. } } diff --git a/samples/03_model_render/model_loader.h b/samples/03_model_render/model_loader.h index 6ab9dfe..c51adb8 100644 --- a/samples/03_model_render/model_loader.h +++ b/samples/03_model_render/model_loader.h @@ -29,8 +29,28 @@ struct MeshPrimitive struct Nodes { + struct Transform + { + mat4 m_GlobalTransforms; + mat4 m_NormalTransforms; + + explicit Transform(const mat4& transform) + : m_GlobalTransforms(transform) + , m_NormalTransforms(transpose(inverse(mat3{transform}))) + { + } + + Transform & + operator=(const mat4& transform) + { + m_GlobalTransforms = transform; + m_NormalTransforms = transpose(inverse(mat3{transform})); + return *this; + } + }; + eastl::vector m_Transforms; - eastl::vector m_GlobalTransforms; + eastl::vector m_GlobalTransforms; /// Parents are also used for bookkeeping eastl::vector m_Parents_; bool m_Dirty = true; @@ -48,7 +68,7 @@ struct Nodes [[nodiscard]] mat4 &operator[](const u32 index); [[nodiscard]] usize GetGlobalTransformByteSize() const; - [[nodiscard]] const mat4 *GetGlobalTransformPtr() const; + [[nodiscard]] const Transform *GetGlobalTransformPtr() const; bool Update(); }; diff --git a/samples/03_model_render/model_render.cpp b/samples/03_model_render/model_render.cpp index 6c2f77a..cafc019 100644 --- a/samples/03_model_render/model_render.cpp +++ b/samples/03_model_render/model_render.cpp @@ -27,7 +27,7 @@ #include constexpr u32 MAX_FRAMES_IN_FLIGHT = 3; -constexpr auto MODEL_FILE = "model/OrientationTest.glb"; +constexpr auto MODEL_FILE = "model/DamagedHelmet.glb"; struct Camera { @@ -79,7 +79,7 @@ main(int, char **) Pipeline pipeline = CreatePipeline(&device, &swapchain, &resourceManager); Camera camera = { - .m_View = glm::lookAt(vec3(0.0f, 12.0f, 12.0f), vec3(0.0f), vec3(0.0f, 1.0f, 0.0f)), + .m_View = glm::lookAt(vec3(0.0f, 2.0f, 2.0f), vec3(0.0f), vec3(0.0f, 1.0f, 0.0f)), .m_Perspective = glm::perspective( 70_deg, Cast(swapchain.m_Extent.width) / Cast(swapchain.m_Extent.height), 0.1f, 100.0f), }; diff --git a/samples/03_model_render/shader/bindless_structs.hlsli b/samples/03_model_render/shader/bindless_structs.hlsli index fe8925b..c173363 100644 --- a/samples/03_model_render/shader/bindless_structs.hlsli +++ b/samples/03_model_render/shader/bindless_structs.hlsli @@ -10,6 +10,7 @@ struct VertexData struct TransformData { float4x4 transform; + float4x4 normalTransform; }; struct MaterialData diff --git a/samples/03_model_render/shader/model.ps.hlsl b/samples/03_model_render/shader/model.ps.hlsl index 68138c6..f7a70d2 100644 --- a/samples/03_model_render/shader/model.ps.hlsl +++ b/samples/03_model_render/shader/model.ps.hlsl @@ -3,6 +3,7 @@ struct FS_Input { float4 inPosition : POSITION; + float4 inNormal : NORMAL; float4 inColor : COLOR0; float2 inUV : TEXCOORD0; }; @@ -12,16 +13,6 @@ struct FS_Output float4 outColor : SV_Target0; }; -float4 ArrayToVector(float arr[4]) -{ - return float4(arr[0], arr[1], arr[2], arr[3]); -} - -float4 ArrayToVector(float4 arr) -{ - return arr; -} - float4 GetAlbedo(uint materialBufferId, int materialId, float2 uv) { uint albedoTexId = materialsBuffer[materialBufferId][materialId].m_AlbedoTex; @@ -37,7 +28,22 @@ float4 GetAlbedo(uint materialBufferId, int materialId, float2 uv) FS_Output main(FS_Input stage_input) { + + // Hereby assume that we always have a point light at + float3 lightPos = float3(6.0f, 6.0f, 6.0f); + // with + float3 lightColor = float3(0.7f, 0.7f, 0.7f); //float3(0.7f, 0.4f, 0.1f); + // and + float3 ambient = float3(0.02f, 0.02f, 0.02f); + + float3 norm = normalize(stage_input.inNormal.xyz); + float3 lightDir = normalize(lightPos - stage_input.inPosition.xyz); + float diff = max(dot(norm, lightDir), 0.0f); + float3 diffuse = diff * lightColor; + + float4 objColor = pcb.m_MaterialIdx < 0 ? stage_input.inColor : GetAlbedo(pcb.materialBufferHandle, pcb.m_MaterialIdx, stage_input.inUV); + FS_Output output; - output.outColor = pcb.m_MaterialIdx < 0 ? stage_input.inColor : GetAlbedo(pcb.materialBufferHandle, pcb.m_MaterialIdx, stage_input.inUV); + output.outColor = float4(objColor.rgb * (diffuse + ambient), objColor.a); return output; } diff --git a/samples/03_model_render/shader/model.vs.hlsl b/samples/03_model_render/shader/model.vs.hlsl index 701b38f..ad70a35 100644 --- a/samples/03_model_render/shader/model.vs.hlsl +++ b/samples/03_model_render/shader/model.vs.hlsl @@ -7,10 +7,11 @@ struct VS_Input struct VS_Output { - float4 outPosition : POSITION; + float4 worldPosition : POSITION; + float4 worldNormal : NORMAL; float4 outColor : COLOR0; float2 outUV : TEXCOORD0; - float4 position : SV_Position; + float4 screenPosition : SV_Position; }; float2 GetUV(uint vertexIdx) @@ -25,27 +26,42 @@ float4 GetPosition(uint vertexIdx) return float4(vertexBuffer[bufferId][vertexIdx].xyz, 1.0f); } +float4 GetNormal(uint vertexIdx) +{ + uint bufferId = pcb.vertexDataHandle; + return vertexDataBuffer[bufferId][vertexIdx].m_Normal; +} + float4 GetColor(uint vertexIdx) { uint bufferId = pcb.vertexDataHandle; return vertexDataBuffer[bufferId][vertexIdx].m_Color0; } -float4x4 GetModel(uint index) +float4x4 GetModelTransform(uint index) { uint bufferId = pcb.nodeBufferHandle; return nodeBuffer[bufferId][index].transform; } +float4x4 GetNormalTransform(uint index) +{ + uint bufferId = pcb.nodeBufferHandle; + return nodeBuffer[bufferId][index].normalTransform; +} + VS_Output main(VS_Input stage_input) { VS_Output output; - output.outPosition = GetPosition(stage_input.vertexIndex); + + float4 globalPosition = mul(GetModelTransform(pcb.m_NodeIdx), GetPosition(stage_input.vertexIndex)); + float4 clipSpace = mul(camera.view, globalPosition); + + output.screenPosition = mul(camera.proj, clipSpace); + output.worldPosition = globalPosition; output.outUV = GetUV(stage_input.vertexIndex); output.outColor = GetColor(stage_input.vertexIndex); - float4 globalPosition = mul(GetModel(pcb.m_NodeIdx), GetPosition(stage_input.vertexIndex)); - float4 clipSpace = mul(camera.view, globalPosition); - output.position = mul(camera.proj, clipSpace); + output.worldNormal = mul(GetNormalTransform(pcb.m_NodeIdx), GetNormal(stage_input.vertexIndex)); return output; }