Download

No distance field shadow on volume cloud

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!

BTW, The version I use is UE 4.21

I got it! Change the SkyLight to Movable to solve this problem.

Hi,

I am currently trying to reproduce the same effect, however it doesn’t work at all…

I have tried with the Ryan Buck’s tutorial but I’m can’t achieve to have my movable objects casting shadow on my clouds (or my clouds on objects).

I have also tried with your code but I’m also stuck with some issues related to “undeclared identifier”…

Any help would be very appreciated :D!

Have a good day!

Lo