diff --git a/src/d3d/d3d9matfx.cpp b/src/d3d/d3d9matfx.cpp index 87873ef..6e66292 100644 --- a/src/d3d/d3d9matfx.cpp +++ b/src/d3d/d3d9matfx.cpp @@ -104,13 +104,18 @@ matfxRender_EnvMap(InstanceDataHeader *header, InstanceData *inst, int32 lightBi d3d::setTexture(1, env->tex); uploadEnvMatrix(env->frame); - d3ddevice->SetPixelShaderConstantF(PSLOC_shininess, &env->coefficient, 1); - SetRenderState(SRCBLEND, BLENDONE); static float zero[4]; static float one[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - d3ddevice->SetPixelShaderConstantF(PSLOC_shininess, &env->coefficient, 1); + struct { + float shininess; + float disableFBA; + float unused[2]; + } fxparams; + fxparams.shininess = env->coefficient; + fxparams.disableFBA = env->fbAlpha ? 0.0f : 1.0f; + d3ddevice->SetPixelShaderConstantF(PSLOC_shininess, (float*)&fxparams, 1); // This clamps the vertex color below. With it we can achieve both PC and PS2 style matfx if(MatFX::modulateEnvMap) d3ddevice->SetPixelShaderConstantF(PSLOC_colorClamp, zero, 1); diff --git a/src/d3d/shaders/matfx_env_PS.h b/src/d3d/shaders/matfx_env_PS.h index b6bf3cb..558ccdc 100644 --- a/src/d3d/shaders/matfx_env_PS.h +++ b/src/d3d/shaders/matfx_env_PS.h @@ -10,7 +10,7 @@ // float4 colorClamp; // sampler2D envTex; // float4 fogColor; -// float shininess; +// float4 fxparams; // // // Registers: @@ -18,7 +18,7 @@ // Name Reg Size // ------------ ----- ---- // fogColor c0 1 -// shininess c1 1 +// fxparams c1 1 // colorClamp c2 1 // envTex s1 1 // @@ -33,24 +33,26 @@ mul r1.xyz, r1, c1.x mul r0.xyz, r0, r1 mul r0.xyz, r0, t0.z + max r0.w, v0.w, c1.y + mul r0.xyz, r0.w, r0 add r1.xyz, v0, -c0 mad r1.xyz, t0.z, r1, c0 mad r0.xyz, r1, v0.w, r0 mov r0.w, v0.w mov oC0, r0 -// approximately 10 instruction slots used (1 texture, 9 arithmetic) +// approximately 12 instruction slots used (1 texture, 11 arithmetic) #endif const BYTE g_ps20_main[] = { 0, 2, 255, 255, 254, 255, - 64, 0, 67, 84, 65, 66, - 28, 0, 0, 0, 203, 0, + 60, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 185, 0, 0, 0, 0, 2, 255, 255, 4, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, - 196, 0, 0, 0, 108, 0, + 178, 0, 0, 0, 108, 0, 0, 0, 2, 0, 2, 0, 1, 0, 10, 0, 120, 0, 0, 0, 0, 0, 0, 0, @@ -62,7 +64,7 @@ const BYTE g_ps20_main[] = 2, 0, 120, 0, 0, 0, 0, 0, 0, 0, 169, 0, 0, 0, 2, 0, 1, 0, - 1, 0, 6, 0, 180, 0, + 1, 0, 6, 0, 120, 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 67, 108, 97, 109, 112, 0, 171, @@ -74,11 +76,8 @@ const BYTE g_ps20_main[] = 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 102, 111, 103, 67, 111, 108, 111, 114, - 0, 115, 104, 105, 110, 105, - 110, 101, 115, 115, 0, 171, - 0, 0, 3, 0, 1, 0, - 1, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 112, 115, + 0, 102, 120, 112, 97, 114, + 97, 109, 115, 0, 112, 115, 95, 50, 95, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, @@ -88,40 +87,45 @@ const BYTE g_ps20_main[] = 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, 49, 0, - 31, 0, 0, 2, 0, 0, - 0, 128, 0, 0, 7, 176, - 31, 0, 0, 2, 0, 0, - 0, 128, 1, 0, 3, 176, - 31, 0, 0, 2, 0, 0, - 0, 128, 0, 0, 15, 144, - 31, 0, 0, 2, 0, 0, - 0, 144, 1, 8, 15, 160, - 66, 0, 0, 3, 0, 0, - 15, 128, 1, 0, 228, 176, - 1, 8, 228, 160, 11, 0, + 171, 171, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 7, 176, 31, 0, 0, 2, + 0, 0, 0, 128, 1, 0, + 3, 176, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 15, 144, 31, 0, 0, 2, + 0, 0, 0, 144, 1, 8, + 15, 160, 66, 0, 0, 3, + 0, 0, 15, 128, 1, 0, + 228, 176, 1, 8, 228, 160, + 11, 0, 0, 3, 1, 0, + 7, 128, 0, 0, 228, 144, + 2, 0, 228, 160, 5, 0, 0, 3, 1, 0, 7, 128, - 0, 0, 228, 144, 2, 0, - 228, 160, 5, 0, 0, 3, - 1, 0, 7, 128, 1, 0, - 228, 128, 1, 0, 0, 160, + 1, 0, 228, 128, 1, 0, + 0, 160, 5, 0, 0, 3, + 0, 0, 7, 128, 0, 0, + 228, 128, 1, 0, 228, 128, 5, 0, 0, 3, 0, 0, 7, 128, 0, 0, 228, 128, - 1, 0, 228, 128, 5, 0, - 0, 3, 0, 0, 7, 128, - 0, 0, 228, 128, 0, 0, - 170, 176, 2, 0, 0, 3, - 1, 0, 7, 128, 0, 0, - 228, 144, 0, 0, 228, 161, - 4, 0, 0, 4, 1, 0, - 7, 128, 0, 0, 170, 176, - 1, 0, 228, 128, 0, 0, - 228, 160, 4, 0, 0, 4, - 0, 0, 7, 128, 1, 0, - 228, 128, 0, 0, 255, 144, - 0, 0, 228, 128, 1, 0, - 0, 2, 0, 0, 8, 128, + 0, 0, 170, 176, 11, 0, + 0, 3, 0, 0, 8, 128, 0, 0, 255, 144, 1, 0, - 0, 2, 0, 8, 15, 128, - 0, 0, 228, 128, 255, 255, - 0, 0 + 85, 160, 5, 0, 0, 3, + 0, 0, 7, 128, 0, 0, + 255, 128, 0, 0, 228, 128, + 2, 0, 0, 3, 1, 0, + 7, 128, 0, 0, 228, 144, + 0, 0, 228, 161, 4, 0, + 0, 4, 1, 0, 7, 128, + 0, 0, 170, 176, 1, 0, + 228, 128, 0, 0, 228, 160, + 4, 0, 0, 4, 0, 0, + 7, 128, 1, 0, 228, 128, + 0, 0, 255, 144, 0, 0, + 228, 128, 1, 0, 0, 2, + 0, 0, 8, 128, 0, 0, + 255, 144, 1, 0, 0, 2, + 0, 8, 15, 128, 0, 0, + 228, 128, 255, 255, 0, 0 }; diff --git a/src/d3d/shaders/matfx_env_PS.hlsl b/src/d3d/shaders/matfx_env_PS.hlsl index 767e313..ccdd5cd 100644 --- a/src/d3d/shaders/matfx_env_PS.hlsl +++ b/src/d3d/shaders/matfx_env_PS.hlsl @@ -10,9 +10,12 @@ sampler2D envTex : register(s1); float4 fogColor : register(c0); -float shininess : register(c1); +float4 fxparams : register(c1); float4 colorClamp : register(c2); +#define shininess (fxparams.x) +#define disableFBA (fxparams.y) + float4 main(VS_out input) : COLOR { float4 pass1 = input.Color; @@ -29,8 +32,11 @@ float4 main(VS_out input) : COLOR // We simulate drawing this in two passes. // First pass with standard blending, second with addition // We premultiply alpha so render state should be one. + // For FB alpha rendering assume that diffuse alpha (pass1.a) was + // written to framebuffer, so just multiply pass2 by it as well then. + float fba = max(pass1.a, disableFBA); float4 color; - color.rgb = pass1.rgb*pass1.a + pass2.rgb; + color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba; color.a = pass1.a; return color; diff --git a/src/d3d/shaders/matfx_env_tex_PS.h b/src/d3d/shaders/matfx_env_tex_PS.h index 21eb196..3a2d442 100644 --- a/src/d3d/shaders/matfx_env_tex_PS.h +++ b/src/d3d/shaders/matfx_env_tex_PS.h @@ -11,7 +11,7 @@ // sampler2D diffTex; // sampler2D envTex; // float4 fogColor; -// float shininess; +// float4 fxparams; // // // Registers: @@ -19,7 +19,7 @@ // Name Reg Size // ------------ ----- ---- // fogColor c0 1 -// shininess c1 1 +// fxparams c1 1 // colorClamp c2 1 // diffTex s0 1 // envTex s1 1 @@ -37,24 +37,26 @@ mul r2.xyz, r2, c1.x mul r0.xyz, r0, r2 mul r0.xyz, r0, t0.z - mad r1.xyz, v0, r1, -c0 mul r2.w, r1.w, v0.w + mad r1.xyz, v0, r1, -c0 mad r1.xyz, t0.z, r1, c0 + max r0.w, r2.w, c1.y + mul r0.xyz, r0.w, r0 mad r2.xyz, r1, r2.w, r0 mov oC0, r2 -// approximately 11 instruction slots used (2 texture, 9 arithmetic) +// approximately 13 instruction slots used (2 texture, 11 arithmetic) #endif const BYTE g_ps20_main[] = { 0, 2, 255, 255, 254, 255, - 75, 0, 67, 84, 65, 66, - 28, 0, 0, 0, 247, 0, + 71, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 229, 0, 0, 0, 0, 2, 255, 255, 5, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, - 240, 0, 0, 0, 128, 0, + 222, 0, 0, 0, 128, 0, 0, 0, 2, 0, 2, 0, 1, 0, 10, 0, 140, 0, 0, 0, 0, 0, 0, 0, @@ -70,7 +72,7 @@ const BYTE g_ps20_main[] = 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 2, 0, 1, 0, 1, 0, 6, 0, - 224, 0, 0, 0, 0, 0, + 140, 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 67, 108, 97, 109, 112, 0, 171, 1, 0, 3, 0, @@ -85,11 +87,8 @@ const BYTE g_ps20_main[] = 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 102, 111, 103, 67, 111, 108, - 111, 114, 0, 115, 104, 105, - 110, 105, 110, 101, 115, 115, - 0, 171, 0, 0, 3, 0, - 1, 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, + 111, 114, 0, 102, 120, 112, + 97, 114, 97, 109, 115, 0, 112, 115, 95, 50, 95, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, @@ -99,46 +98,52 @@ const BYTE g_ps20_main[] = 112, 105, 108, 101, 114, 32, 57, 46, 50, 57, 46, 57, 53, 50, 46, 51, 49, 49, - 49, 0, 31, 0, 0, 2, - 0, 0, 0, 128, 0, 0, - 7, 176, 31, 0, 0, 2, - 0, 0, 0, 128, 1, 0, - 3, 176, 31, 0, 0, 2, - 0, 0, 0, 128, 0, 0, - 15, 144, 31, 0, 0, 2, - 0, 0, 0, 144, 0, 8, - 15, 160, 31, 0, 0, 2, - 0, 0, 0, 144, 1, 8, - 15, 160, 66, 0, 0, 3, - 0, 0, 15, 128, 1, 0, - 228, 176, 1, 8, 228, 160, - 66, 0, 0, 3, 1, 0, - 15, 128, 0, 0, 228, 176, - 0, 8, 228, 160, 11, 0, + 49, 0, 171, 171, 31, 0, + 0, 2, 0, 0, 0, 128, + 0, 0, 7, 176, 31, 0, + 0, 2, 0, 0, 0, 128, + 1, 0, 3, 176, 31, 0, + 0, 2, 0, 0, 0, 128, + 0, 0, 15, 144, 31, 0, + 0, 2, 0, 0, 0, 144, + 0, 8, 15, 160, 31, 0, + 0, 2, 0, 0, 0, 144, + 1, 8, 15, 160, 66, 0, + 0, 3, 0, 0, 15, 128, + 1, 0, 228, 176, 1, 8, + 228, 160, 66, 0, 0, 3, + 1, 0, 15, 128, 0, 0, + 228, 176, 0, 8, 228, 160, + 11, 0, 0, 3, 2, 0, + 7, 128, 0, 0, 228, 144, + 2, 0, 228, 160, 5, 0, 0, 3, 2, 0, 7, 128, - 0, 0, 228, 144, 2, 0, - 228, 160, 5, 0, 0, 3, - 2, 0, 7, 128, 2, 0, - 228, 128, 1, 0, 0, 160, + 2, 0, 228, 128, 1, 0, + 0, 160, 5, 0, 0, 3, + 0, 0, 7, 128, 0, 0, + 228, 128, 2, 0, 228, 128, 5, 0, 0, 3, 0, 0, 7, 128, 0, 0, 228, 128, - 2, 0, 228, 128, 5, 0, - 0, 3, 0, 0, 7, 128, - 0, 0, 228, 128, 0, 0, - 170, 176, 4, 0, 0, 4, - 1, 0, 7, 128, 0, 0, - 228, 144, 1, 0, 228, 128, - 0, 0, 228, 161, 5, 0, + 0, 0, 170, 176, 5, 0, 0, 3, 2, 0, 8, 128, 1, 0, 255, 128, 0, 0, 255, 144, 4, 0, 0, 4, 1, 0, 7, 128, 0, 0, - 170, 176, 1, 0, 228, 128, - 0, 0, 228, 160, 4, 0, - 0, 4, 2, 0, 7, 128, - 1, 0, 228, 128, 2, 0, - 255, 128, 0, 0, 228, 128, - 1, 0, 0, 2, 0, 8, - 15, 128, 2, 0, 228, 128, - 255, 255, 0, 0 + 228, 144, 1, 0, 228, 128, + 0, 0, 228, 161, 4, 0, + 0, 4, 1, 0, 7, 128, + 0, 0, 170, 176, 1, 0, + 228, 128, 0, 0, 228, 160, + 11, 0, 0, 3, 0, 0, + 8, 128, 2, 0, 255, 128, + 1, 0, 85, 160, 5, 0, + 0, 3, 0, 0, 7, 128, + 0, 0, 255, 128, 0, 0, + 228, 128, 4, 0, 0, 4, + 2, 0, 7, 128, 1, 0, + 228, 128, 2, 0, 255, 128, + 0, 0, 228, 128, 1, 0, + 0, 2, 0, 8, 15, 128, + 2, 0, 228, 128, 255, 255, + 0, 0 }; diff --git a/src/gl/gl2_shaders/matfx_env.frag b/src/gl/gl2_shaders/matfx_env.frag index ecba24f..596b655 100644 --- a/src/gl/gl2_shaders/matfx_env.frag +++ b/src/gl/gl2_shaders/matfx_env.frag @@ -1,9 +1,12 @@ uniform sampler2D tex0; uniform sampler2D tex1; -uniform float u_coefficient; +uniform vec2 u_fxparams; uniform vec4 u_colorClamp; +#define shininess (u_fxparams.x) +#define disableFBA (u_fxparams.y) + varying vec4 v_color; varying vec2 v_tex0; varying vec2 v_tex1; @@ -15,7 +18,7 @@ main(void) vec4 color; vec4 pass1 = v_color; - vec4 envColor = pass1; // TODO: colorClamp + vec4 envColor = max(pass1, u_colorClamp); pass1 *= texture2D(tex0, vec2(v_tex0.x, 1.0-v_tex0.y)); vec4 pass2 = envColor*u_coefficient*texture2D(tex1, vec2(v_tex1.x, 1.0-v_tex1.y)); @@ -23,7 +26,8 @@ main(void) pass1.rgb = mix(u_fogColor.rgb, pass1.rgb, v_fog); pass2.rgb = mix(vec3(0.0, 0.0, 0.0), pass2.rgb, v_fog); - color.rgb = pass1.rgb*pass1.a + pass2.rgb; + float fba = max(pass1.a, disableFBA); + color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba; color.a = pass1.a; DoAlphaTest(color.a); diff --git a/src/gl/gl2_shaders/matfx_gl2.inc b/src/gl/gl2_shaders/matfx_gl2.inc index 9d037bd..576ce78 100644 --- a/src/gl/gl2_shaders/matfx_gl2.inc +++ b/src/gl/gl2_shaders/matfx_gl2.inc @@ -34,9 +34,12 @@ const char *matfx_env_frag_src = "uniform sampler2D tex0;\n" "uniform sampler2D tex1;\n" -"uniform float u_coefficient;\n" +"uniform vec2 u_fxparams;\n" "uniform vec4 u_colorClamp;\n" +"#define shininess (u_fxparams.x)\n" +"#define disableFBA (u_fxparams.y)\n" + "varying vec4 v_color;\n" "varying vec2 v_tex0;\n" "varying vec2 v_tex1;\n" @@ -48,7 +51,7 @@ const char *matfx_env_frag_src = " vec4 color;\n" " vec4 pass1 = v_color;\n" -" vec4 envColor = pass1; // TODO: colorClamp\n" +" vec4 envColor = max(pass1, u_colorClamp);\n" " pass1 *= texture2D(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n" " vec4 pass2 = envColor*u_coefficient*texture2D(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));\n" @@ -56,7 +59,8 @@ const char *matfx_env_frag_src = " pass1.rgb = mix(u_fogColor.rgb, pass1.rgb, v_fog);\n" " pass2.rgb = mix(vec3(0.0, 0.0, 0.0), pass2.rgb, v_fog);\n" -" color.rgb = pass1.rgb*pass1.a + pass2.rgb;\n" +" float fba = max(pass1.a, disableFBA);\n" +" color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba;\n" " color.a = pass1.a;\n" " DoAlphaTest(color.a);\n" diff --git a/src/gl/gl3matfx.cpp b/src/gl/gl3matfx.cpp index cb0614d..687c1ab 100644 --- a/src/gl/gl3matfx.cpp +++ b/src/gl/gl3matfx.cpp @@ -30,14 +30,14 @@ namespace gl3 { static Shader *envShader; static int32 u_texMatrix; -static int32 u_coefficient; +static int32 u_fxparams; static int32 u_colorClamp; static void* matfxOpen(void *o, int32, int32) { u_texMatrix = registerUniform("u_texMatrix"); - u_coefficient = registerUniform("u_coefficient"); + u_fxparams = registerUniform("u_fxparams"); u_colorClamp = registerUniform("u_colorClamp"); matFXGlobals.pipelines[PLATFORM_GL3] = makeMatFXPipeline(); @@ -152,7 +152,11 @@ matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, MatFX::Env *env) surfProps[3] = 0.0f; glUniform4fv(U(u_surfProps), 1, surfProps); - glUniform1fv(U(u_coefficient), 1, &env->coefficient); + float fxparams[2]; + fxparams[0] = env->coefficient; + fxparams[1] = env->fbAlpha ? 0.0f : 1.0f; + + glUniform2fv(U(u_fxparams), 1, fxparams); static float zero[4]; static float one[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; // This clamps the vertex color below. With it we can achieve both PC and PS2 style matfx diff --git a/src/gl/shaders/matfx_env.frag b/src/gl/shaders/matfx_env.frag index 43c60ef..0d11871 100644 --- a/src/gl/shaders/matfx_env.frag +++ b/src/gl/shaders/matfx_env.frag @@ -1,9 +1,12 @@ uniform sampler2D tex0; uniform sampler2D tex1; -uniform float u_coefficient; +uniform vec2 u_fxparams; uniform vec4 u_colorClamp; +#define shininess (u_fxparams.x) +#define disableFBA (u_fxparams.y) + in vec4 v_color; in vec2 v_tex0; in vec2 v_tex1; @@ -15,15 +18,16 @@ void main(void) { vec4 pass1 = v_color; - vec4 envColor = pass1; // TODO: colorClamp + vec4 envColor = max(pass1, u_colorClamp); pass1 *= texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y)); - vec4 pass2 = envColor*u_coefficient*texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y)); + vec4 pass2 = envColor*shininess*texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y)); pass1.rgb = mix(u_fogColor.rgb, pass1.rgb, v_fog); pass2.rgb = mix(vec3(0.0, 0.0, 0.0), pass2.rgb, v_fog); - color.rgb = pass1.rgb*pass1.a + pass2.rgb; + float fba = max(pass1.a, disableFBA); + color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba; color.a = pass1.a; DoAlphaTest(color.a); diff --git a/src/gl/shaders/matfx_gl3.inc b/src/gl/shaders/matfx_gl3.inc index fd138c9..873f88e 100644 --- a/src/gl/shaders/matfx_gl3.inc +++ b/src/gl/shaders/matfx_gl3.inc @@ -34,9 +34,12 @@ const char *matfx_env_frag_src = "uniform sampler2D tex0;\n" "uniform sampler2D tex1;\n" -"uniform float u_coefficient;\n" +"uniform vec2 u_fxparams;\n" "uniform vec4 u_colorClamp;\n" +"#define shininess (u_fxparams.x)\n" +"#define disableFBA (u_fxparams.y)\n" + "in vec4 v_color;\n" "in vec2 v_tex0;\n" "in vec2 v_tex1;\n" @@ -48,15 +51,16 @@ const char *matfx_env_frag_src = "main(void)\n" "{\n" " vec4 pass1 = v_color;\n" -" vec4 envColor = pass1; // TODO: colorClamp\n" +" vec4 envColor = max(pass1, u_colorClamp);\n" " pass1 *= texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n" -" vec4 pass2 = envColor*u_coefficient*texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));\n" +" vec4 pass2 = envColor*shininess*texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));\n" " pass1.rgb = mix(u_fogColor.rgb, pass1.rgb, v_fog);\n" " pass2.rgb = mix(vec3(0.0, 0.0, 0.0), pass2.rgb, v_fog);\n" -" color.rgb = pass1.rgb*pass1.a + pass2.rgb;\n" +" float fba = max(pass1.a, disableFBA);\n" +" color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba;\n" " color.a = pass1.a;\n" " DoAlphaTest(color.a);\n"