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
|
"#include \"AtmosphereShadersCommon.fxh\"\n"
"\n"
"cbuffer cbParticipatingMediaScatteringParams\n"
"{\n"
" AirScatteringAttribs g_MediaParams;\n"
"}\n"
"\n"
"Texture2D<float2> g_tex2DOccludedNetDensityToAtmTop;\n"
"SamplerState g_tex2DOccludedNetDensityToAtmTop_sampler;\n"
"\n"
"#include \"LookUpTables.fxh\"\n"
"#include \"PrecomputeCommon.fxh\"\n"
"#include \"ScatteringIntegrals.fxh\"\n"
"\n"
"Texture3D<float3> g_tex3DPreviousSctrOrder;\n"
"SamplerState g_tex3DPreviousSctrOrder_sampler;\n"
"\n"
"Texture2D<float3> g_tex2DSphereRandomSampling;\n"
"\n"
"RWTexture3D</*format = rgba32f*/float3> g_rwtex3DSctrRadiance;\n"
"\n"
"// This shader pre-computes the radiance of light scattered at a given point in given\n"
"// direction. It multiplies the previous order in-scattered light with the phase function \n"
"// for each type of particles and integrates the result over the whole set of directions,\n"
"// see eq. (7) in [Bruneton and Neyret 08].\n"
"[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)]\n"
"void ComputeSctrRadianceCS(uint3 ThreadId : SV_DispatchThreadID)\n"
"{\n"
" // Get attributes for the current point\n"
" float4 f4LUTCoords = LUTCoordsFromThreadID(ThreadId);\n"
" float fAltitude, fCosViewZenithAngle, fCosSunZenithAngle, fCosSunViewAngle;\n"
" InsctrLUTCoords2WorldParams(f4LUTCoords,\n"
" g_MediaParams.fEarthRadius,\n"
" g_MediaParams.fAtmBottomAltitude,\n"
" g_MediaParams.fAtmTopAltitude,\n"
" fAltitude,\n"
" fCosViewZenithAngle,\n"
" fCosSunZenithAngle,\n"
" fCosSunViewAngle );\n"
" float3 f3EarthCentre = float3(0.0, -g_MediaParams.fEarthRadius, 0.0);\n"
" float3 f3RayStart = float3(0.0, fAltitude, 0.0);\n"
" float3 f3ViewDir = ComputeViewDir(fCosViewZenithAngle);\n"
" float3 f3DirOnLight = ComputeLightDir(f3ViewDir, fCosSunZenithAngle, fCosSunViewAngle);\n"
" \n"
" // Compute particle density scale factor\n"
" float2 f2ParticleDensity = exp( -float2(fAltitude, fAltitude) * g_MediaParams.f4ParticleScaleHeight.zw );\n"
" \n"
" float3 f3SctrRadiance = float3(0.0, 0.0, 0.0);\n"
" // Go through a number of samples randomly distributed over the sphere\n"
" for(int iSample = 0; iSample < NUM_RANDOM_SPHERE_SAMPLES; ++iSample)\n"
" {\n"
" // Get random direction\n"
" float3 f3RandomDir = normalize( g_tex2DSphereRandomSampling.Load(int3(iSample,0,0)) );\n"
" // Get the previous order in-scattered light when looking in direction f3RandomDir (the light thus goes in direction -f3RandomDir)\n"
" float4 f4UVWQ = float4(-1.0, -1.0, -1.0, -1.0);\n"
" float3 f3PrevOrderSctr = LookUpPrecomputedScattering(\n"
" f3RayStart,\n"
" f3RandomDir,\n"
" f3EarthCentre,\n"
" g_MediaParams.fEarthRadius,\n"
" f3DirOnLight.xyz,\n"
" g_MediaParams.fAtmBottomAltitude,\n"
" g_MediaParams.fAtmTopAltitude,\n"
" g_tex3DPreviousSctrOrder,\n"
" g_tex3DPreviousSctrOrder_sampler,\n"
" f4UVWQ); \n"
" \n"
" // Apply phase functions for each type of particles\n"
" // Note that total scattering coefficients are baked into the angular scattering coeffs\n"
" float3 f3DRlghInsctr = f2ParticleDensity.x * f3PrevOrderSctr;\n"
" float3 f3DMieInsctr = f2ParticleDensity.y * f3PrevOrderSctr;\n"
" float fCosTheta = dot(f3ViewDir, f3RandomDir);\n"
" ApplyPhaseFunctions(f3DRlghInsctr, f3DMieInsctr, fCosTheta);\n"
"\n"
" f3SctrRadiance += f3DRlghInsctr + f3DMieInsctr;\n"
" }\n"
" // Since we tested N random samples, each sample covered 4*Pi / N solid angle\n"
" // Note that our phase function is normalized to 1 over the sphere. For instance,\n"
" // uniform phase function would be p(theta) = 1 / (4*Pi).\n"
" // Notice that for uniform intensity I if we get N samples, we must obtain exactly I after\n"
" // numeric integration\n"
" f3SctrRadiance *= 4.0*PI / float(NUM_RANDOM_SPHERE_SAMPLES);\n"
"\n"
" g_rwtex3DSctrRadiance[ThreadId] = f3SctrRadiance;\n"
"}\n"
"\n"
|