Howdy,
There are some great resources for HLSL and materials out there BUT for volume textures things seem pretty sparse (except for sparse volume textures
which seem to have some more popularity due to VDB ).
Question:
How can I sample a volume texture to do ray marching in the Materials editor?
Notes:
- Using UE 5.5
- Open to Volumetrics plugin if there is something in there.
- I currently generate my volume textures from c++ similar to the great TBRaymarch Plugin
- Is that plugin now part of the Volumetrics plugin…?
Tried:
I followed this awesome tutorial and got it working just find for a 2D texture (PseudoVolumeTexture). However, tried to switch a volume texture causes the Sampler to never be found.
Example custom hlsl code. Neither sampling mode below worked.
float accumdens = 0;LocalCamVec = normalize(mul(Parameters.CameraVector, (float3x3)LWCToFloat(GetPrimitiveData(Parameters).WorldToLocal)));
for (int i = 0; i < MaxSteps; i++) {// Use Texture3DSample or VolumeTexture.Sample instead of PseudoVolumeTexture
//float cursample = Texture3DSample (VolumeTexture, VolumeTextureSampler, saturate(CurPos)).r;float cursample = VolumeTexture.Sample(VolumeTextureSampler, saturate(CurPos)).r;accumdens += cursample * StepSize;CurPos += -LocalCamVec * StepSize;}
CurPos -= -LocalCamVec * StepSize;CurPos += -LocalCamVec * StepSize * FinalStepSize;
// Final sample with adjusted step size
//float cursample = Texture3DSample (VolumeTexture, VolumeTextureSampler, saturate(CurPos)).r;float cursample = VolumeTexture.Sample(VolumeTextureSampler, saturate(CurPos)).r;accumdens += cursample * StepSize * FinalStepSize;
return accumdens;

Here is an image using a VolumeTexture but manually sweeping through the Z axis (no HLSL just a time + sine node on the Texture UV)… 
Trying to find examples in the Engine code, found:
Engine\Shaders\Private\BasePassPixelShader.usf
which uses it like this:
float4 Vector0 = Texture3DSample(IndirectLightingCache.IndirectLightingCacheTexture0, IndirectLightingCache.IndirectLightingCacheTextureSampler0, VolumeUVs);
So the function exists… hmm…
If a VolumeTexture render method is already implemented I would love to just use that and avoid this whole custom HLSL black voodoo magic.
Some progress made…
- The input texture had to switch to a TextureObject and not a TextureSampler
- Use
SampleLevel
and add the mimap value.
float accumdens = 0;
LocalCamVec = normalize(mul(Parameters.CameraVector, (float3x3)LWCToFloat(GetPrimitiveData(Parameters).WorldToLocal)));
for (int i = 0; i < MaxSteps; i++) {
// Use Texture3DSample instead of PseudoVolumeTexture
float cursample = VolumeTexture.SampleLevel(VolumeTextureSampler, saturate(CurPos),0).r;
accumdens += cursample * StepSize;
CurPos += -LocalCamVec * StepSize;
}
CurPos -= -LocalCamVec * StepSize;
CurPos += -LocalCamVec * StepSize * FinalStepSize;
// Final sample with adjusted step size
float cursample = VolumeTexture.SampleLevel(VolumeTextureSampler, saturate(CurPos),0).r;
accumdens += cursample * StepSize * FinalStepSize;
return accumdens;
Maybe you already know this, just in case:
The syntax for the Texture2DSampler in HLSL for Unreal is:
Texture2DSample([TextureObject], [TextureObject]Sampler, [UV]);
If you name your TextureObject “InTex”, the automatically created sampler would be named “InTexSampler”.
So for example:
Texture2DSample(
InTex,
InTexSampler, float2(0.f, 0.f));
I guess it is the same for the 3D/volume sampler. But maybe you already have a better way to sample.
————————————————————————————————-
Unreal materials always generate HLSL code:
- MaterialEditor → Window → Shader Code → HLSL Code
- contents of Custom nodes get parsed into a function, search for the comment “// uniform_material_expressions” the function should be called something like MaterialFloat3 CustomExpression0(FMaterialPixelParameters Parameters)
I got to know it from from this article:
1 Like
I didn’t know you could view the HLSL code. Thanks for that tip and the link. With all these things combined, I have achieved what I desired.
Voila!