OgreMax中使用offsetmapping

第一个texture unit 里是凹凸贴图,第二个texutre unit里是漫反射贴图

vertex shader和pixex shader如下:

offsetmapping.program:

 

// Bump map with Parallax offset vertex program, support for this is required 
vertex_program my/OffsetMappingVP cg 

   source OffsetMapping.cg 

   default_params
   {
  param_named scale float 1.0
            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 main_vp 
   profiles vs_1_1 arbvp1 

// Bump map with parallax fragment program 
fragment_program my/OffsetMappingFP cg

   source OffsetMapping.cg

   default_params
   {
            param_named_auto lightDiffuse light_diffuse_colour 0 
            param_named_auto lightSpecular light_specular_colour 0 
            // Parallax Height scale and bias 
            param_named scaleBias float4 0.04 -0.02 1 0 
   }

   entry_point main_fp
   profiles ps_2_0 arbfp1

OffsetMapping.cg:

/* Bump mapping with Parallax offset vertex program 
   In this program, we want to calculate the tangent space light end eye vectors 
   which will get passed to the fragment program to produce the per-pixel bump map 
   with parallax offset effect. 
*/

struct outPixel
{
  float4 colour  : COLOR0;
};

// General functions

// Expand a range-compressed vector
half4 expand(half4 v)
{
    return v * 2 - 1;
}
half3 expand(half3 v)
{
    return v * 2 - 1;
}
half2 expand(half2 v)
{
    return v * 2 - 1;
}
half1 expand(half1 v)
{
    return v * 2 - 1;
}

// Returns light direction from light position and vertex position
half3 getLightDirection(float4 lightPosition, float4 position)
{
    // calculate tangent space light vector
    // Get object space light direction
    // Non-normalised since we'll do that in the fragment program anyway
    return lightPosition.xyz -  (position.xyz * lightPosition.w);
}

// Returns eye direction from eye position and vertex position
half3 getEyeDirection(float3 eyePosition, float4 position)
{
    return eyePosition - position.xyz;
}

// Returns a Tangent Binormal Normal matrix
half3x3 getTBNMatrix(float3 tangent, float3 normal)
{
    // 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(tangent, normal);
    
    // Form a rotation matrix out of the vectors
    return half3x3(tangent, binormal, normal);
}

// Returns expanded normal vector from texture map
half3 getNormalMapVector(sampler2D normalMap, float2 uv)
{
    // get bump map vector, again expand from range-compressed
    return expand(tex2D(normalMap, uv).xyz);
}

// Returns displacement vector from normalmaps alpha channel
half getDisplacement(sampler2D normalMap, float2 uv, half scale, half bias)
{
    // get the height using the tex coords
    half height = tex2D(normalMap, uv).a;

    // calculate displacement   
    return (height * scale) + bias;
}

// Returns a specular component from normal vector, specular colour and specular power
half3 getSpecularComponent(float3 normal, float3 halfAngle, float3 specularcolour, float specularPower)
{
    return pow(saturate(dot(normal, halfAngle)), specularPower) * specularcolour;
}

// Returns a per-pixel lighted component from normal vector, lightdir and colour
half3 getLightingComponent(float3 normal, float3 lightDir, float3 colour)
{
    return saturate(dot(normal, lightDir)) * colour;
}

 

float4 lightPosition;
float3 eyePosition;
float4x4 worldViewProj;

float3 lightDiffuse;
float3 lightSpecular;
float4 scaleBias;
sampler2D normalHeightMap;
sampler2D diffuseMap;

struct app2vertOffsetMapping
{
    float4 position : POSITION;
    float3 normal   : NORMAL;
    float2 uv       : TEXCOORD0;
    float3 tangent      : TANGENT0;
};

struct vert2fragOffsetMapping
{
    float4 position     : POSITION;
    float2 uv       : TEXCOORD0;
    float3 lightDir     : TEXCOORD1;
    float3 eyeDir       : TEXCOORD2;
    float3 halfAngle    : TEXCOORD3;
};

/* Vertex program that moves light and eye vectors into texture tangent space at vertex */ 

vert2fragOffsetMapping main_vp(uniform float scale,app2vertOffsetMapping IN) 
{
    vert2fragOffsetMapping OUT;

    // calculate output position 
    OUT.position = mul(worldViewProj, IN.position); 

    // pass the main uvs straight through unchanged 
    OUT.uv = IN.uv*scale; 

    half3 lightDir = getLightDirection(lightPosition, IN.position);
    half3 eyeDir = getEyeDirection(eyePosition, IN.position);
    
    // Form a rotation matrix out of the vectors 
    half3x3 TBN = getTBNMatrix(IN.tangent, IN.normal); 
    
    // Transform the light vector according to this matrix 
    OUT.lightDir = normalize(mul(TBN, lightDir)); 
    OUT.eyeDir = normalize(mul(TBN, eyeDir)); 

    OUT.halfAngle = normalize(OUT.eyeDir + OUT.lightDir);

    return OUT;
}

outPixel main_fp(vert2fragOffsetMapping IN)
{
    outPixel OUT;

    half displacement = getDisplacement(normalHeightMap, IN.uv, scaleBias.x, scaleBias.y);
    
    float3 uv2 = float3(IN.uv, 1);
    
    // calculate the new tex coord to use for normal and diffuse
    float2 newTexCoord = ((IN.eyeDir * displacement) + uv2).xy;
    
    // get the new normal and diffuse values
    half3 normal = getNormalMapVector(normalHeightMap, newTexCoord);
    half3 diffuse = tex2D(diffuseMap, newTexCoord).xyz;
    
    half3 specular = getSpecularComponent(normal, IN.halfAngle, lightSpecular, 32);
    half3 col = diffuse * getLightingComponent(normal, IN.lightDir, lightDiffuse) + specular;
        
    OUT.colour = float4(col, 1);

    return OUT;
}

 

 

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/Cancer05/archive/2008/11/14/3294561.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值