Rim-Lighting Shader Problem

I’m trying to implement a very simple rim-lighting shader, based on shader code extracted from the example here
http://www.catalinzima.com/?page_id=396

The problem is, it’s not really working for me, unfortunately.

Here’s what I get:

As you can see, the rim-lighting effect cuts off sharply, instead of going all the way around.

Here’s the shader code:

Vertex Shader:

varying vec3 normal;
varying vec4 ecPos;

void main()
{
	ecPos = gl_ModelViewMatrix * gl_Vertex;
	
	gl_Position = gl_ProjectionMatrix * ecPos;
	
	normal = gl_NormalMatrix * gl_Normal;

	gl_FrontColor = gl_Color;
	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}

Fragment Shader:

varying vec3 normal;
varying vec4 ecPos;

uniform sampler2D DiffuseMap;	// Diffuse Map (base texture)

uniform float Rim_Start;		// Rim Begin		Range 0.0 > 1.0
uniform float Rim_End;		// Rim End 		Range 0.0 > 1.0
uniform float Rim_Multiplier;	// Rim Multiplier	Range 0.0 > 5.0
uniform vec4 Rim_Color;		// Rim Color

uniform vec3 Light_Direction;	// Light Direction Vector
uniform vec4 Ambient_Color;		// Ambient Light Color
uniform vec4 Light_Color;		// Light Color

const vec3 CameraPosition = vec3(0.0);

void main()
{
	vec4 tex = texture2D(DiffuseMap, gl_TexCoord[0].xy);
	
	vec3 N = normalize(normal);
	vec3 V = normalize(CameraPosition - (ecPos.xyz / ecPos.z));
	float rim = smoothstep(Rim_Start, Rim_End, 1.0 - dot(N,V));
	
	vec3 L = normalize(-Light_Direction);
	float lightAmount = max(dot(N, L), 0.0);
	vec4 lighting = Ambient_Color + vec4(lightAmount) * Light_Color;
	lighting.a = 1.0;
	
	//Multiply color by texture
	gl_FragColor = tex * lighting + rim * Rim_Multiplier * Rim_Color;
}

Anything obvious I’m missing/getting wrong?

Cheers,

a|x
http://machinesdontcare.wordpress.com

Hmm… I thought that the ‘camera’ should always be assumed to be at 0.0,0.0,0.0, though I know there’s no concept of an actual camera in OpenGL.

However, if I alter the CameraPosition variable in the FS to vec3(0.0,0.0,2.0), I get pretty-much the effect I’m looking for. I guess the rim-lighting effect only works for normals that are behind the camera position in Eye Space. I’m very hazy on all these basic concepts though, so if anyone could explain if I have this right, I’m be very grateful.

Also, does moving the camera position in this way cause directional lighting like this to be inaccurate?

Sorry, as ever, for the really basic questions.

a|x
http://machinesdontcare.wordpress.com

I guess the rim-lighting effect only works for normals that are behind the camera position in Eye Space

What do you mean? oÔ

I don’t understand what you do here:


vec3 V = normalize(CameraPosition - (ecPos.xyz / ecPos.z));

vertex position after modelview transformation is in eye space and ecPos is related to the camera position. After this transformation, the camera is considered to be at (0,0,0) looking toward z negative.

So, what you are doing in the last code line is useless and what do you want to do by divinding ecPos.xyz by ecPos.z?

Hi dletozeun,

thanks for getting back to me.

I guess the rim-lighting effect only works for normals that are behind the camera position in Eye Space

I meant that normals that point away from the camera position aren’t properly dealt with. Seemed to make sense to me at the time, but it’s probably based on an incomplete understanding of how the shader works…

I see. So, in fact, I don’t need the CameraPosition variable at all, and V can be just
normalize(-ecPos)
Makes sense.

So, what you are doing in the last code line is useless and what do you want to do by divinding ecPos.xyz by ecPos.z?

Ah, that was a typo. It should have been
ecPos.xyz/ecPos.w
which I thought was the correct way of making a vec3 from a vec4 (rather than just using the xyz values directly).
You may have spotted the root of the problem there, I think.

Thanks again,

a|x
http://machinesdontcare.wordpress.com

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.