Jump to content


Ray Tracer Phong Shader Problem


11 replies to this topic

#1 appleGuy

    New Member

  • Members
  • PipPip
  • 25 posts

Posted 17 July 2007 - 11:52 AM

Hi,

Ive tried to implement the phong shading model. However I cant seem to get it to work correctly. Its based of a lambert shader and the shader actually looks like a lambert shader, however there are no specular highlights or other defining features that make a phong shader.

Code That calculates Shader Colour at pixel level:

public colourRGBA calcPhongShader(ray Ray, float distance, Vector Lights){
        Vector3f cameraSpherePath = new Vector3f(Ray.getDirection());
        cameraSpherePath.scaleAdd(distance, Ray.getOrigin());
        
        //Calculate Sphere Normal
        float oneOverRadius = (1 / _radius);
        Vector3f normal = new Vector3f();
        normal.sub(cameraSpherePath, _centre);
        normal.scale(oneOverRadius);
        normal.normalize();
        
        //Calculate The Bounce Point (Sphere) light Vector
        Vector lightPathArray = new Vector();
        Vector lightPathReflectionArray = new Vector();
        
        lightObject light;
        
        for(int lightIter = 0; lightIter < Lights.size(); lightIter++){
            //ObjectToLight
            Vector3f sphereLight = new Vector3f();
            light = (lightObject)Lights.get(lightIter);
            sphereLight.sub(light.lightPosition, cameraSpherePath);
            sphereLight.normalize();
            lightPathArray.add(sphereLight);
            
            //Reflection Of Object To Light
            Vector3f reflect = new Vector3f();
            Vector3f reflectVar = new Vector3f();
            reflectVar.scale(Ray.getDirection().dot(normal), normal);
            reflectVar.scale(2.0f);
            
            reflect.sub(Ray.getDirection(), reflectVar);
     
            //R = V – 2 * (V·N) * N
            
            reflect.normalize();
                    
            
            lightPathReflectionArray.add(reflect);            
        }
        
        //View Direction Object To Camera
        Vector3f objToCam = new Vector3f();
        objToCam.sub(Ray.getOrigin(), cameraSpherePath);
        objToCam.normalize();
        
        colourRGBA colour = new colourRGBA();
        
        colour.red = this.Ka[0]; // MULTIPLIES BY IAMBENT? 
        colour.green = this.Ka[1]; // MULTIPLIES BY IAMBENT?
        colour.blue = this.Ka[2]; // MULTIPLIES BY IAMBENT?
        
        for(int lightIter = 0; lightIter < Lights.size(); lightIter++){
            Vector3f currentLightPath = (Vector3f)lightPathArray.get(lightIter);
            Vector3f currentLightReflection = (Vector3f)lightPathReflectionArray.get(lightIter);
            lightObject currentLight = (lightObject)Lights.get(lightIter);
            
            float cameraDOTReflection = objToCam.dot(currentLightReflection);
            
            float camDotRefPOW = (float)java.lang.Math.pow(cameraDOTReflection, this.shinyness);
            
            colour.red += (((this.Kd[0] * currentLightPath.dot(normal)) * currentLight.lightDiffuse[0]) + (this.Ks[0] * camDotRefPOW));
            colour.green += (((this.Kd[1] * currentLightPath.dot(normal)) * currentLight.lightDiffuse[1]) + (this.Ks[1] * camDotRefPOW));
            colour.blue += (((this.Kd[2] * currentLightPath.dot(normal)) * currentLight.lightDiffuse[2]) + (this.Ks[2] * camDotRefPOW));
        }
        
        return colour;     
    }
     

Thanks For Any Help
Cheers,
-Alex

#2 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 17 July 2007 - 01:51 PM

I haven't read your code but a common problem ist that you mix up the directions of your light and eye vector. They should both be pointing away from the surface point. Maybe I have some time to look at the code when I'm back from work...
If Prolog is the answer, what is the question ?

#3 appleGuy

    New Member

  • Members
  • PipPip
  • 25 posts

Posted 17 July 2007 - 02:48 PM

anubis said:

I haven't read your code but a common problem ist that you mix up the directions of your light and eye vector. They should both be pointing away from the surface point. Maybe I have some time to look at the code when I'm back from work...

Yeah if you could please have a look that would be great.

The point on sphere to light vector has got to be correct as the lambert shader would not work, which it does.

It seems like the Reflection or sphere to camera origin vectors are incorrect. As that part of the equation is the extension that takes a lambert to a phong.

Also what value for the shinyness (the n power) is used. 0 - 1.0, 0 - 100 ?

Cheers,
Alex

#4 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 17 July 2007 - 03:02 PM

Well... what exactly isn't working ? Picture ? I think 10 for the power value is reasonable for testing purposes.

Edit: Sorry... reread your post. If you are not seeing any highlights... What value are you using right now for the shininess ?
If Prolog is the answer, what is the question ?

#5 appleGuy

    New Member

  • Members
  • PipPip
  • 25 posts

Posted 17 July 2007 - 03:05 PM

anubis said:

Well... what exactly isn't working ? Picture ? I think 10 for the power value is reasonable for testing purposes.

Well my phong shader just looks liker a lambert shader. No specular highlights. Ive made sure that my specular colour is white and the light is in the correct position to create a visible specular mark..
Image:
Posted Image

edit: im using a specular power of 25.0f

#6 roel

    Senior Member

  • Members
  • PipPipPipPip
  • 678 posts

Posted 17 July 2007 - 05:52 PM

