www.pudn.com > GPUGeometryClipmaps.rar > Upsample.fx
// texture
texture coarseLevelTexture;
texture residualTexture;
texture lookupTexture;
// Parameters
uniform float2 TextureOffset;
uniform float Size;
uniform float OneOverSize;
uniform float2 Viewport;
uniform sampler CoarseLevelElevationSampler = sampler_state // coarser level height sampler
{
Texture = (coarseLevelTexture);
MipFilter = None;
MinFilter = Point;
MagFilter = Point;
AddressU = Wrap;
AddressV = Wrap;
};
uniform sampler ResidualSampler = sampler_state
{
Texture = (residualTexture);
MipFilter = None;
MinFilter = Point;
MagFilter = Point;
AddressU = Clamp;
AddressV = Clamp;
};
uniform sampler LookupSampler = sampler_state
{
Texture = (lookupTexture);
MipFilter = None;
MinFilter = Point;
MagFilter = Point;
AddressU = Wrap;
AddressV = Wrap;
};
struct OUTPUT
{
vector position : POSITION;
float2 texcoords : TEXCOORD0;
};
OUTPUT UpSampleVS(float3 position : POSITION, float2 texcoords : TEXCOORD0)
{
OUTPUT output;
output.position = float4(float2(position.x,-position.y) + float2(-1.0, 1.0)/Viewport,0.0,1.0);
output.texcoords = texcoords*Size;
return output;
}
float4 UpsamplePS(float2 p_uv : TEXCOORD0) : COLOR
{
float residual = tex2D(ResidualSampler, p_uv*OneOverSize);
p_uv = floor(p_uv);
float2 p_uv_div2 = p_uv/2;
float2 lookup_tij = p_uv_div2+1;
float4 maskType = tex2D(LookupSampler, lookup_tij);
matrix maskMatrix[4];
maskMatrix[0] = matrix(0, 0, 0, 0,
0, -1.0f/16.0f, 0, 0,
0, 0, 0, 0,
1.0f/256.0f, -9.0f/256.0f, -9.0f/256.0f, 1.0f/256.0f);
maskMatrix[1] = matrix(0, 1, 0, 0,
0, 9.0f/16.0f, 0, 0,
-1.0f/16.0f, 9.0f/16.0f, 9.0f/16.0f, -1.0f/16.0f,
-9.0f/256.0f, 81.0f/256.0f, 81.0f/256.0f, -9.0f/256.0f);
maskMatrix[2] = matrix(0, 0, 0, 0,
0, 9.0f/16.0f, 0, 0,
0, 0, 0, 0,
-9.0f/256.0f, 81.0f/256.0f, 81.0f/256.0f, -9.0f/256.0f);
maskMatrix[3] = matrix(0, 0, 0, 0,
0, -1.0f/16.0f, 0, 0,
0, 0, 0, 0,
1.0f/256.0f, -9.0f/256.0f, -9.0f/256.0f, 1.0f/256.0f);
float2 offset = float2(dot(maskType.bgra, float4(1, 1.5, 1, 1.5)), dot(maskType.bgra, float4(1, 1, 1.5, 1.5)));
float z_predicted=0;
offset = (p_uv_div2-offset+0.5)*OneOverSize+TextureOffset;
for(int i = 0; i < 4; i++) {
float zrowv[4];
for (int j = 0; j < 4; j++) {
float2 vij = offset+float2(i,j)*OneOverSize;
zrowv[j] = tex2D(CoarseLevelElevationSampler, vij);
}
vector mask = mul(maskType.bgra, maskMatrix[i]);
vector zrow = vector(zrowv[0], zrowv[1], zrowv[2], zrowv[3]);
zrow = floor(zrow);
z_predicted = z_predicted+dot(zrow, mask);
}
z_predicted = floor(z_predicted);
// add the residual to get the actual elevation
float zf = z_predicted + residual;
// zf should always be an integer, since it gets packed
// into the integer component of the floating-point texture
zf = floor(zf);
float4 uvc = floor(float4((p_uv_div2+float2(0.5f,0)),
(p_uv_div2+float2(0,0.5f))))*OneOverSize+TextureOffset.xyxy;
// look up the z_predicted value in the coarser levels
float zc0 = floor(tex2D(CoarseLevelElevationSampler, float4(uvc.xy, 0, 1)));
float zc1 = floor(tex2D(CoarseLevelElevationSampler, float4(uvc.zw, 0, 1)));
float zf_zd = zf + ((zc0+zc1)/2-zf+256)/512;
return float4(zf_zd, 0, 0, 0);
}
technique Upsample
{
pass P0
{
VertexShader = compile vs_3_0 UpSampleVS();
PixelShader = compile ps_2_a UpsamplePS();
}
}