PerPixel Lighting With Offset(Parallax) Mapping

From Ogre Wiki

Jump to: navigation, search

Contents

Intro, and materials you can get from this page

Offset - fast, multipass, unlimited-light, method
Offset_Limited3 - fast, 1-pass, 3-light limited, method
(both support ambient, diffuse, specular lighting with 1 diffuse texture,
 and 1 normal texture which has heigh info in its alpha-channel)

see Perpixel II on what I mean fast, nice, and some theory

Shaders: Offset mapping stuff

//**************************************************************************************//
//											//
//			BUMP - NORMAL - OFFSET/PARALLAX - RELIEF			//
//				MAPPING COMES NOW					//
//											//
//**************************************************************************************//


// General functions 

// Expand a range-compressed vector
float3 expand(float3 v)
{
	return (v - 0.5) * 2;
}



void Offset_Vert(
		 float4 position	: POSITION,
		 float3 normal		: NORMAL,
	 	 float2 uv		: TEXCOORD0,
	 	 float3 tangent     	: TEXCOORD1,

	 	 out float4 oPosition	: POSITION,
	 	 out float2 oUv		: TEXCOORD0,
	 	 out float3 oLightDir	: TEXCOORD1,
		 out float3 oEyeDir     : TEXCOORD2,
		 out float3 oHalfAngle	: TEXCOORD3,
	
		 uniform float scale,
		 uniform float4 lightPosition, // object space
	 	 uniform float3 eyePosition,   // object space
	 	 uniform float4x4 worldviewproj)
{
//why normalize lightDir if don't normalize eyeDir? both will be mul-ed
//by matrix! 

	oPosition = mul(worldviewproj , position);
	oUv = uv * scale; 

 	
	float3 eyeDir = eyePosition - position.xyz;
	float3 binormal = cross(tangent, normal);
	float3x3 rotation = float3x3(tangent, binormal, normal);
	eyeDir = normalize(mul(rotation, eyeDir));


	float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w));
	lightDir = normalize(mul(rotation, lightDir));
	
	oHalfAngle = normalize(eyeDir + lightDir); 

	oLightDir = lightDir;
	oEyeDir = eyeDir;

		//changing these variables to calculate with output value and not use them doesn't yield any  
               //boost
	
}

void Offset_Frag(
		  float2 uv	: TEXCOORD0,
		  float3 lightVec : TEXCOORD1,
		  float3 eyeDir : TEXCOORD2,
		  float3 halfAngle: TEXCOORD3,

		  out float4 oColor	: COLOR, 

		  uniform float4 lightDiffuse,
		  uniform float4 lightSpecular,
		  uniform float exponent,
		  uniform float4 scaleBias, 

		  uniform sampler2D   normalHeightMap : register(s0)
		)
{
	float height = tex2D(normalHeightMap, uv).a;
	float scale = scaleBias.x;
	float bias = scaleBias.y;
	float displacement = (height * scale) + bias;
	float3 uv2 = float3(uv, 1); 
	float2 newTexCoord = ((eyeDir * displacement) + uv2).xy;
	float3 bumpVec = expand(tex2D(normalHeightMap, newTexCoord ).xyz);
	float3 N = normalize(bumpVec);

	float NdotL = dot(normalize(lightVec), N);
	float NdotH = dot(normalize(halfAngle), N); 

	float4 Lit = lit(NdotL,NdotH,exponent);
	
	oColor = lightDiffuse * Lit.y + lightSpecular * Lit.z;
		//do I need to normalize here the normal (=bumpvec)?
}

