OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: Normal Mapping with Hardware Skinning and Specular
View page
Source of version: 3
(current)
There are a lot of normal mapping and displacement mapping examples around here, but I found that none of them would work correctly with hardware skinning. To help those who face the same problem, here it is. !!Usage just add the material {MONO()}animatedNormalSpecular{MONO} to your object. The hardware skinning is setup for 3 bones per vertex, which can easily be changed. It also uses the shadow program HardwareSkinningFourShadow which is from the ogre samples, if you have the ogre media samples in your resources path already its not a problem, otherwise, find it! !!Material file {CODE(wrap="1", colors="c++")} vertex_program AnimatedNormalSpecular_VP hlsl { source animatedNormalSpecular.hlsl entry_point main_vp target vs_2_0 column_major_matrices false //required for hlsl skinning includes_skeletal_animation true default_params { param_named_auto worldviewprojmatrix worldviewproj_matrix param_named_auto light_position light_position_object_space 0 param_named_auto eye_position camera_position_object_space param_named_auto worldMatrix3x4Array world_matrix_array_3x4 param_named_auto viewProjectionMatrix viewproj_matrix param_named_auto invworldmatrix inverse_world_matrix } }{CODE} {CODE(wrap="1", colors="c++")} fragment_program AnimatedNormalSpecular_FP hlsl { source animatedNormalSpecular.hlsl entry_point main_fp target ps_2_0 default_params { param_named_auto lightDiffuse light_diffuse_colour 0 param_named_auto ambientLight ambient_light_colour param_named_auto specularLight light_specular_colour 0 param_named specular_power float 64 param_named bumpiness float 1 } }{CODE} {CODE(wrap="1", colors="c++")} material animatedNormalSpecular { technique { pass Single Pass { vertex_program_ref AnimatedNormalSpecular_VP { } fragment_program_ref AnimatedNormalSpecular_FP { } shadow_caster_vertex_program_ref HardwareSkinningFourShadow //this part is in the ogre samples somewhere { } //diffuse map texture_unit { texture_alias base_map texture diffuse.tga filtering linear linear linear } //normal map texture_unit { texture_alias bump_map texture diffuse_normal.tga filtering linear linear linear } // specular map texture_unit specular_map { texture_alias specular_map texture specular.png } } } }{CODE} !!animatedNormalSpecular.hlsl {CODE(wrap="1", colors="c++")} void main_vp( float4 position : POSITION, float2 uv : TEXCOORD0, float3 normal : NORMAL, float3 tangent : TANGENT0, float4 blendIdx : BLENDINDICES, float4 blendWgt : BLENDWEIGHT, out float4 oPosition : POSITION, out float2 oUV : TEXCOORD0, out float3 oLightVector : TEXCOORD1, out float3 oHalfAngle : TEXCOORD2, uniform float4x4 worldviewprojmatrix, uniform float4 light_position, uniform float4 eye_position, uniform float3x4 worldMatrix3x4Array[60], uniform float4x4 viewProjectionMatrix, uniform float4x4 invworldmatrix ) { // Calculate the pixel position using the perspective matrix. oUV = uv; // transform by indexed matrix float4 blendPos = float4(0,0,0,0); int i; for (i = 0; i < 3; ++i) { blendPos += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i]; } // view / projection oPosition = mul(viewProjectionMatrix, blendPos); // transform normal float3 newnormal = float3(0,0,0); for (i = 0; i < 3; ++i) { newnormal += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * blendWgt[i]; } newnormal = mul((float3x3)invworldmatrix, newnormal); newnormal = normalize(newnormal); // transform tangent float3 newtangent = float3(0,0,0); for (i = 0; i < 3; ++i) { newtangent += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], tangent) * blendWgt[i]; } newtangent = mul((float3x3)invworldmatrix, newtangent); newtangent = normalize(newtangent); float3 binormal = cross(newtangent, newnormal); float3x3 rotation = float3x3(newtangent, binormal, newnormal); // Calculate the light vector in object space, // and then transform it into texture space. float3 temp_lightDir0 = normalize(light_position.xyz - (blendPos * light_position.w)); temp_lightDir0 = normalize(mul(rotation, temp_lightDir0)); oLightVector = temp_lightDir0; // Calculate the view vector in object space, // and then transform it into texture space. float3 eyeDir = normalize(eye_position - blendPos); eyeDir = normalize(mul(rotation, eyeDir.xyz)); // Calculate the half angle oHalfAngle = oLightVector + eyeDir; } float4 lightDiffuse ; float4 ambientLight; float4 specularLight; float specular_power; float bumpiness; sampler base_map; sampler bump_map; sampler specular_map; struct PS_INPUT_STRUCT { float2 uv: TEXCOORD0; float3 light_vector: TEXCOORD1; float3 half_angle: TEXCOORD2; }; struct PS_OUTPUT_STRUCT { float4 color0: COLOR0; }; PS_OUTPUT_STRUCT main_fp( PS_INPUT_STRUCT psInStruct ) { PS_OUTPUT_STRUCT psOutStruct; float3 base = tex2D( base_map, psInStruct.uv ); float3 bump = tex2D( bump_map, psInStruct.uv ); float specularLevel = tex2D(specular_map, psInStruct.uv).r; //normalise float3 normalized_light_vector = normalize( psInStruct.light_vector ); float3 normalized_half_angle = normalize( psInStruct.half_angle ); // "Smooth out" the bump based on the bumpiness parameter. // This is simply a linear interpolation between a "flat" // normal and a "bumped" normal. Note that this "flat" // normal is based on the texture space coordinate basis. float3 smooth = { 0.5f, 0.5f, 1.0f }; bump = lerp( smooth, bump, bumpiness ); bump = normalize( ( bump * 2.0f ) - 1.0f ); // These dot products are used for the lighting model // equations. The surface normal dotted with the light // vector is denoted by n_dot_l. The normal vector // dotted with the half angle vector is denoted by n_dot_h. float4 n_dot_l = dot( bump, normalized_light_vector ); float4 n_dot_h = dot( bump, normalized_half_angle ); // Calculate the resulting pixel color, // based on our lighting model. // Ambient + Diffuse + Specular psOutStruct.color0.rgb = ( base * ambientLight) + ( base * lightDiffuse * max( 0, n_dot_l ) ) + ( specularLight * specularLevel * pow( max( 0, n_dot_h ), specular_power ) ); psOutStruct.color0.a = 1.0f; //** Set the alpha component manually return psOutStruct; }{CODE} --- Alias: (alias(Normal_Mapping_with_Hardware_Skinning_and_Specular))
Search by Tags
Search Wiki by Freetags
Latest Changes
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
Critter AI
Mogre Add-ons
MOGRE
Mogre MyGUI wrapper
MOGRE Editable Terrain Manager
...more
Search
Find
Advanced
Search Help
Online Users
26 online users