程序代写代做代考 PowerPoint Presentation

PowerPoint Presentation

16. Practical Raytracing

Dr. Hamish Carr

COMP 5812M: Foundations of Modelling & Rendering
Building a Raytracer
Pixels – rays – geometric intersections
BSSDFs & functions for them
Monte Carlo sampling for rays
Point & area light sources
Shadow rays
Reflective/refractive impulses vs. reflections

COMP 5812M: Foundations of Modelling & Rendering
Core Path Tracer Code
main()
{ // main
for (each pixel)
set pixelRadiance to (0)
Ray r = pixel – eye
for (sample = 0 to nSamples)
pixelRadiance += pathTrace(ray, true)
} // main

COMP 5812M: Foundations of Modelling & Rendering
Path Tracing
Radiance3 pathTrace(Ray ray, bool isEyeRay)
{ // pathTrace
// initialise output sum to zero
Radiance3 output(0.0, 0.0, 0.0);
if (surfel = world->intersect(ray, dist))
{ // ray intersects something, stores it in surfel
// if eye ray hits a light, add emission
if (isEyeRay && surfel.emits)
output += surfel.material.emission;

// compute direct illumination from point & area lights
if ((!isEyeRay) || surfel.reflectsDirect)
{ // direct illumination
output += estimateDirectPointLight(surfel, ray)
output += estimateDirectAreaLight(surfel, ray)
} // direct illumination

// use recursion for impulse scattering
if ((!isEyeRay) || surfel.scattersImpulse)
output += estimateImpulseScattering(surfel, ray, isEyeRay)

// finally, add in indirect illumination
if (!(isEyeRay) || m_indirect)
output += estimateIndirectLight(surfel, ray, isEyeRay)
} // ray intersects something, stores it in surfel
// return the sum
return output;
} // pathTrace

COMP 5812M: Foundations of Modelling & Rendering
Stage I: Emitted Light
A ray might hit an area light source
but not a point source
So all area light sources are also emitters
If we hit them, add an emissive term
But only on the first bounce!

COMP 5812M: Foundations of Modelling & Rendering
Path Tracing, I
Radiance3 pathTrace(Ray ray, bool isEyeRay)
{ // pathTrace
// initialise output sum to zero
Radiance3 output(0.0, 0.0, 0.0);
if (surfel = world->intersect(ray, dist))
{ // ray intersects something, stores it in surfel
// if eye ray hits a light, add emission
if (isEyeRay && surfel.emits)
output += surfel.material.emission;

// compute direct illumination from point & area lights
if ((!isEyeRay) || surfel.reflectsDirect)
{ // direct illumination
output += estimateDirectPointLight(surfel, ray)
output += estimateDirectAreaLight(surfel, ray)
} // direct illumination

// use recursion for impulse scattering
if ((!isEyeRay) || surfel.scattersImpulse)
output += estimateImpulseScattering(surfel, ray, isEyeRay)

// finally, add in indirect illumination
if (!(isEyeRay) || m_indirect)
output += estimateIndirectLight(surfel, ray, isEyeRay)
} // ray intersects something, stores it in surfel
// return the sum
return output;
} // pathTrace

COMP 5812M: Foundations of Modelling & Rendering
Stage II: Direct Light
Direct light can come from:
point sources (an impulse light)
area sources (a distribution)
So we treat them separately

COMP 5812M: Foundations of Modelling & Rendering
Path Tracing, II
Radiance3 pathTrace(Ray ray, bool isEyeRay)
{ // pathTrace
// initialise output sum to zero
Radiance3 output(0.0, 0.0, 0.0);
if (surfel = world->intersect(ray, dist))
{ // ray intersects something, stores it in surfel
// if eye ray hits a light, add emission
if (isEyeRay && surfel.emits)
output += surfel.material.emission;

// compute direct illumination from point & area lights
if ((!isEyeRay) || surfel.reflectsDirect)
{ // direct illumination
output += estimateDirectPointLight(surfel, ray)
output += estimateDirectAreaLight(surfel, ray)
} // direct illumination

// use recursion for impulse scattering
if ((!isEyeRay) || surfel.scattersImpulse)
output += estimateImpulseScattering(surfel, ray, isEyeRay)

// finally, add in indirect illumination
if (!(isEyeRay) || m_indirect)
output += estimateIndirectLight(surfel, ray, isEyeRay)
} // ray intersects something, stores it in surfel
// return the sum
return output;
} // pathTrace

