第一个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