Click here to Skip to main content
Click here to Skip to main content

Basic Illumination Model in C#

, 9 Apr 2013 GPL3
Rate this:
Please Sign up or sign in to vote.
Basic illumination model in C#.

Screenshot - Ambient.png

Ambient

Screenshot - Diffuse.png

Diffuse

Screenshot - Specular.png

Specular

Screenshot - Ambient+Diffuse.png

Ambient+Diffuse

Screenshot - Diffuse+Specular

Diffuse+Specular

Screenshot - Ambient+Diffuse+Specular

Ambient+Diffuse+Specular

Introduction

In my previous article Simple Ray Tracing in C#, we saw how to display spheres using a simple ray tracing algorithm. Now, we will start from the last point and will work with basic illumination models.

By definition, we have three types of light:

  • Ambient
  • Diffuse
  • Specular

Ambient

It is considered as the light distributed by the environment, which contributes to the global illumination independent of the light position, objects, or observer.

Diffuse

It is the light the contribution of which depends on its incidence angle. Diffuse light hit can be reflected in all directions.

Specular

Specular lights represent the bright spots in objects; the more reflective it is the smaller the bright spot.

Background

To proceed with an illumination algorithm, we need to get the ambient, diffuse, and specular constants for the material we want to model; for example, here we use brass constants which are:

K Ambient Diffuse Specular
RED 0.329412 0.780392 0.992157
GREEN 0.223529 0.568627 0.941176
BLUE 0.027451 0.113725 0.807843

Exponent 27.8974

The ray tracing algorithm used is the same as you can see on Simple Ray Tracing in C# with the improvements of a basic illumination model.

The Equations

A Light Source is defined as an R3 (x,y,z) point with a (vx,vy,vz) direction vector.

An Observer is defined as an R3 (x,y,z) point with a (vx,vy,vz) direction vector.

Theta is defined as the angle between a light ray and a normal vector at the intersection point P on the surface.

Phi is defined as the angle between the reflected light ray at the intersection point P on the surface and the viewer ray to the same point P.

The Sphere Equation

  • r2 = (x-cx)2+(y-cy)2+(z-cz)2

Illumination on a given pixel:

  • IAmbient = I * KAmbient
  • IDiffuse = I * KDiffuse * cos(theta)
  • ISpecular = I * KSpecular * cos(phi)n
  • I = IAmbient + IDiffuse + ISpecular

Reflection calculation:

  • i' = i - (2 * n * dot(i, n))

where

  • i = incidence light ray
  • n = normal at intersection
  • i' = reflected ray

The Code

...
if (spherehit != null)
     {
     double intersx  = px + t * vx, intersy = py + t * vy,
                       intersz = pz + t * vz;
     double vNormalX = intersx - spherehit.cx,
                       vNormalY=intersy - spherehit.cy,
                       vNormalZ=intersz - spherehit.cz;
     double cost     = tAlgebra.GetCosAngleV1V2(lvx, lvy, lvz, vNormalX,
                       vNormalY, vNormalZ);
     if (cost < 0) cost = 0;

     double vReflX = 0, vReflY = 0, vReflZ = 0;
     double vEye2IntersX = px - intersx, vEye2IntersY = py - intersy,
                           vEye2IntersZ = pz - intersz;

     tAlgebra.Reflect(lvx,lvy,lvz, vNormalX,vNormalY,vNormalZ,ref vReflX,
                      ref vReflY, ref vReflZ);
     double cosf = tAlgebra.GetCosAngleV1V2(vReflX, vReflY, vReflZ,
                   vEye2IntersX, vEye2IntersY, vEye2IntersZ);
     if (cosf < 0) cosf = 0;

     double result1 = cost * 255.0;
     double result2 = Math.Pow(cosf, spherehit.shininess) * 255.0;
     double rgbR = (spherehit.ambientR * 255.0)+(spherehit.diffuseR *
                    result1) + (spherehit.specularR * result2);
     double rgbG = (spherehit.ambientG * 255.0) +(spherehit.diffuseG *
                    result1) + spherehit.specularG * result2);
     double rgbB = (spherehit.ambientB * 255.0) +(spherehit.diffuseB *
                    result1) + (spherehit.specularB * result2);
     rgbR = Math.Min(rgbR, 255);
     rgbG = Math.Min(rgbG, 255);
     rgbB = Math.Min(rgbB, 255);
     color = Color.FromArgb((int)rgbR, (int)rgbG, (int)rgbB);
     ...
     }
