www.xbdev.net
xbdev - software development
Friday February 20, 2026
Home | Contact | Support | Computer Graphics Powerful and Beautiful ...
     
 

Physically-Based
Rendering

Lights and Rays ...

 



[TOC] Chapter 13: Light Transport I: Surface Reflection


Light transport describes how light interacts with surfaces and other materials to produce an image. One crucial aspect of light transport is surface reflection, which involves how light bounces off a surface and reaches the camera (or observer). This process involves sampling reflection functions, direct lighting, solving the light transport equation, and methods like path tracing to approximate the interaction of light with a scene.

Let's elaborate on the key topics and provide examples with JavaScript code snippets.

Sampling Reflection Functions


When light hits a surface, it can reflect in different ways based on the material properties. The Bidirectional Scattering Distribution Function (BSDF) is used to describe how light is reflected or transmitted at a surface. To compute the lighting at a point, we need to sample the reflection function, which means we generate a direction for light to travel after it interacts with the surface.

BRDF (Bidirectional Reflectance Distribution Function)


A BRDF is a type of BSDF that only deals with light reflection. It describes the ratio of reflected radiance \(L_r\) to the incoming irradiance \(E\), given the incoming and outgoing directions \( \omega_i \) and \( \omega_o \):

\[
f_r(\omega_i, \omega_o) = \frac{dL_r(\omega_o)}{dE(\omega_i)}
\]

This function gives the probability of light being reflected in a given direction.

Example: Sampling a Cosine-Weighted Lambertian BRDF


For diffuse surfaces (Lambertian reflection), we can sample the BRDF using cosine-weighted sampling:

// Generate cosine-weighted random direction for diffuse reflection
function cosineSampleHemisphere() {
    const 
Math.random();
    const 
Math.random();

    const 
Math.sqrt(u);
    const 
theta Math.PI v;

    const 
Math.cos(theta);
    const 
Math.sin(theta);
    const 
Math.sqrt(u); // Cosine-weighted distribution along z-axis

    
return { xy}; // Return the sampled direction in hemisphere
}


This function generates a random direction based on cosine-weighted sampling, which is useful for Lambertian surfaces (purely diffuse reflection).


Sampling Light Sources


The lighting at a point is often calculated by shooting rays towards the light sources and sampling their contribution. Sampling the light source involves generating random positions or directions from which light will arrive at the surface point.

Types of Light Source Sampling


Point Light Sampling: Sample a direction towards a point light.
Area Light Sampling: Sample a position on the surface of an area light.
Environment Light Sampling: Sample from a directional or sky environment.

Example: Sampling a Point Light


To compute lighting from a point light, we shoot a ray towards the light source and check if it reaches the light without being blocked by objects (i.e., shadow rays).

function samplePointLight(lightPossurfacePos) {
    const 
direction = {
        
xlightPos.surfacePos.x,
        
ylightPos.surfacePos.y,
        
zlightPos.surfacePos.z,
    };
    
    const 
distance Math.sqrt(direction.** direction.** direction.** 2);
    
    
// Normalize the direction
    
direction./= distance;
    
direction./= distance;
    
direction./= distance;
    
    return { 
directiondistance };
}


Here, we calculate the direction from a surface point to a point light. We can then trace a ray from the surface point towards the light to compute illumination and check for shadows.


Direct Lighting


Direct lighting refers to the light that directly reaches a surface from a light source, without bouncing off other surfaces. In ray tracing, we calculate direct lighting by casting rays towards light sources and checking if the rays are blocked (shadows) or unblocked (illuminated).

Direct Lighting Equation


The direct lighting equation can be expressed as:

\[
L_o(p, \omega_o) = \int_\Omega f_r(p, \omega_i, \omega_o) L_i(p, \omega_i) \cos \theta_i \, d\omega_i
\]

where:
\(L_o(p, \omega_o)\) is the outgoing radiance in direction \( \omega_o \),
\(f_r(p, \omega_i, \omega_o)\) is the BRDF,
\(L_i(p, \omega_i)\) is the incoming radiance from direction \( \omega_i \),
\(\theta_i\) is the angle between the surface normal and incoming light direction.

Example: Direct Lighting with a Point Light


function directLighting(surfacePossurfaceNormallightPoslightIntensity) {
    const { 
directiondistance } = samplePointLight(lightPossurfacePos);

    
// Compute the dot product between light direction and surface normal
    
const cosTheta Math.max(0surfaceNormal.direction.+
                                  
surfaceNormal.direction.+
                                  
surfaceNormal.direction.z);

    
// If the surface is facing the light
    
if (cosTheta 0) {
        const 
attenuation / (distance distance); // Simple distance attenuation
        
return lightIntensity cosTheta attenuation// Direct lighting contribution
    
}
    return 
0;
}


This function computes the direct lighting from a point light, taking into account the distance to the light, the orientation of the surface (via the dot product), and the light intensity.


The Light Transport Equation


The Light Transport Equation (LTE) governs the behavior of light as it moves through a scene and interacts with surfaces. It is a fundamental equation in rendering and ray tracing. The Rendering Equation, introduced by Kajiya, is a form of the LTE:

