I have shader for geometry pass and for light pass, I understand theory how it should works, but when I try to implement this, my brain explode. Could some one explain me how could I implement shadows from my directional light here ?
******************** GEOMETRY SHADER *************************cbuffer ProjectionBuffer : register(b0){ matrix projectionMatrix;};
cbuffer ViewBuffer : register(b1){ matrix viewMatrix;};
cbuffer WorldBuffer : register(b2){ matrix worldMatrix;};
struct VSInput{ float3 Position : POSITION; float2 TexCoord : TEXCOORD; float3 Normal : NORMAL; float3 Tangent : TANGENT;};
struct VSOutput{ float4 Position : SV_Position; float2 TexCoord : TEXCOORD; float3 WorldPos : WORLD_POS; float3 Normal : NORMAL; float3 Tangent : TANGENT;};
VSOutput main(VSInput input){ VSOutput output;
float4 worldPos = mul(float4(input.Position, 1.0f), worldMatrix); float4 viewPos = mul(worldPos, viewMatrix); output.Position = mul(viewPos, projectionMatrix);
output.WorldPos = worldPos.xyz; output.Normal = mul((float3x3)worldMatrix, input.Normal); output.Tangent = mul((float3x3)worldMatrix, input.Tangent); output.TexCoord = input.TexCoord;
return output;}
*******************************************************cbuffer AmbientLight : register(b1){ float3 ambientLight; float padding;};
Texture2D myTexture : register(t0);SamplerState samplerState : register(s0);
struct PSInput{ float4 Position : SV_Position; float2 TexCoord : TEXCOORD; float3 WorldPos : WORLD_POS; float3 Normal : NORMAL; float3 Tangent : TANGENT;};
struct PSOutput{ float4 Diffuse : SV_Target0; float4 Normal : SV_Target1; float4 Position : SV_Target2; float4 Plane : SV_Target3;};
PSOutput main(PSInput input){ PSOutput output;
output.Diffuse = myTexture.Sample(samplerState, input.TexCoord) * float4(ambientLight, 1.0f);
output.Normal = float4(normalize(input.Normal), 1.0);
output.Position = float4(input.WorldPos, 1.0);
return output;}
***************** LIGHT SHADER **************struct VSInput{ float3 Position : POSITION; float2 TexCoord : TEXCOORD;};
struct VSOutput{ float4 Position : SV_Position; float2 TexCoord : TEXCOORD;};
VSOutput main(VSInput input){ VSOutput output; output.Position = float4(input.Position, 1.0); output.TexCoord = input.TexCoord; return output;}
***********************************************struct Light{ int Type; float3 Position; float3 Direction; float3 Color; float Intensity; float Range; float SpotAngle;};
struct DirectionalLight{ float3 Direction; float Intensity; float3 Color; float Padding;};
StructuredBuffer<Light> Lights : register(t4);cbuffer LightInfo : register(b0){ int LightCount; int align[3];};
cbuffer DirectionalLight : register(b2){ DirectionalLight directionalLight;};
float3 CalculateDirectionalLight(DirectionalLight directionalLight, float3 normal){ float3 lightDir = normalize(-directionalLight.Direction); float diff = max(dot(normal, lightDir), 0.0); return directionalLight.Color * diff * directionalLight.Intensity;}
float3 CalculatePointLight(Light light, float3 worldPos, float3 normal){ float3 lightDir = light.Position - worldPos; float distance = length(lightDir); lightDir = normalize(lightDir);
float diff = max(dot(normal, lightDir), 0.0); float attenuation = 1.0 / (distance * distance + 1e-4);
if (distance < light.Range) { return light.Color * diff * attenuation * light.Intensity; } return float3(0, 0, 0);}
float3 CalculateSpotLight(Light light, float3 worldPos, float3 normal){ float3 lightDir = light.Position - worldPos; float distance = length(lightDir); lightDir = normalize(lightDir);
float theta = dot(lightDir, normalize(-light.Direction)); float epsilon = cos(radians(light.SpotAngle) * 0.5);
if (theta > epsilon && distance < light.Range) { float diff = max(dot(normal, lightDir), 0.0); float attenuation = 1.0 / (distance * distance + 1e-4); float spotEffect = smoothstep(epsilon, 1.0, theta);
return light.Color * diff * attenuation * spotEffect * light.Intensity; } return float3(0, 0, 0);}
Texture2D DiffuseTexture : register(t0);Texture2D NormalTexture : register(t1);Texture2D PositionTexture : register(t2);SamplerState samplerState : register(s0);
struct PSInput{ float4 Position : SV_Position; float2 TexCoord : TEXCOORD;};
float4 main(PSInput input) : SV_Target{ float4 diffuse = DiffuseTexture.Sample(samplerState, input.TexCoord); float3 normal = normalize(NormalTexture.Sample(samplerState, input.TexCoord).xyz); float3 worldPos = PositionTexture.Sample(samplerState, input.TexCoord).xyz;
float3 finalColor = float3(1.0f, 1.0f, 1.0f);
finalColor += CalculateDirectionalLight(directionalLight, normal);
for (int i = 0; i < LightCount; ++i) { Light light = Lights[i]; if (light.Type == 0) { finalColor += CalculatePointLight(light, worldPos, normal); } else if (light.Type == 1) { finalColor += CalculateSpotLight(light, worldPos, normal); } }
return float4(finalColor * diffuse.rgb, diffuse.a);}