Intrinsics1 min read

reflect

Reflects a vector about a normal.

Reading Time
1 min
Word Count
144
Sections
12
Try It Live

Test reflect in a live shader

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

Open Playground

Live Demo

The reflect function computes the reflection of an incident vector about a surface normal.

Signature

bwsl
reflect :: (vecN i, vecN n) -> vecN {...}

Where vecN can be float2, float3, or float4.

Parameters

ParameterTypeDescription
ivecNIncident vector (pointing toward surface)
nvecNSurface normal (must be normalized)

Return Value

Returns the reflected vector: i - 2.0 * dot(n, i) * n.

Example

bwsl
pipeline EnvironmentReflection {
fragment {
float3 normal = normalize(input.normal);
float3 viewDir = normalize(cameraPos - input.worldPos);
// Calculate reflection vector
float3 reflectDir = reflect(-viewDir, normal);
// Sample environment map
float2 envUV = float2(
atan2(reflectDir.z, reflectDir.x) / 6.28318 + 0.5,
asin(reflectDir.y) / 3.14159 + 0.5
);
float3 envColor = sample(envMap, envUV).rgb;
// Blend with base color using fresnel
float fresnel = pow(1.0 - max(dot(normal, viewDir), 0.0), 5.0);
float3 finalColor = lerp(baseColor, envColor, fresnel * reflectivity);
output.color = float4(finalColor, 1.0);
}
}

Common Use Cases

Specular Reflection

bwsl
// Phong specular using reflection
float3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(reflectDir, viewDir), 0.0), shininess);

Cubemap Sampling

bwsl
// Sample reflection cubemap
float3 R = reflect(-viewDir, normal);
float3 envColor = sample(envCubemap, R).rgb;

Ray Bouncing

bwsl
// Bounce ray off surface
float3 newRayDir = reflect(rayDir, hitNormal);

Water Reflections

bwsl
// Calculate water surface reflection
float3 waterNormal = normalize(float3(waveX, 1.0, waveZ));
float3 reflectionVec = reflect(-viewDir, waterNormal);

Mirror Effect

bwsl
// Perfect mirror reflection
float3 mirrorReflect = reflect(incidentRay, surfaceNormal);
float4 mirrorColor = sample(sceneTex, screenUV + offset);

Normal Must Be Normalized

The normal vector n must be normalized for correct results. The incident vector i doesn't need to be normalized, but typically is.

Incident Direction

The incident vector should point toward the surface (opposite to the view direction). That's why you often see reflect(-viewDir, normal).

Compiled Output

When compiled to GLSL:

glsl
reflect(i, n)

When compiled to HLSL:

hlsl
reflect(i, n)

See Also