Specular Shaders Problem

Started by fiendfan1, June 04, 2013, 00:20:57

Previous topic - Next topic

fiendfan1

I am having problems with specular shaders and lighting in general.

Here's the executable so you know what I'm talking about (Download zip, extract, run YFNH.jar): https://github.com/fiendfan1/YFNH-LWJGL/tree/master/3DYFNH/YFNH%20Executable

First of all, All I call is

glLight(id, GL_POSITION, lightPosition);	
glLightModel(GL_LIGHT_MODEL_AMBIENT, ambientInt);
glLight(id, GL_AMBIENT, ambientInt);
glLight(id, GL_SPECULAR, specInt);				
glLight(id, GL_DIFFUSE, diffInt);


to set up the light, but it always follows the camera.

I added some code that just changes the lightPosition FloatBuffer and then updates the light.

I call this code when a certain key is pressed (Q), and it basically makes it look like the highlighted parts are "painted" on. They don't move with movement of the camera.

To update the camera's position I am using:
glPushAttrib(GL_TRANSFORM_BIT);
glMatrixMode(GL_MODELVIEW);
glRotatef(this.parent.rotation.x, 1, 0, 0);
glRotatef(this.parent.rotation.y, 0, 1, 0);
glRotatef(this.parent.rotation.z, 0, 0, 1);
glTranslatef(-this.parent.position.x, -this.parent.position.y, -this.parent.position.z);
glPopAttrib();


The shaders Are:

Vert:
#version 120

varying vec4 varyingColour;

varying vec3 varyingNormal;

varying vec4 varyingVertex;

varying int texID;

attribute int textureID;

void main()
{
	texID = textureID;
	
    // Pass the vertex colour attribute to the fragment shader.
    varyingColour = gl_Color;
    
    // Pass the vertex normal attribute to the fragment shader.
    varyingNormal =  gl_Normal;
    
    // Pass the vertex position attribute to the fragment shader.
    varyingVertex = gl_Vertex;
    
    //Set gl_Position
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    
    //Set texture coords
    gl_TexCoord[0] = gl_MultiTexCoord0;
}


Frag:
#version 120

uniform sampler2D[10] textures;

varying vec4 varyingColour;

varying vec3 varyingNormal;

varying vec4 varyingVertex;

varying int texID;

void main()
{
	//Position of vertex in modelview space
    vec3 vertexPosition = (gl_ModelViewMatrix * varyingVertex).xyz;
    
    //Surface normal of current vertex
    vec3 surfaceNormal = normalize((gl_NormalMatrix * varyingNormal).xyz);
    
    //Direction light has traveled to get to vertexPosition
    vec3 lightDirection = normalize(gl_LightSource[0].position.xyz - vertexPosition);
    
    //Basically how much light is hitting the vertex
    float diffuseLightIntensity = max(0.0, dot(surfaceNormal, lightDirection));
    
    //"Main color" of vertex
    vec3 diffColor = diffuseLightIntensity * varyingColour.rgb;
    
    //Lowest light level possible
    vec3 ambColor = gl_LightModel.ambient;
    
    //Direction light is reflected off of surface normal
    vec3 reflectionDirection = normalize(reflect(-lightDirection, surfaceNormal));
    
    //The intensity of reflection (specular)
    float specular = max(0.0, dot(surfaceNormal, reflectionDirection));
    
    //Instantiate specColor for scope
    vec3 specColor = vec3(0.0, 0.0, 0.0);
    
    if (diffuseLightIntensity != 0.0)
    {
    	//Raise specular to exponent of shininess
        float fspecular = pow(specular, gl_FrontMaterial.shininess);
        specColor = fspecular;
    }
    
    if(texID == -1)
	{	
		//Does not have a texture, just use diffuse, specular, and ambient colors
		gl_FragColor = vec4(ambColor, 1.0) + vec4(diffColor + specColor, 1.0);
	}
	else 
	{
		//Fragment has texture, use the texture's color, and diffuse, specular, and ambient colors
		gl_FragColor = vec4(ambColor, 1.0) + vec4(diffColor * vec3(texture(textures[texID], gl_TexCoord[0].st)) + specColor, 1.0);
	}
}

quew8

From OpenGL FAQs:

Quote
A light's position is transformed by the current ModelView matrix at the time the position is specified with a call to glLight*(). This is analogous to how geometric vertices are transformed by the current ModelView matrix when they are specified with a call to glVertex*()

Perhaps this is your problem?

Also, you don't need the varyingVertex attribute in your shaders. You can access a fragments position with gl_FragCoord (vec4)