Intrinsics1 min read

sample_cmp

Samples a depth texture with comparison.

Reading Time
1 min
Word Count
176
Sections
11
Try It Live

Test sample_cmp in a live shader

Open the playground, start from a visual preset, and wire sample_cmp into the fragment stage to see how it behaves with real values.

Open Playground

Live Demo Pending

This intrinsic does not yet have a self-contained interactive preview. Compute-only and external-resource intrinsics need a different demo path than the current fragment and 3D showcases.

The sample_cmp function samples a depth/shadow texture and performs a comparison operation, returning a filtered comparison result useful for shadow mapping.

Signature

bwsl
sample_cmp :: (texture2D tex, sampler samp, float2 uv, float compareValue) -> float {...}

Parameters

ParameterTypeDescription
textexture2DDepth texture
sampsamplerComparison sampler state
uvfloat2Texture coordinates
compareValuefloatDepth value to compare against

Return Value

Returns a value in [0, 1] representing the comparison result. With filtering enabled, returns the percentage of samples that pass.

Example

bwsl
pipeline ShadowMapping {
fragment {
// Transform position to shadow map space
float4 shadowCoord = lightMatrix * float4(input.worldPos, 1.0);
shadowCoord.xyz /= shadowCoord.w;
// Transform from [-1,1] to [0,1]
float2 shadowUV = shadowCoord.xy * 0.5 + 0.5;
float compareDepth = shadowCoord.z;
// Sample shadow map with hardware PCF
float shadow = sample_cmp(shadowMap, shadowUV, compareDepth);
// Apply shadow
float3 lighting = ambient + diffuse * shadow;
output.color = float4(baseColor * lighting, 1.0);
}
}

Common Use Cases

Basic Shadow Mapping

bwsl
// Hardware-filtered shadow lookup
float shadow = sample_cmp(shadowMap, shadowUV, depth);

PCF Shadows

bwsl
// Multi-sample soft shadows
float shadow = 0.0;
for (int y = -1; y <= 1; y++) {
for (int x = -1; x <= 1; x++) {
float2 offset = float2(x, y) * texelSize;
shadow += sample_cmp(shadowMap, uv + offset, depth);
}
}
shadow /= 9.0;

Cascaded Shadow Maps

bwsl
// Sample appropriate cascade
float shadow;
if (depth < cascade0End) {
shadow = sample_cmp(resources.shadowMap0, resources.shadowSampler, uv0, depth0);
} else if (depth < cascade1End) {
shadow = sample_cmp(resources.shadowMap1, resources.shadowSampler, uv1, depth1);
}

Variance Shadow Mapping (VSM)

bwsl
// Compare for VSM filtering
float2 moments = sample(resources.momentMap, resources.shadowSampler, uv).rg;
float p = step(depth, moments.x);
float variance = moments.y - moments.x * moments.x;

Hardware PCF

When the sampler uses linear filtering, sample_cmp performs hardware-accelerated Percentage Closer Filtering (PCF), averaging the comparison results of neighboring texels.

Sampler Setup

The texture must be bound with a comparison sampler configured for depth comparison. The comparison function (less, greater, etc.) is set in the sampler state.

Compiled Output

When compiled to GLSL:

glsl
texture(shadowSampler, vec3(uv, compareValue))

When compiled to HLSL:

hlsl
tex.SampleCmpLevelZero(shadowSampler, uv, compareValue)

When compiled to Metal:

metal
tex.sample_compare(sampler, uv, compareValue)

See Also