// #pragma enable_d3d11_debug_symbols #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch #pragma kernel MAIN_1 main=MAIN_1 SINGLE_SCATTERING #pragma kernel MAIN_S main=MAIN_S MULTIPLE_SCATTERING SRC_SS #pragma kernel MAIN_M main=MAIN_M MULTIPLE_SCATTERING SRC_MS #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyCommon.hlsl" #define TABLE_SIZE uint(PBRSKYCONFIG_GROUND_IRRADIANCE_TABLE_SIZE) RW_TEXTURE2D(float4, _GroundIrradianceTable); // of TABLE_SIZE RW_TEXTURE2D(float4, _GroundIrradianceTableOrder); // of TABLE_SIZE [numthreads(64, 1, 1)] void main(uint dispatchThreadId : SV_DispatchThreadID) { // We don't care about the extremal points. const float scale = rcp(TABLE_SIZE); const float bias = 0.5 * scale; // Let the hardware and the driver handle the ordering of the computation. uint2 tableCoord = uint2(dispatchThreadId, 0); float uv = tableCoord.x * scale + bias; // As we look at the planet in the direction of the sun, the ground is rotationally invariant. float NdotL = UnmapCosineOfZenithAngle(uv.x); float4 tableEntry = float4(0, 0, 0, 1); #ifdef SINGLE_SCATTERING if (NdotL > 0) { float3 oDepth = ComputeAtmosphericOpticalDepth(_PlanetaryRadius, NdotL, true); float3 transm = TransmittanceFromOpticalDepth(oDepth); tableEntry.rgb = transm * NdotL; } _GroundIrradianceTableOrder[tableCoord] = tableEntry; // One order _GroundIrradianceTable[tableCoord] = tableEntry; // All orders #else // MULTIPLE_SCATTERING // Gather the volume contribution. // Arbitrary number of samples... const int numVolumeSamples = 89; for (int i = 0; i < numVolumeSamples; i++) { float2 f = Fibonacci2d(i, numVolumeSamples); // TODO: Cranley-Patterson Rotation float3 L = SampleHemisphereCosine(f.x, f.y); float cosChi = L.z; float NdotV = -cosChi; float phiL = TWO_PI * f.y; TexCoord4D tc = ConvertPositionAndOrientationToTexCoords(0, NdotV, NdotL, phiL); float3 radiance = 0; #ifdef SRC_SS // Single scattering does not contain the phase function. float LdotV = SphericalDot(NdotV, 0, NdotL, phiL); radiance += lerp(SAMPLE_TEXTURE3D_LOD(_AirSingleScatteringTexture, s_linear_clamp_sampler, float3(tc.u, tc.v, tc.w0), 0).rgb, SAMPLE_TEXTURE3D_LOD(_AirSingleScatteringTexture, s_linear_clamp_sampler, float3(tc.u, tc.v, tc.w1), 0).rgb, tc.a) * AirPhase(LdotV); radiance += lerp(SAMPLE_TEXTURE3D_LOD(_AerosolSingleScatteringTexture, s_linear_clamp_sampler, float3(tc.u, tc.v, tc.w0), 0).rgb, SAMPLE_TEXTURE3D_LOD(_AerosolSingleScatteringTexture, s_linear_clamp_sampler, float3(tc.u, tc.v, tc.w1), 0).rgb, tc.a) * AerosolPhase(LdotV); #else // SRC_MS radiance += lerp(SAMPLE_TEXTURE3D_LOD(_MultipleScatteringTexture, s_linear_clamp_sampler, float3(tc.u, tc.v, tc.w0), 0).rgb, SAMPLE_TEXTURE3D_LOD(_MultipleScatteringTexture, s_linear_clamp_sampler, float3(tc.u, tc.v, tc.w1), 0).rgb, tc.a); #endif // SRC_MS float weight = PI * rcp(numVolumeSamples); tableEntry.rgb += weight * radiance; } _GroundIrradianceTableOrder[tableCoord] = tableEntry; // One order _GroundIrradianceTable[tableCoord] += float4(tableEntry.rgb, 0); // All orders #endif // MULTIPLE_SCATTERING }