Just write the calculated values of the highlight (and the used values in your compuation like vectors, results of dot products, etc) to your debug output and you'll spot the error. Learn to debug, stuff like this is trivial, if you are already stuck in this phase you'll never write an interesting ray tracer.

#7 appleGuy

    New Member

  • Members
  • PipPip
  • 25 posts

Posted 17 July 2007 - 06:46 PM

roel said:

Just write the calculated values of the highlight (and the used values in your compuation like vectors, results of dot products, etc) to your debug output and you'll spot the error. Learn to debug, stuff like this is trivial, if you are already stuck in this phase you'll never write an interesting ray tracer.

That was a helpful post....

Like I've SAID i know where the problem is as its still producing a lambert shader. Hence SPHERETOCAM_DOT_REFLECTION to the specular power is incorrect.

Maybe I'm just learning the basics and not trying to create THE WORLD'S GREATEST RAY TRACER!

Just for the record I know how to debug, but not sure where the math is going wrong as I have followed the formula to the tee.

Please don't post if your not going to contribute positively

-Alex

#8 z80

    Valued Member

  • Members
  • PipPipPip
  • 104 posts

Posted 17 July 2007 - 07:32 PM

Hmm.. A few things look strange to me..

You compute the "reflect" for every light source and put it into an array.. Why? It is calculated from the normal and the direction of the ray.. The light source parameters dont go into this formula.. So why calculate it for every light source?

Then it looks to me like you compute camDotRefPOW as the dot between the vector pointing towards the cam and the reflect vector.. Shouldnt this be the vector pointing towards the light and the reflect vector instead? Think about it, it makes sense: When the ray coming from the eye get reflected and hits near the lightsource you get a highlight.

You probably also wanna check if camDotRefPOW is above zero before using it in your colour-calculation. You could have a negative value there introducing strangeness.

I used this page for reference.

#9 Nicholas Christopher

    Member

  • Members
  • PipPip
  • 77 posts

Posted 17 July 2007 - 07:40 PM

Just an idea here... maybe what you could do is see how you would implement
the lambert shader. Then analyze the differences and similarities between the lambert and phong and you might gain some insight into your problem..

Sorry if I cant give you a more concise answer that would pinpoint exactly what is the problem.
Nicholas Christopher
Architecture software development, and modeling
http:\\www.arconovum.com

#10 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 17 July 2007 - 09:17 PM

Quote

That was a helpful post....

Like I've SAID i know where the problem is as its still producing a lambert shader. Hence SPHERETOCAM_DOT_REFLECTION to the specular power is incorrect.

Maybe I'm just learning the basics and not trying to create THE WORLD'S GREATEST RAY TRACER!

Just for the record I know how to debug, but not sure where the math is going wrong as I have followed the formula to the tee.

Please don't post if your not going to contribute positively

Please don't tell people to shut up... As long as it's civil everybody can write whatever he/she wants. You don't have to take the advice. Afterall you are expecting that people read and debug your code here.

Quote

edit: i'm using a specular power of 25.0f

In general a higher shininess means a narrower spotlight on the surface, which makes sense, since you are taking the power of a dot product from normalized vectors, which is going to be between -1 and 1 (0 and 1 actually, since you are only interested in light sources in front of the surface).

Quote

Then it looks to me like you compute camDotRefPOW as the dot between the vector pointing towards the cam and the reflect vector.. Shouldnt this be the vector pointing towards the light and the reflect vector instead? Think about it, it makes sense: When the ray coming from the eye get reflected and hits near the lightsource you get a highlight.

Doesn't it make just as much sense, that you see a highlight, when the reflected light ray is close to the eye ?

http://en.wikipedia....eflection_model

Wikipedia uses it this way and so does

http://www.devmaster...i/Phong_shading

our own wiki :) And I think that it's really arbitrary, although so far I've only seen the formulation with the reflected light vector. But then of course you would have to compute the reflected light vector, which also would make a lot more sense in the loop there...
If Prolog is the answer, what is the question ?

#11 z80

    Valued Member

  • Members
  • PipPipPip
  • 104 posts

Posted 17 July 2007 - 09:24 PM

anubis said:

Doesn't it make just as much sense, that you see a highlight, when the reflected light ray is close to the eye ?

Same thing, but the opposite direction. Guess I was thinking a bit backwards because that is the direction the rays travel in a backward raytracer like appleGuy is writing.

anubis said:

But then of course you would have to compute the reflected light vector, which also would make a lot more sense in the loop there...

Why not use the eye-to-object vector and reflect that using the normal to get the reflected eye vector? Then you can compute the dot product of this and the direction towards the light. The result is the same but this method is faster since you only have to reflect one vector instead of one reflection per light source.

EDIT: A bit of pseudo-code:

D = eye ray direction

P = intersection point

N = normal


// Compute reflected eye vector

R = D - 2 * (D . N) * N


for each lightsource

	L = normalize(lightsource.pos - P)

	specular = R . L

	if (specular > 0)

		color +=

			material.spec_color *

			pow(specular, material.spec_power);


#12 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 17 July 2007 - 10:14 PM

Well... either way. You are taking the dot product using the reflected light and the object to eye vector or you are doing it in reverse. As I see it the code is taking the dot product between the reflected ray and the object to eye vector. That's got to be wrong I guess the intention really was to compute the reflected light... Why else would it be in the loop ?

He even calls it currentLightReflection in the second loop, which it's clearly not...
If Prolog is the answer, what is the question ?





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users