/*********************************************************************NVMH3**** ******************************************************************************* $Revision: #4 $ Copyright NVIDIA Corporation 2008 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. % This material shows and compares results from four popular and % advanced schemes for emulating displaement mapping. They are: % Relief Mapping, Parallax Mapping, Normal Mapping, and Relief % Mapping with Shadows. Original File by Fabio Policarpo. keywords: material bumpmap date: 071005 Note: Strong discontinuties in the model geometric normal (e.g., very sharp differences from the normals in two or more parts of the same triangle) can cause unusual overall light-attentuation errors. Re-normalizing the rasterized normals in the fragment shader can correct this, but the case was considered rare enough that these extra steps were eliminated for code efficiency. If you see off lighting near sharp model edges, just normalize "IN.normal" in the calculation of the varible "att" (shared by all techniques). To learn more about shading, shaders, and to bounce ideas off other shader authors and users, visit the NVIDIA Shader Library Forums at: http://developer.nvidia.com/forums/ ******************************************************************************* ******************************************************************************/ // Modified for OGRE by mkultra333, 090529 // Got rid of BINORMAL input, now computed in vertex program. // Changed "- tNorm.y*IN.binormal" to "+ tNorm.y*IN.binormal" in fragment program. // Removed WorldITXf, WorldXf and ViewIXf 4x4 matrixes that weren't used. /********** CONNECTOR STRUCTURES *****************/ struct AppVertexData { float4 pos : POSITION; float4 color : COLOR0; float3 normal : NORMAL; // expected to be normalized float2 txcoord : TEXCOORD0; float3 tangent : TANGENT0; // pre-normalized }; struct VertexOutput { float4 hpos : POSITION; float2 UV : TEXCOORD0; float3 vpos : TEXCOORD1; float3 tangent : TEXCOORD2; float3 binormal : TEXCOORD3; float3 normal : TEXCOORD4; float4 lightpos : TEXCOORD5; float4 color : COLOR0; }; /*** SHADER FUNCTIONS **********************************************/ VertexOutput view_spaceVS(AppVertexData IN, uniform float4x4 WvpXf, uniform float4x4 ViewXf, uniform float4x4 WorldViewXf, uniform float TileCount, uniform float3 LampPos ) { VertexOutput OUT = (VertexOutput)0; // isolate WorldViewXf rotation-only part float3x3 modelViewRotXf; modelViewRotXf[0] = WorldViewXf[0].xyz; modelViewRotXf[1] = WorldViewXf[1].xyz; modelViewRotXf[2] = WorldViewXf[2].xyz; float4 Po = float4(IN.pos.xyz,1.0); OUT.hpos = mul(WvpXf,Po); // vertex position in view space (with model transformations) OUT.vpos = mul(WorldViewXf,Po).xyz; // light position in view space float4 Lw = float4(LampPos.xyz,1); // this point in world space OUT.lightpos = mul(ViewXf,Lw); // this point in view space // Calculate the binormal (NB we assume both normal and tangent are // already normalised) // NB looks like nvidia cross params are BACKWARDS to what you'd expect // this equates to NxT, not TxN float3 binormal = cross(IN.tangent, IN.normal); // tangent space vectors in view space (with model transformations) OUT.tangent = mul(modelViewRotXf,IN.tangent); OUT.binormal = mul(modelViewRotXf,binormal); OUT.normal = mul(modelViewRotXf,IN.normal); // copy color and texture coordinates OUT.color = IN.color; // currently ignored by all techniques OUT.UV = TileCount * IN.txcoord.xy; return OUT; } //// ray-intersect functions for relief mapping ////////// float ray_intersect_rm( // use linear and binary search in sampler2D reliefmap, in float2 dp, in float2 ds) { const int linear_search_steps=30; // current size of search window float size = 1.0/linear_search_steps; // current depth position float depth = 0.0; // search front to back for first point inside object for( int i=0;i