Untitled
unknown
glsl
a year ago
6.8 kB
6
Indexable
#define BUMP_2_CHANNEL 1 #define PI 3.141592654f #define CASCADES 4 struct V_OUT { float4 Position : SV_Position; float2 UV : TEXCOORD0; float3 Normal : NORMAL; float3 Tangent : TANGENT; float3 Binormal : BINORMAL; float3 ViewDirection : TEXCOORD1; float ViewDepth : TEXCOORD2; float4 ShadowMapCoords[CASCADES] : TEXCOORD3; }; struct DirectionalLight { float3 AmbientColor; float p1; float3 LightDirection; float p2; float3 LightColor; float SpecularPower; }; ConstantBuffer<DirectionalLight> DirLightCB : register(b3); struct ShadowMapPixel { float4 CascadeDistances; // Max 4 cascades float Bias; float ShadowWidthPercent; float2 TexelSize; float PCFSampleCount; float PCFSampleRange; float CascadeCount; float p; float4 PoissonDisc[16]; }; ConstantBuffer<ShadowMapPixel> ShadowPixelCB : register(b5); struct MaterialProperties { float3 BaseColorFactor; float Roughness; float AlphaCutoff; float IOR; float Dispersion; float Metallic; // Unused until fixed }; ConstantBuffer<MaterialProperties> MatPropCB : register(b1); Texture2D g_texture : register(t0); Texture2D g_normalMap : register(t1); Texture2D g_specularMap : register(t2); TextureCube g_irradiance : register(t3); TextureCube g_envMap : register(t4); Texture2D g_blueNoise : register(t5); Texture2D g_shadowMap : register(t6); SamplerState g_sampler : register(s0); float D_GGX(float NdH, float roughness); float3 F_Schlick(float cosTheta, float3 F0); float G_Smith(float NdL, float NdV, float roughness); float G_Smith_IBL(float NdL, float NdV, float roughness); float4 main(V_OUT input) : SV_Target { float blueNoise = saturate(g_blueNoise.Sample(g_sampler, input.UV).r); float4 cascadeComparison = (input.ViewDepth > ShadowPixelCB.CascadeDistances); float fCascadeIndex = dot(float4(ShadowPixelCB.CascadeCount > 0, ShadowPixelCB.CascadeCount > 1, ShadowPixelCB.CascadeCount > 2, ShadowPixelCB.CascadeCount > 3), cascadeComparison); fCascadeIndex = min(fCascadeIndex, CASCADES); // Why? int iCascadeIndex = (int)fCascadeIndex - 1; float3 shadowCoords = input.ShadowMapCoords[iCascadeIndex]; shadowCoords.y = 1 - shadowCoords.y; shadowCoords.x = ShadowPixelCB.ShadowWidthPercent * (shadowCoords.x + iCascadeIndex); float pixelDepth = shadowCoords.z + ShadowPixelCB.Bias; float test = g_shadowMap.Sample(g_sampler, shadowCoords.xy).r; //return float4(test, test, test, 1); float shadowFactor = 0; int i = 0; for (float y = -ShadowPixelCB.PCFSampleRange; y <= ShadowPixelCB.PCFSampleRange; y++) for (float x = -ShadowPixelCB.PCFSampleRange; x <= ShadowPixelCB.PCFSampleRange; x++) { int poissonIndex = (i * blueNoise * ShadowPixelCB.PCFSampleCount) % ShadowPixelCB.PCFSampleCount; float2 coord = shadowCoords.xy + (float2(x, y) * ShadowPixelCB.PoissonDisc[poissonIndex].xy) * ShadowPixelCB.TexelSize; float shadowMapDepth = g_shadowMap.Sample(g_sampler, coord).r; //return float4(shadowMapDepth, shadowMapDepth, shadowMapDepth * (fCascadeIndex / CASCADES), 1); shadowFactor += pixelDepth < shadowMapDepth; i++; } shadowFactor /= i; float4 tex = g_texture.Sample(g_sampler, input.UV); if (tex.a < MatPropCB.AlphaCutoff) discard; tex.rgb = pow(tex.rgb, 2.2f); #if BUMP_2_CHANNEL float2 bump = g_normalMap.Sample(g_sampler, input.UV).rg; float3 normalTangentSpace; normalTangentSpace.xy = bump * 2.0f - 1.0f; normalTangentSpace.z = sqrt(1.0f - dot(normalTangentSpace.xy, normalTangentSpace.xy)); #else float3 normalTangentSpace = g_normalMap.Sample(g_sampler, input.UV).rgb; normalTangentSpace.xyz = normalTangentSpace.xyz * 2.0f - 1.0f; #endif float3 occlusionRoughnessMetallic = g_specularMap.Sample(g_sampler, input.UV).rgb; float roughness = occlusionRoughnessMetallic.g * MatPropCB.Roughness; float metalness = occlusionRoughnessMetallic.b * MatPropCB.Metallic; float3 N = normalize(normalTangentSpace.x * input.Tangent + normalTangentSpace.y * input.Binormal + normalTangentSpace.z * input.Normal); float3 L = normalize(DirLightCB.LightDirection); float3 V = normalize(input.ViewDirection); float3 H = normalize(-L + V); float3 R = reflect(-V, N); float NdL = saturate(dot(N, -L)) * shadowFactor; float NdV = saturate(dot(N, V)); float HdV = saturate(dot(H, V)); float NdH = saturate(dot(N, H)); float HdL = saturate(dot(H, -L)); float envMapMipLevels = 12; float3 irradiance = g_irradiance.SampleLevel(g_sampler, N, 0).rgb; //============================================================== float3 albedo = tex.rgb * MatPropCB.BaseColorFactor; float3 F0 = lerp(0.04f, albedo, metalness); float D = D_GGX(NdH, roughness); float3 F = F_Schlick(HdV, F0); float G = G_Smith(NdL, NdV, roughness); float kS = max(0, F); float kD = (1.0f - kS); float3 envReflections = g_envMap.SampleLevel(g_sampler, R, roughness * envMapMipLevels).rgb; envReflections *= kS * (1 - roughness) * metalness; float3 specularDFG = (D * F * G) / max(0.001f, 4.0f * NdV); float3 specular = specularDFG * DirLightCB.LightColor * kS; float3 diffuse = irradiance * kD * albedo * DirLightCB.LightColor * NdL; diffuse *= 1 - metalness; float3 ambient = irradiance * kD * albedo * DirLightCB.AmbientColor; float3 Lo = diffuse + specular + ambient + envReflections; Lo = pow(Lo, 1.0f / 2.2f); return float4(Lo, tex.a); } float D_GGX(float NdH, float roughness) { float a = roughness * roughness; float a2 = a * a; float denominator = (NdH * NdH * (a2 - 1.0f) + 1.0f); return a2 / max(0.001f, PI * denominator * denominator); } // 5 is the sharpness, can be modified float3 F_Schlick(float cosTheta, float3 F0) { return F0 + (1.0f - F0) * pow(1.0f - cosTheta, 5.0f); } float G_Smith(float NdL, float NdV, float roughness) { float r = roughness + 1; float k = (r * r) / 8.0f; float ggxL = NdL / (NdL * (1.0f - k) + k); float ggxV = NdV / (NdV * (1.0f - k) + k); return ggxL * ggxV; } float G_Smith_IBL(float NdL, float NdV, float roughness) { float r = roughness; float k = (r * r) / 2.0f; float ggxL = NdL / (NdL * (1.0f - k) + k); float ggxV = NdV / (NdV * (1.0f - k) + k); return ggxL * ggxV; }
Editor is loading...
Leave a Comment