PerPixel Lighting With Offset(Parallax) Mapping
Shader in the Per-Pixel Lighting series
Welcome to the new Ogre Wiki!
If you haven't done so already, be sure to visit the Wiki Portal to read about how the wiki works. Especially the Ogre Wiki Overview page.
If you haven't done so already, be sure to visit the Wiki Portal to read about how the wiki works. Especially the Ogre Wiki Overview page.
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
Table of contents
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
Alias: PerPixel_Lighting_With_Offset(Parallax)_Mapping
Contributors to this page: JustBoo
,
OgreWikiBot
and
jacmoe
.
Page last modified on Tuesday 29 of June, 2010 15:49:50 UTC by JustBoo.
The content on this page is licensed under the terms of the Creative Commons Attribution-ShareAlike License.
As an exception, any source code contributed within the content is released into the Public Domain.
Sidebar
Search box
Online users
101
online users

