Untitled
unknown
glsl
a year ago
6.8 kB
9
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