www.pudn.com > GPUGeometryClipmaps.rar > Render.fx


texture fineLevelTexture; 
texture normalsTexture; 
texture rampTexture; 
 
 
uniform matrix WorldViewProjMatrix; 
uniform float  ZScaleFactor; 
uniform float4 ScaleFactor; 
uniform float4 FineTextureBlockOrigin; 
uniform float2 AlphaOffset; 
uniform float2 ViewerPos; 
uniform float  OneOverWidth; 
uniform float3 LightDirection; 
 
 
uniform sampler ElevationSampler = sampler_state            // fine level height sampler 
{ 
    Texture   = (fineLevelTexture); 
    MipFilter = None; 
    MinFilter = Point; 
    MagFilter = Point; 
    AddressU  = Wrap; 
    AddressV  = Wrap; 
}; 
 
uniform sampler NormalMapSampler = sampler_state             
{ 
    Texture   = (normalsTexture); 
    MipFilter = None; 
    MinFilter = Linear; 
    MagFilter = Linear; 
    AddressU  = Wrap; 
    AddressV  = Wrap; 
}; 
 
uniform sampler ZBasedColorSampler = sampler_state 
{ 
    Texture   = (rampTexture); 
    MipFilter = Linear; 
    MinFilter = Linear; 
    MagFilter = Linear; 
    AddressU  = Clamp; 
    AddressV  = Clamp; 
}; 
 
 
struct OUTPUT 
{ 
    vector pos        : POSITION;    
    float2 uv         : TEXCOORD0;  // coordinates for normal-map lookup 
    float2 zalpha : TEXCOORD1;      // coordinates for elevation-map lookup 
}; 
 
OUTPUT RenderVS(float2 gridPos: TEXCOORD0) 
{ 
    OUTPUT output; 
    // convert from grid xy to world xy coordinates 
    //  ScaleFactor.xy: grid spacing of current level 
    //  ScaleFactor.zw: origin of current block within world 
    float2 worldPos = gridPos * ScaleFactor.xy + ScaleFactor.zw; 
                      
    // compute coordinates for vertex texture 
    //  FineBlockOrig.xy: 1/(w, h) of texture 
    //  FineBlockOrig.zw: origin of block in texture            
    float2 uv = float2(gridPos*FineTextureBlockOrigin.zw+FineTextureBlockOrigin.xy); 
     
    // sample the vertex texture 
    float zf_zd = tex2Dlod(ElevationSampler, float4(uv, 0, 1)); 
 
    // unpack to obtain zf and zd = (zc - zf) 
    //  zf is elevation value in current (fine) level 
    //  zc is elevation value in coarser level 
    float zf   = floor(zf_zd); 
    float zd   = frac(zf_zd) * 512 - 256;       // zd = zc - z 
 
    // compute alpha (transition parameter), and blend elevation. 
    float2 alpha = clamp((abs(worldPos-ViewerPos) - AlphaOffset) * OneOverWidth, 0, 1); 
    alpha.x  = max(alpha.x, alpha.y);    
     
    float z = zf + alpha.x * zd; 
    z = z * ZScaleFactor; 
     
    output.pos = mul(float4(worldPos.x, worldPos.y, z, 1), WorldViewProjMatrix); 
     
    output.uv = uv; 
    output.zalpha = float2(0.5 + z/1600, alpha.x); 
     
     
    return output; 
} 
 
float4 RenderPS(float2 uv: TEXCOORD0, float2 zalpha: TEXCOORD1) : COLOR 
{ 
    // do a texture lookup to get the normal in current level 
    float4 normalfc = tex2D(NormalMapSampler, uv); 
    // normal_fc.xy contains normal at current (fine) level 
    // normal_fc.zw contains normal at coarser level 
    // blend normals using alpha computed in vertex shader   
    float3 normal = float3((1 - zalpha.y) * normalfc.xy + zalpha.y * (normalfc.zw), 1.0); 
     
    // unpack coordinates from [0, 1] to [-1, +1] range, and renormalize. 
    normal = normalize(normal * 2 - 1); 
 
    float s = clamp(dot(normal, LightDirection), 0, 1);  
    return s * tex1D(ZBasedColorSampler, zalpha.x); 
} 
 
 
technique Render 
{ 
    pass P0 
    { 
        VertexShader = compile vs_3_0 RenderVS(); 
        PixelShader  = compile ps_2_a RenderPS(); 
    }   
}