To dither or not to dither (that is to dither)

#10
At last I think I've successfully/faithfully recreated Som in shader form.

I will try to get a demo up over the next few days. Only super neat effect so far is dither (if you don't count the whole replication of Som thing)

Below can be found the shaders. They're not that much to speak of. If you wanted to customize the shaders for your game you could put them in a file or two and they could be used instead.

People mod games by swapping out their own shaders. The registers up top are kept track of by SomEx. They pretty much describe what Som is up to.

Code:
#define cDbgColor "float4 dbgColor : register(c0);"

#define cDimViewport "float2 dimViewport : register(c1);"
#define cFpsRegister "float2 fpsRegister : register(c1[2]);"

#define cFvfFactors "float4 fvfFactors : register(vs,c2);"
#define cColFactors "float4 colFactors : register(c3);"    Â 

#define cColFunction "float4 colFunction : register(ps,c4);"    Â 

#define cX4mWVP "float4x4 x4mWVP : register(vs,c4);"
#define cX4mWV  "float4x4 x4mWV  : register(vs,c8);"
#define cX4mIWV "float4x4 x4mIWV : register(vs,c12);"
#define cX4mW   "float4x4 x4mW   : register(vs,c16);"
#define cX4mIV  "float4x4 x4mIV  : register(vs,c20);"

#define cFogColor   "float3 fogColor   : register(ps,c23);"
#define cFogFactors "float4 fogFactors : register(vs,c24);"
#define cMatAmbient "float4 matAmbient : register(vs,c25);"
#define cMatDiffuse "float4 matDiffuse : register(vs,c26);"
#define cMatEmitted "float4 matEmitted : register(vs,c27);"
#define cEnvAmbient "float3 envAmbient : register(vs,c28);"

#define cLitAmbient(n) "float3 litAmbient["#n"] : register(vs,c32);"
#define cLitLookup1(n) "float  litLookups["#n"] : register(vs,c32[3]);"
#define cLitDiffuse(n) "float3 litDiffuse["#n"] : register(vs,c48);"
#define cLitLookup2(n) "float  litLookups["#n"] : register(vs,c48[3]);"
#define cLitVectors(n) "float4 litVectors["#n"] : register(vs,c64);"
#define cLitFactors(n) "float4 litFactors["#n"] : register(vs,c80);"

#define iNumLights "int numLights : register(vs,i0);"

static const char *som_shader_classic_vs =

    cDbgColor
    cDimViewport
    cFvfFactors
    cColFactors
    cX4mWVP
    cX4mWV
    cX4mW
    cFogFactors
    cMatAmbient
    cMatDiffuse
    cMatEmitted
    cEnvAmbient
    cLitAmbient(8)
    cLitDiffuse(8)
    cLitVectors(8)
    cLitFactors(8)
    iNumLights

    "struct BLIT_INPUT"
    "{"
    "    float4 pos : POSITION; "
    "    float4 col : COLOR;    "
    "    float2 uvs : TEXCOORD; "
    "};"
    "struct UNLIT_INPUT"
    "{"
    "    float4 pos : POSITION; "
    "    float4 col : COLOR;    "
    "    float2 uvs : TEXCOORD; "
    "};"
    "struct BLENDED_INPUT"
    "{"
    "    float4 pos : POSITION; "
    "    float3 lit : NORMAL;   "
    "    float2 uvs : TEXCOORD; "
    "};"

    "struct CLASSIC_OUTPUT"
    "{"
    "    float4 pos : POSITION; "
    "    float4 col : COLOR;    "
    "    float2 uvs : TEXCOORD; "
    "    float  fog : FOG;    Â   "
    "};"

    "CLASSIC_OUTPUT blit(BLIT_INPUT In)"
    "{"
    "    CLASSIC_OUTPUT Out; "

    //screen space calculation
    "    Out.pos.x = In.pos.x/dimViewport.x*2.0f-1.0f; "
    "    Out.pos.y = 1.0f-In.pos.y/dimViewport.y*2.0f; "
    
    "    Out.pos.z = 0.0f; Out.pos.w = 1.0f; "

    //projection space if fvfFactors.w is 0, screen space if 1
    "    Out.pos    = Out.pos*fvfFactors.w+ "
    "        mul(x4mWVP,In.pos)*(1.0f-fvfFactors.w); "    Â 

    "    Out.col = In.col; "
    "    Out.uvs = In.uvs; "
    "    Out.fog = 0.0f;    Â  "

    "    Out.col+=colFactors; " //select texture

    "    Out.col = saturate(Out.col); "

    "    return Out; "
    "}"

    "CLASSIC_OUTPUT unlit(UNLIT_INPUT In)"
    "{"
    "    CLASSIC_OUTPUT Out; "

    "    Out.pos    = mul(x4mWVP,In.pos); "

    "    Out.col = In.col; "
    "    Out.uvs = In.uvs; "        

//    "    float Z = mul(x4mWV,In.pos).z; "
    "    float Z = length(mul(x4mWV,In.pos)); " //rangefog

    "    Out.fog = fogFactors.w-fogFactors.w* "
    "        saturate((fogFactors.y-Z)/  "
    "        (fogFactors.y-fogFactors.x)); "

    "    return Out; "
    "}"

    "struct LIGHT{ float3 ambient; float3 diffuse; };"
    
    "LIGHT Light(int i, float3 P, float3 N)"
    "{"    
    "    float3 D = litVectors[i].xyz-P; float M = length(D); "
        
    "    if((litFactors[i].x-M)*litVectors[i].w<0.0f) return (LIGHT)0; " //Model 2.0+

//    "    float vis = saturate(ceil(litFactors[i].x-M*litFactors[i].w)); " //Model 1.0

    "    float att = 1.0f; " //"    float att = 1,0f*vis; " //Model 1.0

    "    att/=litFactors[i].y+litFactors[i].z*M+litFactors[i].w*M*M; "
            
    "    float3 L = normalize(D*litVectors[i].w +      " //point light
    "        litVectors[i].xyz*(1.0f-litVectors[i].w)); " //directional (assuming normalized)

    "    LIGHT Out = {litAmbient[i].rgb*att, "
    "                 litDiffuse[i].rgb*att*max(0.0f,dot(N,L))}; " 
    "    return Out; "
    "}"

    "CLASSIC_OUTPUT blended(BLENDED_INPUT In)"
    "{"
    "    CLASSIC_OUTPUT Out; "

    "    Out.pos    = mul(x4mWVP,In.pos); "

    "    Out.uvs = In.uvs; "        

//    "    float Z = mul(x4mWV,In.pos).z; "
    "    float Z = length(mul(x4mWV,In.pos)); " //rangefog

    "    Out.fog = fogFactors.w-fogFactors.w* "
    "        saturate((fogFactors.y-Z)/  "
    "        (fogFactors.y-fogFactors.x)); "

    "    float3 P = mul(x4mW,In.pos).xyz; "
    "    float3 N = normalize(mul((float3x3)x4mW,In.lit)); "
    
    "    float4 ambient = {0,0,0,0}, diffuse = {0,0,0,1}; "

    "    [loop] " //silly compiler, tricks are for kids
    "    for(int i=0;i<numLights;i++) " //TODO: Shader Model 1.0
    "    {"
    "        LIGHT sum = Light(i,P,N); "
    
    "        ambient.rgb+=sum.ambient; "
    "        diffuse.rgb+=sum.diffuse; "
    "    }"

    "    ambient.rgb+=envAmbient.rgb; "

    "    Out.col = matAmbient*ambient+matDiffuse*diffuse; "

    "    Out.col+=matEmitted; "
    "    Out.col+=colFactors; " //select texture

    "    Out.col = saturate(Out.col); "

    "    return Out; "
    "}";

static const char *som_shader_classic_ps =
                                    Â   
    cFogColor
    cColFactors
    cColFunction

#define classic_dither(sign) \
    "   float2 f88 = float2(8.0f,8.0f); "\
    "    Out.col.rgb"#sign"=tex2D(sam1,fmod(In.pos,f88)/f88).r/8.0f; "\

#define classic_colorkey(lin,exp) \
    "    clip(Out.col.a-0.3f); "\
    "    Out.col.rgb*=-pow(Out.col.a-"#lin"f,"#exp"f);"\
    "    Out.col.a = 1.0f; "    

    "texture2D tex0 : TEXTURE0;"
    "sampler2D sam0 = sampler_state"
    "{"
    "    Texture = <tex0>; "
    "};"

    "texture2D tex1 : TEXTURE1;" //dither
    "sampler2D sam1 = sampler_state"
    "{"
    "    Texture = <tex1>; "
    "    MinFilter = POINT; "
    "    MagFilter = POINT; "
    "    MipFilter = POINT; "
    "};"

    "struct CLASSIC_INPUT"
    "{"
    "    float4 col : COLOR;    "
    "    float2 uvs : TEXCOORD; "
    "    float  fog : FOG;      "
    "    float2 pos : VPOS;    Â   "
    "};"

    "struct CLASSIC_OUTPUT{ float4 col:COLOR0; };"

    "CLASSIC_OUTPUT blit(CLASSIC_INPUT In)"
    "{"
    "    CLASSIC_OUTPUT Out; "
    
    "    Out.col = tex2D(sam0,In.uvs); "

        classic_colorkey(2.0,1.0)
    
    "    Out.col*=In.col; "

        classic_dither(+)

    "    return Out; "
    "}"    

    "CLASSIC_OUTPUT unlit(CLASSIC_INPUT In)"
    "{"
    "    CLASSIC_OUTPUT Out; "
    
    "    Out.col = tex2D(sam0,In.uvs)*In.col; "    

    "    Out.col.rgb = lerp(Out.col.rgb,fogColor,In.fog); "

        classic_dither(-)

    "    return Out; "
    "}"    

    "CLASSIC_OUTPUT blended(CLASSIC_INPUT In)"
    "{"
    "    CLASSIC_OUTPUT Out; "
    
    "    Out.col = tex2D(sam0,In.uvs); "
    
        classic_colorkey(2.0,1.0)
    
    "    float4 one = {1.0f,1.0f,1.0f,1.0f}; "
    
    "    Out.col = Out.col*In.col*(one-colFunction)+ " //modulate
    "            Â  Out.col*colFunction+In.col*colFunction; " //add

    "    Out.col.rgb = lerp(Out.col.rgb,fogColor,In.fog); "

        classic_dither(-)

    "    return Out; "
    "}";
Reply



Messages In This Thread
Re: To dither or not to dither (that is to dither) - by HolyDiver - 2010-09-14, 06:18 PM



Users browsing this thread:
1 Guest(s)