Hello everyone!
I tried to create a volume cloud according to the following tutorial “Post Page”. But I can’t get the distance field shadow on the volume cloud. My volume cloud just appears purely black.
But the distance field shadow can be displayed in the “Mesh DistanceFields” visualization mode.
That’s weird!
My Volumetric Ray Marcher code show below:
float numFrames = XYFrames * XYFrames;
float accumdist = 0;
float curdensity = 0;
float transmittance = 1;
float3 localcamvec = normalize( mul(Parameters.CameraVector, Primitive.WorldToLocal) ) * StepSize;
float3 LightVectorWS = normalize( mul( LightVector, Primitive.LocalToWorld));
float shadowstepsize = 1 / ShadowSteps;
LightVector *= shadowstepsize;
ShadowDensity *= shadowstepsize;
Density *= StepSize;
float3 lightenergy = 0;
float shadowthresh = -log(ShadowThreshold) / ShadowDensity;
for (int i = 0; i < MaxSteps; i++)
{
float cursample = PseudoVolumeTexture(Tex, TexSampler, saturate(CurPos), XYFrames, numFrames).r;
//Sample Light Absorption and Scattering
if( cursample > 0.001)
{
float3 lpos = CurPos;
float shadowdist = 0;
for (int s = 0; s < ShadowSteps; s++)
{
lpos += LightVector;
float lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(lpos), XYFrames, numFrames).r;
float3 shadowboxtest = floor( 0.5 + ( abs( 0.5 - lpos ) ) );
float exitshadowbox = shadowboxtest .x + shadowboxtest .y + shadowboxtest .z;
shadowdist += lsample;
if(shadowdist > shadowthresh || exitshadowbox >= 1) break;
}
float3 dfpos = 2 * (CurPos - 0.5) * Primitive.LocalObjectBoundsMax.x;
dfpos = TransformLocalPositionToWorld(Parameters, dfpos).xyz;
float dftracedist = 1;
float dfshadow = 1;
float curdist = 0;
float DistanceAlongCone = 0;
for (int d = 0; d < DFSteps; d++)
{
DistanceAlongCone += curdist;
curdist = GetDistanceToNearestSurfaceGlobal(dfpos.xyz);
float SphereSize = DistanceAlongCone * LightTangent;
dfshadow = min( saturate(curdist / SphereSize) , dfshadow);
dfpos.xyz += LightVectorWS * dftracedist * curdist;
dftracedist *= 1.0001;
}
curdensity = saturate(cursample * Density);
float shadowterm = exp(-shadowdist * ShadowDensity);
float3 absorbedlight = shadowterm * curdensity * dfshadow;
lightenergy += absorbedlight * transmittance;
transmittance *= 1-curdensity;
}
CurPos -= localcamvec;
}
CurPos += localcamvec * (1 - FinalStep);
float cursample = PseudoVolumeTexture(Tex, TexSampler, saturate(CurPos), XYFrames, numFrames).r;
//Sample Light Absorption and Scattering
if( cursample > 0.001)
{
float3 lpos = CurPos;
float shadowdist = 0;
for (int s = 0; s < ShadowSteps; s++)
{
lpos += LightVector;
float lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(lpos), XYFrames, numFrames).r;
float3 shadowboxtest = floor( 0.5 + ( abs( 0.5 - lpos ) ) );
float exitshadowbox = shadowboxtest .x + shadowboxtest .y + shadowboxtest .z;
shadowdist += lsample;
if(shadowdist > shadowthresh || exitshadowbox >= 1) break;
}
float3 dfpos = 2 * (CurPos - 0.5) * Primitive.LocalObjectBoundsMax.x;
dfpos = TransformLocalPositionToWorld(Parameters, dfpos).xyz;
float dftracedist = 1;
float dfshadow = 1;
float curdist = 0;
float DistanceAlongCone = 0;
for (int d = 0; d < DFSteps; d++)
{
DistanceAlongCone += curdist;
curdist = GetDistanceToNearestSurfaceGlobal(dfpos.xyz);
float SphereSize = DistanceAlongCone * LightTangent;
dfshadow = min( saturate(curdist / SphereSize) , dfshadow);
dfpos.xyz += LightVectorWS * dftracedist * curdist;
dftracedist *= 1.0001;
}
curdensity = saturate(cursample) * Density;
float shadowterm = exp(-shadowdist * ShadowDensity);
float3 absorbedlight = shadowterm * curdensity * dfshadow;
lightenergy += absorbedlight * transmittance;
transmittance *= 1-curdensity;
}
return float4( lightenergy, transmittance);
Can someone help me? Thanks!