COMP 5812M: Foundations of Modelling & Rendering
Direct Point Lights, I
Radiance3 estimateDirectPointLight(SurfaceElement surfel, Ray ray)
{ // estimateDirectPointLight
 Radiance3 output (0)

  for (source = 0; source < nPointLights; ++source) { // per point light source // cast shadow ray to determine visibility if (lineOfSight(Ray(surfel.location,surfel.normal,pLight[source].position)))  { // if not in shadow // compute the incoming vector Vector omega_i = light.position – surfel.location float distance = omega_i.length() // compute inverse square attenuation Irradiance3 E_i = light.colour / (4 * PI * distance * distance) // use BSDF to convert to light output output += surfel.BSDF(omega_i, -ray.direction) * E_i * max(0, omega_i.dot(surfel.normal)) } // if not in shadow } // per point light source   return output;   } // estimateDirectPointLight COMP 5812M: Foundations of Modelling & Rendering Direct Point Lights, II Radiance3 estimateDirectPointLight(SurfaceElement surfel, Ray ray) { // estimateDirectPointLight  Radiance3 output (0)   for (source = 0; source < nPointLights; ++source) { // per point light source // cast shadow ray to determine visibility if (lineOfSight(Ray(surfel.location, pointLight[source].position)))  { // if not in shadow // compute the incoming vector Vector omega_i = light.position – surfel.location float distance = omega_i.length() // compute inverse square attenuation Irradiance3 E_i = light.colour / (4 * PI * distance * distance) // use BSDF to convert to light output output += surfel.BSDF(omega_i, -ray.direction) * E_i * max(0, omega_i.dot(surfel.normal)) } // if not in shadow } // per point light source   return output;   } // estimateDirectPointLight COMP 5812M: Foundations of Modelling & Rendering Area Light Sources Iterate over many points: Generate random position on the light source with Monte Carlo sampling Trace rays to there COMP 5812M: Foundations of Modelling & Rendering Direct Area Lights Radiance3 estimateDirectAreaLight(SurfaceElement surfel, Ray ray) { // estimateDirectAreaLight  Radiance3 output (0)   for (source = 0; source < nAreaLights; ++source) { // per point light source // generate a random point on the surface of the light SurfaceElement lightSurfel = aLight[source].samplePoint() // cast shadow ray to determine visibility if (lineOfSight(Ray(surfel.location, lightSurfel.location)))  { // if not in shadow // compute the incoming vector Vector omega_i = lightSurfel.location – surfel.location float distance = omega_i.length() // use BSDF to convert to light output output += surfel.BSDF(omega_i, -ray.direction) * aLight[source].power * PI * max(0, omega_i.dot(surfel.normal)) } // if not in shadow } // per point light source   return output;   } // estimateDirectAreaLight COMP 5812M: Foundations of Modelling & Rendering Stage III: Impulse Scattering We can treat this in the indirect computation OR we can trace the perfect reflection as a ray And follow it back an extra bounce i.e. use recursion to simplify the code COMP 5812M: Foundations of Modelling & Rendering Path Tracing, III Radiance3 pathTrace(Ray ray, bool isEyeRay) { // pathTrace // initialise output sum to zero Radiance3 output(0.0, 0.0, 0.0); if (surfel = world->intersect(ray, dist))
{ // ray intersects something, stores it in surfel
// if eye ray hits a light, add emission
if (isEyeRay && surfel.emits)
output += surfel.material.emission;

// compute direct illumination from point & area lights
if ((!isEyeRay) || surfel.reflectsDirect)
{ // direct illumination
output += estimateDirectPointLight(surfel, ray)
output += estimateDirectAreaLight(surfel, ray)
} // direct illumination

// compute impulse scattering
if ((!isEyeRay) || surfel.scattersImpulse)
output += estimateImpulseScattering(surfel, ray, isEyeRay)

// finally, add in indirect illumination
if (!(isEyeRay) || m_indirect)
output += estimateIndirectLight(surfel, ray, isEyeRay)
} // ray intersects something, stores it in surfel
// return the sum
return output;
} // pathTrace

COMP 5812M: Foundations of Modelling & Rendering
Impulse Scattering
Radiance3 estimateImpulseScattering(SurfaceElement surfel, Ray ray, bool isEyeRay)
{ // estimateImpulseScattering
// call routine to do either reflection or refraction
Vector impulseDirection = surfel.getImpulseScatterDirection(-ray.direction)
Ray secondaryRay = Ray(surfel.location, impulseDirection)

// call recursively
return pathTrace(secondaryRay, isEyeRay, isEyeRay) * surfel.impulse.magnitude

} // estimateImpulseScattering

COMP 5812M: Foundations of Modelling & Rendering
Stage IV: Indirect Light
Create a bounce ray
Use extinction factor to terminate
i.e. 100% – total reflectance of surface
eventually all rays will disappear
Path trace it recursively
Set isEyeRay to false

COMP 5812M: Foundations of Modelling & Rendering
Path Tracing, IV
Radiance3 pathTrace(Ray ray, bool isEyeRay)
{ // pathTrace
// initialise output sum to zero
Radiance3 output(0.0, 0.0, 0.0);
if (surfel = world->intersect(ray, dist))
{ // ray intersects something, stores it in surfel
// if eye ray hits a light, add emission
if (isEyeRay && surfel.emits)
output += surfel.material.emission;

// compute direct illumination from point & area lights
if ((!isEyeRay) || surfel.reflectsDirect)
{ // direct illumination
output += estimateDirectPointLight(surfel, ray)
output += estimateDirectAreaLight(surfel, ray)
} // direct illumination

// compute impulse scattering
if ((!isEyeRay) || surfel.scattersImpulse)
output += estimateImpulseScattering(surfel, ray, isEyeRay)

// finally, add in indirect illumination
if (!(isEyeRay) || m_indirect)
output += estimateIndirectLight(surfel, ray, isEyeRay)
} // ray intersects something, stores it in surfel
// return the sum
return output;
} // pathTrace

COMP 5812M: Foundations of Modelling & Rendering
Indirect Light, I
Radiance3 estimateIndirectLight(SurfaceElement &surfel,
const Ray&ray, bool isEyeRay)
{ // estimateIndirectLight
// use materials to determine whether photon was extinguished
if (random() > surfel.extinction_probability())
return 0.0
else
{ // not extinguished
bounceVector = randomVector(surfel.normal)
Ray bounceRay(surfel, bounceVector)
return pathTrace(bounceRay, false)
} // not extinguished

} // estimateIndirectLight

COMP 5812M: Foundations of Modelling & Rendering