📄 vpmover.cg
字号:
void main( float4 xzBuffer : POSITION,
float4 nBuffer : COLOR,
float4 yBuffer : TEXCOORD0,
float4 lodBuffer : TEXCOORD1,
uniform float4x4 worldViewProj,
uniform float4x4 worldMatrix,
uniform float4 cameraPos,
uniform float3 lightAmbient,
uniform float3 lightDiffuse,
uniform float3 lightSpecular, //not used now
uniform float3 lightAtten, //not used now
uniform float4 lightPos,
uniform float4 lightDir,
uniform float4 textureRes, //Texture Resolution. textures cover textureRes x textureRes world units and repeat.
uniform float hiDRange, //High Detail Range. How far until LOD increases start?
uniform float lodFactor, //How quickly to increase LOD.
uniform float meshSize, //MS from terrain class.
out float4 oPosition : POSITION,
out float4 oColor : COLOR,
out float2 oTexCoord0 : TEXCOORD0, //detail textures
out float2 oTexCoord1 : TEXCOORD1,
out float2 oTexCoord2 : TEXCOORD2,
out float2 oTexCoord3 : TEXCOORD3) //alpha map
{
float4 v1, v2;
//position of the vertex until the vertex's LOD is reached (stored in lodBuffer.x)
//one of the triangles containing this vertex will be degenerate.
v1.xz = xzBuffer.xz;
v1.y = yBuffer.x;
v1.w = 1;
//actual position of the vertex after the vertex's LOD is reached (i.e. at lower LOD's)
v2.xz = xzBuffer.yw;
v2.y = yBuffer.y;
v2.w = 1;
//calculate distance from camera to vertex
float dist = distance(cameraPos, v2);
oColor.a = lerp(1, 0, dist / (hiDRange * 4));
//now scale dist based on the LOD equation.
dist = max(0, dist - hiDRange) / lodFactor;
//finally, compare the current LOD to the LOD this vertex is introduced in
//set dist in the range (0, 1), 0 meaning use v1, 1 meaning use v2, and anything between meaning lerp between them
dist = saturate(lodBuffer.x - log2(dist));
//lerp to find actual vertex position (object space)
v2 = lerp(v1, v2, dist);
//extract normals
float4 n1, n2;
//color portions stored as unsigned bytes become floats in 0-1 range... we need them in -1 - 1 range
n1 = nBuffer * 2 - 1;
//then square it, since we took the square root in the app to allow more room for lower numbers
//keep up with the sign by taking absolute value of one of them
n1 = n1 * abs(n1);
//we left the n2 values in there to allow vector processing, now it's time to pull them out.
n2.xz = n1.yw;
//now extract the y based on the fact that x^2 + y^2 + z^2 = 1, therefore y = sqrt(1 - x^2 - z^2)
n1.y = sqrt(1 - dot(n1.xz, n1.xz));
n2.y = sqrt(1 - dot(n2.xz, n2.xz));
//now we have 2 normalized normals for lighting calcs.
//lerp to find actual normal
n2 = lerp(n1, n2, dist);
//transform vertex position to clip space
oPosition = mul(worldViewProj, v2);
//alpha map, tiled once per meshSize
oTexCoord3 = v2.xz / meshSize;
//convert v2 to world position (so detail textures match up on patch seams)
v1 = mul(worldMatrix, v2);
//tile detail texture once every textureRes units, negative textureRes means use alphaMap coords (for base texture)
oTexCoord0 = (textureRes.xx < 0 ? oTexCoord3.xy : v1.xz / textureRes.xx);
oTexCoord1 = v1.xz / textureRes.xx;
oTexCoord2 = v1.xz / textureRes.xx;
//use the top one to outline LOD transitions, or the bottom for normal viewing
//oColor = abs(dist) < 0.02 ? float4(0, 0, 1, 1) : float4(1, 1, 1, 1);
//oColor = 1;
//ambient and diffuse lighting
float4 L = normalize(lightPos - v2);
oColor.rgb = lightAmbient.rgb + lightDiffuse.rgb * max(0, dot(n2.xyz, L.xyz));
}
void fragmain( float4 color : COLOR,
float2 texCoord0 : TEXCOORD0,
float2 texCoord1 : TEXCOORD1,
float2 texCoord2 : TEXCOORD2,
float2 alphaCoord : TEXCOORD3,
out float4 oColor : COLOR,
uniform sampler2D texture0,
uniform sampler2D texture1,
uniform sampler2D texture2,
uniform sampler2D alphaMap)
{
float4 tex0 = tex2D(texture0, texCoord0);
float4 tex1 = tex2D(texture1, texCoord1);
float4 tex2 = tex2D(texture2, texCoord2);
float4 alpha = tex2D(alphaMap, alphaCoord);
oColor = color * (tex0 * alpha.rrrr + tex1 * alpha.gggg + tex2 * alpha.bbbb);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -