1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| FThreeBandSHVector SHBasisFunction3(half3 InputVector) { FThreeBandSHVectorResult; Result.V0.x = 0.282095f; Result.V0.y = -0.488603f * InputVector.y; Result.V0.z = 0.488603f * InputVector.z; Result.V0.w = -0.488603f * InputVector.x;
half3 VectorSquared = InputVector * InputVector; Result.V1.x = 1.092548f * InputVector.x * InputVector.y; Result.V1.y = -1.092548f * InputVector.y * InputVector.z; Result.V1.z = 0.315392f * (3.0f * VectorSquared.z - 1.0f); Result.V1.w = -1.092548f * InputVector.x * InputVector.z; Result.V2 = 0.546274f * (VectorSquared.x - VectorSquared.y);
return Result; }
FThreeBandSHVectorRGB SampleSHRGB(in float3 SampleDirection, in float weight, in float MipLevel) { const float3 SampleColor = SourceCubemapTexture.SampleLevel(SourceCubemapSampler, SampleDirection, MipLevel).rgb;
FThreeBandSHVector Sh3Vector = SHBasisFunction3(SampleDirection); FThreeBandSHVectorRGB Result; Result.R = MulSH3(Sh3Vector, SampleColor.r * weight); Result.G = MulSH3(Sh3Vector, SampleColor.g * weight); Result.B = MulSH3(Sh3Vector, SampleColor.b * weight); return Result; }
void ComputeSkyEnvMapDiffuseIrradianceCS(uint3 ThreadId : SV_DispatchThreadID) { const uint LinearIndex = THREADGROUP_SIZE_X * ThreadId.y + ThreadId.x;
const float3 SampleDirection = UniformSampleSphere((float2(ThreadId.xy)+0.5f) / float2(THREADGROUP_SIZE_X, THREADGROUP_SIZE_Y)).xyz; IrradianceSHShared[LinearIndex] = SampleSHRGB(SampleDirection, UniformSampleSolidAngle, MipIndex);
#if THREADGROUP_SIZE != 64 #error That is the only reduction supported today #endif
GroupMemoryBarrierWithGroupSync();
if (LinearIndex < 32) { IrradianceSHShared[LinearIndex] = AddSH(IrradianceSHShared[LinearIndex], IrradianceSHShared[LinearIndex + 32]); } GroupMemoryBarrierWithGroupSync();
if (LinearIndex < 16) { IrradianceSHShared[LinearIndex] = AddSH(IrradianceSHShared[LinearIndex], IrradianceSHShared[LinearIndex + 16]); } GroupMemoryBarrierWithGroupSync();
if (LinearIndex < 8) { IrradianceSHShared[LinearIndex] = AddSH(IrradianceSHShared[LinearIndex], IrradianceSHShared[LinearIndex + 8]); } if (LinearIndex < 4) { IrradianceSHShared[LinearIndex] = AddSH(IrradianceSHShared[LinearIndex], IrradianceSHShared[LinearIndex + 4]); } if (LinearIndex < 2) { IrradianceSHShared[LinearIndex] = AddSH(IrradianceSHShared[LinearIndex], IrradianceSHShared[LinearIndex + 2]); }
if (LinearIndex < 1) { FThreeBandSHVectorRGB SkyIrradiance = AddSH(IrradianceSHShared[LinearIndex], IrradianceSHShared[LinearIndex + 1]);
const float SqrtPI = sqrt(PI); const float Coefficient0 = 1.0f / (2.0f * SqrtPI); const float Coefficient1 = sqrt(3.0f) / (3.0f * SqrtPI); const float Coefficient2 = sqrt(15.0f) / (8.0f * SqrtPI); const float Coefficient3 = sqrt(5.0f) / (16.0f * SqrtPI); const float Coefficient4 = 0.5f * Coefficient2;
OutIrradianceEnvMapSH[0].x = -Coefficient1 * SkyIrradiance.R.V0[3]; OutIrradianceEnvMapSH[0].y = -Coefficient1 * SkyIrradiance.R.V0[1]; OutIrradianceEnvMapSH[0].z = Coefficient1 * SkyIrradiance.R.V0[2]; OutIrradianceEnvMapSH[0].w = Coefficient0 * SkyIrradiance.R.V0[0] - Coefficient3 * SkyIrradiance.R.V1[2];
OutIrradianceEnvMapSH[1].x = -Coefficient1 * SkyIrradiance.G.V0[3]; OutIrradianceEnvMapSH[1].y = -Coefficient1 * SkyIrradiance.G.V0[1]; OutIrradianceEnvMapSH[1].z = Coefficient1 * SkyIrradiance.G.V0[2]; OutIrradianceEnvMapSH[1].w = Coefficient0 * SkyIrradiance.G.V0[0] - Coefficient3 * SkyIrradiance.G.V1[2];
OutIrradianceEnvMapSH[2].x = -Coefficient1 * SkyIrradiance.B.V0[3]; OutIrradianceEnvMapSH[2].y = -Coefficient1 * SkyIrradiance.B.V0[1]; OutIrradianceEnvMapSH[2].z = Coefficient1 * SkyIrradiance.B.V0[2]; OutIrradianceEnvMapSH[2].w = Coefficient0 * SkyIrradiance.B.V0[0] - Coefficient3 * SkyIrradiance.B.V1[2];
OutIrradianceEnvMapSH[3].x = Coefficient2 * SkyIrradiance.R.V1[0]; OutIrradianceEnvMapSH[3].y = -Coefficient2 * SkyIrradiance.R.V1[1]; OutIrradianceEnvMapSH[3].z = 3.0f * Coefficient3 * SkyIrradiance.R.V1[2]; OutIrradianceEnvMapSH[3].w = -Coefficient2 * SkyIrradiance.R.V1[3];
OutIrradianceEnvMapSH[4].x = Coefficient2 * SkyIrradiance.G.V1[0]; OutIrradianceEnvMapSH[4].y = -Coefficient2 * SkyIrradiance.G.V1[1]; OutIrradianceEnvMapSH[4].z = 3.0f * Coefficient3 * SkyIrradiance.G.V1[2]; OutIrradianceEnvMapSH[4].w = -Coefficient2 * SkyIrradiance.G.V1[3];
OutIrradianceEnvMapSH[5].x = Coefficient2 * SkyIrradiance.B.V1[0]; OutIrradianceEnvMapSH[5].y = -Coefficient2 * SkyIrradiance.B.V1[1]; OutIrradianceEnvMapSH[5].z = 3.0f * Coefficient3 * SkyIrradiance.B.V1[2]; OutIrradianceEnvMapSH[5].w = -Coefficient2 * SkyIrradiance.B.V1[3];
OutIrradianceEnvMapSH[6].x = Coefficient4 * SkyIrradiance.R.V2; OutIrradianceEnvMapSH[6].y = Coefficient4 * SkyIrradiance.G.V2; OutIrradianceEnvMapSH[6].z = Coefficient4 * SkyIrradiance.B.V2; OutIrradianceEnvMapSH[6].w = 1.0f; } }
|