Archive for March 31st, 2008

31
Mar
08

Vertex Displacement Mapping + Normalmap

Normal mapping and vertex-displacement mapping from the same texture.
This ones uses the Kineme texture tools to create the displacement texture. It’s a classic use of the technique.

Not sure I’ll ever use this one ‘in anger’ but it’s an interesting test. I’m glad the lighting works so well, too.

The base colour comes from the normal map, incidentally.

Vertex Displace Mountains 03
Vertex Displace Mountains 04
Vertex Displace Mountains 05

The final screenshot shows the mesh from the back. Not quite sure why it looks so different from that side…

Next I have to work out if I can use the same technique with radial displacement. Think that might be a bit more tricky.

Advertisements
31
Mar
08

Bump Mapping

Thought I’d have a go using the Normal Map code from the last post to do some bump-mapping.
Turns out it’s quite easy to use the output of the Normal Map CIFilter as normals in a Fragment Shader. All that needs to be done is to transform it into the correct range by multiplying the RGB value of each pixel by 2.0, then subtracting 1.0.

Some examples using a simple Phong lighting model, and normals extracted from first a static image, then the live video from the iSight camera, run through the Normal Map CIFilter:

Bump Mapping 01
Bump Mapping 02

Here’s the GLSL code:

Vertex Shader:

varying vec3 normal, lightDir, eyeVec;

void main()
{
	// Normal from mesh
	normal = gl_NormalMatrix * gl_Normal;

	// Current Vertex coordinates transformed into World space
	vec3 Vertex = vec3(gl_ModelViewMatrix * gl_Vertex);

	// Light Direction
	lightDir = vec3(gl_LightSource[0].position.xyz - Vertex);
	// Eye Vector
	eyeVec = -Vertex;

	gl_Position = ftransform();

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

Fragment Shader:

varying vec3 normal, lightDir, eyeVec;
uniform sampler2D texture;
uniform sampler2D normalMap;

void main (void)
{
	// Base color
	vec4 final_color =
	(gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) +
	(gl_LightSource[0].ambient * gl_FrontMaterial.ambient);

	vec3 N = texture2D(normalMap, gl_TexCoord[0].st).rgb * 2.0 - 1.0;
	//vec3 N = normalize(normal);	// Normal
	vec3 L = normalize(lightDir);	// Light Direction (normalized)
	float lambertTerm = dot(N,L);	// Base lighting (no ambient or specular contribution)

	if(lambertTerm > 0.0)
	{
		// Add diffuse contribution
		final_color += gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * lambertTerm;
		// Compute specular contribution
		vec3 E = normalize(eyeVec);
		vec3 R = reflect(-L, N);
		float specular = pow(max(dot(R, E), 0.0), gl_FrontMaterial.shininess);
		// Add specular contribution
		final_color += gl_LightSource[0].specular * gl_FrontMaterial.specular * specular;
	}

	// Output
	gl_FragColor = final_color;// * texture2D(texture, gl_TexCoord[0].xy);
}

Note
You’ll need to stick the GLSL shader inside a Lighting Patch in order to be able to set the properties for the light.
You’ll get an error in the Frag shader about the varying normal not being used.




Twitter

March 2008
M T W T F S S
« Feb   Apr »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Links

Blog Stats

  • 481,010 hits
Advertisements