mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 14:16:50 +00:00
291 lines
7.1 KiB
C++
291 lines
7.1 KiB
C++
//========= 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
|