struct VSInput { float3 Position : POSITION0; float3 Normal : NORMAL0; float3 Texture : TEXCOORD0; }; struct VSOutput { float4 Position : SV_POSITION; float3 Normal : NORMAL0; float2 Texture : TEXCOORD0; float3 LightDirection : NORMAL1; float3 ViewDirection : NORMAL2; }; struct ShaderData { float4x4 Transform; float4x4 ModelView; float4 LightPosition; // view space uint32_t Selected; }; [[vk::binding(0, 0)]] ConstantBuffer data; [[vk::binding(0, 1)]] SamplerState samplers[2]; [[vk::binding(1, 1)]] Texture2D texture; struct PushConstant { int SamplerIndex; }; [[vk::push_constant]] struct PushConstant constants; [shader("vertex")] VSOutput VSMain(VSInput input) { VSOutput output = (VSOutput)0; output.Position = mul(data.Transform, float4(input.Position.xyz, 1.0)); output.Normal = mul((float3x3)data.ModelView, input.Normal); output.Texture = input.Texture.xy * 1.0; float4 viewPosition = mul(data.ModelView, float4(input.Position.xyz, 1.0)); output.LightDirection = (data.LightPosition - viewPosition).xyz; output.ViewDirection = -viewPosition.xyz; return output; } [shader("pixel")] float4 PSMain(VSOutput input) : SV_TARGET { float3 color = texture.Sample(samplers[constants.SamplerIndex], input.Texture).bgr; 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); diffuse = 1.0; specular = 0.0; return float4(diffuse * color + specular, 1.0); } struct VSOutlineOutput { float4 Position : SV_POSITION; }; [shader("vertex")] VSOutlineOutput VSOutlineMain(VSInput input) { VSOutlineOutput output = (VSOutlineOutput)0; float3 position = input.Position.xyz + input.Normal.xyz * 0.01; output.Position = mul(data.Transform, float4(position, 1.0)); return output; } [shader("pixel")] float4 PSOutlineMain(VSOutlineOutput input) : SV_TARGET { return float4(1.0, 1.0, 1.0, 1.0); }