You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
7.1 KiB
290 lines
7.1 KiB
//========= 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
|
|
|