// LFS Pixel Shader : World // Vertex shader output structures struct VS_OUTPUT { float4 oPos : POSITION; float oFog : FOG; float4 VCol : COLOR0; float2 oT0 : TEXCOORD0; }; /* struct VS_OUTPUT_ENV { float4 oPos : POSITION; float oFog : FOG; float4 VCol : COLOR0; float3 NormalEnv : TEXCOORD0; float3 EyeToVEnv : TEXCOORD1; }; */ struct VS_OUTPUT_PAINT { float4 oPos : POSITION; float oFog : FOG; float4 VCol : COLOR0; float2 oT0 : TEXCOORD0; float3 NormalEnv : TEXCOORD1; float3 EyeToVEnv : TEXCOORD2; }; // Global variables float4 light_dir_env : register(c4); float4 lightmap_col : register(c5); float4 shine_consts : register(c6); float4 reflection_tint : register(c7); sampler2D s_T0 : register(s0); sampler2D s_T1 : register(s1); // Main functions // PSHADER_NO_TEXTURE float4 ps_no_texture( in VS_OUTPUT In ) : COLOR { return In.VCol; } // PSHADER_SIMPLE_1 float4 ps_simple_1( in VS_OUTPUT In ) : COLOR { float4 tex_col = tex2D(s_T0, In.oT0); return tex_col * In.VCol; } // PSHADER_SIMPLE_2 float4 ps_simple_2( in VS_OUTPUT In ) : COLOR { float4 tex_col = tex2D(s_T0, In.oT0); return tex_col * In.VCol * float4(2.0f, 2.0f, 2.0f, 1.0f); // mul2x } // PSHADER_OVERLAY_ONLY float4 ps_overlay_only( in VS_OUTPUT In ) : COLOR // for the first pass of an overlay material when shadowed { float4 tex_col = tex2D(s_T0, In.oT0); float col_bright = 2.0f * tex_col.a; // black pixels in the transparent areas of the overlay return tex_col * In.VCol * float4(col_bright, col_bright, col_bright, 1.0f); // mul2x } // PSHADER_SIMPLE_BRIGHT float4 ps_simple_bright( in VS_OUTPUT In ) : COLOR // unused - for testing only { float4 tex_col = tex2D(s_T0, In.oT0); return tex_col * In.VCol * float4(4.0f, 4.0f, 4.0f, 1.0f); } // function for use in shaders below float4 calc_env(float4 start, float3 NormalEnv, float3 EyeToVEnv, float facing_reflectivity, float final_env_mul) { float3 normal_env = normalize(NormalEnv); float3 e_env = normalize(EyeToVEnv); // eye to vertex float E_dot_N = min(0.0f, dot(e_env, normal_env)); float3 env_dir = e_env - 2.0f * E_dot_N * normal_env; // reflection of e_env float4 envmap_col = tex2D(s_T1, env_dir.xy * float2(0.5f, 0.5f) + float2(0.5f, 0.5f)) * reflection_tint; float schlick = pow(1.0f + E_dot_N, 5); float reflectivity_mul = lerp(facing_reflectivity, 1.0f, schlick); #ifdef VARIABLE_SHINE reflectivity_mul *= final_env_mul; // affects environment map and highlight #endif // multiplied by bound(0, r4.z * 12, 1) to avoid downward reflection (environment map is a modified sky dome) // multiplied again by 4 because the environment map is rendered at quarter brightness float env_map_mul = reflectivity_mul * saturate(env_dir.z * 12.0f) * 4.0f; float4 ret = start + float4(envmap_col.rgb * env_map_mul, 0.0f); // add environment map #ifdef HIGHLIGHT_EXP // not defined when weather is overcast float x = max(0.0f, dot(light_dir_env.xyz, env_dir)); // detect highlight ret.rgb += lightmap_col.rgb * (pow(x, HIGHLIGHT_EXP) * HIGHLIGHT_MUL * reflectivity_mul); // add highlight #endif #ifdef ALPHA // reflectivity_mul is used here to reduce glass transparency at high angles of incidence ret.a = lerp(ret.a, 1.0f, reflectivity_mul); // destination pixel is multiplied by (1 - ret.a) #endif return ret; } // PSHADER_REFLECT_PLAIN float4 ps_reflect_plain( in VS_OUTPUT_PAINT In ) : COLOR // a glassy or metallic reflection (non-transparent) { const float facing_reflectivity = shine_consts.x; float4 env = calc_env(float4(0.0f, 0.0f, 0.0f, 1.0f), In.NormalEnv, In.EyeToVEnv, facing_reflectivity, 1.0f); return env; } // PSHADER_REFLECT_OVERLAY float4 ps_reflect_overlay( in VS_OUTPUT_PAINT In ) : COLOR // a glassy or metallic reflection (non-transparent) with an overlay { float4 texture_col = tex2D(s_T0, In.oT0); float4 diffuse = texture_col * In.VCol * float4(2.0f, 2.0f, 2.0f, 1.0f); // diffuse const float facing_reflectivity = shine_consts.x; float4 env = calc_env(float4(0.0f, 0.0f, 0.0f, 1.0f), In.NormalEnv, In.EyeToVEnv, facing_reflectivity, 1.0f); return lerp(env, diffuse, texture_col.a); } // PSHADER_WORLD_VSHINE - variable shine for paint with or without transparency - VARIABLE_SHINE is defined // PSHADER_WORLD_CSHINE_SOLID - constant shine for paint // PSHADER_WORLD_CSHINE_ALPHA - for transparent glass - ALPHA is defined float4 ps_world_shiny( in VS_OUTPUT_PAINT In ) : COLOR { float4 texture_col = tex2D(s_T0, In.oT0); float4 ret = texture_col * In.VCol * float4(2.0f, 2.0f, 2.0f, 1.0f); // diffuse #ifdef ALPHA // D3DRS_SRCBLEND is D3DBLEND_ONE so that the environment map is not reduced by transparency // multiply the diffuse lighting by alpha here, to give it the same effect as D3DBLEND_SRCALPHA ret.rgb *= texture_col.a; #endif const float facing_reflectivity = shine_consts.x; ret = calc_env(ret, In.NormalEnv, In.EyeToVEnv, facing_reflectivity, texture_col.a); return ret; }