Skip to main content

Diffuse transmission and scattering

Diffuse transmission lets light emerge from the opposite side of a thin or scattering surface, useful for leaves, paper, and translucent ceramics.

The DiffuseTransmissionPlant sample demonstrates this capability. Drag to orbit and scroll to zoom.

GitHub
Loading examplePreparing GPU resources…

PBRMaterial reference​

PBRMaterial from @luma.gl/experimental is a typed engine Material backed by the shared pbrMaterial shader module. Its material fields are defined by PBRMaterialUniforms from @luma.gl/shadertools. Pass them through createPBRMaterial(device, {uniforms}) or update them with material.setProps({pbrMaterial: {...}}).

The fields below are optional. Defaults are the shared shader defaults; imported assets can supply other values.

FieldTypeDefaultDescription
diffuseTransmissionFactornumber0Fraction of dielectric diffuse energy transmitted into the opposite hemisphere.
diffuseTransmissionColorFactorReadonly<Vector3 | NumberArray3>[1, 1, 1]RGB tint of transmitted diffuse light.
diffuseTransmissionMapEnabledbooleanfalseEnables diffuse-transmission factor texture sampling.
diffuseTransmissionColorMapEnabledbooleanfalseEnables diffuse-transmission color texture sampling.
thicknessFactornumber0Volume thickness scale in model-space units.
multiscatterColorFactorReadonly<Vector3 | NumberArray3>[0, 0, 0]Experimental volume-scattering albedo.
multiscatterColorMapEnabledbooleanfalseEnables scattering-albedo texture sampling.
scatterAnisotropynumber0Henyey–Greenstein scattering anisotropy, ranging from -1 to 1.

PBRMaterialBindings​

Texture resources are supplied separately through PBRMaterialBindings. Each field below is optional and accepts Texture | null. createPBRMaterial() derives map-enabled flags from these resources. Enable the corresponding Model shader define listed below when supplying a texture; the helper does not choose the model shader defines.

FieldModel defineDescription
pbr_diffuseTransmissionSamplerHAS_DIFFUSETRANSMISSIONMAP: trueTexture resource for the diffuseTransmission slot.
pbr_diffuseTransmissionColorSamplerHAS_DIFFUSETRANSMISSIONCOLORMAP: trueTexture resource for the diffuseTransmissionColor slot.
pbr_multiscatterColorSamplerHAS_MULTISCATTERCOLORMAP: trueTexture resource for the multiscatterColor slot.

Supporting APIs​

createPBRMaterial​

createPBRMaterial(device, {uniforms, bindings, factory}) from @luma.gl/experimental returns a PBRMaterial. uniforms sets the fields listed above, bindings supplies material textures, and the optional factory shares a compatible binding schema across materials. The helper derives map-enabled flags from the supplied bindings; explicit uniform values take precedence.

MaterialFactory​

createPBRMaterialFactory(device) from @luma.gl/experimental creates a reusable engine MaterialFactory configured with the pbrMaterial shader module. Pass this factory to createPBRMaterial() when creating several compatible materials.

Material​

Material from @luma.gl/engine owns material uniforms and texture resources. setProps({pbrMaterial: {...}}) updates uniform values. Pass the material to a compatible Model through its material prop; models sharing it observe the same updates. Use clone({bindings: {...}}) when an appearance needs separate texture resources. Adding a texture or changing a shader feature may require matching defines and a compatible model shader layout.

See the materials guide and pbrMaterial reference.

The extended PBR shader path is disabled by default. Set USE_MATERIAL_EXTENSIONS: true in the Model construction defines to enable this feature; uniform values alone do not enable it. The glTF material parser supplies this define for imported extension materials.

Usage​

import {Model} from '@luma.gl/engine';
import {createPBRMaterial, type PBRMaterial} from '@luma.gl/experimental';

// device is an initialized Device.
const material: PBRMaterial = createPBRMaterial(device, {
uniforms: {
diffuseTransmissionFactor: 0.7,
diffuseTransmissionColorFactor: [0.6, 0.9, 0.4],
thicknessFactor: 0.2,
multiscatterColorFactor: [0.8, 0.9, 0.6],
scatterAnisotropy: 0.2
}
});

// modelProps contains your existing shaders, geometry, and buffer layout.
const model = new Model(device, {
...modelProps,
material,
defines: {...modelProps.defines, USE_MATERIAL_EXTENSIONS: true}
});

Scattering is a local, thickness-aware single-scattering approximation. Screen-space diffusion and random-walk multiple scattering are not implemented.

glTF support​

KHR_materials_diffuse_transmission is a release candidate rather than a ratified extension. The unratified KHR_materials_volume_scatter draft requires KHR_materials_volume. The plant sample demonstrates diffuse transmission; ScatteringSkull is a separate sample for the scattering draft.

See glTF materials and textures, glTF animation, and the extension support matrix for adapter details and current support limits.

All engine features