//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Teeth renderer // // $Header: $ // $NoKeywords: $ //=============================================================================// #include "BaseVSShader.h" #include "mathlib/vmatrix.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" DEFINE_FALLBACK_SHADER( Eyes, Eyes_dx6 ) BEGIN_VS_SHADER( Eyes_dx6, "Help for Eyes" ) BEGIN_SHADER_PARAMS SHADER_PARAM( IRIS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "iris texture" ) SHADER_PARAM( IRISFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame for the iris texture" ) SHADER_PARAM( GLINT, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "glint texture" ) SHADER_PARAM( EYEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "origin for the eyes" ) SHADER_PARAM( EYEUP, SHADER_PARAM_TYPE_VEC3, "[0 0 1]", "up vector for the eyes" ) SHADER_PARAM( IRISU, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0 ]", "U projection vector for the iris" ) SHADER_PARAM( IRISV, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "V projection vector for the iris" ) SHADER_PARAM( GLINTU, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "U projection vector for the glint" ) SHADER_PARAM( GLINTV, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "V projection vector for the glint" ) END_SHADER_PARAMS SHADER_INIT_PARAMS() { // FLASHLIGHTFIXME params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); } SHADER_INIT { LoadTexture( FLASHLIGHTTEXTURE ); LoadTexture( BASETEXTURE ); LoadTexture( IRIS ); } void SetTextureTransform( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, MaterialMatrixMode_t textureTransform, int uparam, int vparam ) { Vector4D u, v; params[uparam]->GetVecValue( u.Base(), 4 ); params[vparam]->GetVecValue( v.Base(), 4 ); // Need to transform these puppies into camera space // they are defined in world space VMatrix mat, invTrans; pShaderAPI->GetMatrix( MATERIAL_VIEW, mat.m[0] ); mat = mat.Transpose(); // Compute the inverse transpose of the matrix // NOTE: I only have to invert it here because VMatrix is transposed // with respect to what gets returned from GetMatrix. mat.InverseGeneral( invTrans ); invTrans = invTrans.Transpose(); // Transform the u and v planes into view space Vector4D uview, vview; uview.AsVector3D() = invTrans.VMul3x3( u.AsVector3D() ); vview.AsVector3D() = invTrans.VMul3x3( v.AsVector3D() ); uview[3] = u[3] - DotProduct( mat.GetTranslation(), uview.AsVector3D() ); vview[3] = v[3] - DotProduct( mat.GetTranslation(), vview.AsVector3D() ); float m[16]; m[0] = uview[0]; m[1] = vview[0]; m[2] = 0.0f; m[3] = 0.0f; m[4] = uview[1]; m[5] = vview[1]; m[6] = 0.0f; m[7] = 0.0f; m[8] = uview[2]; m[9] = vview[2]; m[10] = 1.0f; m[11] = 0.0f; m[12] = uview[3]; m[13] = vview[3]; m[14] = 0.0f; m[15] = 1.0f; pShaderAPI->MatrixMode( textureTransform ); pShaderAPI->LoadMatrix( m ); } void DrawFlashlight_Iris( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) { SHADOW_STATE { SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); // Alpha blend pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); pShaderShadow->EnableDepthWrites( false ); pShaderShadow->EnableAlphaWrites( false ); int flags = SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | SHADER_DRAW_NORMAL; pShaderShadow->DrawFlags( flags ); FogToBlack(); pShaderShadow->EnableLighting( true ); pShaderShadow->EnableCustomPixelPipe( true ); pShaderShadow->CustomTextureStages( 2 ); pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_VERTEXCOLOR ); pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); // alpha stage 0 // get alpha from constant alpha pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); // alpha stage 1 // get alpha from $basetexture pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_PREVIOUSSTAGE ); pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Shove the view position into texcoord 0 before the texture matrix. pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_EYE_LINEAR ); pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); // iris transform pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, true ); pShaderShadow->TexGen( SHADER_TEXTURE_STAGE1, SHADER_TEXGENPARAM_EYE_LINEAR ); } DYNAMIC_STATE { SetFlashlightFixedFunctionTextureTransform( MATERIAL_TEXTURE0 ); // NOTE: This has to come after the loadmatrix since the loadmatrix screws with the // transform flags!!!!!! // Specify that we have XYZ texcoords that need to be divided by W before the pixel shader. // NOTE Tried to divide XY by Z, but doesn't work. pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 3, true ); BindTexture( SHADER_SAMPLER0, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); BindTexture( SHADER_SAMPLER1, IRIS, IRISFRAME ); SetTextureTransform( params, pShaderAPI, MATERIAL_TEXTURE1, IRISU, IRISV ); } Draw(); } void DrawFlashlight( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) { // whites DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true ); // iris DrawFlashlight_Iris( params, pShaderAPI, pShaderShadow ); } void DrawUsingSoftwareLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) { // whites SHADOW_STATE { pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | SHADER_DRAW_TEXCOORD0 ); FogToFogColor(); } DYNAMIC_STATE { BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); } Draw(); // iris SHADOW_STATE { pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR ); pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_EYE_LINEAR ); pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); FogToFogColor(); } DYNAMIC_STATE { BindTexture( SHADER_SAMPLER0, IRIS, IRISFRAME ); SetTextureTransform( params, pShaderAPI, MATERIAL_TEXTURE0, IRISU, IRISV ); } Draw(); // Glint SHADOW_STATE { pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, 1.0f ); pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); pShaderShadow->EnableConstantColor( true ); pShaderShadow->EnableDepthWrites( false ); pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true ); pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_EYE_LINEAR ); pShaderShadow->DrawFlags( SHADER_DRAW_POSITION ); FogToBlack(); } DYNAMIC_STATE { BindTexture( SHADER_SAMPLER0, GLINT ); SetTextureTransform( params, pShaderAPI, MATERIAL_TEXTURE0, GLINTU, GLINTV ); } Draw( ); } SHADER_DRAW { SHADOW_STATE { SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); } bool hasFlashlight = UsingFlashlight( params ); if( hasFlashlight ) { DrawFlashlight( params, pShaderAPI, pShaderShadow ); } else { DrawUsingSoftwareLighting( params, pShaderAPI, pShaderShadow ); } } END_SHADER