Skip to main content
gamedev.net
🔒 Locked

Lighting Algorithm

Started by RenderMe Apr 13, 2009 at 9:13 AM 3 replies 2k views
Original Post
RenderMe
RenderMe
Hey all, I was wondering if it would be possible for you guys to help me understand a lighting algorithm I found online. The source of this algorithm is : Lighting Algorithm And the algorithm is: (would be greatful if someone could show me how to tag code correctly)

-- some helper functions
zeroclip(X) = [(x when x > 0.0 else 0.0) for x in X]
oneclip(X)  = [(x when x < 1.0 else 1.0) for x in X]
unit(x) = x / |x| when |x| != 0.0 else 0.0
    
-- some pseudo-code to do the lighting
lightfunc(n, v, material, lights, camerapos) : (r,g,b) =
do {

    -- let n = surface normal (nx,ny,nz)
    -- let v = point in space (x,y,z)
    -- let lights = [light0, light1, ... ]
    -- let camerapos = (x,y,z)

    scolor = material.specularcolor -- (r,g,b)
    dcolor = material.diffusecolor  -- (r,g,b)
    acolor = material.ambientcolor  -- (r,g,b)
    shiny =  material.shininess     -- (a scalar, an exponent >= 0)
    
    -- start off the diffuse and specular
    -- at pitch black
    diffuse = [0.0, 0.0, 0.0]
    specular = [0.0, 0.0, 0.0]
    -- copy the ambient color (for the eyelight ex/cred
    -- code, you can change it here to rely on distance
    -- from the camera)
    ambient = acolor

    for l in lights
    do {
        -- get the light position and color from the light
        -- let lx = light position (x,y,z)
        -- let lc = light color (r,g,b)
        lx, lc = l

        -- first calculate the addition this light makes
        -- to the diffuse part
        ddiffuse = zeroclip(lc * (n . unit(lx - v))
        -- accumulate that
        diffuse += ddiffuse

        -- calculate the specular exponent
        k = zeroclip(n . unit(unit(camerapos - v) + unit(lx - v)))
        -- calculate the addition to the specular highlight
        -- k^shiny is a scalar, lc is (r,g,b)
        dspecular = zeroclip(k^shiny * lc)
        -- acumulate that
        specular += dspecular
    }
    -- after working on all the lights, clamp the diffuse value to 1
    d = oneclip(diffuse)
    -- note that d,dcolor,specular and scolor are all (r,g,b).
    -- * here represents component-wise multiplication
    rgb = oneclip(ambient + d*dcolor + specular*scolor)
    return rgb
}

On the whole I understand what the function does - for each light in the scene add the diffuse and specular contribution to a pixel. The bits im confused with is the helper functions i dont quite understand this guys pseudocode. Could someone please explain these or maybe provide the c++ equivalent. Also where the pseudocode says lc = light color (rgb) does he mean the ambient? If not what does he mean?? Finally, where does he make use of the lights ambient, diffuse and specular? I only see the material which i'm understanding as being the polygon. Thanks in advance [Edited by - RenderMe on April 13, 2009 10:24:58 AM]
MJP
MJP
It looks to me like the is using the same light color for the ambient, diffuse, and specular calculations. So there's only one color associated with each light.

BTW the tags you can use for formatting code are explained in the forum FAQ

[Edited by - MJP on April 13, 2009 10:47:13 AM]
SeraphLance
SeraphLance
That's some weird pseudocode. Two of the helper functions are written in really awkward almost-python, and the third is in a mathematical notation. I can't even begin to decode that lighting function.


zeroclip(X) = [(x when x > 0.0 else 0.0) for x in X]
oneclip(X) = [(x when x < 1.0 else 1.0) for x in X]
unit(x) = x / |x| when |x| != 0.0 else 0.0

For some C-like equivalents (not quite C++):
//basically, doesn't let the number go below zero.float[] zeroclip(X){   for(int i = 0; i<X.length; i++)   {      if(X < 0) X = 0;   }   return X;}//basically, doesn't let the number go above 1.float[] oneclip(X){   for(int i = 0; i<X.length; i++)   {      if(X > 1) X = 1;   }   return X;}//this is called "normalizing" by pretty much everyone else in the world.vector unit(x){   if (x.length == 0.0) return 0.0; //short circuit to prevent divide by zero.   return x / x.length;}


[Edited by - SeraphLance on April 13, 2009 10:03:30 AM]
RenderMe
RenderMe
Thanks for the info both, I kinda feel sorry for the students that have to pick that up [totally]
RenderMe
RenderMe
For anyone interested I opted to ignore the original algorithm and wrote my own based on the formula, Color = Ka*ambientColor + SumOf(Kd*diffuseColor*(N dot L) + Ks*specularColor*(R dot V)^shininess)--- although i have yet to implement shinyness

void Pipeline::calcLight(Triangle &t, vector<Light> &lights){	//Color = Ka*ambientColor + SumOf(Kd*diffuseColor*(N dot L) + Ks*specularColor*(R dot V)^shininess)	Color ka = t.ambientcolor;	Color kd = t.diffusecolor;	Color ks = t.specularcolor;	//ambientColor = white	Color ambientColor(1.0, 1.0, 1.0);	//Ka*ambientColor	float ambientFactorR = ka.r*ambientColor.r;	float ambientFactorG = ka.g*ambientColor.g;	float ambientFactorB = ka.b*ambientColor.b;	//Kd*diffuseColor*(N dot L)	float diffuseFactorR, diffuseFactorG, diffuseFactorB;	diffuseFactorR = diffuseFactorG = diffuseFactorB = 0;	//Ks*specularColor*(R dot V)^shininess	float specularFactorR, specularFactorG, specularFactorB;	specularFactorR = specularFactorG = specularFactorB = 0;	//for each pixel in the triangle	for(int i = 0; i < 3; i++)	{		//for all the lights in the scene		for(int j = 0; j < lights.size(); j++)		{						//diffuseColor = surfaceColor * lightColor			Color diffuseColor(lights[j].getDiffuse().r *kd.r, lights[j].getDiffuse().g*kd.g, lights[j].getDiffuse().b*kd.b);			//specularColor = lightColor			Color specularColor(lights[j].getSpecular());			//Kd*diffuseColor*(N dot L)			float dotProd;			dotProd = t.n * lights[j].worldVector();						diffuseFactorR += kd.r * diffuseColor.r * dotProd;			diffuseFactorG += kd.g * diffuseColor.g * dotProd;			diffuseFactorB += kd.b * diffuseColor.b * dotProd;				//Ks*specularColor*(R dot V)^shininess			//R = 2*N*(N dot L) - L			Vector3 R;			R = 2*t.n*dotProd - lights[j].worldVector();			float dotProd2;			dotProd2 = R * state.eyePos;						specularFactorR += ka.r * specularColor.r * dotProd2;			specularFactorG += ka.g * specularColor.g * dotProd2;			specularFactorB += ka.b * specularColor.b * dotProd2;		}		//Finally set the triangles color values		t.c.r = ambientFactorR + diffuseFactorR + specularFactorR;		t.c.g = ambientFactorG + diffuseFactorG + specularFactorG;		t.c.b = ambientFactorB + diffuseFactorB + specularFactorB;	}}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.