2010-09-14, 06:18 PM
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.
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; "
"}";