/* COMPATIBILITY - HLSL compilers - Cg compilers - FX11 */ /* * (Inaccurate) Phosphor shader * Author: Themaister * License: Public Domain */ #include "../../compat_includes.inc" #pragma parameter INPUT_GAMMA "Input Gamma" 2.4 0.0 10.0 0.01 #pragma parameter OUTPUT_GAMMA "Output Gamma" 2.2 0.0 10.0 0.01 // Used to counteract the desaturation effect of weighting. #pragma parameter COLOR_BOOST "Color Boost" 1.45 0.0 10.0 0.01 #ifdef PARAMETER_UNIFORM uniform float INPUT_GAMMA; uniform float OUTPUT_GAMMA; uniform float COLOR_BOOST; #else // Constants used with gamma correction. #define INPUT_GAMMA 2.4 #define OUTPUT_GAMMA 2.2 #define COLOR_BOOST 1.45 #endif #define GAMMA_IN(color) pow(color, float3(INPUT_GAMMA, INPUT_GAMMA, INPUT_GAMMA)) #define GAMMA_OUT(color) pow(color, float3(1.0 / OUTPUT_GAMMA, 1.0 / OUTPUT_GAMMA, 1.0 / OUTPUT_GAMMA)) #define TEX2D(coords) GAMMA_IN( COMPAT_Sample(decal, coords).rgb ) struct out_vertex { float4 position : COMPAT_POS; float2 texCoord : TEXCOORD0; // Extra args defined here float2 coord : TEXCOORD2; float2 coord_prev : TEXCOORD3; float2 coord_prev_prev : TEXCOORD4; float2 tex_index : TEXCOORD5; #ifndef HLSL_4 float4 Color : COLOR; #endif }; uniform COMPAT_Texture2D(decal); uniform float4x4 modelViewProj; out_vertex main_vertex(COMPAT_IN_VERTEX) { out_vertex OUT; #ifdef HLSL_4 float4 position = VIN.position; float2 texCoord = VIN.texCoord; #else OUT.Color = color; #endif OUT.position = mul(modelViewProj, position); float2 one_x = float2(1.0 / (3.0 * COMPAT_texture_size.x), 0.0); OUT.coord = texCoord - 0.0 * one_x; OUT.coord_prev = texCoord - 1.0 * one_x; OUT.coord_prev_prev = texCoord - 2.0 * one_x; OUT.tex_index = texCoord * COMPAT_texture_size; return OUT; } float3 to_focus(float pixel) { pixel = fmod(pixel + 3.0, 3.0); if (pixel >= 2.0) // Blue return float3(pixel - 2.0, 0.0, 3.0 - pixel); else if (pixel >= 1.0) // Green return float3(0.0, 2.0 - pixel, pixel - 1.0); else // Red return float3(1.0 - pixel, pixel, 0.0); } float4 phosphor(float2 coord, float2 coord_prev, float2 coord_prev_prev, float2 tex_index) { float y = fmod(tex_index.y, 1.0); float intensity = exp(-0.2 * y); float3 color = TEX2D(coord); float3 color_prev = TEX2D(coord_prev); float3 color_prev_prev = TEX2D(coord_prev_prev); float pixel_x = 3.0 * tex_index.x; float3 focus = to_focus(pixel_x - 0.0); float3 focus_prev = to_focus(pixel_x - 1.0); float3 focus_prev_prev = to_focus(pixel_x - 2.0); float3 result = 0.8 * color * focus + 0.6 * color_prev * focus_prev + 0.3 * color_prev_prev * focus_prev_prev; result = 2.3 * pow(result, float3(1.4, 1.4, 1.4)); result *= float3( COLOR_BOOST, COLOR_BOOST, COLOR_BOOST ); return float4(clamp( GAMMA_OUT(intensity * result), 0.0, 1.0 ), 1.0); } float4 main_fragment(COMPAT_IN_FRAGMENT) : COMPAT_Output { return phosphor(VOUT.coord, VOUT.coord_prev, VOUT.coord_prev_prev, VOUT.tex_index); } COMPAT_END