parallaxOcclusion
parallaxOcclusion(v_uv : Node<vec2>, dispTex : Node<Texture>, parallaxScale : Node<float>, blueNoiseTex : Node<Texture>|null, minSamples : Node<int>, maxSamples : Node<int>, refineSteps : Node<int>, edgeMargin : Node<float>) : Node<vec3>Parallax Occlusion Mapping (POM) node for high-quality surface displacement.
Algorithm
- Ray-marches through displacement texture along view direction
- Adaptive sampling: more samples at grazing angles
- Binary search refinement for sub-texel precision
- Blue noise jittering to eliminate banding artifacts
- Edge fading prevents UV stretching at borders
- Computes depth offset for correct depth buffer integration
Benefits
- Creates deep surface detail without tessellation
- Accurate self-shadowing and occlusion
- Smooth interpolation via binary refinement
- Perceptually uniform with blue noise sampling
- Automatic LOD via adaptive sample count
Parameters
v_uvNode<vec2>UV coordinates node.
dispTexNode<Texture>Displacement/height map texture (white=raised, black=recessed).
parallaxScaleoptionalNode<float>Scale factor controlling depth of parallax effect.
Default is
Default is
0.05.blueNoiseTexoptionalNode<Texture> | nullOptional blue noise texture for jitter (reduces banding).
Default is
Default is
null.minSamplesoptionalNode<int>Minimum ray-march samples (used at perpendicular view).
Default is
Default is
24.maxSamplesoptionalNode<int>Maximum ray-march samples (used at grazing angles).
Default is
Default is
96.refineStepsoptionalNode<int>Binary search refinement iterations for precision.
Default is
Default is
3.edgeMarginoptionalNode<float>UV margin for edge fade (prevents stretching).
Default is
Default is
0.02.Returns
Node<vec3> — Displaced UV coordinates (xy) and depth pixel offset (z).See also
- {@link https://web.archive.org/web/20150419215321/http://sunandblackcat.com/tipFullView.php?l=eng&topicid=28}
- {@link https://learnopengl.com/Advanced-Lighting/Parallax-Mapping}
Example
import { parallaxOcclusion } from '@three-blocks/core';
import { texture, uv } from 'three/tsl';
const material = new MeshStandardNodeMaterial();
const heightMap = texture(heightTexture);
const blueNoise = texture(blueNoiseTexture);
// Apply POM to displace UVs
const result = parallaxOcclusion(
uv(),
heightMap,
0.08, // parallax depth scale
blueNoise, // optional noise for quality
32, // min samples
128, // max samples
4 // refinement steps
);
// Use displaced UVs for texture sampling
material.colorNode = texture(diffuseTex, result.xy);
material.normalNode = normalMap(texture(normalTex, result.xy));