\[
L_o(p, \omega_o) = L_e(p, \omega_o) + \int_\Omega f_r(p, \omega_i, \omega_o) L_i(p, \omega_i) \cos \theta_i \, d\omega_i
\]

where:
\(L_o(p, \omega_o)\) is the outgoing radiance at point \(p\) in direction \( \omega_o \),
\(L_e(p, \omega_o)\) is the emitted radiance (if the point is a light source),
\(f_r(p, \omega_i, \omega_o)\) is the BSDF (or BRDF in the case of reflection),
\(L_i(p, \omega_i)\) is the incoming radiance from direction \( \omega_i \),
\(\theta_i\) is the angle between the incoming light direction and the surface normal.

Solving the Light Transport Equation


The equation is usually solved using numerical methods like Monte Carlo integration due to its complexity (it's an integral equation).

Code Snippet: Solving the Rendering Equation


function renderingEquation(surfacePossurfaceNormallightsbrdfnumSamples) {
    
let outgoingRadiance 0;

    
// For each light source
    
for (const light of lights) {
        for (
let i 0numSamplesi++) {
            
// Sample light source
            
const { directiondistance } = samplePointLight(light.positionsurfacePos);

            
// Compute incoming radiance from the light
            
const incomingRadiance light.intensity / (distance distance);

            
// Evaluate BRDF (assuming Lambertian for this example)
            
const brdfValue brdf(surfaceNormaldirection);

            
// Compute the cosine term
            
const cosTheta Math.max(0dot(surfaceNormaldirection));

            
// Accumulate the outgoing radiance
            
outgoingRadiance += incomingRadiance brdfValue cosTheta;
        }
    }

    return 
outgoingRadiance numSamples// Average the samples
}


In this snippet, we solve the rendering equation for a surface point by sampling light sources and evaluating the BRDF (here, assumed to be Lambertian).


Path Tracing


Path Tracing is a Monte Carlo method to approximate the solution to the light transport equation. It works by shooting rays (paths) into the scene, bouncing them off surfaces according to the material's BSDF, and accumulating the light contribution at each bounce until a termination condition is met.

Path Tracing Algorithm Steps


1. Shoot a ray from the camera through a pixel.
2. If the ray hits a surface, calculate the direct lighting at the intersection point.
3. Sample the BSDF to generate a new direction for the ray.
4. Trace the new ray (recursive step) and repeat the process.
5. Terminate the ray after a certain number of bounces or probabilistically using Russian roulette.
6. Accumulate the contribution of the light from each bounce to the pixel color.

Example: Simple Path Tracing


function pathTrace(rayscenedepth) {
    if (
depth <= 0) {
        return { 
r0g0b}; // Return black if the ray bounces too many times
    
}

    const 
hit intersectScene(rayscene); // Find the first intersection
    
if (!hit) {
        return { 
r0g0b}; // Return black if no intersection
    
}

    
// Direct lighting at the hit point
    
let color directLighting(hit.positionhit.normalscene.lightshit.material);

    
//

 
Recursive reflection based on the BSDF (e.g., Lambertian reflection)
    const 
newDirection sampleBRDF(hit.normal);
    const 
newRay = { originhit.positiondirectionnewDirection };

    const 
reflectedColor pathTrace(newRayscenedepth 1);

    
// Accumulate the reflected color with a weight based on the material
    
color.+= reflectedColor.hit.material.reflectivity;
    
color.+= reflectedColor.hit.material.reflectivity;
    
color.+= reflectedColor.hit.material.reflectivity;

    return 
color;
}


In this basic path tracer, we recursively trace rays through the scene, calculating direct lighting and accumulating light from reflected paths.







Ray-Tracing with WebGPU kenwright WebGPU Development Cookbook - coding recipes for all your webgpu needs! WebGPU by Example: Fractals, Image Effects, Ray-Tracing, Procedural Geometry, 2D/3D, Particles, Simulations WebGPU Games WGSL 2d 3d interactive web-based fun learning WebGPU Compute WebGPU API - Owners WebGPU & WGSL Essentials: A Hands-On Approach to Interactive Graphics, Games, 2D Interfaces, 3D Meshes, Animation, Security and Production Kenwright graphics and animations using the webgpu api 12 week course kenwright learn webgpu api kenwright programming compute and graphics applications with html5 and webgpu api kenwright real-time 3d graphics with webgpu kenwright webgpu for dummies kenwright webgpu api develompent a quick start guide kenwright webgpu by example 2022 kenwright webgpu gems kenwright webgpu interactive compute and graphics visualization cookbook kenwright wgsl webgpu shading language cookbook kenwright WebGPU Shader Language Development: Vertex, Fragment, Compute Shaders for Programmers Kenwright wgsl webgpugems shading language cookbook kenwright WGSL Fundamentals book kenwright WebGPU Data Visualization Cookbook kenwright Special Effects Programming with WebGPU kenwright WebGPU Programming Guide: Interactive Graphics and Compute Programming with WebGPU & WGSL kenwright



 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2025 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.