I'm trying to code Rayleigh part of Nishita's model (Display Method of the Sky Color Taking into Account Multiple Scattering). I get black screen no colors. Can anyone find the issue for me?
#define InnerRadius 6320000
#define OutterRadius 6420000
#define PI 3.141592653
#define Isteps 20
#define Ksteps 10
static float3 RayleighCoeffs = float3(6.55e-6, 1.73e-5, 2.30e-5);
RWTexture2D<float4> SkyColors : register (u0);
cbuffer CSCONSTANTBUF : register( b0 )
{
float fHeight;
float3 vSunDir;
}
float Density(float Height)
{
return exp(-Height/8340);
}
float RaySphereIntersection(float3 RayOrigin, float3 RayDirection, float3 SphereOrigin, float Radius)
{
float t1, t0;
float3 L = SphereOrigin - RayOrigin;
float tCA = dot(L, RayDirection);
if (tCA < 0) return -1;
float lenL = length(L);
float D2 = (lenL*lenL) - (tCA*tCA);
float Radius2 = (Radius*Radius);
if (D2<=Radius2)
{
float tHC = sqrt(Radius2 - D2);
t0 = tCA-tHC;
t1 = tCA+tHC;
}
else
return -1;
return t1;
}
float RayleighPhaseFunction(float cosTheta)
{
return ((3/(16*PI))*(1+cosTheta*cosTheta));
}
float OpticalDepth(float3 StartPosition, float3 EndPosition)
{
float3 Direction = normalize(EndPosition - StartPosition);
float RayLength = RaySphereIntersection(StartPosition, Direction, float3(0, 0, 0), OutterRadius);
float SampleLength = RayLength / Isteps;
float3 tmpPos = StartPosition + 0.5 * SampleLength * Direction;
float tmp;
for (int i=0; i<Isteps; i++)
{
tmp += Density(length(tmpPos)-InnerRadius);
tmpPos += SampleLength * Direction;
}
return tmp*SampleLength;
}
static float fExposure = -2;
float3 HDR( float3 LDR)
{
return 1.0f - exp( fExposure * LDR );
}
[numthreads(32, 32, 1)] //disptach 8, 8, 1 it's 256 by 256 image
void ComputeSky(uint3 DTID : SV_DispatchThreadID)
{
float X = ((2 * DTID.x) / 255) - 1;
float Y = 1 - ((2 * DTID.y) / 255);
float r = sqrt(((X*X)+(Y*Y)));
float Theta = r * (PI);
float Phi = atan2(Y, X);
static float3 Eye = float3(0, 10, 0);
float ViewOD = 0, SunOD = 0, tmpDensity = 0;
float3 Attenuation = 0, tmp = 0, Irgb = 0;
//if (r<=1)
{
float3 ViewDir = normalize(float3(sin(Theta)*cos(Phi), cos(Theta),sin(Theta)*sin(Phi) ));
float ViewRayLength = RaySphereIntersection(Eye, ViewDir, float3(0, 0, 0), OutterRadius);
float SampleLength = ViewRayLength / Ksteps;
//vSunDir = normalize(vSunDir);
float cosTheta = dot(normalize(vSunDir), ViewDir);
float3 tmpPos = Eye + 0.5 * SampleLength * ViewDir;
for(int k=0; k<Ksteps; k++)
{
float SunRayLength = RaySphereIntersection(tmpPos, vSunDir, float3(0, 0, 0), OutterRadius);
float3 TopAtmosphere = tmpPos + SunRayLength*vSunDir;
ViewOD = OpticalDepth(Eye, tmpPos);
SunOD = OpticalDepth(tmpPos, TopAtmosphere);
tmpDensity = Density(length(tmpPos)-InnerRadius);
Attenuation = exp(-RayleighCoeffs*(ViewOD+SunOD));
tmp += tmpDensity*Attenuation;
tmpPos += SampleLength * ViewDir;
}
Irgb = RayleighCoeffs*RayleighPhaseFunction(cosTheta)*tmp*SampleLength;
SkyColors[DTID.xy] = float4(Irgb, 1);
}
}
↧