2021-09-09 20:42:29 -04:00

91 lines
3.5 KiB
Plaintext

// #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
}