From 256969454f407860ff453a1402feb0769817a3c5 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Tue, 7 Apr 2026 18:54:28 -0500 Subject: [PATCH] phong lighting --- shader/triangle.hlsl | 37 +++++++++++++++++++++++++------------ src/main.cpp | 22 +++++++++++++--------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/shader/triangle.hlsl b/shader/triangle.hlsl index eea69e3..a9b7139 100644 --- a/shader/triangle.hlsl +++ b/shader/triangle.hlsl @@ -10,15 +10,16 @@ struct VSOutput float4 Position : SV_POSITION; float3 Normal : NORMAL0; float2 Texture : TEXCOORD0; + float3 LightDirection : NORMAL1; + float3 ViewDirection : NORMAL2; }; struct ShaderData { - float4x4 Projection; - float4x4 View; - float4x4 Model; - float4 lightPosition; - uint32_t selected; + float4x4 Transform; + float4x4 ModelView; + float4 LightPosition; // view space + uint32_t Selected; }; struct PushConstant { @@ -35,10 +36,14 @@ struct PushConstant constants; VSOutput VSMain(VSInput input) { VSOutput output = (VSOutput)0; - output.Position = mul(constants.data.Get().Projection, mul(constants.data.Get().View, mul(constants.data.Get().Model, float4(input.Position.xyz, 1.0)))); - //output.Normal = mul((float3x3)constants.data.Get().Model, input.Normal); - output.Normal = input.Normal * 0.5 + 0.5; + output.Position = mul(constants.data.Get().Transform, float4(input.Position.xyz, 1.0)); + output.Normal = mul((float3x3)constants.data.Get().ModelView, input.Normal); output.Texture = input.Texture.xy; + + float4 viewPosition = mul(constants.data.Get().ModelView, float4(input.Position.xyz, 1.0)); + output.LightDirection = (constants.data.Get().LightPosition - viewPosition).xyz; + output.ViewDirection = -viewPosition.xyz; + return output; } @@ -47,13 +52,22 @@ float4 PSMain(VSOutput input) : SV_TARGET { float3 color = textures[0].Sample(samplers[0], input.Texture).bgr; - return float4(color, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightDirection); + float3 V = normalize(input.ViewDirection); + float3 R = reflect(-L, N); + + const float a = 16.0; + const float specularIntensity = 0.8; + float3 specular = pow(max(dot(R, V), 0), a) * specularIntensity; + float3 diffuse = max(dot(N, L), 0.001); + + return float4(diffuse * color + specular, 1.0); } struct VSOutlineOutput { float4 Position : SV_POSITION; - float3 Normal : NORMAL0; }; [shader("vertex")] @@ -61,8 +75,7 @@ VSOutlineOutput VSOutlineMain(VSInput input) { VSOutlineOutput output = (VSOutlineOutput)0; float3 position = input.Position.xyz + input.Normal.xyz * 0.01; - output.Position = mul(constants.data.Get().Projection, mul(constants.data.Get().View, mul(constants.data.Get().Model, float4(position, 1.0)))); - output.Normal = input.Normal; + output.Position = mul(constants.data.Get().Transform, float4(position, 1.0)); return output; } diff --git a/src/main.cpp b/src/main.cpp index 27ffe21..dad2b8b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -129,12 +129,10 @@ VkDescriptorSet textureDescriptorSet{ VK_NULL_HANDLE }; XMINT2 windowSize{}; struct ShaderData { - XMFLOAT4X4 projection; - XMFLOAT4X4 view; - XMFLOAT4X4 model; - //XMFLOAT4X4 model[3]; - XMFLOAT4 lightPosition{ 0.0f, -10.0f, 10.0f, 0.0f }; - uint32_t selected{ 1 }; + XMFLOAT4X4 transform; + XMFLOAT4X4 modelView; + XMFLOAT4 lightPosition; + uint32_t selected; }; ShaderData shaderData{}; @@ -1191,9 +1189,15 @@ int main() VK_CHECK_SWAPCHAIN(vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, presentSemaphores[frameIndex], VK_NULL_HANDLE, &imageIndex)); // shader data - XMStoreFloat4x4(&shaderData.projection, currentProjection()); - XMStoreFloat4x4(&shaderData.view, currentView()); - XMStoreFloat4x4(&shaderData.model, currentModel()); + XMMATRIX model = currentModel(); + XMMATRIX view = currentView(); + XMMATRIX modelView = model * view; + XMMATRIX transform = modelView * currentProjection(); + XMStoreFloat4x4(&shaderData.transform, transform); + XMStoreFloat4x4(&shaderData.modelView, modelView); + XMVECTOR lightPosition = XMVector3Transform(XMVectorSet(-3, -3, 0, 0), view); + XMStoreFloat4(&shaderData.lightPosition, lightPosition); + size_t frameOffset = shaderDataDevice.stride * frameIndex; void * frameData = (void *)(((VkDeviceSize)shaderDataDevice.mappedData) + frameOffset); VkDeviceSize frameSize{ (sizeof (ShaderData)) };