sqrt[-1]
07-06-2010, 07:06 PM
I am writing a shader that does texture atlasing without edge filter issues - and I just though I would share. (emulating array textures on hardware that does not have array textures)
Cg code for mip level calculation:
(copied from http://linedef.com/personal/demos/?p=virtual-texturing)
#define SUB_TEXTURE_SIZE 512.0
#define SUB_TEXTURE_MIPCOUNT 10
float MipLevel( float2 uv )
{
float2 dx = ddx( uv * SUB_TEXTURE_SIZE );
float2 dy = ddy( uv * SUB_TEXTURE_SIZE );
float d = max( dot( dx, dx ), dot( dy, dy ) );
// Clamp the value to the max mip level counts
const float rangeClamp = pow(2, (SUB_TEXTURE_MIPCOUNT - 1) * 2);
d = clamp(d, 1.0, rangeClamp);
float mipLevel = 0.5 * log2(d);
mipLevel = floor(mipLevel);
return mipLevel;
}
Calculating half texel offset for selected mip level also
#define SUB_TEXTURE_SIZE 512.0
#define SUB_TEXTURE_MIPCOUNT 10
float MipLevel( float2 uv, out float a_halfOffset )
{
float2 dx = ddx( uv * SUB_TEXTURE_SIZE );
float2 dy = ddy( uv * SUB_TEXTURE_SIZE );
float d = max( dot( dx, dx ), dot( dy, dy ) );
// Clamp the value to the max mip level counts
const float rangeClamp = pow(2, SUB_TEXTURE_MIPCOUNT - 1);
d = clamp(sqrt(d), 1.0, rangeClamp);
float mipLevel = log2(d);
mipLevel = floor(mipLevel);
a_halfOffset = d * (1.0 / pow(2.0, SUB_TEXTURE_MIPCOUNT));
return mipLevel;
}
You can then use tex2Dlod to lookup the texture (with adjusted UV's to clamp the edge filtering - clamp to edge or mirror repeating only)
Edit:
Just realised that you can calculate the half pixel size by simply
a_halfOffset = pow(2.0, mipLevel - SUB_TEXTURE_MIPCOUNT);
Cg code for mip level calculation:
(copied from http://linedef.com/personal/demos/?p=virtual-texturing)
#define SUB_TEXTURE_SIZE 512.0
#define SUB_TEXTURE_MIPCOUNT 10
float MipLevel( float2 uv )
{
float2 dx = ddx( uv * SUB_TEXTURE_SIZE );
float2 dy = ddy( uv * SUB_TEXTURE_SIZE );
float d = max( dot( dx, dx ), dot( dy, dy ) );
// Clamp the value to the max mip level counts
const float rangeClamp = pow(2, (SUB_TEXTURE_MIPCOUNT - 1) * 2);
d = clamp(d, 1.0, rangeClamp);
float mipLevel = 0.5 * log2(d);
mipLevel = floor(mipLevel);
return mipLevel;
}
Calculating half texel offset for selected mip level also
#define SUB_TEXTURE_SIZE 512.0
#define SUB_TEXTURE_MIPCOUNT 10
float MipLevel( float2 uv, out float a_halfOffset )
{
float2 dx = ddx( uv * SUB_TEXTURE_SIZE );
float2 dy = ddy( uv * SUB_TEXTURE_SIZE );
float d = max( dot( dx, dx ), dot( dy, dy ) );
// Clamp the value to the max mip level counts
const float rangeClamp = pow(2, SUB_TEXTURE_MIPCOUNT - 1);
d = clamp(sqrt(d), 1.0, rangeClamp);
float mipLevel = log2(d);
mipLevel = floor(mipLevel);
a_halfOffset = d * (1.0 / pow(2.0, SUB_TEXTURE_MIPCOUNT));
return mipLevel;
}
You can then use tex2Dlod to lookup the texture (with adjusted UV's to clamp the edge filtering - clamp to edge or mirror repeating only)
Edit:
Just realised that you can calculate the half pixel size by simply
a_halfOffset = pow(2.0, mipLevel - SUB_TEXTURE_MIPCOUNT);