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 PlaygroundLive 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
| Parameter | Type | Description |
|---|---|---|
i | vecN | Incident vector (pointing toward surface) |
n | vecN | Surface 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)