GLSL and Environment Mapping

Started by
-1 comments, last by Eldritch 17 years, 8 months ago
Attempted to write a GLSL shader for environment mapping. It works, though with some graphical artifacts. When I turn around, I see a seam in the environment map (texture is tileable), and when I look up, I see a strange type of artifact that looks much like.. well.. hard to describe.. it looks like when you apply the UV Mapping type "circular" to a mesh in 3D Studio Max... anyways, it looks weird. Here is the fragment shader (where all the magic is done). If anyone sees anything out of the ordinary, let me know.

const vec3 Xunit = vec3(1.0, 0.0, 0.0);
const vec3 Yunit = vec3(0.0, 1.0, 0.0);

uniform sampler2D TexMap1;
uniform sampler2D TexMap2;
uniform int UseFog;
uniform float MixRatio;

varying vec3 normal;
varying vec4 ecPos;

void main()
{
	// Calculate global ambience.
	vec4 ambientGlobal = gl_LightModel.ambient * gl_FrontMaterial.ambient;
	
	// Calculate normal.
	vec3 n = normalize(normal);
	
	// Initiate color to global ambience.
	vec4 color = ambientGlobal;

	// Compute reflection vector.
	vec3 reflectDir = reflect(vec3(ecPos), normal);

	// Compute altitude and azimuth angles.
	vec2 index;
	index.y = dot(normalize(reflectDir), Yunit);
	reflectDir.y = 0.0;
	index.x = dot(normalize(reflectDir), Xunit);

	// Translate index values into proper range.
	if (reflectDir.z > 0.0)
	{
		index = (index + 1.0) * 0.5;
	}
	else
	{
		index.t = (index.t + 1.0) * 0.5;
		index.s = (-index.s) * 0.5 + 1.0;
	}
	
	// For each of the 4 lights affecting this object, calculate their color addition.
	for (int i = 1; i < 5; i++)
	{
		if (gl_LightSource.linearAttenuation > 0.0)
		{
			// Calculate light's direction.
			vec3 vec = vec3(gl_LightSource.position - ecPos);
			vec3 lightDir = normalize(vec);

			// Calculate light distance.
			float dist = length(vec);

			// Calculate half vector.
			vec3 halfVector = normalize(gl_LightSource.halfVector.xyz);

			// Calculate diffuse component.
			vec4 diffuse = gl_FrontMaterial.diffuse * gl_LightSource.diffuse;

			// Calculate ambient component.
			vec4 ambient = gl_FrontMaterial.ambient * gl_LightSource.ambient;

			// Calculate dot product between normal and light.
			float NdotL = max(dot(n, normalize(lightDir)), 0.0);

			// Calculate attenuation.
			float att = 1.0 / (gl_LightSource.constantAttenuation +
					   gl_LightSource.linearAttenuation * dist +
					   gl_LightSource.quadraticAttenuation * dist * dist);

			// Add attenuation and diffuse and ambient components.
			color += att * (diffuse * NdotL + ambient);

			// Calculate dot product between normal and half vector.
			vec3 halfV = normalize(halfVector);
			float NdotHV = max(dot(n, halfV), 0.0);

			// Add specular component and calculate highlight.
			color += att * gl_FrontMaterial.specular * gl_LightSource.specular *
				 pow(NdotHV, gl_FrontMaterial.shininess);
		}
	}

	// Get fragment from envmap.
	vec3 envColor = vec3(texture2D(TexMap2, index));
	
	// Multiply the average color with texture color.
	color = color * texture2D(TexMap1, gl_TexCoord[0].st);

	// Mix lighting, texture map and environment map.
	vec3 finalColor = mix(envColor, vec3(color), MixRatio);

	
	// Calculate exp2 fog.
	if (UseFog == 1)
	{
		const float LOG2E = 1.442695;
		float fog = exp2(-gl_Fog.density * gl_Fog.density *
				 gl_FogFragCoord * gl_FogFragCoord * LOG2E);
		fog = clamp(fog, 0.0, 1.0);
		finalColor = mix(vec3(gl_Fog.color), color.rgb, fog);
	}

	// Set fragment color.
	gl_FragColor = vec4(finalColor, color.a);
}

This topic is closed to new replies.

Advertisement