summaryrefslogtreecommitdiff
path: root/materialsystem/stdshaders/color_projection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'materialsystem/stdshaders/color_projection.cpp')
-rw-r--r--materialsystem/stdshaders/color_projection.cpp290
1 files changed, 290 insertions, 0 deletions
diff --git a/materialsystem/stdshaders/color_projection.cpp b/materialsystem/stdshaders/color_projection.cpp
new file mode 100644
index 0000000..e8d0a50
--- /dev/null
+++ b/materialsystem/stdshaders/color_projection.cpp
@@ -0,0 +1,290 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+
+#include "BaseVSShader.h"
+
+#include "color_projection_ps20.inc"
+#include "color_projection_vs20.inc"
+
+#include "../materialsystem_global.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+static ConVar *mat_color_projection = NULL;
+
+typedef struct SProjectionInfo
+{
+ bool m_bNeedBlindMK;
+ bool m_bNeedMonochrome;
+ bool m_bNeedAnomylize;
+ float m_flCPU;
+ float m_flCPV;
+ float m_flAM;
+ float m_flAYI;
+} TProjectionInfo;
+
+#define MAX_PROJECTIONS 8
+
+TProjectionInfo ProjectionInfo[ MAX_PROJECTIONS ] =
+{
+ { true, false, false, 0.735f, 0.265f, 1.273463f, -0.073894f }, // protanopia red-green blindness (no red cones)
+ { true, false, false, 1.14f, -0.14f, 0.968437f, 0.003331f }, // deutanopia red-green blindness (no green cones)
+ { true, false, false, 0.171f, -0.003f, 0.062921f, 0.292119f }, // tritanopia blue-yellow blindness (no blue cones)
+ { false, true, false, 0.0f, 0.0f, 0.0f, 0.0f }, // typical achromatopsia (no cones; rod monochromat)
+ { true, false, true, 0.735f, 0.265f, 1.273463f, -0.073894f }, // protanomaly (anomalous red cones)
+ { true, false, true, 1.14f, -0.14f, 0.968437f, 0.003331f }, // deutanomaly (anomalous green cones)
+ { true, false, true, 0.171f, -0.003f, 0.062921f, 0.292119f }, // tritanomaly (anomalous blue cones)
+ { false, true, true, 0.0f, 0.0f, 0.0f, 0.0f } // atypical achromatopsia (low cones; cone monochromat)
+};
+
+#if 0
+
+#define cpu ProjectionInfo[ 2 ].m_flCPU
+#define cpv ProjectionInfo[ 2 ].m_flCPV
+#define am ProjectionInfo[ 2 ].m_flAM
+#define ayi ProjectionInfo[ 2 ].m_flAYI
+
+
+Vector rgb_from_xyz( Vector vNum )
+{
+ Vector vResult;
+
+ vResult.x=( 3.063218*vNum.x-1.393325*vNum.y-0.475802*vNum.z);
+ vResult.y=(-0.969243*vNum.x+1.875966*vNum.y+0.041555*vNum.z);
+ vResult.z=( 0.067871*vNum.x-0.228834*vNum.y+1.069251*vNum.z);
+
+ return vResult;
+}
+
+Vector xyz_from_rgb( Vector vNum )
+{
+ Vector vResult;
+
+ vResult.x=(0.430574*vNum.x+0.341550*vNum.y+0.178325*vNum.z);
+ vResult.y=(0.222015*vNum.x+0.706655*vNum.y+0.071330*vNum.z);
+ vResult.z=(0.020183*vNum.x+0.129553*vNum.y+0.939180*vNum.z);
+
+ return vResult;
+}
+
+Vector anomylize( Vector a, Vector b )
+{
+ return ( ( 1.75f * b ) + a ) / 2.75f;
+}
+
+Vector monochrome( Vector r)
+{
+ float z = (r.x*0.299+r.y*0.587+r.z*0.114);
+
+ return Vector( z, z, z );;
+}
+
+
+Vector blindMK( Vector vColor )
+{
+ const float wx=0.312713;
+ const float wy=0.329016;
+ const float wz=0.358271;
+
+ Vector c_xyz = xyz_from_rgb( vColor );
+
+ float sum_xyz=c_xyz.x+c_xyz.y+c_xyz.z;
+
+ Vector2D c_uv;
+ c_uv.x=0;
+ c_uv.y=0;
+
+ if ( sum_xyz!=0 )
+ {
+ c_uv.x=c_xyz.x/sum_xyz;
+ c_uv.y=c_xyz.y/sum_xyz;
+ }
+
+ float nx=wx*c_xyz.y/wy;
+ float nz=wz*c_xyz.y/wy;
+
+ Vector d_xyz;
+ d_xyz.y=0;
+
+ float clm;
+ if ( c_uv.x< cpu )
+ {
+ clm=(cpv-c_uv.y)/(cpu-c_uv.x);
+ }
+ else
+ {
+ clm=(c_uv.y-cpv)/(c_uv.x-cpu);
+ }
+
+ float clyi=c_uv.y-c_uv.x*clm;
+ Vector2D d_uv;
+ d_uv.x=(ayi-clyi)/(clm-am);
+ d_uv.y=(clm*d_uv.x)+clyi;
+
+ Vector s_xyz;
+ s_xyz.x=d_uv.x*c_xyz.y/d_uv.y;
+ s_xyz.y=c_xyz.y;
+ s_xyz.z=(1-(d_uv.x+d_uv.y))*c_xyz.y/d_uv.y;
+
+ Vector s_rgb = rgb_from_xyz( s_xyz );
+
+ d_xyz.x=nx-s_xyz.x;
+ d_xyz.z=nz-s_xyz.z;
+
+ Vector d_rgb = rgb_from_xyz( d_xyz );
+
+ Vector adj_rgb;
+
+ adj_rgb.Init();
+
+ if ( d_rgb.x!=0 )
+ {
+ adj_rgb.x=( s_rgb.x<0 ? 0 : 1)-s_rgb.x/d_rgb.x;
+ }
+ if ( d_rgb.y!=0 )
+ {
+ adj_rgb.y=( s_rgb.y<0 ? 0 : 1)-s_rgb.y/d_rgb.y;
+ }
+ if ( d_rgb.z!=0 )
+ {
+ adj_rgb.z=( s_rgb.z<0 ? 0 : 1)-s_rgb.z/d_rgb.z;
+ }
+
+ float adjust = 0;
+ if ( adj_rgb.x >= 0 && adj_rgb.x <= 1 )
+ {
+ adjust = adj_rgb.x;
+ }
+ if ( adj_rgb.y >= 0 && adj_rgb.y <= 1 && adj_rgb.y > adjust )
+ {
+ adjust = adj_rgb.y;
+ }
+ if ( adj_rgb.z >= 0 && adj_rgb.z <= 1 && adj_rgb.z > adjust )
+ {
+ adjust = adj_rgb.z;
+ }
+
+ s_rgb.x=s_rgb.x+(adjust*d_rgb.x);
+ s_rgb.y=s_rgb.y+(adjust*d_rgb.y);
+ s_rgb.z=s_rgb.z+(adjust*d_rgb.z);
+
+ return s_rgb;
+}
+
+#endif
+
+
+BEGIN_VS_SHADER( color_projection, "Help for deferred color correction" )
+ BEGIN_SHADER_PARAMS
+ SHADER_PARAM( FRAME_TEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_FullFrameFB1", "" )
+
+ SHADER_PARAM( HSV_CORRECTION, SHADER_PARAM_TYPE_VEC3, "[ 0.0 0.0 0.0 ]", "" )
+ SHADER_PARAM( CONTRAST_CORRECTION, SHADER_PARAM_TYPE_FLOAT, "0.0", "" )
+
+ END_SHADER_PARAMS
+
+ SHADER_INIT_PARAMS()
+ {
+ SET_FLAGS2( MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE );
+
+#if 0
+ Vector vResult;
+ vResult = blindMK( Vector( 1, 0, 0 ) );
+ vResult = blindMK( Vector( 1, 0, 0 ) );
+ vResult = blindMK( Vector( 1, 0, 0 ) );
+ vResult = blindMK( Vector( 1, 0, 0 ) );
+ vResult = blindMK( Vector( 1, 0, 0 ) );
+ vResult = blindMK( Vector( 1, 0, 0 ) );
+
+ Msg( "%g %g %g", vResult.x, vResult.y, vResult.z );
+
+#endif
+ }
+
+ SHADER_FALLBACK
+ {
+ return 0;
+ }
+
+ SHADER_INIT
+ {
+ if ( mat_color_projection == NULL )
+ {
+ mat_color_projection = cvar->FindVar( "mat_color_projection" );
+ }
+
+ if ( params[ FRAME_TEXTURE ]->IsDefined() == false )
+ {
+ params[ FRAME_TEXTURE ]->SetStringValue( "_rt_FullFrameFB1" );
+ }
+// params[ FRAME_TEXTURE ]->SetStringValue( "rj/colors" );
+ LoadTexture( FRAME_TEXTURE );
+ }
+
+ SHADER_DRAW
+ {
+ SHADOW_STATE
+ {
+ SetInitialShadowState( );
+
+ pShaderShadow->EnableDepthWrites( false );
+ pShaderShadow->EnableDepthTest( false );
+// pShaderShadow->EnableBlending( true );
+// pShaderShadow->BlendOp( SHADER_BLEND_OP_REVSUBTRACT );
+// EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
+
+ pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
+
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false );
+
+ pShaderShadow->EnableSRGBWrite( false );
+ pShaderShadow->EnableAlphaWrites( true ); // writing water fog alpha always.
+
+ int fmt = VERTEX_POSITION;
+ int nTexCoordDims[ 2 ] = { 2, 3 };
+ pShaderShadow->VertexShaderVertexFormat( fmt, 2, nTexCoordDims, 0 );
+
+ DECLARE_STATIC_VERTEX_SHADER( color_projection_vs20 );
+ SET_STATIC_VERTEX_SHADER( color_projection_vs20 );
+
+ DECLARE_STATIC_PIXEL_SHADER( color_projection_ps20 );
+ SET_STATIC_PIXEL_SHADER( color_projection_ps20 );
+ }
+
+ DYNAMIC_STATE
+ {
+ pShaderAPI->SetDefaultState();
+
+ BindTexture( SHADER_SAMPLER4, FRAME_TEXTURE, -1 );
+
+ int nIndex = mat_color_projection->GetInt() - 1;
+ if ( nIndex < 0 || nIndex >= MAX_PROJECTIONS )
+ {
+ nIndex = 0;
+ }
+
+ Vector4D vCorrectionParms;
+
+ vCorrectionParms.x = ProjectionInfo[ nIndex ].m_flCPU;
+ vCorrectionParms.y = ProjectionInfo[ nIndex ].m_flCPV;
+ vCorrectionParms.z = ProjectionInfo[ nIndex ].m_flAM;
+ vCorrectionParms.w = ProjectionInfo[ nIndex ].m_flAYI;
+ pShaderAPI->SetPixelShaderConstant( 1, vCorrectionParms.Base() );
+
+ DECLARE_DYNAMIC_VERTEX_SHADER( color_projection_vs20 );
+ SET_DYNAMIC_VERTEX_SHADER( color_projection_vs20 );
+
+ DECLARE_DYNAMIC_PIXEL_SHADER( color_projection_ps20 );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( NEED_BLINDMK, ProjectionInfo[ nIndex ].m_bNeedBlindMK );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( NEED_MONOCHROME, ProjectionInfo[ nIndex ].m_bNeedMonochrome );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( NEED_ANOMYLIZE, ProjectionInfo[ nIndex ].m_bNeedAnomylize );
+ SET_DYNAMIC_PIXEL_SHADER( color_projection_ps20 );
+ }
+ Draw();
+ }
+END_SHADER