GCarty

CubeMapGen-like functionality in HLSL

Discussion created by GCarty on Dec 21, 2010

I've written an HLSL shader to add mipmaps to a cubemap texture, but I can't work out how to get rid of those damned seams!

Here's the code I'm currently using -- anyone got any ideas how I could implement an edge fix similar to that used by CubeMapGen?


#include "../Shared/Common.fxh"
#include "../Shared/CommonVariables.fxh"
#include "../Shared/CommonFunctions.fxh"

#undef BINDTEXTURE
#if defined GAME || defined M2_USE_DXRENDERER
    #define BINDTEXTURE(a)
#else
    #define BINDTEXTURE(a) Texture = (a);
#endif

//half pixel dimensions in UV space (used for an offset in mip generation);
float2    g_TexSize;
//the LOD number to sampled from texture
int g_LODNum;
//the face to sample on a cube map
int g_CubeMapFaceNum;

texture TexRaw : TEXTURE
<
    int texcoord = 0;
    int MapChannel = 1;
    int samplerId = 0;
    string UIName = "TexRaw";
>;
sampler samplerRaw    :    register( s0 ) = sampler_state
{
    BINDTEXTURE(Tex0)
};


/***************************************
  VERTEXDECL
***************************************/
int vertexInput : VERTEXDECL
<
    string POSITION = "POSITION0";
    string COLOUR = "COLOR0";
    string TEXCOORD0 = "TEXCOORD0";
    string TECHNIQUE0 = "defaultTechnique";
> = 0;

struct VS_Input
{
    float4 m_position    : POSITION0;
    float4 m_colour        : COLOR0;
    float2 m_texCoord0    : TEXCOORD0;
};

struct VS_Output_Cube
{
    float4 m_position        : POSITION0;
    float4 m_texCoord0        : TEXCOORD0;
    float4 m_rollover        : TEXCOORD1;
};

half4 PS_Sample_Down_Cube( VS_Output_Cube In ) : COLOR
{
    float edgeLimit = 4.0/max(g_TexSize.x, g_TexSize.y);

    float4 m_texCoord0 = In.m_texCoord0;
    float4 m_texCoord1 = In.m_texCoord0;
    float m_weighting = 0.0;
    float3 limitsTest = m_texCoord0.xyz + In.m_rollover.xyz;        // remove the fixed 1
    float3 absLimitsTest = abs(limitsTest)+edgeLimit-1.0;
    float3 limitsTestSigns = sign(limitsTest);
    if (absLimitsTest.x > 0.0)
    {
        m_texCoord1.x = limitsTestSigns.x;
        m_texCoord1 += edgeLimit*In.m_rollover;
        m_weighting = min(0.5*absLimitsTest.x/edgeLimit);
        m_texCoord0.x = limitsTestSigns.x*(1.0 - edgeLimit);
    }
    if (absLimitsTest.y > 0.0)
    {
        m_texCoord1.y = limitsTestSigns.y;
        m_texCoord1 += edgeLimit*In.m_rollover;
        m_weighting = max(m_weighting, 0.5*absLimitsTest.y/edgeLimit);
        m_texCoord0.y = limitsTestSigns.y*(1.0 - edgeLimit);
    }
    if (absLimitsTest.z > 0.0)
    {
        m_texCoord1.z = limitsTestSigns.z;
        m_texCoord1 += edgeLimit*In.m_rollover;
        m_weighting = max(m_weighting, 0.5*absLimitsTest.z/edgeLimit);
        m_texCoord0.z = limitsTestSigns.z*(1.0 - edgeLimit);
    }
    float4 diffuse = Gamma((1.0 - m_weighting)*Degamma(texCUBElod(samplerRaw, m_texCoord0)) + m_weighting*Degamma(texCUBElod(samplerRaw, m_texCoord1)));
    return diffuse;
}

VS_Output_Cube ScreenSpaceShaderVS_Cube( VS_Input In )
{
    VS_Output_Cube Out;

    Out.m_position = In.m_position;
    Out.m_position.z = In.m_position.z * (1.0f / 16777215.0f);
    float2 rescaledTexCoord = (In.m_texCoord0.xy*2.0f - float2(1, 1));
#ifdef PC
    rescaledTexCoord += 1.0/g_TexSize;
#endif

    if ( g_CubeMapFaceNum == 1)
    {
        Out.m_texCoord0 = float4(-1.0, -rescaledTexCoord.y, rescaledTexCoord.x, g_LODNum);
        Out.m_rollover = float4(1.0, 0.0, 0.0, 0.0);
    }
    else if ( g_CubeMapFaceNum == 2)
    {
        Out.m_texCoord0 = float4(rescaledTexCoord.x, 1.0, rescaledTexCoord.y, g_LODNum);
        Out.m_rollover = float4(0.0, -1.0, 0.0, 0.0);
    }
    else if ( g_CubeMapFaceNum == 3)
    {
        Out.m_texCoord0 = float4(rescaledTexCoord.x, -1.0, -rescaledTexCoord.y, g_LODNum);
        Out.m_rollover = float4(0.0, 1.0, 0.0, 0.0);
    }
    else if ( g_CubeMapFaceNum == 4)
    {
        Out.m_texCoord0 = float4(rescaledTexCoord.x, -rescaledTexCoord.y, 1.0, g_LODNum);
        Out.m_rollover = float4(0.0, 0.0, -1.0, 0.0);
    }
    else if ( g_CubeMapFaceNum == 5)
    {
        Out.m_texCoord0 = float4(-rescaledTexCoord.x, -rescaledTexCoord.y, -1.0, g_LODNum);
        Out.m_rollover = float4(0.0, 0.0, 1.0, 0.0);
    }
    else
    {
        Out.m_texCoord0 = float4(1.0, -rescaledTexCoord.y, -rescaledTexCoord.x, g_LODNum);
        Out.m_rollover = float4(-1.0, 0.0, 0.0, 0.0);
    }
    return Out;
}


technique GenMipMapsCube
<
    string SCE_VP_COMPILE_FLAGS=" ";
    string SCE_FP_COMPILE_FLAGS=" ";
    DECLARE_HDR();
>
{
    pass p0
    {
        AlphaTestEnable = False;
        AlphaBlendEnable = False;
        AlphaRef = 1;
        ColorWriteEnable = Red|Green|Blue|Alpha;
        VERTEXSHADER    =    compile VS_3_0 ScreenSpaceShaderVS_Cube();
        PIXELSHADER        =    compile PS_3_0 PS_Sample_Down_Cube();
    }
}

 

 

Outcomes