Edit*

Solved...I'm apparently just an idiot The method I was using to create my sphere models and UV maps was inverting things (the normals I'm guessing) inadvertently. I was trying to avoid as much distortion in the texture as possible, but that method is apparently no good for this. Loading just a basic sphere instead solves the problem below. I'll leave this up on the off-chance it's helpful to someone else making the same mistake. But, mods, no hard feelings if you'd rather just delete it.

Hello,

I've been learning opengl for a couple months now, and decided to start implementing shaders (probably rather late, I'd been avoiding them out of intimidation, and having my hands full with the rest of opengl) . Up until now I've simply been using the basic ones from the tutorials here:

#version 440 core // Input vertex data, different for all executions of this shader. layout(location = 0) in vec3 vertexPosition_modelspace; layout(location = 1) in vec2 vertexUV; layout(location = 2) in vec3 vertexNormal_modelspace; // Output data ; will be interpolated for each fragment. out vec2 UV; out vec3 Position_worldspace; out vec3 Normal_cameraspace; out vec3 EyeDirection_cameraspace; out vec3 LightDirection_cameraspace; // Values that stay constant for the whole mesh. uniform mat4 MVP; uniform mat4 V; uniform mat4 M; uniform vec3 LightPosition_worldspace; void main(){ // Output position of the vertex, in clip space : MVP * position gl_Position = MVP * vec4(vertexPosition_modelspace,1); // Position of the vertex, in worldspace : M * position Position_worldspace = (M * vec4(vertexPosition_modelspace,1)).xyz; // Vector that goes from the vertex to the camera, in camera space. // In camera space, the camera is at the origin (0,0,0). vec3 vertexPosition_cameraspace = ( V * M * vec4(vertexPosition_modelspace,1)).xyz; EyeDirection_cameraspace = vec3(0,0,0) - vertexPosition_cameraspace; // Vector that goes from the vertex to the light, in camera space. M is ommited because it's identity. vec3 LightPosition_cameraspace = ( V * vec4(LightPosition_worldspace,1)).xyz; LightDirection_cameraspace = LightPosition_cameraspace + EyeDirection_cameraspace; // Normal of the the vertex, in camera space Normal_cameraspace = ( V * M * vec4(vertexNormal_modelspace,0)).xyz; // Only correct if ModelMatrix does not scale the model ! Use its inverse transpose if not. // UV of the vertex. No special space for this one. UV = vertexUV; }

#version 440 core // Interpolated values from the vertex shaders in vec2 UV; in vec3 Position_worldspace; in vec3 Normal_cameraspace; in vec3 EyeDirection_cameraspace; in vec3 LightDirection_cameraspace; // Ouput data out vec4 color; // Values that stay constant for the whole mesh. uniform sampler2D myTextureSampler; uniform mat4 MV; uniform vec3 LightPosition_worldspace; void main(){ // Light emission properties // You probably want to put them as uniforms vec3 LightColor = vec3(10,10,10); float LightPower = 100000.0f; // Material properties vec4 MaterialDiffuseColor = texture2D( myTextureSampler, UV ); vec3 MaterialAmbientColor = vec3(.4,.4,.4) * MaterialDiffuseColor.rgb; vec3 MaterialSpecularColor = vec3(.2,.2,.2); // Distance to the light float distance = length( LightPosition_worldspace - Position_worldspace ); // Normal of the computed fragment, in camera space vec3 n = normalize( Normal_cameraspace ); // Direction of the light (from the fragment to the light) vec3 l = normalize( LightDirection_cameraspace ); // Cosine of the angle between the normal and the light direction, // clamped above 0 // - light is at the vertical of the triangle -> 1 // - light is perpendicular to the triangle -> 0 // - light is behind the triangle -> 0 float cosTheta = clamp( dot( n,l ), 0,1 ); // Eye vector (towards the camera) vec3 E = normalize(EyeDirection_cameraspace); // Direction in which the triangle reflects the light vec3 R = reflect(-l,n); // Cosine of the angle between the Eye vector and the Reflect vector, // clamped to 0 // - Looking into the reflection -> 1 // - Looking elsewhere -> < 1 float cosAlpha = clamp( dot( E,R ), 0,1 ); color.rgb = // Ambient : simulates indirect lighting MaterialAmbientColor + // Diffuse : "color" of the object MaterialDiffuseColor.rgb * LightColor * LightPower * cosTheta / (distance*distance) + // Specular : reflective highlight, like a mirror MaterialSpecularColor * LightColor * LightPower * pow(cosAlpha,5) / (distance*distance); color.a = MaterialDiffuseColor.a; }

//ModelMatrix generation //set newPosition, value used for collision. objVec[i]->rotation is quaternion. objVec[i]->newPosition = objVec[i]->ObjectToOrbit + (objVec[i]->rotation * ( objVec[i]->origPosition -objVec[i]->ObjectToOrbit)); //translate ModelMatrix. planetRotation is object spin. objVec[i]->ModelMatrix = glm::translate( objVec[i]->newPosition) * glm::rotate(objVec[i]->planetRotation, glm::vec3(0,1,0))* glm::scale(glm::vec3(objVec[i]->Pscale, objVec[i]->Pscale, objVec[i]->Pscale)) ;

//set light source before sending to GLSL else if(type == planet) { lightPos = ObjectToOrbit;//position of lightsource in world coordinates glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z); }

I thought initially I'm messing up the position in worldspace during rotation, and therefore glsl thinks that the planet is rotating in the wrong direction. However, collision, raytracing, and everything else looks accurate, so I'm unsure if that's the issue.

Then, I thought since I'm scaling the object, that perhaps I needed to use the transpose/inverse of the object. But, my implementations of it did not turn out right(it's possible I was doing it incorrectly). I would create a new mat4 for the inverted model matrix, calculate it by "glm::transpose(glm::inverse(ModelMatrix))" and then pass it into GLSL and change the vertex shader to look like:

//T is the transposed/inverted ModelMatrix Normal_cameraspace = ( V * T * vec4(vertexNormal_modelspace,0)).xyz;

This is probably the wrong way to do it. Though, I can remove the scaling entirely, negating the need to invert and I still have the lighting on the wrong side.

**Edited by Misantes, 09 July 2014 - 02:11 AM.**