...

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

andalmeida
Engineer IBM
Brazil Brazil
Senior Analyst
 
Founder of TIHunter Vagas de TI
 
Linkedin Profile
Follow on   LinkedIn

Comments and Discussions

 
QuestionHow can I do this on my project? Pinmembertazugur16-Aug-13 6:35 
AnswerRe: How can I do this on my project? Pinmemberandalmeida21-Aug-13 9:14 
GeneralRe: How can I do this on my project? Pinmembertazugur21-Aug-13 9:58 
GeneralRe: How can I do this on my project? Pinmemberandalmeida21-Aug-13 10:03 
GeneralRe: How can I do this on my project? Pinmembertazugur21-Aug-13 10:29 
GeneralRe: How can I do this on my project? Pinmemberandalmeida21-Aug-13 10:06 
GeneralRe: How can I do this on my project? Pinmembertazugur21-Aug-13 10:16 
GeneralRe: How can I do this on my project? Pinmemberandalmeida21-Aug-13 10:19 
GeneralMy vote of 5 Pinmembermanoj kumar choubey26-Feb-12 22:16 
GeneralLast article on Raytracing Pinmemberandalmeida29-Apr-09 3:03 
GeneralSpecular Highlight [modified] Pinmemberefi_germany3-Aug-07 9:43 
GeneralRe: Specular Highlight Pinmemberandalmeida3-Aug-07 10:01 
Hi,
 
the observer and light are on same side of object for those tracings...
 
Follows the settings:
 
// observer/eye/camera
double px = 0.0;
double py = 0.0;
double pz = 600.0;
 
// light position
double lpx = 200.0;
double lpy = 200.0;
double lpz = 200.0;
 

// sphere centered at (0,0,90) radius=100
tSphere sph1 = new tSphere(0.0, 0.0, 90.0, 100.0, 0.0, 0.0, 255.0);

// ambient properties for the material
sph1.ambientR = 0.329412;
sph1.ambientG = 0.223529;
sph1.ambientB = 0.027451;
 
// specular properties for the material
sph1.specularR = 0.992157;
sph1.specularG = 0.941176;
sph1.specularB = 0.807843;
sph1.shininess = 27.8974;
 
sph1.diffuseR = 0.780392;
sph1.diffuseG = 0.568627;
sph1.diffuseB = 0.113725;
 
double intersx = px + t * vx, intersy = py + t * vy,
intersz = pz + t * vz;
double vNormalX = intersx - spherehit.cx, vNormalY=intersy -
spherehit.cy, vNormalZ=intersz - spherehit.cz;
 
//diffuse calculation: based on the angle theta (the angle between
ray direction and surface normal at intersection)
double cost = tAlgebra.GetCosAngleV1V2(lvx, lvy, lvz, vNormalX,
vNormalY, vNormalZ);
 
double vReflX = 0, vReflY = 0, vReflZ = 0;
double vEye2IntersX = px - intersx, vEye2IntersY = py - intersy,
vEye2IntersZ = pz - intersz;
tAlgebra.Reflect(lvx,lvy,lvz, vNormalX,vNormalY,vNormalZ,ref vReflX,
ref vReflY, ref vReflZ);

// specular calculation: based on the angle phi (the angle between
viewing direction and reflected ray direction)
double cosf = tAlgebra.GetCosAngleV1V2(vReflX, vReflY, vReflZ,
vEye2IntersX, vEye2IntersY, vEye2IntersZ);
 
Anyway, i have applied some rotation to the final points in some shots Smile | :)
 
Anderson J. Almeida
Systems Analyst
SimSysBr

GeneralRe: Specular Highlight Pinmemberefi_germany3-Aug-07 10:24 
GeneralRe: Specular Highlight Pinmemberandalmeida3-Aug-07 12:38 
GeneralRe: Specular Highlight Pinmemberandalmeida10-Aug-07 6:34 
Generalnice one PinmemberAmar Chaudhary26-Jul-07 14:45 
GeneralRe: nice one Pinmemberandalmeida29-Jul-07 4:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 9 Apr 2013
Article Copyright 2007 by andalmeida
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid