Backlog/engine/rend/shaders/lit_mesh.frag.hlsl

165 lines
4.2 KiB
HLSL

Texture2D<float4> Texture : register(t0, space2);
SamplerState Sampler : register(s0, space2);
Texture2D<float> DirectionalShadowDepthMap : register(t1, space2);
SamplerState DirectionalShadowSampler : register(s1, space2);
cbuffer Uniforms : register(b0, space3)
{
float4 viewPos;
float4 lightPosition;
float4 directionalLight;
float4 directionalLightColor;
float2 screenSize;
float time;
};
// from learnopengl.com
float3 BlinnPhong(float3 normal, float3 fragPos, float3 lightPos, float3 lightColor)
{
float dist = length(lightPos - fragPos);
// attenuation
float maxDist = 15;
float cutoff1 = 2;
float cutoff2 = 4;
float cutoffFactor = 0.5;
float attenuation = 1.0 / (dist * dist);
if (dist > cutoff1)
{
attenuation *= cutoffFactor;
}
if (dist > cutoff2)
{
attenuation *= cutoffFactor;
}
if (dist > maxDist)
{
attenuation = 0;
}
if (attenuation > 1.0)
{
attenuation = 1.0;
}
if(length(normal) < 0.1)
{
return fragPos * lightColor * attenuation;
}
// diffuse parameter
float3 lightDir = normalize(lightPos - fragPos);
float diff = max(dot(lightDir, normal), 0.0);
float3 diffuse = diff * lightColor;
// specular parameter
float3 viewDir = normalize(fragPos - viewPos.xyz);
float3 reflectDir = reflect(-lightDir, normal);
float spec = 0.0;
float3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(normal, halfwayDir), 0.0), 30.0);
float3 specular = spec * lightColor * 2;
diffuse *= attenuation;
specular *= attenuation;
return diffuse + specular;
//return lightColor * 100 * attenuation;
}
float shadowCalculation(float3 fragPos, float4 DirectionalShadowFragPos)
{
float3 shadowProjection = DirectionalShadowFragPos.xyz / DirectionalShadowFragPos.w;
shadowProjection = shadowProjection * 0.5 + 0.5 ;
shadowProjection.x = shadowProjection.x;
float2 uv = shadowProjection.xy;
uv.y = -uv.y;
float depthSample = DirectionalShadowDepthMap.Sample(DirectionalShadowSampler, uv);
float fragDepth = DirectionalShadowFragPos.z;
float bias = 0.005;
float shadow = fragDepth - bias > depthSample ? 1.0 : 0.0;
return shadow;
}
float3 DirectionalLight(float3 normal, float3 fragPos, float4 DirectionalShadowFragPos)
{
float3 lightDir = directionalLight.xyz;
float diff = max(dot(lightDir, normal), 0.0);
float3 diffuse = diff * directionalLightColor.xyz;
// specular parameter
float3 viewDir = normalize(fragPos - viewPos.xyz);
float3 reflectDir = reflect(-lightDir, normal);
float spec = 0.0;
float3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(normal, halfwayDir), 0.0), 30.0);
float3 specular = spec * directionalLightColor.xyz * 2;
// shadow mapping
diffuse = diffuse * (1.0 - shadowCalculation(fragPos, DirectionalShadowFragPos));
return diffuse;
}
float4 main(
float4 ScreenPosition: SV_POSITION,
float2 UV : TEXCOORD0,
float3 WorldPos: TEXCOORD1,
float3 Normal: TEXCOORD2,
float4 DirectionalShadowFragPos: TEXCOORD3
) : SV_Target0
{
float4 s = Texture.Sample(Sampler, UV);
float alpha = s.w;
if(alpha < 0.01)
{
discard;
}
float3 lightPos = lightPosition.xyz; //+ float3(0, 20, 0);
float3 lightColor = float3(0.8, 0.8, 0.5);
float3 ambient = float3(0.1,0.1,0.1);
float3 col = s.xyz;
float3 c2 = col * ambient
+ col * BlinnPhong(Normal, WorldPos, lightPos, lightColor)
+ col * DirectionalLight(Normal, WorldPos, DirectionalShadowFragPos);
float4 rv = float4(pow(c2, 1.0 / 2.2), alpha);
// === debug bone zone
// float3 shadowProjection = DirectionalShadowFragPos.xyz / DirectionalShadowFragPos.w;
// shadowProjection = shadowProjection * 0.5 + 0.5 ;
// shadowProjection.x = shadowProjection.x;
// float2 uv = shadowProjection.xy;
// uv.y = -uv.y;
// float depthSample = DirectionalShadowDepthMap.Sample(DirectionalShadowSampler, uv);
// float fragDepth = shadowProjection.z;
// float t = DirectionalShadowFragPos.z;
// t = depthSample;
// rv = float4(t, t, t, 1.0);
// rv.x = rv.x + lightPos.x * 0.0001;
return rv;
}