//----------------------------------------------------------------------------- // GR - translucency query //----------------------------------------------------------------------------- BlendType_t CBaseVSShader::EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar ) { // Either we've got a constant modulation bool isTranslucent = IsAlphaModulating(); // Or we've got a vertex alpha isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); // Or we've got a texture alpha (for blending or alpha test) isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); if ( ( detailTextureVar != -1 ) && ( ! isTranslucent ) ) { isTranslucent = TextureIsTranslucent( detailTextureVar, isBaseTexture ); } if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE ) { return isTranslucent ? BT_BLENDADD : BT_ADD; // Additive } else { return isTranslucent ? BT_BLEND : BT_NONE; // Normal blending } }
BlendType_t CBaseOES2Shader::EvaluateBlendRequirements(int textureVar, bool isBaseTexture, int detailTextureVar) { IMaterialVar **params = s_ppParams; bool isTranslucent = IsAlphaModulating() || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA) || (!(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST) && TextureIsTranslucent(textureVar, isBaseTexture)) || ((detailTextureVar != -1) && TextureIsTranslucent(detailTextureVar, isBaseTexture)); if (CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE) return isTranslucent ? BT_BLENDADD : BT_ADD; return isTranslucent ? BT_BLEND : BT_NONE; }
//ConVar mat_debug_flashlight_only( "mat_debug_flashlight_only", "0" ); void CBaseShader::SetAdditiveBlendingShadowState( int textureVar, bool isBaseTexture ) { Assert( IsSnapshotting() ); // Either we've got a constant modulation bool isTranslucent = IsAlphaModulating(); // Or we've got a vertex alpha isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); // Or we've got a texture alpha isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); /* if ( mat_debug_flashlight_only.GetBool() ) { if (isTranslucent) { EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA); //s_pShaderShadow->EnableAlphaTest( true ); //s_pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.99f ); } else { EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ZERO); } } else */ { if (isTranslucent) { EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); } else { EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); } } }
void CBaseShader::SetNormalBlendingShadowState( int textureVar, bool isBaseTexture ) { Assert( IsSnapshotting() ); // Either we've got a constant modulation bool isTranslucent = IsAlphaModulating(); // Or we've got a vertex alpha isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); // Or we've got a texture alpha isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); if (isTranslucent) { EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); } else { DisableAlphaBlending(); } }
//----------------------------------------------------------------------------- // Multiply by lightmap pass //----------------------------------------------------------------------------- void CBaseShader::FixedFunctionMultiplyByLightmapPass( int baseTextureVar, int frameVar, int baseTextureTransformVar, float alphaOverride ) { if (IsSnapshotting()) { s_pShaderShadow->EnableAlphaTest( false ); s_pShaderShadow->EnableBlending( true ); SingleTextureLightmapBlendMode(); s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, true ); s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE1, true ); s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); s_pShaderShadow->EnableCustomPixelPipe( true ); s_pShaderShadow->CustomTextureStages( 2 ); // Stage zero color is not used, this op doesn't matter s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_CONSTANTCOLOR ); // This here will perform color = lightmap * (cc alpha) + 1 * (1- cc alpha) s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_PREVIOUSSTAGEALPHA, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); int flags = SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD1; // Multiply the constant alpha by the texture alpha for total alpha if (TextureIsTranslucent(baseTextureVar, true)) { s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); flags |= SHADER_DRAW_TEXCOORD0; } else { s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, false ); s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG2, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); } // Alpha isn't used, it doesn't matter what we set it to. s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); s_pShaderShadow->DrawFlags( flags ); Draw(); s_pShaderShadow->EnableCustomPixelPipe( false ); } else { // Put the alpha in the color channel to modulate the color down.... float alpha = (alphaOverride < 0) ? GetAlpha() : alphaOverride; if (g_pConfig->overbright == 2.0f) s_pShaderAPI->Color4f( 0.5f, 0.5f, 0.5f, alpha ); else s_pShaderAPI->Color4f( 1.0f, 1.0f, 1.0f, alpha ); if (TextureIsTranslucent(baseTextureVar, true)) { SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, baseTextureTransformVar ); BindTexture( SHADER_TEXTURE_STAGE0, baseTextureVar, frameVar ); } LoadIdentity( MATERIAL_TEXTURE1 ); s_pShaderAPI->BindLightmap( SHADER_TEXTURE_STAGE1 ); FogToWhite(); Draw(); } }
//----------------------------------------------------------------------------- // Fixed function multiply by detail texture pass //----------------------------------------------------------------------------- void CBaseShader::FixedFunctionMultiplyByDetailPass( int baseTextureVar, int frameVar, int textureTransformVar, int detailVar, int detailScaleVar ) { IMaterialVar** params = s_ppParams; if (!params[detailVar]->IsDefined()) return; if (IsSnapshotting()) { s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); bool translucentTexture = TextureIsTranslucent( baseTextureVar, true ) || IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, translucentTexture ); s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE1, true ); s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); // Mod 2x blend here EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR ); s_pShaderShadow->EnableCustomPixelPipe( true ); s_pShaderShadow->CustomTextureStages( 2 ); // We need to blend towards grey based on alpha... // We can never get the perfect alpha (vertex alpha * cc alpha * texture alpha) // so we'll just choose to use cc alpha * texture alpha int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1; // Compute alpha, stage 0 is used, stage 1 isn't. if ( translucentTexture ) { s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); flags |= SHADER_DRAW_TEXCOORD0; } else { bool hasVertexAlpha = (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA) != 0; if (hasVertexAlpha) { flags |= SHADER_DRAW_COLOR; } s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_ALPHA, hasVertexAlpha ? SHADER_TEXOP_MODULATE : SHADER_TEXOP_SELECTARG2, SHADER_TEXARG_VERTEXCOLOR, SHADER_TEXARG_CONSTANTCOLOR ); } s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); // This here will perform color = vertex light * alpha + 0.5f * (1 - alpha) // Stage 0 really doesn't do anything s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_PREVIOUSSTAGEALPHA, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); s_pShaderShadow->DrawFlags( flags ); Draw( ); s_pShaderShadow->EnableCustomPixelPipe( false ); DisableAlphaBlending(); } else { if (TextureIsTranslucent( baseTextureVar, true ) ) { SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, textureTransformVar ); BindTexture( SHADER_TEXTURE_STAGE0, baseTextureVar, frameVar ); } BindTexture( SHADER_TEXTURE_STAGE1, detailVar, frameVar ); SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, textureTransformVar, detailScaleVar ); float alpha = GetAlpha(); s_pShaderAPI->Color4ub( 128, 128, 128, 255 * alpha ); FogToGrey(); Draw( ); } }
//----------------------------------------------------------------------------- // Fixed function Base * detail pass //----------------------------------------------------------------------------- void CBaseShader::FixedFunctionBaseTimesDetailPass( int baseTextureVar, int frameVar, int baseTextureTransformVar, int detailVar, int detailScaleVar ) { IMaterialVar** params = s_ppParams; // We can't do this one one pass if CC and VC are both active... bool hasDetail = (detailVar != -1) && params[detailVar]->IsDefined(); bool detailInSecondPass = hasDetail && IsColorModulating() && (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) || IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA)); if (IsSnapshotting()) { IMaterialVar** params = s_ppParams; s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); // alpha test s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); // Alpha blending SetDefaultBlendingShadowState( baseTextureVar, true ); // independently configure alpha and color s_pShaderShadow->EnableAlphaPipe( true ); // Here's the color states (NOTE: SHADER_DRAW_COLOR == use Vertex Color) s_pShaderShadow->EnableConstantColor( IsColorModulating() ); s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, true ); int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0; // Detail texture.. if (hasDetail && (!detailInSecondPass)) { s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE1, true ); // Force mod2x s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 2.0f ); flags |= SHADER_DRAW_TEXCOORD1; } // Here's the alpha states s_pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); s_pShaderShadow->EnableVertexAlpha( IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA) ); s_pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, TextureIsTranslucent(baseTextureVar, true) ); if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) flags |= SHADER_DRAW_COLOR; s_pShaderShadow->DrawFlags( flags ); Draw(); s_pShaderShadow->EnableAlphaPipe( false ); } else { SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, baseTextureTransformVar ); BindTexture( SHADER_TEXTURE_STAGE0, baseTextureVar, frameVar ); // Detail texture.. if (hasDetail && (!detailInSecondPass)) { BindTexture( SHADER_TEXTURE_STAGE1, detailVar, frameVar ); SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, baseTextureTransformVar, detailScaleVar ); } SetModulationDynamicState(); DefaultFog(); Draw(); } if (detailInSecondPass) { FixedFunctionMultiplyByDetailPass( baseTextureVar, frameVar, baseTextureTransformVar, detailVar, detailScaleVar ); } }