|
| 1 | +#include "BasicStructures.fxh" |
| 2 | +#include "PBR_Structures.fxh" |
| 3 | +#include "FullScreenTriangleVSOutput.fxh" |
| 4 | + |
| 5 | +#define FLT_EPS 5.960464478e-8 |
| 6 | + |
| 7 | +cbuffer cbCameraAttribs |
| 8 | +{ |
| 9 | + CameraAttribs g_Camera; |
| 10 | +} |
| 11 | + |
| 12 | +cbuffer cbPBRRendererAttibs |
| 13 | +{ |
| 14 | + PBRRendererShaderParameters g_PBRRendererAttibs; |
| 15 | +} |
| 16 | + |
| 17 | +Texture2D<float3> g_TextureBaseColor; |
| 18 | +Texture2D<float2> g_TextureMaterialData; |
| 19 | +Texture2D<float4> g_TextureNormal; |
| 20 | +Texture2D<float> g_TextureDepth; |
| 21 | +Texture2D<float4> g_TextureSSR; |
| 22 | + |
| 23 | +TextureCube<float3> g_TextureEnvironmentMap; |
| 24 | +SamplerState g_TextureEnvironmentMap_sampler; |
| 25 | + |
| 26 | +TextureCube<float3> g_TextureIrradianceMap; |
| 27 | +SamplerState g_TextureIrradianceMap_sampler; |
| 28 | + |
| 29 | +TextureCube<float3> g_TexturePrefilteredEnvironmentMap; |
| 30 | +SamplerState g_TexturePrefilteredEnvironmentMap_sampler; |
| 31 | + |
| 32 | +Texture2D<float2> g_TextureBRDFIntegrationMap; |
| 33 | +SamplerState g_TextureBRDFIntegrationMap_sampler; |
| 34 | + |
| 35 | +struct SurfaceInformation |
| 36 | +{ |
| 37 | + float3 BaseColor; |
| 38 | + float Roughness; |
| 39 | + float Metalness; |
| 40 | + float3 Normal; |
| 41 | +}; |
| 42 | + |
| 43 | +float3 FresnelSchlickRoughness(float CosTheta, float3 F0, float roughness) |
| 44 | +{ |
| 45 | + float Alpha = 1.0 - roughness; |
| 46 | + return F0 + (max(float3(Alpha, Alpha, Alpha), F0) - F0) * pow(clamp(1.0 - CosTheta, 0.0, 1.0), 5.0); |
| 47 | +} |
| 48 | + |
| 49 | +float3 SampleEnvironmentMap(float3 Coord) |
| 50 | +{ |
| 51 | + return g_PBRRendererAttibs.IBLScale * g_TextureEnvironmentMap.SampleLevel(g_TextureEnvironmentMap_sampler, float3(+1.0, -1.0, +1.0) * Coord, 0.5); |
| 52 | +} |
| 53 | + |
| 54 | +float3 SampleIrradianceMap(float3 Coord) |
| 55 | +{ |
| 56 | + return g_PBRRendererAttibs.IBLScale * g_TextureIrradianceMap.Sample(g_TextureIrradianceMap_sampler, float3(+1.0, -1.0, +1.0) * Coord); |
| 57 | +} |
| 58 | + |
| 59 | +float3 SamplePrefilteredEnvironmentMap(float3 Coord, float MipLevel) |
| 60 | +{ |
| 61 | + return g_PBRRendererAttibs.IBLScale * g_TexturePrefilteredEnvironmentMap.SampleLevel(g_TexturePrefilteredEnvironmentMap_sampler, float3(+1.0, -1.0, +1.0) * Coord, MipLevel); |
| 62 | +} |
| 63 | + |
| 64 | +float2 SampleBRDFIntegrationMap(float2 Coord) |
| 65 | +{ |
| 66 | + return g_TextureBRDFIntegrationMap.Sample(g_TextureBRDFIntegrationMap_sampler, Coord); |
| 67 | +} |
| 68 | + |
| 69 | +float3 ComputeDiffuseIBL(float3 N) |
| 70 | +{ |
| 71 | + return SampleIrradianceMap(N); |
| 72 | +} |
| 73 | + |
| 74 | +float3 ComputeSpecularIBL(float2 Location, float3 F0, float3 N, float3 V, float Roughness) |
| 75 | +{ |
| 76 | + float NdotV = saturate(dot(N, V)); |
| 77 | + float3 R = reflect(-V, N); |
| 78 | + float2 BRDF_LUT = SampleBRDFIntegrationMap(float2(NdotV, Roughness)); |
| 79 | + float4 SSR = g_TextureSSR.Load(int3(Location, 0)); |
| 80 | + float3 T1 = SamplePrefilteredEnvironmentMap(R, Roughness * g_PBRRendererAttibs.PrefilteredCubeMipLevels); |
| 81 | + float3 T2 = (F0 * BRDF_LUT.x + BRDF_LUT.yyy); |
| 82 | + return lerp(T1, SSR.rgb, SSR.w * g_Camera.f4ExtraData[0].w) * T2; |
| 83 | +} |
| 84 | + |
| 85 | +SurfaceInformation ExtractGBuffer(FullScreenTriangleVSOutput VSOut) |
| 86 | +{ |
| 87 | + float2 MaterialData = g_TextureMaterialData.Load(int3(VSOut.f4PixelPos.xy, 0)); |
| 88 | + |
| 89 | + SurfaceInformation Information; |
| 90 | + Information.BaseColor = g_TextureBaseColor.Load(int3(VSOut.f4PixelPos.xy, 0)); |
| 91 | + Information.Roughness = MaterialData.x; |
| 92 | + Information.Metalness = MaterialData.y; |
| 93 | + Information.Normal = normalize(g_TextureNormal.Load(int3(VSOut.f4PixelPos.xy, 0)).xyz); |
| 94 | + return Information; |
| 95 | +} |
| 96 | + |
| 97 | +float3 CreateViewDir(float2 NormalizedXY) |
| 98 | +{ |
| 99 | + float4 RayStart = mul(float4(NormalizedXY, DepthToNormalizedDeviceZ(0.0), 1.0f), g_Camera.mViewProjInv); |
| 100 | + float4 RayEnd = mul(float4(NormalizedXY, DepthToNormalizedDeviceZ(1.0), 1.0f), g_Camera.mViewProjInv); |
| 101 | + |
| 102 | + RayStart.xyz /= RayStart.w; |
| 103 | + RayEnd.xyz /= RayEnd.w; |
| 104 | + return normalize(RayStart.xyz - RayEnd.xyz);; |
| 105 | +} |
| 106 | + |
| 107 | +float4 ComputeLightingPS(FullScreenTriangleVSOutput VSOut) : SV_Target0 |
| 108 | +{ |
| 109 | + float Depth = g_TextureDepth.Load(int3(VSOut.f4PixelPos.xy, 0)); |
| 110 | + float3 ViewDir = CreateViewDir(VSOut.f2NormalizedXY); |
| 111 | + if (Depth >= 1.0 - FLT_EPS) |
| 112 | + return float4(SampleEnvironmentMap(-ViewDir), 1.0); |
| 113 | + |
| 114 | + SurfaceInformation SurfInfo = ExtractGBuffer(VSOut); |
| 115 | + float3 F0 = lerp(float3(0.04, 0.04, 0.04), SurfInfo.BaseColor, SurfInfo.Metalness); |
| 116 | + float3 F = FresnelSchlickRoughness(saturate(dot(SurfInfo.Normal, ViewDir)), F0, SurfInfo.Roughness); |
| 117 | + |
| 118 | + float3 kS = F; |
| 119 | + float3 kD = (float3(1.0, 1.0, 1.0) - kS) * (1.0 - SurfInfo.Metalness); |
| 120 | + |
| 121 | + float3 Diffuse = SurfInfo.BaseColor * ComputeDiffuseIBL(SurfInfo.Normal); |
| 122 | + float3 Specular = ComputeSpecularIBL(VSOut.f4PixelPos.xy, F0, SurfInfo.Normal, ViewDir, SurfInfo.Roughness); |
| 123 | + |
| 124 | + return float4(kD * Diffuse + Specular, 1.0); |
| 125 | +} |
0 commit comments