void Offset_Lim3_Vert(
		 float4 position	: POSITION,
		 float3 normal		: NORMAL,
	 	 float2 uv		: TEXCOORD0,
	 	 float3 tangent     	: TEXCOORD1, 

	 	 out float4 oPosition	: POSITION,
	 	 out float2 oUv		: TEXCOORD0,
	 	 out float3 oLightDir0  : TEXCOORD1,
		 out float3 oLightDir1  : TEXCOORD2,
		 out float3 oLightDir2	: TEXCOORD3,	
		 out float3 oHalfAngle0	: TEXCOORD4,
		 out float3 oHalfAngle1	: TEXCOORD5,
		 out float3 oHalfAngle2	: TEXCOORD6,
		 out float3 oEyeDir     : TEXCOORD7,
	 
 		 uniform float scale,
		 uniform float4 lightPosition0, // object space
		 uniform float4 lightPosition1, // object space
		 uniform float4 lightPosition2, // object space
	 	 uniform float3 eyePosition,   // object space
	 	 uniform float4x4 worldviewproj )
{
	oPosition = mul(worldviewproj , position);
	oUv = uv * scale; 

	float3 eyeDir = eyePosition - position.xyz;
	float3 binormal = cross(tangent, normal);
	float3x3 rotation = float3x3(tangent, binormal, normal);
	eyeDir = normalize(mul(rotation, eyeDir));



	 
	oEyeDir = eyeDir;
 

 	float3 temp_lightDir = normalize(lightPosition0.xyz -  (position * lightPosition0.w));
	oLightDir0 = normalize(mul(rotation, temp_lightDir));
	oHalfAngle0 = normalize(eyeDir + oLightDir0);

	temp_lightDir = normalize(lightPosition1.xyz -  (position * lightPosition1.w));
	oLightDir1 = normalize(mul(rotation, temp_lightDir));
	oHalfAngle1 = normalize(eyeDir + oLightDir1);
	
	temp_lightDir = normalize(lightPosition2.xyz -  (position * lightPosition2.w));
	oLightDir2 = normalize(mul(rotation, temp_lightDir));
	oHalfAngle2 = normalize(eyeDir + oLightDir2);
}


void Offset_Lim3_Frag( 
	 	 float2 uv		: TEXCOORD0,
	 	 float3 LightDir0  	: TEXCOORD1,
		 float3 LightDir1  	: TEXCOORD2,
		 float3 LightDir2	: TEXCOORD3,	
		 float3 HalfAngle0	: TEXCOORD4,
		 float3 HalfAngle1	: TEXCOORD5,
		 float3 HalfAngle2	: TEXCOORD6,
	 	 float3 EyeDir     	: TEXCOORD7, 

		  out float4 oColor	: COLOR, 

		uniform float4 lightDiffuse0,
		uniform float4 lightDiffuse1,
		uniform float4 lightDiffuse2, 

		uniform float4 lightSpecular0,
		uniform float4 lightSpecular1,
		uniform float4 lightSpecular2, 

		uniform float exponent0,
//		uniform float exponent1,
//		uniform float exponent2, 

		uniform float4 ambient,

		uniform float4 scaleBias,
			
		  uniform sampler2D   normalHeightMap, //: register(s0)
		  uniform sampler2D diffuseMap 
		)
{
	float height = tex2D(normalHeightMap, uv).a;
	float scale = scaleBias.x;
	float bias = scaleBias.y;
	float displacement = (height * scale) + bias;
	float3 uv2 = float3(uv, 1); 
	float2 newTexCoord = ((EyeDir * displacement) + uv2).xy;
	float3 bumpVec = expand(tex2D(normalHeightMap, newTexCoord ).xyz);
	float3 diffusetex = tex2D(diffuseMap, newTexCoord).xyz; 

	float3 N = normalize(bumpVec);


	float NdotL0 = dot(normalize(LightDir0), N);
	float NdotH0 = dot(normalize(HalfAngle0), N);
	float4 Lit0 = lit(NdotL0,NdotH0,exponent0); 

	float NdotL1 = dot(normalize(LightDir1), N);
	float NdotH1 = dot(normalize(HalfAngle1), N);
	float4 Lit1 = lit(NdotL1,NdotH1,exponent0); 

	float NdotL2 = dot(normalize(LightDir2), N);
	float NdotH2 = dot(normalize(HalfAngle2), N);
	float4 Lit2 = lit(NdotL2,NdotH2,exponent0);
	
	oColor = float4(diffusetex,1) * 
		(lightDiffuse0 * Lit0.y + lightDiffuse1 * Lit1.y + lightDiffuse2 * Lit2.y)
	+ lightSpecular0 * Lit0.z + lightSpecular1 * Lit1.z + lightSpecular2 * Lit2.z
	 + ambient;
}

Materials: Offset mapping stuff

//**************************************************************************************//
//											//
//			BUMP - NORMAL - OFFSET/PARALLAX - RELIEF			//
//				MAPPING COMES NOW					//
//				(WITH TEXTURING)					//
//**************************************************************************************//

