material

MF_RayMarchHeightMap

  • Exposure: public
  • UE Version: 4.27

avatar author

XavierPan

January 11, 2022, 8:43 am

Click the button above, it will automatically copy blueprint in your clipboard. Then in Unreal Engine blueprint editor, paste it with ctrl + v

2 comments

  • avatar author

    XavierPan

    January 11, 2022, 8:44 am

    //Custom : RayMarch Heightmap //////////////// Ray March HeightMap Function ///////////////////////////

    // Tex // Input Texture Object // startZ // Input float for start height of texture // UV // Input float2 containing UVs // NumSteps // Input float for Max Steps // StepSize // Input float for ray step size // TraceVec // Input float3 for TraceVector, scaled by StepSize // FinalStepTraceVec // Input float3 for TraceVector, scaled by StepSize // FinalStepSize // Input float for length of the final step // bias // Input float for ray starting bias // heightscale // Input float for heightmap scale // TemporalJitter // Input bool (using int) to toggle Temporal Jitter // threshold // Input float for particle density

    if(startZ<=threshold) return 0;

    float TimeLerp = 1; float DepthDiff = 0; float LastDiff = -bias;

    //We scale Z by 2 since the heightmap represents two halves of as symmetrical volume texture, split along Z where texture = 0 float3 RayStepUVz = float3(TraceVec.x, TraceVec.y, TraceVec.z*2);

    float accum = 0; float3 RayUVz = float3(UV, (startZ) );

    if(TemporalJitter) { // jitter the starting position int3 randpos = int3(Parameters.SvPosition.xy, View.StateFrameIndexMod8); float rand = float(Rand3DPCG16(randpos).x) / 0xffff; RayUVz += RayStepUVz * rand; }

    int i = 0; while (i < NumSteps) {

    RayUVz += RayStepUVz;

    RayUVz.xy = saturate(RayUVz.xy); float SampleDepth = dot( channel, Tex.SampleLevel(TexSampler, RayUVz.xy,0) ); DepthDiff = abs(RayUVz.z) - abs(SampleDepth);

        if (DepthDiff <= 0)
        {
    
            if(LastDiff > 0)
            {
                TimeLerp = saturate( LastDiff / (LastDiff - DepthDiff));
                accum += StepSize * (1-TimeLerp);
                //accum+=StepSize;
            }
            else
            {
                accum+=StepSize;
            }
        }
        else
        if(LastDiff <= 0)
        {
            TimeLerp = saturate( LastDiff / (LastDiff - DepthDiff));
            accum += StepSize * (TimeLerp);
            //accum+=StepSize;
        }
    
    LastDiff = DepthDiff;
    
    i++;

    }

    //Run one more iteration outside of the loop. Using the Box Intersection in the material graph, we precompute the number of whole steps that can be run which leaves one final 'short step' which is the remainder that is traced here. This was cheaper than checking or clamping the UVs inside of the loop. RayUVz += RayStepUVz; RayUVz.xy = saturate(RayUVz.xy); float SampleDepth = dot( channel, Tex.SampleLevel(TexSampler, RayUVz.xy,0) ); DepthDiff = abs(RayUVz.z) - abs(SampleDepth);

    if (DepthDiff <= 0)
    {
        accum+=StepSize;
    }
    else
    if(LastDiff <= 0)
    {
        TimeLerp = saturate( LastDiff / (LastDiff - DepthDiff));
        accum += StepSize * (TimeLerp);

    }

    return accum;

  • avatar author

    XavierPan

    January 11, 2022, 8:45 am

    //Custom : ShaderComplexity float3 colors[10];

    colors[0]=float3(0,1,0.127); colors[1]=float3(0,1,0); colors[2]=float3(0.046,0.52,0); colors[3]=float3(0.215,0.215,0); colors[4]=float3(0.52,0.046,0); colors[5]=float3(0.7,0,0); colors[6]=float3(1,0,0); colors[7]=float3(1,0,0.5); colors[8]=float3(1,0.9,0.9); colors[9]=float3(1,1,1);

    Steps/=MaxSteps-1; Steps=saturate(Steps);

    float cindex = floor((Steps)8); float cphase = frac((Steps)8);

    return lerp(colors[cindex],colors[cindex+1],cphase);