From Ogre Wiki
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