vertex_program Offset_Vert cg
{
 	source ARNOLD.cg 
 
 	default_params
	{
		param_named_auto lightPosition light_position_object_space 0
		param_named_auto eyePosition camera_position_object_space
		param_named_auto worldviewproj worldviewproj_matrix
	}  

	entry_point Offset_Vert
	profiles vs_1_1 arbvp1
} 

fragment_program Offset_Frag cg
{
	source ARNOLD.cg 

	default_params
	{
		param_named_auto lightDiffuse light_diffuse_colour 0
		param_named_auto lightSpecular light_specular_colour 0
		param_named exponent float 127

		param_named scaleBias float4 0.04 -0.02 1 0  

			//why use a float4 is I only use x and y of it?
	}  

	entry_point Offset_Frag
	profiles ps_2_0 arbfp1
} 

vertex_program Offset_Lim3_Vert cg
{
	source ARNOLD.cg

	default_params
	 {
		param_named_auto lightPosition0 light_position_object_space 0
		param_named_auto lightPosition1 light_position_object_space 1
		param_named_auto lightPosition2 light_position_object_space 2
		param_named_auto eyePosition camera_position_object_space
		param_named_auto worldviewproj worldviewproj_matrix
	} 

	entry_point Offset_Lim3_Vert 
	profiles vs_1_1 arbvp1
}

fragment_program Offset_Lim3_Frag cg
{
	source ARNOLD.cg 

	default_params
	{
		param_named_auto lightDiffuse0 light_diffuse_colour 0
		param_named_auto lightDiffuse1 light_diffuse_colour 1
		param_named_auto lightDiffuse2 light_diffuse_colour 2 

		param_named_auto lightSpecular0 light_specular_colour 0
		param_named_auto lightSpecular1 light_specular_colour 1
		param_named_auto lightSpecular2 light_specular_colour 2 

		param_named exponent0 float 127
//		param_named exponent1 float 127
//		param_named exponent2 float 127
		//If changed, needs adjusting in Fragshader's every lit!!!!!  

		param_named ambient float4 0.0 0.0 0.0 1.0 

		param_named scaleBias float4 0.04 -0.02 1 0 
	} 

	entry_point Offset_Lim3_Frag
	profiles ps_2_0 arbfp1
}

//Any lights, offset with specular
//Apart from being slow, this sax, 'cuz diffuse texture's uv's cannot be offsetted
//due to the iteration (or at least I can't do it easily)
//(and due to I cannot transfer data beetwen Fragshaders of different passes)
material Offset
{
	technique
	{
		pass
		{	
			vertex_program_ref Ambient
			{
			}	
		}
		pass
		{
			// do this for each light
			iteration once_per_light
 			scene_blend add
			 

			// Vertex program reference
			vertex_program_ref Offset_Vert
			{
				param_named scale float 5
			}
			// Fragment program
			fragment_program_ref Offset_Frag
			{	
			} 

			// Base bump map
			texture_unit
			{
				texture CC-slateb_NH.dds
				filtering trilinear
				//filtering anisotropic
				//max_anisotropy 3
				//colour_op replace
			}
		}
		//Decal pass
		pass
		{
			lighting off
			
 			vertex_program_ref OneTexture
			{
				param_named scale float 5
			}   

			scene_blend modulate
			texture_unit
 			{
				//filtering anisotropic
				//max_anisotropy 3
				filtering trilinear
				texture CC-slateb.dds
			}			
		}
	}	
} 

material Offset_Limited3
{
	technique
 	{
//		pass
//		{	
//			vertex_program_ref Ambient
//			{
//			}
//		}
		pass
  		{ 
	 		// do this for each light
//			iteration once_per_light		
//			scene_blend add
			
			// Vertex program reference
			vertex_program_ref Offset_Lim3_Vert
			{
				param_named scale float 5
//				param_named lightnum float 2
	 		}  

			// Fragment program
			fragment_program_ref Offset_Lim3_Frag
			{
//				param_named lightnum float 2
			}
			
			// Base bump map
			texture_unit
	 		{
				texture CC-slateb_NH.dds
				filtering trilinear
				//filtering anisotropic
				//max_anisotropy 3
				//colour_op replace
			}
			
			texture_unit
			{
				//filtering anisotropic
	 			//max_anisotropy 3
				filtering trilinear
				texture CC-slateb.dds
			}
		}
	}
}

Contact

the name is guilderstein, contact at end lines Perpixel I wiki page
Personal tools
administration