From 7309a5f13f63fdcc7b1e090f6c176113a9d95061 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Mon, 23 Dec 2013 14:58:45 -0800 Subject: [PATCH] Added many shader source files This should include the latest version of every shader that was in the 2007 SDK. It also includes a smattering of debug shaders, both VR distortion shaders, and other assorted shaders that will hopefully be useful. None of these new files are included in the game shader DLL project. If you need to modify one of these shaders for use in your mod you will need to rename it so that you don't collide with the version of that shader that lives in stdshader_dx9.dll. --- .../materialsystem/stdshaders/BlurFilterX.cpp | 122 ++ .../stdshaders/BlurFilterX_dx80.cpp | 86 + .../materialsystem/stdshaders/BlurFilterY.cpp | 136 ++ .../stdshaders/BlurFilterY_dx80.cpp | 91 ++ .../stdshaders/BlurFilter_ps11.psh | 18 + .../stdshaders/BlurFilter_ps2x.fxc | 91 ++ .../stdshaders/BlurFilter_vs11.fxc | 34 + .../stdshaders/BlurFilter_vs20.fxc | 39 + mp/src/materialsystem/stdshaders/Cable.psh | 27 + mp/src/materialsystem/stdshaders/Cable.vsh | 117 ++ .../stdshaders/DebugDrawDepth_ps2x.fxc | 23 + .../stdshaders/DebugDrawDepth_vs20.fxc | 38 + .../stdshaders/DebugDrawEnvmapMask.cpp | 94 ++ .../stdshaders/DebugDrawEnvmapMask_ps2x.fxc | 26 + .../stdshaders/DebugDrawEnvmapMask_vs20.fxc | 39 + .../stdshaders/DebugTextureView.cpp | 104 ++ .../stdshaders/DebugTextureView_ps2x.fxc | 81 + .../stdshaders/DebugTextureView_vs20.fxc | 23 + mp/src/materialsystem/stdshaders/Eyes.psh | 16 + .../stdshaders/Eyes_Overbright2.psh | 18 + .../materialsystem/stdshaders/Eyes_vs20.fxc | 145 ++ .../stdshaders/LightmappedGeneric.psh | 15 + ...mappedGeneric_AddBaseAlphaMaskedEnvMap.psh | 17 + ...htmappedGeneric_AddEnvMapMaskNoTexture.psh | 17 + .../LightmappedGeneric_AddEnvMapNoTexture.psh | 15 + ...tmappedGeneric_BaseAlphaMaskedEnvMapV2.psh | 22 + .../LightmappedGeneric_BaseTexture.psh | 14 + .../LightmappedGeneric_BaseTexture.vsh | 38 + .../LightmappedGeneric_BaseTextureBlend.vsh | 43 + .../LightmappedGeneric_BumpmappedEnvmap.psh | 66 + .../LightmappedGeneric_BumpmappedEnvmap.vsh | 96 ++ ...ghtmappedGeneric_BumpmappedEnvmap_ps14.psh | 72 + ...ghtmappedGeneric_BumpmappedEnvmap_ps14.vsh | 92 ++ .../LightmappedGeneric_BumpmappedLightmap.psh | 79 + .../LightmappedGeneric_BumpmappedLightmap.vsh | 54 + ...edGeneric_BumpmappedLightmap_base_ps14.psh | 39 + ...edGeneric_BumpmappedLightmap_base_ps14.vsh | 55 + ...dGeneric_BumpmappedLightmap_blend_ps14.psh | 47 + ...dGeneric_BumpmappedLightmap_blend_ps14.vsh | 57 + .../stdshaders/LightmappedGeneric_Decal.psh | 47 + .../stdshaders/LightmappedGeneric_Decal.vsh | 56 + .../stdshaders/LightmappedGeneric_Detail.psh | 18 + .../LightmappedGeneric_DetailNoTexture.psh | 16 + ...ghtmappedGeneric_DetailSelfIlluminated.psh | 23 + .../LightmappedGeneric_EnvMapNoTexture.psh | 21 + .../LightmappedGeneric_EnvMapV2.psh | 20 + .../LightmappedGeneric_LightingOnly.vsh | 45 + ...mappedGeneric_LightingOnly_Overbright2.psh | 6 + ...ghtmappedGeneric_MaskedEnvMapNoTexture.psh | 24 + .../LightmappedGeneric_MaskedEnvMapV2.psh | 22 + .../LightmappedGeneric_MultiplyByLighting.psh | 20 + ...pedGeneric_MultiplyByLightingNoTexture.psh | 20 + ...pedGeneric_MultiplyByLightingSelfIllum.psh | 23 + .../LightmappedGeneric_NoTexture.psh | 14 + ...ightmappedGeneric_SSBumpmappedLightmap.psh | 34 + .../LightmappedGeneric_SelfIlluminated.psh | 21 + ...tmappedGeneric_SelfIlluminatedEnvMapV2.psh | 27 + ...dGeneric_SelfIlluminatedMaskedEnvMapV2.psh | 28 + .../LightmappedGeneric_VertexColor.vsh | 15 + .../stdshaders/Refract_model_vs11.vsh | 105 ++ .../stdshaders/Refract_ps11.psh | 36 + .../stdshaders/Refract_vs20.fxc | 140 ++ .../stdshaders/Refract_world_vs11.vsh | 168 ++ .../materialsystem/stdshaders/ShadowModel.psh | 22 + .../materialsystem/stdshaders/ShadowModel.vsh | 85 + mp/src/materialsystem/stdshaders/Teeth.vsh | 97 ++ .../stdshaders/UnlitGeneric.psh | 13 + .../UnlitGeneric_BaseAlphaMaskedEnvMap.psh | 19 + .../stdshaders/UnlitGeneric_Detail.psh | 15 + ...litGeneric_DetailBaseAlphaMaskedEnvMap.psh | 29 + .../stdshaders/UnlitGeneric_DetailEnvMap.psh | 25 + .../UnlitGeneric_DetailEnvMapMask.psh | 29 + ...UnlitGeneric_DetailEnvMapMaskNoTexture.psh | 21 + .../UnlitGeneric_DetailEnvMapNoTexture.psh | 19 + .../UnlitGeneric_DetailNoTexture.psh | 10 + .../stdshaders/UnlitGeneric_EnvMap.psh | 17 + .../stdshaders/UnlitGeneric_EnvMapMask.psh | 19 + .../UnlitGeneric_EnvMapMaskNoTexture.psh | 17 + .../UnlitGeneric_EnvMapNoTexture.psh | 15 + .../stdshaders/UnlitGeneric_LightingOnly.vsh | 21 + ...nlitGeneric_MaskBaseByDetailAlpha_ps11.fxc | 20 + .../stdshaders/UnlitGeneric_NoTexture.psh | 7 + .../stdshaders/VertexLitGeneric.psh | 13 + ...rtexLitGeneric_BaseAlphaMaskedEnvMapV2.psh | 17 + .../stdshaders/VertexLitGeneric_BlendTint.psh | 17 + .../stdshaders/VertexLitGeneric_Detail.psh | 16 + ...tGeneric_DetailBaseAlphaMaskedEnvMapV2.psh | 18 + .../VertexLitGeneric_DetailEnvMapV2.psh | 16 + .../VertexLitGeneric_DetailMaskedEnvMapV2.psh | 18 + .../VertexLitGeneric_DetailNoTexture.psh | 12 + ...VertexLitGeneric_DetailSelfIlluminated.psh | 22 + ...tGeneric_DetailSelfIlluminatedEnvMapV2.psh | 24 + ...ic_DetailSelfIlluminatedMaskedEnvMapV2.psh | 26 + .../VertexLitGeneric_Detail_LerpBase.psh | 15 + .../VertexLitGeneric_Detail_additive.psh | 15 + ...exLitGeneric_Detail_additive_selfillum.psh | 15 + .../VertexLitGeneric_EnvMapNoTexture.psh | 14 + .../stdshaders/VertexLitGeneric_EnvMapV2.psh | 14 + .../VertexLitGeneric_EnvmappedBumpmapV2.psh | 36 + ...Generic_EnvmappedBumpmapV2_MultByAlpha.psh | 42 + ...ic_EnvmappedBumpmapV2_MultByAlpha_ps14.psh | 42 + ...rtexLitGeneric_EnvmappedBumpmapV2_ps14.psh | 39 + ...LitGeneric_EnvmappedBumpmap_NoLighting.vsh | 93 ++ ...neric_EnvmappedBumpmap_NoLighting_ps14.vsh | 90 ++ ...VertexLitGeneric_MaskedEnvMapNoTexture.psh | 15 + .../VertexLitGeneric_MaskedEnvMapV2.psh | 16 + .../stdshaders/VertexLitGeneric_NoTexture.psh | 9 + .../VertexLitGeneric_SelfIllumOnly.psh | 5 + .../VertexLitGeneric_SelfIllumOnly.vsh | 41 + .../VertexLitGeneric_SelfIlluminated.psh | 19 + ...rtexLitGeneric_SelfIlluminatedEnvMapV2.psh | 21 + ...tGeneric_SelfIlluminatedMaskedEnvMapV2.psh | 23 + .../stdshaders/VertexLitTexture.psh | 15 + .../VertexLitTexture_Overbright2.psh | 16 + .../WaterCheapFresnelOpaque_ps14.psh | 40 + .../stdshaders/WaterCheapFresnel_ps14.psh | 39 + .../WaterCheapNoFresnelOpaque_ps11.psh | 19 + .../stdshaders/WaterCheapNoFresnel_ps11.psh | 18 + .../stdshaders/WaterCheapOpaque_ps11.psh | 26 + .../stdshaders/WaterCheapOpaque_ps14.psh | 31 + .../WaterCheapPerVertexFresnel_vs11.vsh | 100 ++ .../stdshaders/WaterCheap_ps11.psh | 26 + .../stdshaders/WaterCheap_ps14.psh | 30 + .../stdshaders/WaterCheap_ps2x.fxc | 152 ++ .../stdshaders/WaterCheap_vs11.vsh | 88 + .../stdshaders/WaterCheap_vs14.vsh | 96 ++ .../stdshaders/WaterCheap_vs20.fxc | 84 + .../stdshaders/WaterReflect_ps11.psh | 27 + .../stdshaders/WaterRefractFresnel_ps11.psh | 24 + .../stdshaders/WaterRefract_ps11.psh | 13 + .../materialsystem/stdshaders/Water_ps14.psh | 96 ++ .../materialsystem/stdshaders/Water_ps14.vsh | 95 ++ .../materialsystem/stdshaders/Water_vs11.vsh | 102 ++ .../materialsystem/stdshaders/Water_vs20.fxc | 117 ++ .../stdshaders/WorldTexture.psh | 14 + .../stdshaders/WorldTwoTextureBlend.psh | 21 + .../WorldTwoTextureBlend_DetailAlpha.psh | 25 + .../WorldTwoTextureBlend_SelfIlluminated.psh | 27 + .../stdshaders/WorldVertexAlpha.psh | 10 + .../stdshaders/WorldVertexAlpha.vsh | 37 + .../stdshaders/WorldVertexAlpha_ps2x.fxc | 43 + .../stdshaders/WorldVertexTransition.psh | 18 + .../stdshaders/WorldVertexTransition.vsh | 48 + .../WorldVertexTransition_BlendBase2.psh | 16 + .../WorldVertexTransition_Editor.psh | 10 + .../WorldVertexTransition_Seamless.psh | 23 + .../WorldVertexTransition_Seamless.vsh | 54 + .../stdshaders/WorldVertexTransition_dx8.cpp | 537 ++++++ .../stdshaders/WorldVertexTransition_ps14.psh | 32 + .../stdshaders/WorldVertexTransition_ps2x.fxc | 47 + .../stdshaders/WorldVertexTransition_vs14.vsh | 52 + .../stdshaders/WorldVertexTransition_vs20.fxc | 64 + .../materialsystem/stdshaders/cable_dx6.cpp | 62 + .../materialsystem/stdshaders/cable_dx8.cpp | 132 ++ .../materialsystem/stdshaders/cable_dx9.cpp | 141 ++ .../materialsystem/stdshaders/cable_ps2x.fxc | 54 + .../materialsystem/stdshaders/cable_vs20.fxc | 80 + mp/src/materialsystem/stdshaders/cloud.cpp | 76 + .../materialsystem/stdshaders/cloud_dx8.cpp | 77 + .../materialsystem/stdshaders/cloud_dx9.cpp | 94 ++ .../materialsystem/stdshaders/cloud_ps11.psh | 6 + .../materialsystem/stdshaders/cloud_ps20.fxc | 26 + .../materialsystem/stdshaders/cloud_vs11.vsh | 26 + .../materialsystem/stdshaders/cloud_vs20.fxc | 37 + .../materialsystem/stdshaders/debugdepth.cpp | 113 ++ .../materialsystem/stdshaders/debugluxel.cpp | 140 ++ .../stdshaders/debugmodifyvertex.cpp | 93 ++ .../stdshaders/debugmorphaccumulator_dx9.cpp | 64 + .../stdshaders/debugmorphaccumulator_ps30.fxc | 16 + .../stdshaders/debugmorphaccumulator_vs30.fxc | 23 + .../stdshaders/debugmrttexture.cpp | 86 + .../stdshaders/debugmrttexture_ps2x.fxc | 26 + .../stdshaders/debugmrttexture_vs20.fxc | 29 + .../stdshaders/debugnormalmap.cpp | 148 ++ .../stdshaders/debugsoftwarevertexshader.cpp | 56 + .../stdshaders/debugtangentspace.cpp | 133 ++ .../stdshaders/debugtangentspace.vsh | 34 + .../stdshaders/debugtangentspace_vs11.fxc | 51 + .../stdshaders/debugtangentspace_vs20.fxc | 55 + .../stdshaders/depthtodestalpha_ps20b.fxc | 11 + .../stdshaders/depthtodestalpha_vs20.fxc | 23 + .../materialsystem/stdshaders/depthwrite.cpp | 207 +++ .../stdshaders/depthwrite_ps2x.fxc | 44 + .../stdshaders/depthwrite_vs20.fxc | 83 + mp/src/materialsystem/stdshaders/detail.cpp | 37 + .../materialsystem/stdshaders/detail_ps11.psh | 12 + .../materialsystem/stdshaders/detail_vs11.vsh | 56 + .../materialsystem/stdshaders/eye_refract.cpp | 253 +++ .../stdshaders/eye_refract_helper.cpp | 461 ++++++ .../stdshaders/eye_refract_helper.h | 69 + .../stdshaders/eye_refract_ps2x.fxc | 494 ++++++ .../stdshaders/eye_refract_vs20.fxc | 217 +++ mp/src/materialsystem/stdshaders/eyeball.cpp | 37 + .../stdshaders/eyeglint_dx9.cpp | 66 + .../stdshaders/eyeglint_ps2x.fxc | 32 + .../stdshaders/eyeglint_vs20.fxc | 38 + mp/src/materialsystem/stdshaders/eyes.cpp | 186 +++ mp/src/materialsystem/stdshaders/eyes.vsh | 80 + mp/src/materialsystem/stdshaders/eyes_dx6.cpp | 251 +++ .../stdshaders/eyes_dx8_dx9_helper.cpp | 550 +++++++ .../stdshaders/eyes_dx8_dx9_helper.h | 54 + mp/src/materialsystem/stdshaders/eyes_dx9.cpp | 84 + .../stdshaders/eyes_flashlight2_ps11.psh | 17 + .../stdshaders/eyes_flashlight_inc.fxc | 92 ++ .../stdshaders/eyes_flashlight_ps11.fxc | 9 + .../stdshaders/eyes_flashlight_ps2x.fxc | 15 + .../stdshaders/eyes_flashlight_vs11.vsh | 115 ++ .../stdshaders/eyes_flashlight_vs20.fxc | 145 ++ .../materialsystem/stdshaders/eyes_ps2x.fxc | 68 + ...flesh_interior_blended_pass_dx8_helper.cpp | 271 ++++ .../flesh_interior_blended_pass_dx8_ps11.psh | 15 + .../flesh_interior_blended_pass_dx8_vs11.vsh | 114 ++ .../flesh_interior_blended_pass_helper.cpp | 355 ++++ .../flesh_interior_blended_pass_helper.h | 68 + .../flesh_interior_blended_pass_ps2x.fxc | 127 ++ .../flesh_interior_blended_pass_vs20.fxc | 155 ++ ...ghtmappedgeneric_basealphamaskedenvmap.psh | 22 + .../lightmappedgeneric_basetextureblend.psh | 9 + .../stdshaders/lightmappedgeneric_decal.cpp | 135 ++ .../lightmappedgeneric_decal_ps2x.fxc | 59 + .../lightmappedgeneric_decal_vs20.fxc | 74 + .../stdshaders/lightmappedgeneric_dx6.cpp | 288 ++++ .../stdshaders/lightmappedgeneric_dx8.cpp | 802 +++++++++ .../stdshaders/lightmappedgeneric_dx9.cpp | 164 ++ .../lightmappedgeneric_dx9_helper.cpp | 1085 +++++++++++++ .../lightmappedgeneric_dx9_helper.h | 99 ++ .../stdshaders/lightmappedgeneric_envmap.psh | 20 + .../lightmappedgeneric_flashlight_vs11.fxc | 122 ++ .../lightmappedgeneric_flashlight_vs20.fxc | 184 +++ .../stdshaders/lightmappedgeneric_inc.vsh | 110 ++ ...dgeneric_lightingonly_overbright2_ps11.fxc | 12 + .../lightmappedgeneric_lightingonly_vs11.fxc | 51 + .../lightmappedgeneric_maskedenvmap.psh | 22 + ...iplybylightingbasealphamaskedselfillum.psh | 24 + ...eneric_multiplybylightingbasenotexture.psh | 20 + .../stdshaders/lightmappedgeneric_ps11.fxc | 122 ++ .../stdshaders/lightmappedgeneric_ps2_3_x.h | 583 +++++++ .../stdshaders/lightmappedgeneric_ps2x.fxc | 59 + ...ghtmappedgeneric_selfilluminatedenvmap.psh | 27 + ...pedgeneric_selfilluminatedmaskedenvmap.psh | 27 + .../stdshaders/lightmappedgeneric_vs11.vsh | 20 + .../stdshaders/lightmappedgeneric_vs20.fxc | 254 +++ mp/src/materialsystem/stdshaders/refract.cpp | 111 ++ .../stdshaders/refract_dx60.cpp | 16 + .../stdshaders/refract_dx80.cpp | 317 ++++ .../stdshaders/refract_dx9_helper.cpp | 342 ++++ .../stdshaders/refract_dx9_helper.h | 62 + .../stdshaders/refract_ps2x.fxc | 250 +++ .../stdshaders/shadowmodel_dx8.cpp | 97 ++ .../stdshaders/shadowmodel_dx9.cpp | 154 ++ .../stdshaders/shadowmodel_ps20.fxc | 20 + .../stdshaders/shadowmodel_vs20.fxc | 81 + .../stdshaders/skin_dx9_helper.cpp | 977 +++++++++++ .../stdshaders/skin_dx9_helper.h | 35 + .../materialsystem/stdshaders/skin_ps20b.fxc | 371 +++++ .../materialsystem/stdshaders/skin_vs20.fxc | 173 ++ mp/src/materialsystem/stdshaders/sky_dx6.cpp | 15 + mp/src/materialsystem/stdshaders/sky_dx9.cpp | 126 ++ .../stdshaders/sky_hdr_compressed_ps2x.fxc | 29 + .../sky_hdr_compressed_rgbs_ps2x.fxc | 81 + .../materialsystem/stdshaders/sky_hdr_dx9.cpp | 297 ++++ mp/src/materialsystem/stdshaders/sky_ps2x.fxc | 27 + mp/src/materialsystem/stdshaders/sky_vs20.fxc | 64 + mp/src/materialsystem/stdshaders/sprite.cpp | 379 +++++ .../materialsystem/stdshaders/sprite_dx6.cpp | 289 ++++ .../materialsystem/stdshaders/sprite_dx9.cpp | 490 ++++++ .../materialsystem/stdshaders/sprite_ps11.psh | 15 + .../materialsystem/stdshaders/sprite_ps2x.fxc | 61 + .../materialsystem/stdshaders/sprite_vs11.vsh | 9 + .../materialsystem/stdshaders/sprite_vs20.fxc | 65 + .../materialsystem/stdshaders/spritecard.cpp | 484 ++++++ .../stdshaders/spritecard_ps11.fxc | 72 + .../stdshaders/spritecard_ps2x.fxc | 194 +++ .../stdshaders/spritecard_vsxx.fxc | 347 ++++ mp/src/materialsystem/stdshaders/teeth.cpp | 578 +++++++ .../stdshaders/teeth_bump_ps2x.fxc | 101 ++ .../stdshaders/teeth_bump_vs20.fxc | 152 ++ .../materialsystem/stdshaders/teeth_dx6.cpp | 69 + .../materialsystem/stdshaders/teeth_dx8.cpp | 116 ++ .../stdshaders/teeth_flashlight_ps2x.fxc | 66 + .../stdshaders/teeth_flashlight_vs20.fxc | 149 ++ .../materialsystem/stdshaders/teeth_ps2x.fxc | 48 + .../materialsystem/stdshaders/teeth_vs20.fxc | 127 ++ .../unlitgeneric_basetimesdetail.psh | 24 + .../stdshaders/unlitgeneric_dx6.cpp | 310 ++++ .../stdshaders/unlitgeneric_dx8.cpp | 72 + .../stdshaders/unlitgeneric_dx9.cpp | 200 +++ .../stdshaders/unlitgeneric_inc.vsh | 142 ++ .../unlitgeneric_lightingonly_vs11.fxc | 47 + .../unlitgeneric_notexture_ps11.fxc | 9 + .../unlitgeneric_notexture_ps2x.fxc | 14 + .../stdshaders/unlitgeneric_ps11.fxc | 12 + .../stdshaders/unlitgeneric_ps2x.fxc | 19 + .../stdshaders/unlitgeneric_vs11.vsh | 23 + .../stdshaders/unlitgeneric_vs20.fxc | 91 ++ .../vertexlit_and_unlit_generic_bump_ps2x.fxc | 350 ++++ .../vertexlit_and_unlit_generic_bump_vs20.fxc | 198 +++ .../vertexlit_and_unlit_generic_ps2x.fxc | 484 ++++++ .../vertexlit_and_unlit_generic_vs20.fxc | 249 +++ .../vertexlit_lighting_only_ps2x.fxc | 68 + .../stdshaders/vertexlit_notexture.psh | 13 + ...vertexlitgeneric_basealphamaskedenvmap.psh | 19 + ...litgeneric_detailbasealphamaskedenvmap.psh | 21 + .../vertexlitgeneric_detailenvmap.psh | 19 + .../vertexlitgeneric_detailmaskedenvmap.psh | 21 + ...litgeneric_detailselfilluminatedenvmap.psh | 28 + ...eric_detailselfilluminatedmaskedenvmap.psh | 29 + .../stdshaders/vertexlitgeneric_dx6.cpp | 421 +++++ .../stdshaders/vertexlitgeneric_dx7.cpp | 413 +++++ .../stdshaders/vertexlitgeneric_dx8.cpp | 807 ++++++++++ .../stdshaders/vertexlitgeneric_dx9.cpp | 520 ++++++ .../stdshaders/vertexlitgeneric_dx95_helper.h | 71 + .../vertexlitgeneric_dx9_helper.cpp | 1434 +++++++++++++++++ .../stdshaders/vertexlitgeneric_dx9_helper.h | 144 ++ .../stdshaders/vertexlitgeneric_envmap.psh | 17 + .../vertexlitgeneric_flashlight_vs11.vsh | 137 ++ .../stdshaders/vertexlitgeneric_inc.vsh | 145 ++ ...texlitgeneric_lightingonly_overbright2.psh | 5 + ...tgeneric_lightingonly_overbright2_ps11.fxc | 9 + .../vertexlitgeneric_maskedenvmap.psh | 19 + ...vertexlitgeneric_selfilluminatedenvmap.psh | 25 + ...litgeneric_selfilluminatedmaskedenvmap.psh | 26 + .../stdshaders/vertexlitgeneric_vs11.vsh | 22 + .../stdshaders/volume_clouds.cpp | 59 + .../stdshaders/volume_clouds_helper.cpp | 138 ++ .../stdshaders/volume_clouds_helper.h | 41 + .../stdshaders/volume_clouds_ps2x.fxc | 66 + .../stdshaders/volume_clouds_vs20.fxc | 103 ++ .../stdshaders/vr_distort_hud.cpp | 224 +++ .../stdshaders/vr_distort_hud_ps2x.fxc | 78 + .../stdshaders/vr_distort_hud_vs20.fxc | 26 + .../stdshaders/vr_distort_texture.cpp | 213 +++ .../stdshaders/vr_distort_texture_ps2x.fxc | 49 + .../stdshaders/vr_distort_texture_vs20.fxc | 26 + mp/src/materialsystem/stdshaders/water.cpp | 614 +++++++ .../materialsystem/stdshaders/water_dudv.cpp | 95 ++ .../materialsystem/stdshaders/water_dx60.cpp | 15 + .../materialsystem/stdshaders/water_dx80.cpp | 419 +++++ .../materialsystem/stdshaders/water_dx81.cpp | 311 ++++ .../materialsystem/stdshaders/water_ps2x.fxc | 110 ++ .../stdshaders/water_ps2x_helper.h | 239 +++ .../stdshaders/waterreflect_ps14.psh | 8 + .../stdshaders/waterrefract_ps14.psh | 23 + .../stdshaders/worldtwotextureblend.cpp | 500 ++++++ .../stdshaders/worldtwotextureblend_dx6.cpp | 258 +++ .../stdshaders/worldtwotextureblend_dx8.cpp | 175 ++ .../stdshaders/worldtwotextureblend_ps2x.fxc | 217 +++ .../stdshaders/worldvertexalpha.cpp | 259 +++ .../stdshaders/worldvertexalpha_dx8.cpp | 113 ++ .../stdshaders/worldvertextransition.cpp | 157 ++ .../stdshaders/worldvertextransition_dx6.cpp | 52 + .../worldvertextransition_dx6_helper.cpp | 206 +++ .../worldvertextransition_dx6_helper.h | 39 + .../worldvertextransition_dx8_helper.cpp | 81 + .../worldvertextransition_dx8_helper.h | 44 + .../materialsystem/stdshaders/BlurFilterX.cpp | 122 ++ .../stdshaders/BlurFilterX_dx80.cpp | 86 + .../materialsystem/stdshaders/BlurFilterY.cpp | 136 ++ .../stdshaders/BlurFilterY_dx80.cpp | 91 ++ .../stdshaders/BlurFilter_ps11.psh | 18 + .../stdshaders/BlurFilter_ps2x.fxc | 91 ++ .../stdshaders/BlurFilter_vs11.fxc | 34 + .../stdshaders/BlurFilter_vs20.fxc | 39 + sp/src/materialsystem/stdshaders/Cable.psh | 27 + sp/src/materialsystem/stdshaders/Cable.vsh | 117 ++ .../stdshaders/DebugDrawDepth_ps2x.fxc | 23 + .../stdshaders/DebugDrawDepth_vs20.fxc | 38 + .../stdshaders/DebugDrawEnvmapMask.cpp | 94 ++ .../stdshaders/DebugDrawEnvmapMask_ps2x.fxc | 26 + .../stdshaders/DebugDrawEnvmapMask_vs20.fxc | 39 + .../stdshaders/DebugTextureView.cpp | 104 ++ .../stdshaders/DebugTextureView_ps2x.fxc | 81 + .../stdshaders/DebugTextureView_vs20.fxc | 23 + sp/src/materialsystem/stdshaders/Eyes.psh | 16 + .../stdshaders/Eyes_Overbright2.psh | 18 + .../materialsystem/stdshaders/Eyes_vs20.fxc | 145 ++ .../stdshaders/LightmappedGeneric.psh | 15 + ...mappedGeneric_AddBaseAlphaMaskedEnvMap.psh | 17 + ...htmappedGeneric_AddEnvMapMaskNoTexture.psh | 17 + .../LightmappedGeneric_AddEnvMapNoTexture.psh | 15 + ...tmappedGeneric_BaseAlphaMaskedEnvMapV2.psh | 22 + .../LightmappedGeneric_BaseTexture.psh | 14 + .../LightmappedGeneric_BaseTexture.vsh | 38 + .../LightmappedGeneric_BaseTextureBlend.vsh | 43 + .../LightmappedGeneric_BumpmappedEnvmap.psh | 66 + .../LightmappedGeneric_BumpmappedEnvmap.vsh | 96 ++ ...ghtmappedGeneric_BumpmappedEnvmap_ps14.psh | 72 + ...ghtmappedGeneric_BumpmappedEnvmap_ps14.vsh | 92 ++ .../LightmappedGeneric_BumpmappedLightmap.psh | 79 + .../LightmappedGeneric_BumpmappedLightmap.vsh | 54 + ...edGeneric_BumpmappedLightmap_base_ps14.psh | 39 + ...edGeneric_BumpmappedLightmap_base_ps14.vsh | 55 + ...dGeneric_BumpmappedLightmap_blend_ps14.psh | 47 + ...dGeneric_BumpmappedLightmap_blend_ps14.vsh | 57 + .../stdshaders/LightmappedGeneric_Decal.psh | 47 + .../stdshaders/LightmappedGeneric_Decal.vsh | 56 + .../stdshaders/LightmappedGeneric_Detail.psh | 18 + .../LightmappedGeneric_DetailNoTexture.psh | 16 + ...ghtmappedGeneric_DetailSelfIlluminated.psh | 23 + .../LightmappedGeneric_EnvMapNoTexture.psh | 21 + .../LightmappedGeneric_EnvMapV2.psh | 20 + .../LightmappedGeneric_LightingOnly.vsh | 45 + ...mappedGeneric_LightingOnly_Overbright2.psh | 6 + ...ghtmappedGeneric_MaskedEnvMapNoTexture.psh | 24 + .../LightmappedGeneric_MaskedEnvMapV2.psh | 22 + .../LightmappedGeneric_MultiplyByLighting.psh | 20 + ...pedGeneric_MultiplyByLightingNoTexture.psh | 20 + ...pedGeneric_MultiplyByLightingSelfIllum.psh | 23 + .../LightmappedGeneric_NoTexture.psh | 14 + ...ightmappedGeneric_SSBumpmappedLightmap.psh | 34 + .../LightmappedGeneric_SelfIlluminated.psh | 21 + ...tmappedGeneric_SelfIlluminatedEnvMapV2.psh | 27 + ...dGeneric_SelfIlluminatedMaskedEnvMapV2.psh | 28 + .../LightmappedGeneric_VertexColor.vsh | 15 + .../stdshaders/Refract_model_vs11.vsh | 105 ++ .../stdshaders/Refract_ps11.psh | 36 + .../stdshaders/Refract_vs20.fxc | 140 ++ .../stdshaders/Refract_world_vs11.vsh | 168 ++ .../materialsystem/stdshaders/ShadowModel.psh | 22 + .../materialsystem/stdshaders/ShadowModel.vsh | 85 + sp/src/materialsystem/stdshaders/Teeth.vsh | 97 ++ .../stdshaders/UnlitGeneric.psh | 13 + .../UnlitGeneric_BaseAlphaMaskedEnvMap.psh | 19 + .../stdshaders/UnlitGeneric_Detail.psh | 15 + ...litGeneric_DetailBaseAlphaMaskedEnvMap.psh | 29 + .../stdshaders/UnlitGeneric_DetailEnvMap.psh | 25 + .../UnlitGeneric_DetailEnvMapMask.psh | 29 + ...UnlitGeneric_DetailEnvMapMaskNoTexture.psh | 21 + .../UnlitGeneric_DetailEnvMapNoTexture.psh | 19 + .../UnlitGeneric_DetailNoTexture.psh | 10 + .../stdshaders/UnlitGeneric_EnvMap.psh | 17 + .../stdshaders/UnlitGeneric_EnvMapMask.psh | 19 + .../UnlitGeneric_EnvMapMaskNoTexture.psh | 17 + .../UnlitGeneric_EnvMapNoTexture.psh | 15 + .../stdshaders/UnlitGeneric_LightingOnly.vsh | 21 + ...nlitGeneric_MaskBaseByDetailAlpha_ps11.fxc | 20 + .../stdshaders/UnlitGeneric_NoTexture.psh | 7 + .../stdshaders/VertexLitGeneric.psh | 13 + ...rtexLitGeneric_BaseAlphaMaskedEnvMapV2.psh | 17 + .../stdshaders/VertexLitGeneric_BlendTint.psh | 17 + .../stdshaders/VertexLitGeneric_Detail.psh | 16 + ...tGeneric_DetailBaseAlphaMaskedEnvMapV2.psh | 18 + .../VertexLitGeneric_DetailEnvMapV2.psh | 16 + .../VertexLitGeneric_DetailMaskedEnvMapV2.psh | 18 + .../VertexLitGeneric_DetailNoTexture.psh | 12 + ...VertexLitGeneric_DetailSelfIlluminated.psh | 22 + ...tGeneric_DetailSelfIlluminatedEnvMapV2.psh | 24 + ...ic_DetailSelfIlluminatedMaskedEnvMapV2.psh | 26 + .../VertexLitGeneric_Detail_LerpBase.psh | 15 + .../VertexLitGeneric_Detail_additive.psh | 15 + ...exLitGeneric_Detail_additive_selfillum.psh | 15 + .../VertexLitGeneric_EnvMapNoTexture.psh | 14 + .../stdshaders/VertexLitGeneric_EnvMapV2.psh | 14 + .../VertexLitGeneric_EnvmappedBumpmapV2.psh | 36 + ...Generic_EnvmappedBumpmapV2_MultByAlpha.psh | 42 + ...ic_EnvmappedBumpmapV2_MultByAlpha_ps14.psh | 42 + ...rtexLitGeneric_EnvmappedBumpmapV2_ps14.psh | 39 + ...LitGeneric_EnvmappedBumpmap_NoLighting.vsh | 93 ++ ...neric_EnvmappedBumpmap_NoLighting_ps14.vsh | 90 ++ ...VertexLitGeneric_MaskedEnvMapNoTexture.psh | 15 + .../VertexLitGeneric_MaskedEnvMapV2.psh | 16 + .../stdshaders/VertexLitGeneric_NoTexture.psh | 9 + .../VertexLitGeneric_SelfIllumOnly.psh | 5 + .../VertexLitGeneric_SelfIllumOnly.vsh | 41 + .../VertexLitGeneric_SelfIlluminated.psh | 19 + ...rtexLitGeneric_SelfIlluminatedEnvMapV2.psh | 21 + ...tGeneric_SelfIlluminatedMaskedEnvMapV2.psh | 23 + .../stdshaders/VertexLitTexture.psh | 15 + .../VertexLitTexture_Overbright2.psh | 16 + .../WaterCheapFresnelOpaque_ps14.psh | 40 + .../stdshaders/WaterCheapFresnel_ps14.psh | 39 + .../WaterCheapNoFresnelOpaque_ps11.psh | 19 + .../stdshaders/WaterCheapNoFresnel_ps11.psh | 18 + .../stdshaders/WaterCheapOpaque_ps11.psh | 26 + .../stdshaders/WaterCheapOpaque_ps14.psh | 31 + .../WaterCheapPerVertexFresnel_vs11.vsh | 100 ++ .../stdshaders/WaterCheap_ps11.psh | 26 + .../stdshaders/WaterCheap_ps14.psh | 30 + .../stdshaders/WaterCheap_ps2x.fxc | 152 ++ .../stdshaders/WaterCheap_vs11.vsh | 88 + .../stdshaders/WaterCheap_vs14.vsh | 96 ++ .../stdshaders/WaterCheap_vs20.fxc | 84 + .../stdshaders/WaterReflect_ps11.psh | 27 + .../stdshaders/WaterRefractFresnel_ps11.psh | 24 + .../stdshaders/WaterRefract_ps11.psh | 13 + .../materialsystem/stdshaders/Water_ps14.psh | 96 ++ .../materialsystem/stdshaders/Water_ps14.vsh | 95 ++ .../materialsystem/stdshaders/Water_vs11.vsh | 102 ++ .../materialsystem/stdshaders/Water_vs20.fxc | 117 ++ .../stdshaders/WorldTexture.psh | 14 + .../stdshaders/WorldTwoTextureBlend.psh | 21 + .../WorldTwoTextureBlend_DetailAlpha.psh | 25 + .../WorldTwoTextureBlend_SelfIlluminated.psh | 27 + .../stdshaders/WorldVertexAlpha.psh | 10 + .../stdshaders/WorldVertexAlpha.vsh | 37 + .../stdshaders/WorldVertexAlpha_ps2x.fxc | 43 + .../stdshaders/WorldVertexTransition.psh | 18 + .../stdshaders/WorldVertexTransition.vsh | 48 + .../WorldVertexTransition_BlendBase2.psh | 16 + .../WorldVertexTransition_Editor.psh | 10 + .../WorldVertexTransition_Seamless.psh | 23 + .../WorldVertexTransition_Seamless.vsh | 54 + .../stdshaders/WorldVertexTransition_dx8.cpp | 537 ++++++ .../stdshaders/WorldVertexTransition_ps14.psh | 32 + .../stdshaders/WorldVertexTransition_ps2x.fxc | 47 + .../stdshaders/WorldVertexTransition_vs14.vsh | 52 + .../stdshaders/WorldVertexTransition_vs20.fxc | 64 + .../materialsystem/stdshaders/cable_dx6.cpp | 62 + .../materialsystem/stdshaders/cable_dx8.cpp | 132 ++ .../materialsystem/stdshaders/cable_dx9.cpp | 141 ++ .../materialsystem/stdshaders/cable_ps2x.fxc | 54 + .../materialsystem/stdshaders/cable_vs20.fxc | 80 + sp/src/materialsystem/stdshaders/cloud.cpp | 76 + .../materialsystem/stdshaders/cloud_dx8.cpp | 77 + .../materialsystem/stdshaders/cloud_dx9.cpp | 94 ++ .../materialsystem/stdshaders/cloud_ps11.psh | 6 + .../materialsystem/stdshaders/cloud_ps20.fxc | 26 + .../materialsystem/stdshaders/cloud_vs11.vsh | 26 + .../materialsystem/stdshaders/cloud_vs20.fxc | 37 + .../materialsystem/stdshaders/debugdepth.cpp | 113 ++ .../materialsystem/stdshaders/debugluxel.cpp | 140 ++ .../stdshaders/debugmodifyvertex.cpp | 93 ++ .../stdshaders/debugmorphaccumulator_dx9.cpp | 64 + .../stdshaders/debugmorphaccumulator_ps30.fxc | 16 + .../stdshaders/debugmorphaccumulator_vs30.fxc | 23 + .../stdshaders/debugmrttexture.cpp | 86 + .../stdshaders/debugmrttexture_ps2x.fxc | 26 + .../stdshaders/debugmrttexture_vs20.fxc | 29 + .../stdshaders/debugnormalmap.cpp | 148 ++ .../stdshaders/debugsoftwarevertexshader.cpp | 56 + .../stdshaders/debugtangentspace.cpp | 133 ++ .../stdshaders/debugtangentspace.vsh | 34 + .../stdshaders/debugtangentspace_vs11.fxc | 51 + .../stdshaders/debugtangentspace_vs20.fxc | 55 + .../stdshaders/depthtodestalpha_ps20b.fxc | 11 + .../stdshaders/depthtodestalpha_vs20.fxc | 23 + .../materialsystem/stdshaders/depthwrite.cpp | 207 +++ .../stdshaders/depthwrite_ps2x.fxc | 44 + .../stdshaders/depthwrite_vs20.fxc | 83 + sp/src/materialsystem/stdshaders/detail.cpp | 37 + .../materialsystem/stdshaders/detail_ps11.psh | 12 + .../materialsystem/stdshaders/detail_vs11.vsh | 56 + .../materialsystem/stdshaders/eye_refract.cpp | 253 +++ .../stdshaders/eye_refract_helper.cpp | 461 ++++++ .../stdshaders/eye_refract_helper.h | 69 + .../stdshaders/eye_refract_ps2x.fxc | 494 ++++++ .../stdshaders/eye_refract_vs20.fxc | 217 +++ sp/src/materialsystem/stdshaders/eyeball.cpp | 37 + .../stdshaders/eyeglint_dx9.cpp | 66 + .../stdshaders/eyeglint_ps2x.fxc | 32 + .../stdshaders/eyeglint_vs20.fxc | 38 + sp/src/materialsystem/stdshaders/eyes.cpp | 186 +++ sp/src/materialsystem/stdshaders/eyes.vsh | 80 + sp/src/materialsystem/stdshaders/eyes_dx6.cpp | 251 +++ .../stdshaders/eyes_dx8_dx9_helper.cpp | 550 +++++++ .../stdshaders/eyes_dx8_dx9_helper.h | 54 + sp/src/materialsystem/stdshaders/eyes_dx9.cpp | 84 + .../stdshaders/eyes_flashlight2_ps11.psh | 17 + .../stdshaders/eyes_flashlight_inc.fxc | 92 ++ .../stdshaders/eyes_flashlight_ps11.fxc | 9 + .../stdshaders/eyes_flashlight_ps2x.fxc | 15 + .../stdshaders/eyes_flashlight_vs11.vsh | 115 ++ .../stdshaders/eyes_flashlight_vs20.fxc | 145 ++ .../materialsystem/stdshaders/eyes_ps2x.fxc | 68 + ...flesh_interior_blended_pass_dx8_helper.cpp | 271 ++++ .../flesh_interior_blended_pass_dx8_ps11.psh | 15 + .../flesh_interior_blended_pass_dx8_vs11.vsh | 114 ++ .../flesh_interior_blended_pass_helper.cpp | 355 ++++ .../flesh_interior_blended_pass_helper.h | 68 + .../flesh_interior_blended_pass_ps2x.fxc | 127 ++ .../flesh_interior_blended_pass_vs20.fxc | 155 ++ ...ghtmappedgeneric_basealphamaskedenvmap.psh | 22 + .../lightmappedgeneric_basetextureblend.psh | 9 + .../stdshaders/lightmappedgeneric_decal.cpp | 135 ++ .../lightmappedgeneric_decal_ps2x.fxc | 59 + .../lightmappedgeneric_decal_vs20.fxc | 74 + .../stdshaders/lightmappedgeneric_dx6.cpp | 288 ++++ .../stdshaders/lightmappedgeneric_dx8.cpp | 802 +++++++++ .../stdshaders/lightmappedgeneric_dx9.cpp | 164 ++ .../lightmappedgeneric_dx9_helper.cpp | 1085 +++++++++++++ .../lightmappedgeneric_dx9_helper.h | 99 ++ .../stdshaders/lightmappedgeneric_envmap.psh | 20 + .../lightmappedgeneric_flashlight_vs11.fxc | 122 ++ .../lightmappedgeneric_flashlight_vs20.fxc | 184 +++ .../stdshaders/lightmappedgeneric_inc.vsh | 110 ++ ...dgeneric_lightingonly_overbright2_ps11.fxc | 12 + .../lightmappedgeneric_lightingonly_vs11.fxc | 51 + .../lightmappedgeneric_maskedenvmap.psh | 22 + ...iplybylightingbasealphamaskedselfillum.psh | 24 + ...eneric_multiplybylightingbasenotexture.psh | 20 + .../stdshaders/lightmappedgeneric_ps11.fxc | 122 ++ .../stdshaders/lightmappedgeneric_ps2_3_x.h | 583 +++++++ .../stdshaders/lightmappedgeneric_ps2x.fxc | 59 + ...ghtmappedgeneric_selfilluminatedenvmap.psh | 27 + ...pedgeneric_selfilluminatedmaskedenvmap.psh | 27 + .../stdshaders/lightmappedgeneric_vs11.vsh | 20 + .../stdshaders/lightmappedgeneric_vs20.fxc | 254 +++ sp/src/materialsystem/stdshaders/refract.cpp | 111 ++ .../stdshaders/refract_dx60.cpp | 16 + .../stdshaders/refract_dx80.cpp | 317 ++++ .../stdshaders/refract_dx9_helper.cpp | 342 ++++ .../stdshaders/refract_dx9_helper.h | 62 + .../stdshaders/refract_ps2x.fxc | 250 +++ .../stdshaders/shadowmodel_dx8.cpp | 97 ++ .../stdshaders/shadowmodel_dx9.cpp | 154 ++ .../stdshaders/shadowmodel_ps20.fxc | 20 + .../stdshaders/shadowmodel_vs20.fxc | 81 + .../stdshaders/skin_dx9_helper.cpp | 977 +++++++++++ .../stdshaders/skin_dx9_helper.h | 35 + .../materialsystem/stdshaders/skin_ps20b.fxc | 371 +++++ .../materialsystem/stdshaders/skin_vs20.fxc | 173 ++ sp/src/materialsystem/stdshaders/sky_dx6.cpp | 15 + sp/src/materialsystem/stdshaders/sky_dx9.cpp | 126 ++ .../stdshaders/sky_hdr_compressed_ps2x.fxc | 29 + .../sky_hdr_compressed_rgbs_ps2x.fxc | 81 + .../materialsystem/stdshaders/sky_hdr_dx9.cpp | 297 ++++ sp/src/materialsystem/stdshaders/sky_ps2x.fxc | 27 + sp/src/materialsystem/stdshaders/sky_vs20.fxc | 64 + sp/src/materialsystem/stdshaders/sprite.cpp | 379 +++++ .../materialsystem/stdshaders/sprite_dx6.cpp | 289 ++++ .../materialsystem/stdshaders/sprite_dx9.cpp | 490 ++++++ .../materialsystem/stdshaders/sprite_ps11.psh | 15 + .../materialsystem/stdshaders/sprite_ps2x.fxc | 61 + .../materialsystem/stdshaders/sprite_vs11.vsh | 9 + .../materialsystem/stdshaders/sprite_vs20.fxc | 65 + .../materialsystem/stdshaders/spritecard.cpp | 484 ++++++ .../stdshaders/spritecard_ps11.fxc | 72 + .../stdshaders/spritecard_ps2x.fxc | 194 +++ .../stdshaders/spritecard_vsxx.fxc | 347 ++++ sp/src/materialsystem/stdshaders/teeth.cpp | 578 +++++++ .../stdshaders/teeth_bump_ps2x.fxc | 101 ++ .../stdshaders/teeth_bump_vs20.fxc | 152 ++ .../materialsystem/stdshaders/teeth_dx6.cpp | 69 + .../materialsystem/stdshaders/teeth_dx8.cpp | 116 ++ .../stdshaders/teeth_flashlight_ps2x.fxc | 66 + .../stdshaders/teeth_flashlight_vs20.fxc | 149 ++ .../materialsystem/stdshaders/teeth_ps2x.fxc | 48 + .../materialsystem/stdshaders/teeth_vs20.fxc | 127 ++ .../unlitgeneric_basetimesdetail.psh | 24 + .../stdshaders/unlitgeneric_dx6.cpp | 310 ++++ .../stdshaders/unlitgeneric_dx8.cpp | 72 + .../stdshaders/unlitgeneric_dx9.cpp | 200 +++ .../stdshaders/unlitgeneric_inc.vsh | 142 ++ .../unlitgeneric_lightingonly_vs11.fxc | 47 + .../unlitgeneric_notexture_ps11.fxc | 9 + .../unlitgeneric_notexture_ps2x.fxc | 14 + .../stdshaders/unlitgeneric_ps11.fxc | 12 + .../stdshaders/unlitgeneric_ps2x.fxc | 19 + .../stdshaders/unlitgeneric_vs11.vsh | 23 + .../stdshaders/unlitgeneric_vs20.fxc | 91 ++ .../vertexlit_and_unlit_generic_bump_ps2x.fxc | 350 ++++ .../vertexlit_and_unlit_generic_bump_vs20.fxc | 198 +++ .../vertexlit_and_unlit_generic_ps2x.fxc | 484 ++++++ .../vertexlit_and_unlit_generic_vs20.fxc | 249 +++ .../vertexlit_lighting_only_ps2x.fxc | 68 + .../stdshaders/vertexlit_notexture.psh | 13 + ...vertexlitgeneric_basealphamaskedenvmap.psh | 19 + ...litgeneric_detailbasealphamaskedenvmap.psh | 21 + .../vertexlitgeneric_detailenvmap.psh | 19 + .../vertexlitgeneric_detailmaskedenvmap.psh | 21 + ...litgeneric_detailselfilluminatedenvmap.psh | 28 + ...eric_detailselfilluminatedmaskedenvmap.psh | 29 + .../stdshaders/vertexlitgeneric_dx6.cpp | 421 +++++ .../stdshaders/vertexlitgeneric_dx7.cpp | 413 +++++ .../stdshaders/vertexlitgeneric_dx8.cpp | 807 ++++++++++ .../stdshaders/vertexlitgeneric_dx9.cpp | 520 ++++++ .../stdshaders/vertexlitgeneric_dx95_helper.h | 71 + .../vertexlitgeneric_dx9_helper.cpp | 1434 +++++++++++++++++ .../stdshaders/vertexlitgeneric_dx9_helper.h | 144 ++ .../stdshaders/vertexlitgeneric_envmap.psh | 17 + .../vertexlitgeneric_flashlight_vs11.vsh | 137 ++ .../stdshaders/vertexlitgeneric_inc.vsh | 145 ++ ...texlitgeneric_lightingonly_overbright2.psh | 5 + ...tgeneric_lightingonly_overbright2_ps11.fxc | 9 + .../vertexlitgeneric_maskedenvmap.psh | 19 + ...vertexlitgeneric_selfilluminatedenvmap.psh | 25 + ...litgeneric_selfilluminatedmaskedenvmap.psh | 26 + .../stdshaders/vertexlitgeneric_vs11.vsh | 22 + .../stdshaders/volume_clouds.cpp | 59 + .../stdshaders/volume_clouds_helper.cpp | 138 ++ .../stdshaders/volume_clouds_helper.h | 41 + .../stdshaders/volume_clouds_ps2x.fxc | 66 + .../stdshaders/volume_clouds_vs20.fxc | 103 ++ .../stdshaders/vr_distort_hud.cpp | 224 +++ .../stdshaders/vr_distort_hud_ps2x.fxc | 78 + .../stdshaders/vr_distort_hud_vs20.fxc | 26 + .../stdshaders/vr_distort_texture.cpp | 213 +++ .../stdshaders/vr_distort_texture_ps2x.fxc | 49 + .../stdshaders/vr_distort_texture_vs20.fxc | 26 + sp/src/materialsystem/stdshaders/water.cpp | 614 +++++++ .../materialsystem/stdshaders/water_dudv.cpp | 95 ++ .../materialsystem/stdshaders/water_dx60.cpp | 15 + .../materialsystem/stdshaders/water_dx80.cpp | 419 +++++ .../materialsystem/stdshaders/water_dx81.cpp | 311 ++++ .../materialsystem/stdshaders/water_ps2x.fxc | 110 ++ .../stdshaders/water_ps2x_helper.h | 239 +++ .../stdshaders/waterreflect_ps14.psh | 8 + .../stdshaders/waterrefract_ps14.psh | 23 + .../stdshaders/worldtwotextureblend.cpp | 500 ++++++ .../stdshaders/worldtwotextureblend_dx6.cpp | 258 +++ .../stdshaders/worldtwotextureblend_dx8.cpp | 175 ++ .../stdshaders/worldtwotextureblend_ps2x.fxc | 217 +++ .../stdshaders/worldvertexalpha.cpp | 259 +++ .../stdshaders/worldvertexalpha_dx8.cpp | 113 ++ .../stdshaders/worldvertextransition.cpp | 157 ++ .../stdshaders/worldvertextransition_dx6.cpp | 52 + .../worldvertextransition_dx6_helper.cpp | 206 +++ .../worldvertextransition_dx6_helper.h | 39 + .../worldvertextransition_dx8_helper.cpp | 81 + .../worldvertextransition_dx8_helper.h | 44 + 710 files changed, 74048 insertions(+) create mode 100644 mp/src/materialsystem/stdshaders/BlurFilterX.cpp create mode 100644 mp/src/materialsystem/stdshaders/BlurFilterX_dx80.cpp create mode 100644 mp/src/materialsystem/stdshaders/BlurFilterY.cpp create mode 100644 mp/src/materialsystem/stdshaders/BlurFilterY_dx80.cpp create mode 100644 mp/src/materialsystem/stdshaders/BlurFilter_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/BlurFilter_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/BlurFilter_vs11.fxc create mode 100644 mp/src/materialsystem/stdshaders/BlurFilter_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/Cable.psh create mode 100644 mp/src/materialsystem/stdshaders/Cable.vsh create mode 100644 mp/src/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp create mode 100644 mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/DebugTextureView.cpp create mode 100644 mp/src/materialsystem/stdshaders/DebugTextureView_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/DebugTextureView_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/Eyes.psh create mode 100644 mp/src/materialsystem/stdshaders/Eyes_Overbright2.psh create mode 100644 mp/src/materialsystem/stdshaders/Eyes_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_Detail.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh create mode 100644 mp/src/materialsystem/stdshaders/Refract_model_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/Refract_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/Refract_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/Refract_world_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/ShadowModel.psh create mode 100644 mp/src/materialsystem/stdshaders/ShadowModel.vsh create mode 100644 mp/src/materialsystem/stdshaders/Teeth.vsh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_Detail.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc create mode 100644 mp/src/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheap_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheap_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/WaterCheap_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheap_vs14.vsh create mode 100644 mp/src/materialsystem/stdshaders/WaterCheap_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/WaterReflect_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/WaterRefract_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/Water_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/Water_ps14.vsh create mode 100644 mp/src/materialsystem/stdshaders/Water_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/Water_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/WorldTexture.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldTwoTextureBlend.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexAlpha.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexAlpha.vsh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition.vsh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition_Editor.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh create mode 100644 mp/src/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/cable_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/cable_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/cable_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/cable_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/cable_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/cloud.cpp create mode 100644 mp/src/materialsystem/stdshaders/cloud_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/cloud_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/cloud_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/cloud_ps20.fxc create mode 100644 mp/src/materialsystem/stdshaders/cloud_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/cloud_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/debugdepth.cpp create mode 100644 mp/src/materialsystem/stdshaders/debugluxel.cpp create mode 100644 mp/src/materialsystem/stdshaders/debugmodifyvertex.cpp create mode 100644 mp/src/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc create mode 100644 mp/src/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc create mode 100644 mp/src/materialsystem/stdshaders/debugmrttexture.cpp create mode 100644 mp/src/materialsystem/stdshaders/debugmrttexture_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/debugmrttexture_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/debugnormalmap.cpp create mode 100644 mp/src/materialsystem/stdshaders/debugsoftwarevertexshader.cpp create mode 100644 mp/src/materialsystem/stdshaders/debugtangentspace.cpp create mode 100644 mp/src/materialsystem/stdshaders/debugtangentspace.vsh create mode 100644 mp/src/materialsystem/stdshaders/debugtangentspace_vs11.fxc create mode 100644 mp/src/materialsystem/stdshaders/debugtangentspace_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc create mode 100644 mp/src/materialsystem/stdshaders/depthtodestalpha_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/depthwrite.cpp create mode 100644 mp/src/materialsystem/stdshaders/depthwrite_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/depthwrite_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/detail.cpp create mode 100644 mp/src/materialsystem/stdshaders/detail_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/detail_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/eye_refract.cpp create mode 100644 mp/src/materialsystem/stdshaders/eye_refract_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/eye_refract_helper.h create mode 100644 mp/src/materialsystem/stdshaders/eye_refract_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/eye_refract_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/eyeball.cpp create mode 100644 mp/src/materialsystem/stdshaders/eyeglint_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/eyeglint_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/eyeglint_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/eyes.cpp create mode 100644 mp/src/materialsystem/stdshaders/eyes.vsh create mode 100644 mp/src/materialsystem/stdshaders/eyes_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.h create mode 100644 mp/src/materialsystem/stdshaders/eyes_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/eyes_flashlight2_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/eyes_flashlight_inc.fxc create mode 100644 mp/src/materialsystem/stdshaders/eyes_flashlight_ps11.fxc create mode 100644 mp/src/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/eyes_flashlight_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/eyes_flashlight_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/eyes_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.h create mode 100644 mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_decal.cpp create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_envmap.psh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_inc.vsh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/refract.cpp create mode 100644 mp/src/materialsystem/stdshaders/refract_dx60.cpp create mode 100644 mp/src/materialsystem/stdshaders/refract_dx80.cpp create mode 100644 mp/src/materialsystem/stdshaders/refract_dx9_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/refract_dx9_helper.h create mode 100644 mp/src/materialsystem/stdshaders/refract_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/shadowmodel_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/shadowmodel_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/shadowmodel_ps20.fxc create mode 100644 mp/src/materialsystem/stdshaders/shadowmodel_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/skin_dx9_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/skin_dx9_helper.h create mode 100644 mp/src/materialsystem/stdshaders/skin_ps20b.fxc create mode 100644 mp/src/materialsystem/stdshaders/skin_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/sky_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/sky_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/sky_hdr_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/sky_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/sky_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/sprite.cpp create mode 100644 mp/src/materialsystem/stdshaders/sprite_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/sprite_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/sprite_ps11.psh create mode 100644 mp/src/materialsystem/stdshaders/sprite_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/sprite_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/sprite_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/spritecard.cpp create mode 100644 mp/src/materialsystem/stdshaders/spritecard_ps11.fxc create mode 100644 mp/src/materialsystem/stdshaders/spritecard_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc create mode 100644 mp/src/materialsystem/stdshaders/teeth.cpp create mode 100644 mp/src/materialsystem/stdshaders/teeth_bump_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/teeth_bump_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/teeth_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/teeth_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/teeth_flashlight_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/teeth_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/teeth_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_inc.vsh create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_ps11.fxc create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/unlitgeneric_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/vertexlit_notexture.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_envmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_inc.vsh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh create mode 100644 mp/src/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh create mode 100644 mp/src/materialsystem/stdshaders/volume_clouds.cpp create mode 100644 mp/src/materialsystem/stdshaders/volume_clouds_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/volume_clouds_helper.h create mode 100644 mp/src/materialsystem/stdshaders/volume_clouds_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/volume_clouds_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/vr_distort_hud.cpp create mode 100644 mp/src/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/vr_distort_hud_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/vr_distort_texture.cpp create mode 100644 mp/src/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/vr_distort_texture_vs20.fxc create mode 100644 mp/src/materialsystem/stdshaders/water.cpp create mode 100644 mp/src/materialsystem/stdshaders/water_dudv.cpp create mode 100644 mp/src/materialsystem/stdshaders/water_dx60.cpp create mode 100644 mp/src/materialsystem/stdshaders/water_dx80.cpp create mode 100644 mp/src/materialsystem/stdshaders/water_dx81.cpp create mode 100644 mp/src/materialsystem/stdshaders/water_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/water_ps2x_helper.h create mode 100644 mp/src/materialsystem/stdshaders/waterreflect_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/waterrefract_ps14.psh create mode 100644 mp/src/materialsystem/stdshaders/worldtwotextureblend.cpp create mode 100644 mp/src/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc create mode 100644 mp/src/materialsystem/stdshaders/worldvertexalpha.cpp create mode 100644 mp/src/materialsystem/stdshaders/worldvertexalpha_dx8.cpp create mode 100644 mp/src/materialsystem/stdshaders/worldvertextransition.cpp create mode 100644 mp/src/materialsystem/stdshaders/worldvertextransition_dx6.cpp create mode 100644 mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.h create mode 100644 mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp create mode 100644 mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.h create mode 100644 sp/src/materialsystem/stdshaders/BlurFilterX.cpp create mode 100644 sp/src/materialsystem/stdshaders/BlurFilterX_dx80.cpp create mode 100644 sp/src/materialsystem/stdshaders/BlurFilterY.cpp create mode 100644 sp/src/materialsystem/stdshaders/BlurFilterY_dx80.cpp create mode 100644 sp/src/materialsystem/stdshaders/BlurFilter_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/BlurFilter_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/BlurFilter_vs11.fxc create mode 100644 sp/src/materialsystem/stdshaders/BlurFilter_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/Cable.psh create mode 100644 sp/src/materialsystem/stdshaders/Cable.vsh create mode 100644 sp/src/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp create mode 100644 sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/DebugTextureView.cpp create mode 100644 sp/src/materialsystem/stdshaders/DebugTextureView_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/DebugTextureView_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/Eyes.psh create mode 100644 sp/src/materialsystem/stdshaders/Eyes_Overbright2.psh create mode 100644 sp/src/materialsystem/stdshaders/Eyes_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_Detail.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh create mode 100644 sp/src/materialsystem/stdshaders/Refract_model_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/Refract_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/Refract_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/Refract_world_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/ShadowModel.psh create mode 100644 sp/src/materialsystem/stdshaders/ShadowModel.vsh create mode 100644 sp/src/materialsystem/stdshaders/Teeth.vsh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_Detail.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc create mode 100644 sp/src/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheap_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheap_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/WaterCheap_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheap_vs14.vsh create mode 100644 sp/src/materialsystem/stdshaders/WaterCheap_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/WaterReflect_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/WaterRefract_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/Water_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/Water_ps14.vsh create mode 100644 sp/src/materialsystem/stdshaders/Water_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/Water_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/WorldTexture.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldTwoTextureBlend.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexAlpha.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexAlpha.vsh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition.vsh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition_Editor.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh create mode 100644 sp/src/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/cable_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/cable_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/cable_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/cable_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/cable_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/cloud.cpp create mode 100644 sp/src/materialsystem/stdshaders/cloud_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/cloud_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/cloud_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/cloud_ps20.fxc create mode 100644 sp/src/materialsystem/stdshaders/cloud_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/cloud_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/debugdepth.cpp create mode 100644 sp/src/materialsystem/stdshaders/debugluxel.cpp create mode 100644 sp/src/materialsystem/stdshaders/debugmodifyvertex.cpp create mode 100644 sp/src/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc create mode 100644 sp/src/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc create mode 100644 sp/src/materialsystem/stdshaders/debugmrttexture.cpp create mode 100644 sp/src/materialsystem/stdshaders/debugmrttexture_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/debugmrttexture_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/debugnormalmap.cpp create mode 100644 sp/src/materialsystem/stdshaders/debugsoftwarevertexshader.cpp create mode 100644 sp/src/materialsystem/stdshaders/debugtangentspace.cpp create mode 100644 sp/src/materialsystem/stdshaders/debugtangentspace.vsh create mode 100644 sp/src/materialsystem/stdshaders/debugtangentspace_vs11.fxc create mode 100644 sp/src/materialsystem/stdshaders/debugtangentspace_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc create mode 100644 sp/src/materialsystem/stdshaders/depthtodestalpha_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/depthwrite.cpp create mode 100644 sp/src/materialsystem/stdshaders/depthwrite_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/depthwrite_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/detail.cpp create mode 100644 sp/src/materialsystem/stdshaders/detail_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/detail_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/eye_refract.cpp create mode 100644 sp/src/materialsystem/stdshaders/eye_refract_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/eye_refract_helper.h create mode 100644 sp/src/materialsystem/stdshaders/eye_refract_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/eye_refract_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/eyeball.cpp create mode 100644 sp/src/materialsystem/stdshaders/eyeglint_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/eyeglint_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/eyeglint_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/eyes.cpp create mode 100644 sp/src/materialsystem/stdshaders/eyes.vsh create mode 100644 sp/src/materialsystem/stdshaders/eyes_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.h create mode 100644 sp/src/materialsystem/stdshaders/eyes_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/eyes_flashlight2_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/eyes_flashlight_inc.fxc create mode 100644 sp/src/materialsystem/stdshaders/eyes_flashlight_ps11.fxc create mode 100644 sp/src/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/eyes_flashlight_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/eyes_flashlight_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/eyes_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.h create mode 100644 sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_decal.cpp create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_envmap.psh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_inc.vsh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/refract.cpp create mode 100644 sp/src/materialsystem/stdshaders/refract_dx60.cpp create mode 100644 sp/src/materialsystem/stdshaders/refract_dx80.cpp create mode 100644 sp/src/materialsystem/stdshaders/refract_dx9_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/refract_dx9_helper.h create mode 100644 sp/src/materialsystem/stdshaders/refract_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/shadowmodel_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/shadowmodel_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/shadowmodel_ps20.fxc create mode 100644 sp/src/materialsystem/stdshaders/shadowmodel_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/skin_dx9_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/skin_dx9_helper.h create mode 100644 sp/src/materialsystem/stdshaders/skin_ps20b.fxc create mode 100644 sp/src/materialsystem/stdshaders/skin_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/sky_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/sky_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/sky_hdr_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/sky_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/sky_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/sprite.cpp create mode 100644 sp/src/materialsystem/stdshaders/sprite_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/sprite_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/sprite_ps11.psh create mode 100644 sp/src/materialsystem/stdshaders/sprite_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/sprite_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/sprite_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/spritecard.cpp create mode 100644 sp/src/materialsystem/stdshaders/spritecard_ps11.fxc create mode 100644 sp/src/materialsystem/stdshaders/spritecard_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/spritecard_vsxx.fxc create mode 100644 sp/src/materialsystem/stdshaders/teeth.cpp create mode 100644 sp/src/materialsystem/stdshaders/teeth_bump_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/teeth_bump_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/teeth_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/teeth_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/teeth_flashlight_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/teeth_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/teeth_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_inc.vsh create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_ps11.fxc create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/unlitgeneric_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/vertexlit_notexture.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_envmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_inc.vsh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh create mode 100644 sp/src/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh create mode 100644 sp/src/materialsystem/stdshaders/volume_clouds.cpp create mode 100644 sp/src/materialsystem/stdshaders/volume_clouds_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/volume_clouds_helper.h create mode 100644 sp/src/materialsystem/stdshaders/volume_clouds_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/volume_clouds_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/vr_distort_hud.cpp create mode 100644 sp/src/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/vr_distort_hud_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/vr_distort_texture.cpp create mode 100644 sp/src/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/vr_distort_texture_vs20.fxc create mode 100644 sp/src/materialsystem/stdshaders/water.cpp create mode 100644 sp/src/materialsystem/stdshaders/water_dudv.cpp create mode 100644 sp/src/materialsystem/stdshaders/water_dx60.cpp create mode 100644 sp/src/materialsystem/stdshaders/water_dx80.cpp create mode 100644 sp/src/materialsystem/stdshaders/water_dx81.cpp create mode 100644 sp/src/materialsystem/stdshaders/water_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/water_ps2x_helper.h create mode 100644 sp/src/materialsystem/stdshaders/waterreflect_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/waterrefract_ps14.psh create mode 100644 sp/src/materialsystem/stdshaders/worldtwotextureblend.cpp create mode 100644 sp/src/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc create mode 100644 sp/src/materialsystem/stdshaders/worldvertexalpha.cpp create mode 100644 sp/src/materialsystem/stdshaders/worldvertexalpha_dx8.cpp create mode 100644 sp/src/materialsystem/stdshaders/worldvertextransition.cpp create mode 100644 sp/src/materialsystem/stdshaders/worldvertextransition_dx6.cpp create mode 100644 sp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.h create mode 100644 sp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp create mode 100644 sp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.h diff --git a/mp/src/materialsystem/stdshaders/BlurFilterX.cpp b/mp/src/materialsystem/stdshaders/BlurFilterX.cpp new file mode 100644 index 00000000..f462423a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BlurFilterX.cpp @@ -0,0 +1,122 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "BlurFilter_vs20.inc" +#include "BlurFilter_ps20.inc" +#include "BlurFilter_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( BlurFilterX, "Help for BlurFilterX", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT + { + if( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "BlurFilterX_DX80"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Render targets are pegged as sRGB on POSIX, so just force these reads and writes + bool bForceSRGBReadAndWrite = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs(); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bForceSRGBReadAndWrite ); + pShaderShadow->EnableSRGBWrite( bForceSRGBReadAndWrite ); + + // Pre-cache shaders + blurfilter_vs20_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "BlurFilter_vs20", vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b ); +#ifndef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( APPROX_SRGB_ADAPTER, bForceSRGBReadAndWrite ); +#endif + SET_STATIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + } + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + + float v[4]; + + // The temp buffer is 1/4 back buffer size + ITexture *src_texture = params[BASETEXTURE]->GetTextureValue(); + int width = src_texture->GetActualWidth(); + float dX = 1.0f / width; + + // Tap offsets + v[0] = 1.3366f * dX; + v[1] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 ); + v[0] = 3.4295f * dX; + v[1] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 ); + v[0] = 5.4264f * dX; + v[1] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 ); + + v[0] = 7.4359f * dX; + v[1] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 0, v, 1 ); + v[0] = 9.4436f * dX; + v[1] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 1, v, 1 ); + v[0] = 11.4401f * dX; + v[1] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 2, v, 1 ); + v[0] = v[1] = v[2] = v[3] = 1.0; + pShaderAPI->SetPixelShaderConstant( 3, v, 1 ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/BlurFilterX_dx80.cpp b/mp/src/materialsystem/stdshaders/BlurFilterX_dx80.cpp new file mode 100644 index 00000000..6eecfef2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BlurFilterX_dx80.cpp @@ -0,0 +1,86 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "BaseVSShader.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( BlurFilterX, BlurFilterX_DX80 ) + +BEGIN_VS_SHADER_FLAGS( BlurFilterX_DX80, "Help for BlurFilterX_DX80", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT + { + if( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + { + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Pre-cache shaders + pShaderShadow->SetVertexShader( "BlurFilter_vs11", 0 ); + pShaderShadow->SetPixelShader( "BlurFilter_ps11", 0 ); + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER3, BASETEXTURE, -1 ); + + // The temp buffer is 1/4 back buffer size + ITexture *src_texture=params[BASETEXTURE]->GetTextureValue(); + int width = src_texture->GetActualWidth(); + float dX = 2.0f / width; + + // 4 Tap offsets, expected from pixel center + float v[4][4]; + v[0][0] = -1.5f * dX; + v[0][1] = 0; + v[1][0] = -0.5f * dX; + v[1][1] = 0; + v[2][0] = 0.5f * dX; + v[2][1] = 0; + v[3][0] = 1.5f * dX; + v[3][1] = 0; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &v[0][0], 4 ); + + v[0][0] = v[0][1] = v[0][2] = v[0][3] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 1, v[0], 1 ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + pShaderAPI->SetPixelShaderIndex( 0 ); + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/BlurFilterY.cpp b/mp/src/materialsystem/stdshaders/BlurFilterY.cpp new file mode 100644 index 00000000..57db29c0 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BlurFilterY.cpp @@ -0,0 +1,136 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "BaseVSShader.h" +#include "BlurFilter_vs20.inc" +#include "BlurFilter_ps20.inc" +#include "BlurFilter_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( BlurFilterY, "Help for BlurFilterY", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( FRAMETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if ( !( params[BLOOMAMOUNT]->IsDefined() ) ) + { + params[BLOOMAMOUNT]->SetFloatValue( 1.0 ); + } + } + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "BlurFilterY_DX80"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Render targets are pegged as sRGB on POSIX, so just force these reads and writes + bool bForceSRGBReadAndWrite = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs(); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bForceSRGBReadAndWrite ); + pShaderShadow->EnableSRGBWrite( bForceSRGBReadAndWrite ); + + // Pre-cache shaders + DECLARE_STATIC_VERTEX_SHADER( blurfilter_vs20 ); + SET_STATIC_VERTEX_SHADER( blurfilter_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b ); +#ifndef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( APPROX_SRGB_ADAPTER, bForceSRGBReadAndWrite ); +#endif + SET_STATIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + } + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + + // The temp buffer is 1/4 back buffer size + ITexture *src_texture = params[BASETEXTURE]->GetTextureValue(); + int height = src_texture->GetActualWidth(); + float dY = 1.0f / height; +// dY *= 0.4; + float v[4]; + + // Tap offsets + v[0] = 0.0f; + v[1] = 1.3366f * dY; + v[2] = 0; + v[3] = 0; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 ); + v[0] = 0.0f; + v[1] = 3.4295f * dY; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 ); + v[0] = 0.0f; + v[1] = 5.4264f * dY; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 ); + + v[0] = 0.0f; + v[1] = 7.4359f * dY; + pShaderAPI->SetPixelShaderConstant( 0, v, 1 ); + v[0] = 0.0f; + v[1] = 9.4436f * dY; + pShaderAPI->SetPixelShaderConstant( 1, v, 1 ); + v[0] = 0.0f; + v[1] = 11.4401f * dY; + pShaderAPI->SetPixelShaderConstant( 2, v, 1 ); + + v[0]=v[1]=v[2]=params[BLOOMAMOUNT]->GetFloatValue(); + + pShaderAPI->SetPixelShaderConstant( 3, v, 1 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 ); + SET_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/BlurFilterY_dx80.cpp b/mp/src/materialsystem/stdshaders/BlurFilterY_dx80.cpp new file mode 100644 index 00000000..5e01d608 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BlurFilterY_dx80.cpp @@ -0,0 +1,91 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "BaseVSShader.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( BlurFilterY, BlurFilterY_DX80 ) + +BEGIN_VS_SHADER_FLAGS( BlurFilterY_DX80, "Help for BlurFilterY_DX80", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( FRAMETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) + END_SHADER_PARAMS + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + if ( !( params[BLOOMAMOUNT]->IsDefined() ) ) + params[BLOOMAMOUNT]->SetFloatValue(1.0); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + { + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Pre-cache shaders + pShaderShadow->SetVertexShader( "BlurFilter_vs11", 0 ); + pShaderShadow->SetPixelShader( "BlurFilter_ps11", 0 ); + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER3, BASETEXTURE, -1 ); + + int width, height; + pShaderAPI->GetBackBufferDimensions( width, height ); + + // The temp buffer is 1/4 back buffer size + float dY = 2.0f / height; + + // 4 Tap offsets, expected from pixel center + float v[4][4]; + v[0][0] = 0; + v[0][1] = -1.5f * dY; + v[1][0] = 0; + v[1][1] = -0.5f * dY; + v[2][0] = 0; + v[2][1] = 0.5f * dY; + v[3][0] = 0; + v[3][1] = 1.5f * dY; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &v[0][0], 4 ); + + v[0][0] = v[0][1] = v[0][2] = params[BLOOMAMOUNT]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 1, v[0], 1 ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + pShaderAPI->SetPixelShaderIndex( 0 ); + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/BlurFilter_ps11.psh b/mp/src/materialsystem/stdshaders/BlurFilter_ps11.psh new file mode 100644 index 00000000..6bc9bc57 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BlurFilter_ps11.psh @@ -0,0 +1,18 @@ +ps.1.1 + +// 1221 filter constants +def c0, 0.1667f, 0.1667f, 0.1667f, 0.3333f + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0.rgb, t0, c0 +mad r0.rgb, t1, c0.a, r0 +mad r0.rgb, t2, c0.a, r0 +mad r0.rgb, t3, c0, r0 + +mul r0.rgb, r0, c1 + +mov r0.a, t0.a + diff --git a/mp/src/materialsystem/stdshaders/BlurFilter_ps2x.fxc b/mp/src/materialsystem/stdshaders/BlurFilter_ps2x.fxc new file mode 100644 index 00000000..bfd082b3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BlurFilter_ps2x.fxc @@ -0,0 +1,91 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "APPROX_SRGB_ADAPTER" "0..1" [ps20b] [PC] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler TexSampler : register( s0 ); + +struct PS_INPUT +{ + float2 coordTap0 : TEXCOORD0; + float2 coordTap1 : TEXCOORD1; + float2 coordTap2 : TEXCOORD2; + float2 coordTap3 : TEXCOORD3; + float2 coordTap1Neg : TEXCOORD4; + float2 coordTap2Neg : TEXCOORD5; + float2 coordTap3Neg : TEXCOORD6; +}; + +float2 psTapOffs[3] : register( c0 ); +float3 scale_factor : register( c3 ); + +float4 SampleTexture( sampler texSampler, float2 uv ) +{ + float4 cSample = tex2D( texSampler, uv ); + + #if ( APPROX_SRGB_ADAPTER ) + { + cSample.rgb = max( cSample.rgb, float3( 0.00001f, 0.00001f, 0.00001f ) ); // rsqrt doesn't like inputs of zero + + float3 ooSQRT; // + ooSQRT.r = rsqrt( cSample.r ); // + ooSQRT.g = rsqrt( cSample.g ); // Approximate linear-to-sRGB conversion + ooSQRT.b = rsqrt( cSample.b ); // + cSample.rgb *= ooSQRT.rgb; // + } + #endif + + return cSample; +} + +float4 main( PS_INPUT i ) : COLOR +{ + float4 s0, s1, s2, s3, s4, s5, s6, color; + + // Sample taps with coordinates from VS + s0 = SampleTexture( TexSampler, i.coordTap0 ); + s1 = SampleTexture( TexSampler, i.coordTap1 ); + s2 = SampleTexture( TexSampler, i.coordTap2 ); + s3 = SampleTexture( TexSampler, i.coordTap3 ); + s4 = SampleTexture( TexSampler, i.coordTap1Neg ); + s5 = SampleTexture( TexSampler, i.coordTap2Neg ); + s6 = SampleTexture( TexSampler, i.coordTap3Neg ); + + color = s0 * 0.2013f; + color += ( s1 + s4 ) * 0.2185f; + color += ( s2 + s5 ) * 0.0821f; + color += ( s3 + s6 ) * 0.0461f; + + // Compute tex coords for other taps + float2 coordTap4 = i.coordTap0 + psTapOffs[0]; + float2 coordTap5 = i.coordTap0 + psTapOffs[1]; + float2 coordTap6 = i.coordTap0 + psTapOffs[2]; + float2 coordTap4Neg = i.coordTap0 - psTapOffs[0]; + float2 coordTap5Neg = i.coordTap0 - psTapOffs[1]; + float2 coordTap6Neg = i.coordTap0 - psTapOffs[2]; + + // Sample the taps + s1 = SampleTexture( TexSampler, coordTap4 ); + s2 = SampleTexture( TexSampler, coordTap5 ); + s3 = SampleTexture( TexSampler, coordTap6 ); + s4 = SampleTexture( TexSampler, coordTap4Neg ); + s5 = SampleTexture( TexSampler, coordTap5Neg ); + s6 = SampleTexture( TexSampler, coordTap6Neg ); + + color += ( s1 + s4 ) * 0.0262f; + color += ( s2 + s5 ) * 0.0162f; + color += ( s3 + s6 ) * 0.0102f; + color.xyz*=scale_factor.xyz; + + #if ( APPROX_SRGB_ADAPTER ) + { + color.xyz *= color.xyz; // Approximate sRGB-to-linear conversion + } + #endif + + return color; + //return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} + diff --git a/mp/src/materialsystem/stdshaders/BlurFilter_vs11.fxc b/mp/src/materialsystem/stdshaders/BlurFilter_vs11.fxc new file mode 100644 index 00000000..0a213522 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BlurFilter_vs11.fxc @@ -0,0 +1,34 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 coordTap0 : TEXCOORD0; + float2 coordTap1 : TEXCOORD1; + float2 coordTap2 : TEXCOORD2; + float2 coordTap3 : TEXCOORD3; +}; + +float2 vsTapOffs[4] : register ( SHADER_SPECIFIC_CONST_0 ); + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.projPos = float4( v.vPos, 1.0f ); + + o.coordTap0 = v.vBaseTexCoord + vsTapOffs[0]; + o.coordTap1 = v.vBaseTexCoord + vsTapOffs[1]; + o.coordTap2 = v.vBaseTexCoord + vsTapOffs[2]; + o.coordTap3 = v.vBaseTexCoord + vsTapOffs[3]; + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/BlurFilter_vs20.fxc b/mp/src/materialsystem/stdshaders/BlurFilter_vs20.fxc new file mode 100644 index 00000000..3c37fa74 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BlurFilter_vs20.fxc @@ -0,0 +1,39 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 coordTap0 : TEXCOORD0; + float2 coordTap1 : TEXCOORD1; + float2 coordTap2 : TEXCOORD2; + float2 coordTap3 : TEXCOORD3; + float2 coordTap1Neg : TEXCOORD4; + float2 coordTap2Neg : TEXCOORD5; + float2 coordTap3Neg : TEXCOORD6; +}; + +float2 vsTapOffs[3] : register ( SHADER_SPECIFIC_CONST_0 ); + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.projPos = float4( v.vPos, 1.0f ); + o.coordTap0 = v.vBaseTexCoord; + o.coordTap1 = v.vBaseTexCoord + vsTapOffs[0]; + o.coordTap2 = v.vBaseTexCoord + vsTapOffs[1]; + o.coordTap3 = v.vBaseTexCoord + vsTapOffs[2]; + o.coordTap1Neg = v.vBaseTexCoord - vsTapOffs[0]; + o.coordTap2Neg = v.vBaseTexCoord - vsTapOffs[1]; + o.coordTap3Neg = v.vBaseTexCoord - vsTapOffs[2]; + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/Cable.psh b/mp/src/materialsystem/stdshaders/Cable.psh new file mode 100644 index 00000000..a73b1130 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Cable.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; See the vertex shader for info +; +; This shader takes: +; t0 = normal map +; t1 = base texture +; v0 = directional light color +; t2 = directional light direction (biased into 0-1) +; c0 = percent of dirlight to add as ambient +; +; Output: +; (t0 dot t1) * v0 +;------------------------------------------------------------------------------ + +tex t0 ; Get the 3-vector from the normal map +tex t1 ; Interpret tcoord t1 as color data. +texcoord t2 + +dp3 r1, t0_bx2, t2_bx2 ; r1 = normalMap dot dirLightDir +add r0, r1, c0 ; + 0.5 + +mul r1, v0, r0 ; scale the dot product by the dirlight's actual color +mul r0.rgb, r1, t1 + ; scale by the texture color + +mul r0.a, t1.a, v0.a diff --git a/mp/src/materialsystem/stdshaders/Cable.vsh b/mp/src/materialsystem/stdshaders/Cable.vsh new file mode 100644 index 00000000..857a2e3b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Cable.vsh @@ -0,0 +1,117 @@ +vs.1.1 + +#include "macros.vsh" + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; The cable equation is: +; [L dot N] * C * T +; +; where: +; C = directional light color +; T = baseTexture +; N = particle normal (stored in the normal map) +; L = directional light direction +; +; $SHADER_SPECIFIC_CONST_0 = Directional light direction +;------------------------------------------------------------------------------ + + +;------------------------------------------------------------------------------ +; Transform position from object to projection space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Setup the tangent space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$tmp1 ); +&AllocateRegister( \$tmp2 ); +&AllocateRegister( \$tmp3 ); +&AllocateRegister( \$r ); + +; Get S crossed with T (call it R) +mov $tmp1, $vTangentS +mov $tmp2, $vTangentT + +mul $tmp3, $vTangentS.yzxw, $tmp2.zxyw +mad $r, -$vTangentS.zxyw, $tmp2.yzxw, $tmp3 + +&FreeRegister( \$tmp2 ); +&FreeRegister( \$tmp3 ); + +&AllocateRegister( \$s ); + +; Normalize S (into $s) +dp3 $s.w, $vTangentS, $vTangentS +rsq $s.w, $s.w +mul $s.xyz, $vTangentS, $s.w + +; Normalize R (into $r) +dp3 $r.w, $r, $r +rsq $r.w, $r.w +mul $r.xyz, $r, $r.w + +&AllocateRegister( \$t ); + +; Regenerate T (into $t) +mul $t, $r.yzxw, $tmp1.zxyw +mad $t, -$r.zxyw, $tmp1.yzxw, $t + +&FreeRegister( \$tmp1 ); + +;------------------------------------------------------------------------------ +; Transform the light direction (into oD1) +;------------------------------------------------------------------------------ + +&AllocateRegister( \$lightDirection ); + +dp3 $lightDirection.x, $s, $SHADER_SPECIFIC_CONST_0 +dp3 $lightDirection.y, $t, $SHADER_SPECIFIC_CONST_0 +dp3 $lightDirection.z, $r, $SHADER_SPECIFIC_CONST_0 + +&FreeRegister( \$r ); +&FreeRegister( \$s ); +&FreeRegister( \$t ); + +; Scale into 0-1 range (we're assuming light direction was normalized prior to here) +add oT2, $lightDirection, $cHalf ; + 0.5 +&FreeRegister( \$lightDirection ); + +;------------------------------------------------------------------------------ +; Copy texcoords for the normal map and base texture +;------------------------------------------------------------------------------ + +mov oT0, $vTexCoord0 +mov oT1, $vTexCoord1 + +; Pass the dirlight color through +mov oD0.xyzw, $vColor + + diff --git a/mp/src/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc b/mp/src/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc new file mode 100644 index 00000000..c90ef086 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc @@ -0,0 +1,23 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float4 projPos : POSITION; + float3 zValue : TEXCOORD0; +}; + +const float3 g_ZFilter : register( c1 ); +const float3 g_ModulationColor : register( c2 ); + +float4 main( PS_INPUT i ) : COLOR +{ + float z = dot( i.zValue, g_ZFilter ); + z = saturate( z ); + float4 color = float4( z, z, z, 1.0f ); + color.rgb *= g_ModulationColor; + return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} diff --git a/mp/src/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc b/mp/src/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc new file mode 100644 index 00000000..647acde0 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc @@ -0,0 +1,38 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float2 cDepthFactor : register( SHADER_SPECIFIC_CONST_0 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 zValue : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + o.zValue.x = (o.projPos.z - cDepthFactor.y) / cDepthFactor.x; + o.zValue.y = (o.projPos.w - cDepthFactor.y) / cDepthFactor.x; + return o; +} + + + + diff --git a/mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp b/mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp new file mode 100644 index 00000000..9f3c34bf --- /dev/null +++ b/mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp @@ -0,0 +1,94 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "BaseVSShader.h" +#include "debugdrawenvmapmask_vs20.inc" +#include "debugdrawenvmapmask_ps20.inc" +#include "debugdrawenvmapmask_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( DebugDrawEnvmapMask, "Help for DebugDrawEnvmapMask", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SHOWALPHA, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_INIT + { + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { +// Assert( 0 ); + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); + SET_STATIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); + SET_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); + SET_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); + } + } + DYNAMIC_STATE + { + int numBones = s_pShaderAPI->GetCurrentNumBones(); + + DECLARE_DYNAMIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); + + bool bShowAlpha = params[SHOWALPHA]->GetIntValue() ? true : false; + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( SHOWALPHA, bShowAlpha ); + SET_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( SHOWALPHA, bShowAlpha ); + SET_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); + } + + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc b/mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc new file mode 100644 index 00000000..f97589af --- /dev/null +++ b/mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc @@ -0,0 +1,26 @@ +// DYNAMIC: "SHOWALPHA" "0..1" + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); + +struct PS_INPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); +#if SHOWALPHA + float4 result = float4( baseColor.a, baseColor.a, baseColor.a, 1.0f ); +#else + float4 result = float4( baseColor.rgb, 1.0f ); +#endif + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} diff --git a/mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc b/mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc new file mode 100644 index 00000000..33aa5dac --- /dev/null +++ b/mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc @@ -0,0 +1,39 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + return o; +} + + + + diff --git a/mp/src/materialsystem/stdshaders/DebugTextureView.cpp b/mp/src/materialsystem/stdshaders/DebugTextureView.cpp new file mode 100644 index 00000000..70d73d34 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/DebugTextureView.cpp @@ -0,0 +1,104 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "shaderlib/cshader.h" + +#include "debugtextureview_vs20.inc" +#include "debugtextureview_ps20.inc" +#include "debugtextureview_ps20b.inc" + +DEFINE_FALLBACK_SHADER( DebugTextureView, DebugTextureView_dx9 ) +BEGIN_VS_SHADER( DebugTextureView_dx9, "Help for DebugTextureView" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( SHOWALPHA, SHADER_PARAM_TYPE_BOOL, "0", "" ) + END_SHADER_PARAMS + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "UnlitGeneric"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaTest( true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( debugtextureview_vs20 ); + SET_STATIC_VERTEX_SHADER( debugtextureview_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( debugtextureview_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( SHOWALPHA, params[SHOWALPHA]->GetIntValue() != 0 ); + SET_STATIC_PIXEL_SHADER( debugtextureview_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( debugtextureview_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( SHOWALPHA, params[SHOWALPHA]->GetIntValue() != 0 ); + SET_STATIC_PIXEL_SHADER( debugtextureview_ps20 ); + } + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + //pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + + float cPsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + if ( ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA16161616F ) || + ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA16161616 ) || + ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGB323232F ) || + ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA32323232F ) ) + { + if ( pTexture->IsCubeMap() ) + cPsConst0[0] = 1.0f; + else + cPsConst0[1] = 1.0f; + } + pShaderAPI->SetPixelShaderConstant( 0, cPsConst0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( debugtextureview_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( debugtextureview_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ISCUBEMAP, pTexture->IsCubeMap() ); + SET_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ISCUBEMAP, pTexture->IsCubeMap() ); + SET_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/DebugTextureView_ps2x.fxc b/mp/src/materialsystem/stdshaders/DebugTextureView_ps2x.fxc new file mode 100644 index 00000000..4b22d55b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/DebugTextureView_ps2x.fxc @@ -0,0 +1,81 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "SHOWALPHA" "0..1" +// DYNAMIC: "ISCUBEMAP" "0..1" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler g_tSampler : register( s0 ); + +struct PS_INPUT +{ + float2 texCoord : TEXCOORD0; +}; + +const float3 g_vConst0 : register( c0 ); +#define g_flIsHdrCube g_vConst0.x +#define g_flIsHdr2D g_vConst0.y + +float4 main( PS_INPUT i ) : COLOR +{ + float4 sample = tex2D( g_tSampler, i.texCoord ); + float4 result = { 0.0f, 0.0f, 0.0f, 1.0f }; + + result.rgb = sample.rgb; + #if SHOWALPHA + result.rgb = sample.a; + #endif + + if ( g_flIsHdr2D ) + result.rgb *= MAX_HDR_OVERBRIGHT; + + #if ISCUBEMAP + bool bNoDataForThisPixel = false; + float3 vec = float3( 0, 0, 0 ); + float x = i.texCoord.x; + float y = i.texCoord.y; + float x2 = frac( ( i.texCoord.x ) * 3.0f ) * 2.0f - 1.0f; + float y2 = frac( ( i.texCoord.y ) * 4.0f ) * 2.0f - 1.0f; + if ( ( x >= 0.3333f ) && ( x <= 0.6666f ) ) //Center row + { + if ( y >= 0.75f ) + vec = float3( x2, 1.0, y2 ); + else if ( y >= 0.5f ) + vec = float3( x2, y2, -1.0 ); + else if ( y >= 0.25f ) + vec = float3( x2, -1.0, -y2 ); + else if ( y >= 0.0f ) + vec = float3( x2, -y2, 1.0 ); + } + else if ( ( y >= 0.25f ) && ( y <= 0.5f ) ) + { + if ( x <= 0.3333f ) + vec = float3( -1.0f, -x2, -y2 ); + else if (x >= 0.6666f) + vec = float3( 1.0f, x2, -y2 ); + else + bNoDataForThisPixel = true; + } + else + { + bNoDataForThisPixel = true; + } + + float4 cBase = texCUBE( g_tSampler, vec ); + #if SHOWALPHA + cBase.rgb = cBase.a; + #endif + + if ( g_flIsHdrCube ) + cBase.rgb *= ENV_MAP_SCALE; + + if ( bNoDataForThisPixel == true ) + cBase.rgb = float3( 0.9f, 0.4f, 0.15f ); + + result.rgb = cBase.rgb; + result.a = 1.0f; // - bNoDataForThisPixel; + #endif + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} diff --git a/mp/src/materialsystem/stdshaders/DebugTextureView_vs20.fxc b/mp/src/materialsystem/stdshaders/DebugTextureView_vs20.fxc new file mode 100644 index 00000000..48c3b7e4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/DebugTextureView_vs20.fxc @@ -0,0 +1,23 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" + +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vUv0 : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + o.vProjPos.xyzw = mul( i.vPos.xyzw, cModelViewProj ); + o.vUv0.xy = i.vTexCoord0.xy; + return o; +} diff --git a/mp/src/materialsystem/stdshaders/Eyes.psh b/mp/src/materialsystem/stdshaders/Eyes.psh new file mode 100644 index 00000000..6e5e5646 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Eyes.psh @@ -0,0 +1,16 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw the eyes +; t0 - texture +; t1 - iris +; t2 - glint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +lrp r0, t1.a, t1, t0 ; Blend in the iris with the background +mad r0.rgb, r0, v0, t2 + ; Modulate by the illumination, add in the glint +mov r0.a, t0.a diff --git a/mp/src/materialsystem/stdshaders/Eyes_Overbright2.psh b/mp/src/materialsystem/stdshaders/Eyes_Overbright2.psh new file mode 100644 index 00000000..11119233 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Eyes_Overbright2.psh @@ -0,0 +1,18 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw the eyes +; t0 - texture +; t1 - iris +; t2 - glint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +lrp r0, t1.a, t1, t0 ; Blend in the iris with the background +mul_x2 r0, v0, r0 ; Modulate by the illumination with overbright + +add r0.rgb, r0, t2 + ; Add in the glint +mov r0.a, t0.a diff --git a/mp/src/materialsystem/stdshaders/Eyes_vs20.fxc b/mp/src/materialsystem/stdshaders/Eyes_vs20.fxc new file mode 100644 index 00000000..b055eed7 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Eyes_vs20.fxc @@ -0,0 +1,145 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== +// $SHADER_SPECIFIC_CONST_0 = eyeball origin +// $SHADER_SPECIFIC_CONST_1 = eyeball up * 0.5 +// $SHADER_SPECIFIC_CONST_2 = iris projection U +// $SHADER_SPECIFIC_CONST_3 = iris projection V +// $SHADER_SPECIFIC_CONST_4 = glint projection U +// $SHADER_SPECIFIC_CONST_5 = glint projection V +//============================================================================= + +// STATIC: "INTRO" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "vortwarp_vs20_helper.h" + +static const int g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; + +const float3 cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 ); +const float3 cHalfEyeballUp : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cGlintProjectionU : register( SHADER_SPECIFIC_CONST_4 ); +const float4 cGlintProjectionV : register( SHADER_SPECIFIC_CONST_5 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_6 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_7 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_8 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates + + float3 vPosFlex : POSITION1; // Delta positions for flexing +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; // Fixed-function fog factor +#endif + float2 baseTC : TEXCOORD0; // Base texture coordinate + float2 irisTC : TEXCOORD1; // Iris texture coordinates + float2 glintTC : TEXCOORD2; // Glint texture coordinates + float3 vColor : TEXCOORD3; // Vertex-lit color + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + + float4 vPosition = v.vPos; + float3 dummy = v.vPos.xyz; // dummy values that can't be optimized out + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, vPosition.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, dummy, vPosition.xyz ); +#endif + + // Transform the position and dummy normal (not doing the dummy normal causes invariance issues with the flashlight!) + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, dummy, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + +#if INTRO + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, dummy, dummy, dummy ); +#endif + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, vProjPos, g_FogType ); +#endif + + // Normal = (Pos - Eye origin) - just step on dummy normal created above + worldNormal = worldPos - cEyeOrigin; + + // Normal -= 0.5f * (Normal dot Eye Up) * Eye Up + float normalDotUp = -dot( worldNormal, cHalfEyeballUp) * 0.5f; + worldNormal = normalize(normalDotUp * cHalfEyeballUp + worldNormal); + + // Vertex lighting +#if ( USE_STATIC_CONTROL_FLOW || defined ( SHADER_MODEL_VS_3_0 ) ) + o.vColor = DoLighting( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert ); +#else + o.vColor = DoLightingUnrolled( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); +#endif + + // Texture 0 is the base texture + // Texture 1 is a planar projection used for the iris + // Texture 2 is a planar projection used for the glint + o.baseTC = v.vTexCoord0; + o.irisTC.x = dot( cIrisProjectionU, float4(worldPos, 1) ); + o.irisTC.y = dot( cIrisProjectionV, float4(worldPos, 1) ); + o.glintTC.x = dot( cGlintProjectionU, float4(worldPos, 1) ); + o.glintTC.y = dot( cGlintProjectionV, float4(worldPos, 1) ); + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric.psh new file mode 100644 index 00000000..a6794e7e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh new file mode 100644 index 00000000..7b042e7a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t2 ; cube map +tex t3 ; envmap mask + +mul r0.rgb, t2, 1-t3.a +mul r0.rgb, c2, r0 ; apply the envmaptint ++ mul r0.a, c2.a, v0.a diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh new file mode 100644 index 00000000..ccc2c7b1 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t2 ; cube map +tex t3 ; envmap mask + +mul r0.rgb, t2, t3 +mul r0.rgb, c2, r0 ++ mul r0.a, c2.a, v0.a diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh new file mode 100644 index 00000000..fd4fd7a5 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t2 ; cube map + +mul r0.rgb, t2, c2 ++ mul r0.a, v0.a, c2.a diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh new file mode 100644 index 00000000..236db8e3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul r1, t2, 1-t3.a ; envmap * envmapmask (alpha) +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh new file mode 100644 index 00000000..75aab35b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh @@ -0,0 +1,14 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 +mul r0, t0, c0 + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh new file mode 100644 index 00000000..6cef1e5d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh @@ -0,0 +1,38 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh new file mode 100644 index 00000000..8eea421f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh @@ -0,0 +1,43 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + +dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + +mov oT2, $vTexCoord1 + +; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. +mov oD0, $vColor diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh new file mode 100644 index 00000000..ba349187 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh @@ -0,0 +1,66 @@ +; STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +ps.1.1 + +;------------------------------------------------------------------------------ +; Environment mapping on a bumped surface +; t0 - Normalmap +; t3 - Cube environment map (*must* be a cube map!) +; +; c0 - color to multiply the results by +; c1 - envmap contrast +; c2 - envmap saturation +; c3 - grey weights +; c4 - fresnel amount +; Input texture coords required here are a little wonky. +; tc0.uv <- U,V into the normal map +; tc1.uvw, tc2.uvw, tc3.uvw <- 3x3 matrix transform +; from tangent space->env map space +; tc1.q, tc2.q, tc3.q <- eye vector in env map space +;------------------------------------------------------------------------------ + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +; FIXME FIXME - Need to do specialized versions of this with and without: +; - constant color +; - fresnel amount of exactly 0 or 1 or in between +; - envmap contrast of 0, 1, or in between +; - envmap saturation of 0, 1, or in between + +; r0 = constant color * result of bump into envmap +mul r0.rgb, t3, c0 + +; dot eye-vector with per-pixel normal from t0 +dp3_sat r1, v0_bx2, t0_bx2 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +mul r1.rgb, r0, r0 ; color squared ++mul r0.a, 1-r1.a, 1-r1.a ; squared + +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color ++mul r0.a, r0.a, r0.a ; quartic + +dp3 r1.rgb, r0, c3 ; color greyscaled ++mul r0.a, r0.a, 1-r1.a ; quintic + +; FIXME - these should be able to pair (I think), but don't on nvidia for some reason. +; (I think) cannot pair due to use of >2 constants in single stage +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale +mad r0.a, r0.a, c6.a, c4.a ; Take Fresnel R(0) into consideration + +mul r0.rgb, r0, r0.a ; multiply output color by result of fresnel calc + +#if NORMALMAPALPHAENVMAPMASK ++mul r0.a, c0.a, t0.a ; Fade amount * alpha from the texture +#else ++mov r0.a, c0.a ; Just use the fade amount +#endif + + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh new file mode 100644 index 00000000..73769dce --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh @@ -0,0 +1,96 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Shader specific constant: +; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; Move it into the w component of the texture coords, as the wacky +; pixel shader wants it there. +mov oT1.w, $worldEyeVect.x +mov oT2.w, $worldEyeVect.y +mov oT3.w, $worldEyeVect.z + +alloc $tangentEyeVect + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal + +&FreeRegister( \$worldEyeVect ); + +&Normalize( $tangentEyeVect ); + +; stick the tangent space eye vector into oD0 +mad oD0.xyz, $tangentEyeVect, $cHalf, $cHalf + +&FreeRegister( \$tangentEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh new file mode 100644 index 00000000..2a4efc7d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh @@ -0,0 +1,72 @@ +; STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +ps.1.4 +;------------------------------------------------------------------------------ +; Phase 1 +;------------------------------------------------------------------------------ +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! +;mov r0.rgba, r4 + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +#if NORMALMAPALPHAENVMAPMASK +; Alpha gets lost after phase marker, so store it here +mov r5, r0.a +#endif + +;------------------------------------------------------------------------------ +; Phase 2 +;------------------------------------------------------------------------------ +; What's left over from the last phase: +; r0 - normal +; r1 - free +; r2 - vector to sample in envmap +; r3 - free +; r4 - normal +; r5 - normal map alpha (rgba) + +phase + +; Sample environment map +texld r3, r2 + +; dot eye-vector with per-pixel normal from r0 +dp3_sat r1, v0_bx2, r0_bx2 + +; Result goes in output color (multiply by constant color c0) +mul r0.rgb, r3, c0 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +mul r1.rgb, r0, r0 ++mul r0.a, 1-r1.a, 1-r1.a ; squared + +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color ++mul r0.a, r0.a, r0.a ; quartic + +dp3 r1.rgb, r0, c3 ++mul r0.a, r0.a, 1-r1.a ; quintic + +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale +mad r0.a, r0.a, c6.a, c4.a ; Take Fresnel R(0) into consideration + +mul r0.rgb, r0, r0.a ; multiply output color by result of fresnel calc + +#if NORMALMAPALPHAENVMAPMASK ++mul r0.a, c0.a, r5.r ; Fade amount * alpha from the texture +#else ++mov r0.a, c0.a ; Just use the fade amount +#endif diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh new file mode 100644 index 00000000..ea0f143a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh @@ -0,0 +1,92 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Shader specific constant: +; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; eye vector +mov oT4.xyz, $worldEyeVect + +alloc $tangentEyeVect + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal + +&FreeRegister( \$worldEyeVect ); + +&Normalize( $tangentEyeVect ); + +; stick the tangent space eye vector into oD0 +mad oD0.xyz, $tangentEyeVect, $cHalf, $cHalf + +&FreeRegister( \$tangentEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh new file mode 100644 index 00000000..9e55248e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh @@ -0,0 +1,79 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - Normalmap +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +; c0, c1, c2 - Axes of the lightmap coordinate system in tangent space +;------------------------------------------------------------------------------ + +; Get the 3-vector from the normal map +tex t0 + +; Sample the lightmaps +tex t1 +tex t2 +tex t3 + +; output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) + + +; r0 = ( N dot basis[0] ) +; don't "_sat" here so that everything adds up to one even if the normal is outside of the basis!!!!! +dp3 r0, t0_bx2, c0 + +; r1 = ( N dot basis[1] ) +dp3 r1, t0_bx2, c1 + +;---- +; r0 = ( N dot basis[0] ) +; r1 = ( N dot basis[1] ) +;---- + +; r0.rgb = ( N dot basis[0] )^2 +mul r0.rgb, r0, r0 + +; r1.a = ( N dot basis[1] )^2 ++mul r1.a, r1, r1 + +;---- +; r0.rgb = ( N dot basis[0] )^2 +; r1.a = ( N dot basis[1] )^2 +;---- + +mul t1, r0, t1 + +;---- +; r1.a = ( N dot basis[1] )^2 +; t1 = lightmapColor[0] * ( N dot basis[0] )^2 +;---- + +dp3 r0, t0_bx2, c2 + +;---- +; r1.a = ( N dot basis[1] )^2 +; t1 = lightmapColor[0] * ( N dot basis[0] )^2 +; r0 = ( N dot basis[2] ) +;---- + +mad t1.rgb, r1.a, t2, t1 ++mul r0.a, r0, r0 + +;---- +; t1.rgb = lightmapColor[0] * ( N dot basis[0] )^2 + lightmapColor[1] * ( N dot basis[1] )^2 +; r0.a = ( N dot basis[2] )^2 +;---- + +mad r0.rgba, r0.a, t3, t1 + +;---- +; r0.rgb = lightmapColor[0] * ( N dot basis[0] )^2 + +; lightmapColor[1] * ( N dot basis[1] )^2 + +; lightmapColor[2] * ( N dot basis[2] )^2 +;---- diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh new file mode 100644 index 00000000..229a839a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh @@ -0,0 +1,54 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +; Compute the texture coordinates given the offset between +; each bumped lightmap +&AllocateRegister( \$offset ); +mov $offset.xy, $vTexCoord2 +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +add oT1.xy, $offset, $vTexCoord1 +mad oT2.xy, $offset, $cTwo, $vTexCoord1 +; make a 3 +alloc $three +add $three, $cOne, $cTwo +mad oT3.xy, $offset, $three, $vTexCoord1 +free $three + +&FreeRegister( \$offset ); diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh new file mode 100644 index 00000000..39a25964 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - Normalmap +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; t4 - Base +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +; c0, c1, c2 - Axes of the lightmap coordinate system in tangent space +;------------------------------------------------------------------------------ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 + +; Sample the lightmaps +texld r1, t1 +texld r2, t2 +texld r3, t3 + +; Sample the base texture +texld r4, t4 + +; output = (lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) ) * base + +dp3 r5.r, r0_bx2, c0 +dp3 r5.g, r0_bx2, c1 +dp3 r5.b, r0_bx2, c2 +mul r5.rgb, r5, r5 +mul r1, r1, r5.r +mad r1, r2, r5.g, r1 +mad r1, r3, r5.g, r1 + +; assume overbright_2 !!! +mul_x2 r0, r1, r4 diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh new file mode 100644 index 00000000..a78d0851 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh @@ -0,0 +1,55 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +; Compute the texture coordinates given the offset between +; each bumped lightmap +&AllocateRegister( \$offset ); +mov $offset.xy, $vTexCoord2 +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +add oT1.xy, $offset, $vTexCoord1 +mad oT2.xy, $offset, $cTwo, $vTexCoord1 +alloc $three +add $three, $cOne, $cTwo +mad oT3.xy, $offset, $three, $vTexCoord1 +free $three +dp4 oT4.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT4.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + +&FreeRegister( \$offset ); diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh new file mode 100644 index 00000000..f17f14cf --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh @@ -0,0 +1,47 @@ +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - Normalmap +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; t4 - Base1 +; t5 - Base2 +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +; c0, c1, c2 - Axes of the lightmap coordinate system in tangent space +;------------------------------------------------------------------------------ +ps.1.4 + +; output = (lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) ) * lerp(base1, base2, lightmapColor[0].a) + +; Get the 3-vector from the normal map +texld r0, t0 + +dp3 r5.r, r0_bx2, c0 +dp3 r5.g, r0_bx2, c1 +dp3 r5.b, r0_bx2, c2 +mul r5.rgb, r5, r5 + +phase + +; Sample the lightmaps +texld r1, t1 +texld r2, t2 +texld r3, t3 + +; Sample the base textures +texld r4, t4 +texld r5, t5 + +mul r1, r1, r5.r +mad r1, r2, r5.g, r1 +mad r1, r3, r5.g, r1 + +; blend base textures +lrp r4, r4, r5, r1.a + +; assume overbright_2 !!! +mul_x2 r0, r1, r4 diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh new file mode 100644 index 00000000..7773d335 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh @@ -0,0 +1,57 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +; Compute the texture coordinates given the offset between +; each bumped lightmap +&AllocateRegister( \$offset ); +mov $offset.xy, $vTexCoord2 +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +add oT1.xy, $offset, $vTexCoord1 +mad oT2.xy, $offset, $cTwo, $vTexCoord1 +alloc $three +add $three, $cOne, $cTwo +mad oT3.xy, $offset, $three, $vTexCoord1 +free $three +dp4 oT4.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT4.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 +dp4 oT5.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT5.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + +&FreeRegister( \$offset ); diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.psh new file mode 100644 index 00000000..86e627e5 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.psh @@ -0,0 +1,47 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - decal texture +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +; c0, c1, c2 - ( ( N dot basis[0] )^2 ), ( ( N dot basis[1] )^2 ), ( ( N dot basis[2] )^2 ) +;------------------------------------------------------------------------------ + +; Get the decal color +tex t0 + +; Sample the lightmaps +tex t1 +tex t2 +tex t3 + +; output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) + + +; r0 = lightmapColor[0] * ( ( N dot basis[0] )^2 ) +mul r0, t1, c0 + +; r0 = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + lightmapColor[1] * ( ( N dot basis[1] )^2 ) +mad r0, t2, c1, r0 + +; r0 = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) +mad r0, t3, c2, r0 + +; Modulate by decal texture +mul r0.rgb, r0, t0 ++ mov r0.a, t0.a + +; Modulate by constant color +mul r0, r0, c3 + +; Modulate by per-vertex factor +mul r0, r0, v0 + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh new file mode 100644 index 00000000..a9db9faa --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh @@ -0,0 +1,56 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +; Compute the texture coordinates given the offset between +; each bumped lightmap +&AllocateRegister( \$offset ); +mov $offset.x, $vTexCoord2.x +mov $offset.y, $cZero +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +add oT1.xy, $offset, $vTexCoord1 +mad oT2.xy, $offset, $cTwo, $vTexCoord1 +; make a 3 +alloc $three +add $three, $cOne, $cTwo +mad oT3.xy, $offset, $three, $vTexCoord1 +free $three +mov oD0, $vColor + +&FreeRegister( \$offset ); diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_Detail.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_Detail.psh new file mode 100644 index 00000000..89b6c322 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_Detail.psh @@ -0,0 +1,18 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r1.rgb, r0, t2 ; detail texture +lrp r0.rgb, c2, r1, r0 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh new file mode 100644 index 00000000..a9129757 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh @@ -0,0 +1,16 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t1 +tex t2 +mul r0.rgb, t1, v0 + ; base times vertex color (with alpha) +mov r0.a, v0.a +mul_x2 r0.rgb, r0, t2 ; detail texture +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh new file mode 100644 index 00000000..a9e05150 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh @@ -0,0 +1,23 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r1.rgb, r0, t2 ; detail texture +lrp r0.rgb, c2, r1, r0 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, c1, t0 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lightmap diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh new file mode 100644 index 00000000..919da94c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t1 +tex t2 + +mov r0.rgb, v0 + ; vertex color +mul r0.a, v0.a, t2.a ; vertex alpha * envmap alpha + +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh new file mode 100644 index 00000000..f0205e86 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh new file mode 100644 index 00000000..5f740f86 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh @@ -0,0 +1,45 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform +; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform +; $SHADER_SPECIFIC_CONST_4 = Modulation color +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +; YUCK! This is to make texcoords continuous for mat_softwaretl +mov oT0, $cZero +; Texture coordinates +mov oT1, $vTexCoord1 + +mov oD0, $cOne + + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh new file mode 100644 index 00000000..30bd9f76 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh @@ -0,0 +1,6 @@ +ps.1.1 + +tex t1 + +mov r0.rgba, t1 + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh new file mode 100644 index 00000000..ee59d663 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh @@ -0,0 +1,24 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t1 +tex t2 +tex t3 + +mov r0.rgb, v0 ; vertex color +mul r1, t2, t3 ; envmap * envmapmask + +mad r0.rgb, r1, c2, r0 + ; + envmap * envmapmask * envmaptint (color only) +mul r0.a, v0.a, r1.a ; alpha = vertex alpha * envmap alpha * envmapmask alpha + +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh new file mode 100644 index 00000000..398ed46a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul r1, t2, t3 ; envmap * envmapmask +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh new file mode 100644 index 00000000..7944e730 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c2, 1.0f, 1.0f, 1.0f, 1.0f + +tex t0 +tex t1 + +; Blend between grey and lightmap color based on total alpha + +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mul_sat r1.a, t0, v0 ; base times vertex alpha +lrp r0, r1.a, r1, c2 ; interpolate between white + color diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh new file mode 100644 index 00000000..e0fb27b7 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c2, 1.0f, 1.0f, 1.0f, 1.0f + +tex t0 +tex t1 + +; Blend between grey and lightmap color based on total alpha + +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mov_sat r1.a, v0 ; vertex alpha +lrp r0, r1.a, r1, c2 ; interpolate between white + color diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh new file mode 100644 index 00000000..1282ecac --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh @@ -0,0 +1,23 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c2, 1.0f, 1.0f, 1.0f, 1.0f + +tex t0 +tex t1 + +; Blend between white and lightmap color based on total alpha +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mov_sat r1.a, v0 ; opacity == vertex opacity (no alpha in texture) + +lrp r0.rgb, t0.a, c1, r1 ; Blend between self-illum + lightmap ++ mov r0.a, c2.a + +lrp r0.rgb, r1.a, r0, c2 ; interpolate between white + color diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh new file mode 100644 index 00000000..f02de34b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh @@ -0,0 +1,14 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t1 +mul r0.rgb, t1, v0 + ; base times vertex color (with alpha) +mov r0.a, v0.a +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh new file mode 100644 index 00000000..bdcb7783 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh @@ -0,0 +1,34 @@ +ps.1.1 +def c0, 1,0,0,0 +def c1, 0,1,0,0 +def c2, 0,0,1,0 + +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - Normalmap +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +;------------------------------------------------------------------------------ + +; Get the 3-vector from the normal map +tex t0 + +; Sample the lightmaps +tex t1 +tex t2 +tex t3 + +; output = lightmapColor[0] * n.r + lightmapColor[1] * n.g + lightmapColor[2] * n.b + + +mov r0, t0 +dp3 r1, t0, c0 +mul r0.rgb, r1, t1 +dp3 r1, t0, c1 +mad r0.rgb, r1, t2, r0 +dp3 r1, t0, c2 +mad r0.rgb, r1, t3, r0 diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh new file mode 100644 index 00000000..cf800a2e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 + +mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, c1, t0 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lightmap diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh new file mode 100644 index 00000000..9fd0a1c5 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r1, t0.a, t0 ; Self illum +mad r1, c1, r1, t1 ; Self illum * tint + lightmap + +mul r0.rgb, r1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh new file mode 100644 index 00000000..1e62a416 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh @@ -0,0 +1,28 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0.rgb, t0, v0 + ; base times vertex color (with alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r1, c1, t0.a ; Self illum alpha * tint +mad r1, t0, r1, t1 ; Self illum * tint + lightmap +mul r0.rgb, r1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t2, t3 ; envmap * envmapmask +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) + diff --git a/mp/src/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh b/mp/src/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh new file mode 100644 index 00000000..a434a941 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh @@ -0,0 +1,15 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "LightmappedGeneric_inc.vsh" + +$detail = 0; +$envmap = 0; +$envmapcameraspace = 0; +$envmapsphere = 0; +$vertexcolor = 1; + +&LightmappedGeneric( $detail, $envmap, $envmapcameraspace, $envmapsphere, + $vertexcolor ); + diff --git a/mp/src/materialsystem/stdshaders/Refract_model_vs11.vsh b/mp/src/materialsystem/stdshaders/Refract_model_vs11.vsh new file mode 100644 index 00000000..a6eea2b7 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Refract_model_vs11.vsh @@ -0,0 +1,105 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; c0 = (0, 1, 2, 0.5) +; c1 = (1/2.2, 0, 0, 0) +; c2 = camera position *in world space* +; c4-c7 = modelViewProj matrix (transpose) +; c8-c11 = ViewProj matrix (transpose) +; c12-c15 = model->view matrix (transpose) +; c16 = [fogStart, fogEnd, fogRange, undefined] +; +; Vertex components (as specified in the vertex DECL) +; $vPos = Position +; $vTexCoord0.xy = TexCoord0 +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +; Vertex components +; $vPos = Position +; $vNormal = normal +; $vTexCoord0.xy = TexCoord0 +; $vTangentS = S axis of Texture space +; $vTangentT = T axis of Texture space + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +alloc $worldPos +alloc $worldNormal +alloc $worldTangentS +alloc $worldTangentT + +&SkinPositionNormalAndTangentSpace( $worldPos, $worldNormal, + $worldTangentS, $worldTangentT ); + +alloc $projPos + +; Transform position from world to projection space +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 + +&CalcFog( $worldPos, $projPos ); + +alloc $worldEyeVect + +; Get the eye vector in world space +add $worldEyeVect.xyz, -$worldPos, $cEyePos + +alloc $tangentEyeVect +; transform the eye vector to tangent space +dp3 oT3.x, $worldEyeVect, $worldTangentS +dp3 oT3.y, $worldEyeVect, $worldTangentT +dp3 oT3.z, $worldEyeVect, $worldNormal + +alloc $bumpTexCoord + +dp4 $bumpTexCoord.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 $bumpTexCoord.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + +; dudv map +mov oT0.xy, $bumpTexCoord + +; refract tint + alpha channel +mov oT2.xy, $bumpTexCoord +mov oT3.xy, $bumpTexCoord + +free $bumpTexCoord + +mov oPos, $projPos + +; special case perspective correct texture projection so that the texture fits exactly on the screen + +; flip Y by multiplying by -1 +mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_4.w + +; transform from [-w,w] to [0,2*w] +; The reason this is w is because we are in perspective space/homogenous clip space. +add $projPos.xy, $projPos.xy, $projPos.w + +; transform from [0,2*w] to [0,w] +; We'll end up dividing by w in the pixel shader to get to [0,1] +mul $projPos.xy, $projPos.xy, $cHalf + +mov oT1.xy, $projPos.xy + +; emit w to both z and w in case the driver screws up and divides by z +mov oT1.z, $projPos.w +mov oT1.w, $projPos.w + +free $projPos +free $worldPos +free $worldEyeVect +free $tangentEyeVect +free $w +free $worldNormal +free $worldTangentS +free $worldTangentT diff --git a/mp/src/materialsystem/stdshaders/Refract_ps11.psh b/mp/src/materialsystem/stdshaders/Refract_ps11.psh new file mode 100644 index 00000000..f3fe34d2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Refract_ps11.psh @@ -0,0 +1,36 @@ +; STATIC: "REFRACTTINTTEXTURE" "0..1" +; STATIC: "NORMALMAPALPHA" "0..1" + +ps.1.1 + +; t0: +; texture: dudv map +; texcoords: dudvmap texcoords +; t1: +; texture: refraction render target +; texcoords: + +tex t0 ; sample dudv map +texbem t1, t0 ; refraction + +#if REFRACTTINTTEXTURE +tex t2 +#endif + +#if NORMALMAPALPHA +tex t3 +#endif + +; refracttint +#if REFRACTTINTTEXTURE +mul_x2 r0, t1, t2 +#else +mov r0, t1 +#endif + +#if NORMALMAPALPHA +mul r0.rgb, r0, c0 + +mov r0.a, t3.a +#else +mul r0.rgb, r0, c0 +#endif diff --git a/mp/src/materialsystem/stdshaders/Refract_vs20.fxc b/mp/src/materialsystem/stdshaders/Refract_vs20.fxc new file mode 100644 index 00000000..698dd192 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Refract_vs20.fxc @@ -0,0 +1,140 @@ +//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "MODEL" "0..1" +// STATIC: "COLORMODULATE" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const bool g_bModel = MODEL ? true : false; + +const float4 cBumpTexCoordTransform[4] : register( SHADER_SPECIFIC_CONST_1 ); + +const float g_flTime : register( SHADER_SPECIFIC_CONST_5 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vBaseTexCoord : TEXCOORD0; +#if !MODEL + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL0; +#else + float4 vUserData : TANGENT; +#endif +#if COLORMODULATE + float4 vColor : COLOR0; +#endif +}; + +struct VS_OUTPUT +{ + float4 vProjPos_POSITION : POSITION; +#if !defined( _X360 ) + float vFog : FOG; +#endif + float4 vBumpTexCoord : TEXCOORD0; + float3 vTangentEyeVect : TEXCOORD1; + float3 vWorldNormal : TEXCOORD2; + float3 vWorldTangent : TEXCOORD3; + float3 vWorldBinormal : TEXCOORD4; + float3 vRefractXYW : TEXCOORD5; + float3 vWorldViewVector : TEXCOORD6; +#if COLORMODULATE + float4 vColor : COLOR0; +#endif + float4 fogFactorW : COLOR1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + +#if COLORMODULATE + o.vColor = v.vColor; +#endif + + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + + float3 vObjNormal; +#if MODEL + float4 vObjTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vObjNormal, vObjTangent ); + + SkinPositionNormalAndTangentSpace( + g_bSkinning, + v.vPos, vObjNormal, vObjTangent, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal, worldTangentS, worldTangentT ); +#else + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + worldPos = mul( v.vPos, cModel[0] ); + worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); +#endif + + // World normal + o.vWorldNormal.xyz = normalize( worldNormal.xyz ); + + // Projected position + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos_POSITION = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + //o.projNormal.xyz = mul( worldNormal, cViewProj ); + + // Map projected position to the refraction texture + float2 vRefractPos; + vRefractPos.x = vProjPos.x; + vRefractPos.y = -vProjPos.y; // invert Y + vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; + + // Refraction transform + o.vRefractXYW = float3(vRefractPos.x, vRefractPos.y, vProjPos.w); + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + o.fogFactorW = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE ); +#if !defined( _X360 ) + o.vFog = o.fogFactorW; +#endif + + // Eye vector + float3 vWorldEyeVect = normalize( cEyePos - vWorldPos ); + o.vWorldViewVector.xyz = -vWorldEyeVect.xyz; + + // Transform to the tangent space + o.vTangentEyeVect.x = dot( vWorldEyeVect, worldTangentS ); + o.vTangentEyeVect.y = dot( vWorldEyeVect, worldTangentT ); + o.vTangentEyeVect.z = dot( vWorldEyeVect, worldNormal ); + + // Tranform bump coordinates + o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); + o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); + + // Tranform bump coordinates (note wz, not zw) + o.vBumpTexCoord.w = dot( v.vBaseTexCoord, cBumpTexCoordTransform[2] ); + o.vBumpTexCoord.z = dot( v.vBaseTexCoord, cBumpTexCoordTransform[3] ); + + + // Tangent space transform + o.vWorldNormal.xyz = normalize( worldNormal.xyz ); + o.vWorldTangent.xyz = worldTangentS.xyz; + o.vWorldBinormal.xyz = worldTangentT.xyz; + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/Refract_world_vs11.vsh b/mp/src/materialsystem/stdshaders/Refract_world_vs11.vsh new file mode 100644 index 00000000..90f0debe --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Refract_world_vs11.vsh @@ -0,0 +1,168 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; c0 = (0, 1, 2, 0.5) +; c1 = (1/2.2, 0, 0, 0) +; c2 = camera position *in world space* +; c4-c7 = modelViewProj matrix (transpose) +; c8-c11 = ViewProj matrix (transpose) +; c12-c15 = model->view matrix (transpose) +; c16 = [fogStart, fogEnd, fogRange, undefined] +; +; Vertex components (as specified in the vertex DECL) +; $vPos = Position +; $vTexCoord0.xy = TexCoord0 +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +; Vertex components +; $vPos = Position +; $vNormal = normal +; $vTexCoord0.xy = TexCoord0 +; $vTangentS = S axis of Texture space +; $vTangentT = T axis of Texture space + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +alloc $worldPos +alloc $worldNormal +alloc $worldTangentS +alloc $worldTangentT +alloc $projPos + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +dp3 $worldPos.x, $vPos, $cModel0 +dp3 $worldPos.y, $vPos, $cModel1 +dp3 $worldPos.z, $vPos, $cModel2 + +dp3 $worldNormal.x, $vNormal, $cModel0 +dp3 $worldNormal.y, $vNormal, $cModel1 +dp3 $worldNormal.z, $vNormal, $cModel2 + +dp3 $worldTangentS.x, $vTangentS, $cModel0 +dp3 $worldTangentS.y, $vTangentS, $cModel1 +dp3 $worldTangentS.z, $vTangentS, $cModel2 + +dp3 $worldTangentT.x, $vTangentT, $cModel0 +dp3 $worldTangentT.y, $vTangentT, $cModel1 +dp3 $worldTangentT.z, $vTangentT, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +alloc $worldEyeVect + +; Get the eye vector in world space +add $worldEyeVect.xyz, -$worldPos, $cEyePos + +alloc $tangentEyeVect +alloc $bumpTexCoord + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $worldTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $worldTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $worldNormal + +&Normalize( $tangentEyeVect ); + +; stick the tangent space eye vector into oD0 +mad oD0.xyz, $tangentEyeVect, $cHalf, $cHalf + +dp4 $bumpTexCoord.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 $bumpTexCoord.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + +; dudv map +mov oT0.xy, $bumpTexCoord + +; refract tint +mov oT3.xy, $bumpTexCoord + +free $bumpTexCoord + +alloc $newProjPos +alloc $w + +mov oPos, $projPos + +; special case perspective correct texture projection so that the texture fits exactly on the screen +mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_4.w +add $projPos.xy, $projPos.xy, $projPos.w +mul $projPos.xy, $projPos.xy, $cHalf + +; Do the perspective divide here. .yuck . . we aren't going to be perspective correct +rcp $w.w, $projPos.w +mul $projPos, $projPos, $w.w + +#max $projPos.x, $projPos.x, -$cOne +#min $projPos.x, $projPos.x, $cOne +#max $projPos.z, $projPos.z, $cZero +#min $projPos.z, $projPos.z, $cOne + +;------------------------------------------------------------------------------ +; Transform the tangentS from world to view space +;------------------------------------------------------------------------------ + +alloc $projTangentS + +; we only care about x and y +dp3 $projTangentS.x, $worldTangentS, $cViewProj0 +dp3 $projTangentS.y, $worldTangentS, $cViewProj1 + +; project tangentS +mul $projTangentS.xy, $projTangentS.xy, $w.w + +;max $projTangentS.xy, $projTangentS.xy, $cOne +;min $projTangentS.xy, $projTangentS.xy, -$cOne + +;------------------------------------------------------------------------------ +; Transform the tangentT from world to view space +;------------------------------------------------------------------------------ + +alloc $projTangentT +alloc $texCoord + +; we only care about x and y +dp3 $projTangentT.x, $worldTangentT, $cViewProj0 +dp3 $projTangentT.y, $worldTangentT, $cViewProj1 + +; project tangentT +mul $projTangentT.xy, $projTangentT.xy, $w.w + +;max $projTangentT.xy, $projTangentT.xy, $cOne +;min $projTangentT.xy, $projTangentT.xy, -$cOne + +;max $projPos.xy, $projPos.xy, $cOne +;min $projPos.xy, $projPos.xy, -$cOne + +mul oT1.x, $projTangentS.x, $SHADER_SPECIFIC_CONST_3.x +mul oT1.y, $projTangentT.x, $SHADER_SPECIFIC_CONST_3.x +mov oT1.z, $projPos.x ; huh? + +mul $texCoord.x, $projTangentS.y, -$SHADER_SPECIFIC_CONST_3.x +mul $texCoord.y, $projTangentT.y, -$SHADER_SPECIFIC_CONST_3.x +mov $texCoord.z, $projPos.y +mov oT2.xyz, $texCoord +mov oT3.xyz, $texCoord + +free $texCoord +free $projPos +free $worldPos +free $worldEyeVect +free $tangentEyeVect +free $w +free $projTangentS +free $projTangentT +free $newProjPos +free $worldNormal +free $worldTangentS +free $worldTangentT diff --git a/mp/src/materialsystem/stdshaders/ShadowModel.psh b/mp/src/materialsystem/stdshaders/ShadowModel.psh new file mode 100644 index 00000000..a7514020 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/ShadowModel.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c0,1.0f, 1.0f, 1.0f, 1.0f + +tex t0 ; shadow color +texkill t1 ; Clip +texkill t2 +texkill t3 ; backface cull + +; Darkening equation, compute a color = (shadow color * shadow alpha + 1- shadow alpha) +;sub r1, t0, v0.a ; r1 = shadow alpha +lrp r0.rgb, t0.a, v0, c0 + ; r0.rgb = (shadow color * shadow alpha + 1 - shadow alpha) +mov r0.a, c0.a ; r0.a = 1 + diff --git a/mp/src/materialsystem/stdshaders/ShadowModel.vsh b/mp/src/materialsystem/stdshaders/ShadowModel.vsh new file mode 100644 index 00000000..3e4b9eba --- /dev/null +++ b/mp/src/materialsystem/stdshaders/ShadowModel.vsh @@ -0,0 +1,85 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_2 = Shadow texture matrix +; $SHADER_SPECIFIC_CONST_3 = Tex origin +; $SHADER_SPECIFIC_CONST_4 = Tex Scale +; $SHADER_SPECIFIC_CONST_5 = [Shadow falloff offset, 1/Shadow distance, Shadow scale, 0 ] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending (whacks r1-r7, positions in r7, normals in r8) +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&SkinPositionAndNormal( $worldPos, $worldNormal ); + +; Transform the position from world to view space +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Transform position into texture space (from 0 to 1) +;------------------------------------------------------------------------------ +&AllocateRegister( \$texturePos ); +dp4 $texturePos.x, $worldPos, $SHADER_SPECIFIC_CONST_0 +dp4 $texturePos.y, $worldPos, $SHADER_SPECIFIC_CONST_1 +dp4 $texturePos.z, $worldPos, $SHADER_SPECIFIC_CONST_2 +&FreeRegister( \$worldPos ); + +;------------------------------------------------------------------------------ +; Figure out the shadow fade amount +;------------------------------------------------------------------------------ +&AllocateRegister( \$shadowFade ); +sub $shadowFade, $texturePos.z, $SHADER_SPECIFIC_CONST_5.x +mul $shadowFade, $shadowFade, $SHADER_SPECIFIC_CONST_5.y + +;------------------------------------------------------------------------------ +; Offset it into the texture +;------------------------------------------------------------------------------ +&AllocateRegister( \$actualTextureCoord ); +mul $actualTextureCoord.xyz, $SHADER_SPECIFIC_CONST_4, $texturePos +add oT0.xyz, $actualTextureCoord, $SHADER_SPECIFIC_CONST_3 +;mov oT0.xyz, $texturePos +&FreeRegister( \$actualTextureCoord ); + +;------------------------------------------------------------------------------ +; We're doing clipping by using texkill +;------------------------------------------------------------------------------ +mov oT1.xyz, $texturePos ; also clips when shadow z < 0 ! +sub oT2.xyz, $cOne, $texturePos +sub oT2.z, $cOne, $shadowFade.z ; clips when shadow z > shadow distance +&FreeRegister( \$texturePos ); + +;------------------------------------------------------------------------------ +; We're doing backface culling by using texkill also (wow yucky) +;------------------------------------------------------------------------------ +; Transform z component of normal in texture space +; If it's negative, then don't draw the pixel +dp3 oT3, $worldNormal, -$SHADER_SPECIFIC_CONST_2 +&FreeRegister( \$worldNormal ); + +;------------------------------------------------------------------------------ +; Shadow color, falloff +;------------------------------------------------------------------------------ +mov oD0, $cModulationColor +mul oD0.w, $shadowFade.x, $SHADER_SPECIFIC_CONST_5.z +&FreeRegister( \$shadowFade ); + diff --git a/mp/src/materialsystem/stdshaders/Teeth.vsh b/mp/src/materialsystem/stdshaders/Teeth.vsh new file mode 100644 index 00000000..065f0703 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Teeth.vsh @@ -0,0 +1,97 @@ +vs.1.1 + +# STATIC: "INTRO" "0..1" +# STATIC: "HALF_LAMBERT" "0..1" +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "LIGHT_COMBO" "0..21" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0 = xyz = mouth forward direction vector, w = illum factor +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +$WARPPARAM = $SHADER_SPECIFIC_CONST_2; +$ENTITY_ORIGIN = $SHADER_SPECIFIC_CONST_3; + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +alloc $worldPos +alloc $worldNormal +&SkinPositionAndNormal( $worldPos, $worldNormal ); + +;------------------------------------------------------------------------------ +; Optional intro warping +;------------------------------------------------------------------------------ +if ( $INTRO == 1 ) +{ + alloc $tmp + sub $tmp.xyz, $worldPos, $ENTITY_ORIGIN + mul $tmp.xy, $tmp, $WARPPARAM + add $worldPos.xyz, $tmp, $ENTITY_ORIGIN + free $tmp +} + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +alloc $projPos + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +&CalcFog( $worldPos, $projPos ); + +free $projPos + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ +alloc $linearColor +&DoDynamicLightingToLinear( $worldPos, $worldNormal, $linearColor ); + +;------------------------------------------------------------------------------ +; Factor in teeth darkening factors +;------------------------------------------------------------------------------ + +alloc $tmp + +mul $linearColor.xyz, $SHADER_SPECIFIC_CONST_0.w, $linearColor ; FIXME Color darkened by illumination factor +dp3 $tmp, $worldNormal, $SHADER_SPECIFIC_CONST_0 ; Figure out mouth forward dot normal +max $tmp, $cZero, $tmp ; clamp from 0 to 1 +mul $linearColor.xyz, $tmp, $linearColor ; Darken by forward dot normal too + +;------------------------------------------------------------------------------ +; Output color (gamma correction) +;------------------------------------------------------------------------------ + +alloc $gammaColor +&LinearToGamma( $linearColor, $gammaColor ); +free $linearColor +mul oD0.xyz, $gammaColor.xyz, $cOverbrightFactor +mov oD0.w, $cOne ; make sure all components are defined + + +free $gammaColor +free $worldPos +free $worldNormal +free $tmp + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +mov oT0, $vTexCoord0 + + + diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric.psh new file mode 100644 index 00000000..53fab24d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric.psh @@ -0,0 +1,13 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color + +mul r0, t0, v0 \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh new file mode 100644 index 00000000..1ed9314e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0.rgb, t1, 1-t2.a ; can't use mad cause can't use 3 texture registers +mul r0.rgb, c2, r0 ; apply the envmaptint +mad r0.rgb, t0, v0, r0 ++ mul r0.a, t0, v0 diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_Detail.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_Detail.psh new file mode 100644 index 00000000..5fcb3f31 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_Detail.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t3 ; detail texture + +mul r0, t0, v0 +mul_x2 r0.rgb, r0, t3 \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh new file mode 100644 index 00000000..69693331 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh @@ -0,0 +1,29 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +;mul r0.rgb, t1, 1-t2.a ; can't use mad cause can't use 3 texture registers +;mul r0.rgb, c2, r0 ; apply the envmaptint +;mad r0.rgb, t0, v0, r0 +;+ mul r0.a, t0, v0 +;mul_x2 r0.rgb, r0, t3 ; mod2x detail texture + +; version 2: applies the mod2x *before* environment map +mul r0, t0, v0 ; Base times modulation color +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture +mul r1, t1, 1-t2.a ; Have to invert the alpha for basealpha (feh!) +mul r1, c2, r1 ; apply the envmaptint +add r0.rgb, r0, r1 ; add in the envmap diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh new file mode 100644 index 00000000..dab6efbb --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh @@ -0,0 +1,25 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +;mul r1, c2, t1 +;mad r0.rgb, t0, v0, r1 +;+ mul r0.a, t0, v0 +;mul_x2 r0.rgb, r0, t3 ; mod2x detail texture + +; version 2: applies the mod2x *before* environment map +mul r0, t0, v0 ; Base times modulation color +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture +mad r0.rgb, c2, t1, r0 ; add in tinted envmap diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh new file mode 100644 index 00000000..29411c9b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh @@ -0,0 +1,29 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +;mul r0.rgb, t1, t2 ; can't use mad cause can't use 3 texture registers +;mul r0.rgb, c2, r0 ; apply the envmaptint +;mad r0.rgb, t0, v0, r0 +;+ mul r0.a, t0, v0 +;mul_x2 r0.rgb, r0, t3 ; mod2x detail texture + +; version 2: applies the mod2x *before* environment map +mul r0, t0, v0 ; Base times modulation color +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture +mul r1, t1, t2 ; Envmap * envmapmask +mul r1, c2, r1 ; apply the envmaptint +add r0.rgb, r0, r1 ; add in the envmap diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh new file mode 100644 index 00000000..e8c6f3cb --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +; version 2 doesn't make sense here! +mul r0, t1, t2 +mul r0.rgb, c2, r0 +mul r0, r0, v0 +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh new file mode 100644 index 00000000..829849b9 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t1 ; cube map +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +; version 2 doesn't make sense here! +mul r0, v0, t1 +mul r0.rgb, r0, c2 +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh new file mode 100644 index 00000000..c79dc2ce --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh @@ -0,0 +1,10 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Just use the vertex color +;------------------------------------------------------------------------------ + +tex t3 + +mul_x2 r0.rgb, v0, t3 ++ mov r0.a, v0.a \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh new file mode 100644 index 00000000..9116997f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map + +mul r1, c2, t1 +mad r0.rgb, t0, v0, r1 ++ mul r0.a, t0, v0 diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh new file mode 100644 index 00000000..f8de572c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0.rgb, t1, t2 ; can't use mad cause can't use 3 texture registers +mul r0.rgb, c2, r0 ; apply the envmaptint +mad r0.rgb, t0, v0, r0 ++ mul r0.a, t0, v0 diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh new file mode 100644 index 00000000..a9bd7e46 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0, t1, t2 +mul r0.rgb, c2, r0 +mul r0, r0, v0 diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh new file mode 100644 index 00000000..966255fd --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t1 ; cube map + +mul r0, v0, t1 +mul r0.rgb, r0, c2 diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh b/mp/src/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh new file mode 100644 index 00000000..6361c811 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh @@ -0,0 +1,21 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +&AllocateRegister( \$worldPos ); +&SkinPosition( $worldPos ); + +; Transform the position from world to view space +dp4 oPos.x, $worldPos, $cViewProj0 +dp4 oPos.y, $worldPos, $cViewProj1 +dp4 oPos.z, $worldPos, $cViewProj2 +dp4 oPos.w, $worldPos, $cViewProj3 + +&FreeRegister( \$worldPos ); + +mov oD0, $cOne + + diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc b/mp/src/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc new file mode 100644 index 00000000..f46a7617 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc @@ -0,0 +1,20 @@ +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD3; +}; + +sampler BaseTextureSampler : register( s0 ); +sampler DetailTextureSampler : register( s3 ); + +float4 main( PS_INPUT i ) : COLOR +{ + // Sample frames from texture 0 + float4 base= tex2D( BaseTextureSampler, i.texCoord0 ); + float4 detail=tex2D( DetailTextureSampler, i.texCoord1 ); + + return float4(base.rgb, base.a * detail.a); +} diff --git a/mp/src/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh b/mp/src/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh new file mode 100644 index 00000000..feb29ba6 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh @@ -0,0 +1,7 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Just use the vertex color +;------------------------------------------------------------------------------ + +mov r0, v0 diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric.psh new file mode 100644 index 00000000..9824a915 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric.psh @@ -0,0 +1,13 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 + +mul r0, t0, c3 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh new file mode 100644 index 00000000..1844c402 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh @@ -0,0 +1,17 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif + diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh new file mode 100644 index 00000000..f719821b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh @@ -0,0 +1,17 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 + +mul r0, c3, t0 +lrp r0.rgb, c1, c3, r0 +lrp r0.rgb, t0.a, r0, t0 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#else ++mov r0.a, c3 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail.psh new file mode 100644 index 00000000..f42d54ac --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail.psh @@ -0,0 +1,16 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +mul r0, t0, c3 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r1.rgb, r0, t3 ; detail texture +lrp r0.rgb, c1, r1, r0 + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh new file mode 100644 index 00000000..09bf59ca --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh @@ -0,0 +1,18 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r0.rgb, r0, t3 ; detail texture +mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh new file mode 100644 index 00000000..12b2295c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh @@ -0,0 +1,16 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t3 ; detail texture + +mul r0, t0, c3 ; base times modulation +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r0.rgb, r0, t3 ; detail texture +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh new file mode 100644 index 00000000..ec35a8ba --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh @@ -0,0 +1,18 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, t2 ; Envmap * mask +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r0.rgb, r0, t3 ; detail texture +mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh new file mode 100644 index 00000000..d75a2790 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh @@ -0,0 +1,12 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t3 + +mul r0, v0, c3 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r0.rgb, r0, t3 ; detail texture + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh new file mode 100644 index 00000000..4b80e91b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh @@ -0,0 +1,22 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +; interpolate between illuminated + non-selfilluminated +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +#if WRITEONETODESTALPHA +mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh new file mode 100644 index 00000000..e625791a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh @@ -0,0 +1,24 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t1 +tex t3 + +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh new file mode 100644 index 00000000..119633a9 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh @@ -0,0 +1,26 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 ; base +tex t1 ; env map +tex t2 ; mask +tex t3 ; detail + +mul r0.rgb, t0, c3 + ; base times modulation +mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +mul r1, t2, t1 ; envmapmask * envmap +mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh new file mode 100644 index 00000000..7a9ce740 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh @@ -0,0 +1,15 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +lrp r0, c1, t3, t0 ; Lerp between textures +mul r0, r0, c3 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh new file mode 100644 index 00000000..64501f74 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh @@ -0,0 +1,15 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +mul r1, c1, t3 +mad r0, t0, c3, r1 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh new file mode 100644 index 00000000..07f9d387 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh @@ -0,0 +1,15 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +mul r0, c3, t0 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, c1, t3, r0 + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh new file mode 100644 index 00000000..4ce3caca --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh @@ -0,0 +1,14 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t1 ; cube map + +mul r0.rgb, t1, c2 + ; envmap * envmaptint (color only) + +mov r0.a, c3.a ; Use alpha from modulation... (?) + +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh new file mode 100644 index 00000000..80ef4330 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh @@ -0,0 +1,14 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map + +mul r0, t0, c3 ; base times modulation +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh new file mode 100644 index 00000000..e6b0c6e4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh @@ -0,0 +1,36 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Environment mapping on a bumped surface +; t0 - Normalmap +; t3 - Cube environment map (*must* be a cube map!) +; +; c0 - color to multiply the results by +; Input texture coords required here are a little wonky. +; tc0.uv <- U,V into the normal map +; tc1.uvw, tc2.uvw, tc3.uvw <- 3x3 matrix transform +; from tangent space->env map space +; tc1.q, tc2.q, tc3.q <- eye vector in env map space +;------------------------------------------------------------------------------ +; This version doesn't multiply by lighting. + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +; result goes in output color +mul r0.rgb, t3, c0 ; constant color ++mov r0.a, c0.a + +mul r1.rgb, r0, r0 +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color +dp3 r1.rgb, r0, c3 +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale + + diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh new file mode 100644 index 00000000..9fa7db3e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh @@ -0,0 +1,42 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Environment mapping on a bumped surface +; t0 - Normalmap +; t3 - Cube environment map (*must* be a cube map!) +; +; c0 - color to multiply the results by +; Input texture coords required here are a little wonky. +; tc0.uv <- U,V into the normal map +; tc1.uvw, tc2.uvw, tc3.uvw <- 3x3 matrix transform +; from tangent space->env map space +; tc1.q, tc2.q, tc3.q <- eye vector in env map space +;------------------------------------------------------------------------------ +; This version doesn't multiply by lighting. + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +; result goes in output color +mul r0.rgb, t3, c0 ; constant color ++mov r0.a, c0.a + +mul r1.rgb, r0, r0 +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color +dp3 r1.rgb, r0, c3 +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale + +; Multiply the output color by the alpha channel of the normal map. +mul r0.rgb, t0.a, r0 + + + + + diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh new file mode 100644 index 00000000..eac900c9 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh @@ -0,0 +1,42 @@ +ps.1.4 +;------------------------------------------------------------------------------ +; Phase 1 +;------------------------------------------------------------------------------ +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! +;mov r0.rgba, r4 + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) +; Alpha gets lost after phase marker, so store it here +mov r5, r0.a +;------------------------------------------------------------------------------ +; Phase 2 +;------------------------------------------------------------------------------ +phase +; Sample environment map +texld r3, r2 +; Result goes in output color (multiply by constant color c0) +mul r0.rgb, r3, c0 ++mov r0.a, c0.a + +mul r1.rgb, r0, r0 +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color +dp3 r1.rgb, r0, c3 +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale + +; mult by alpha +mul r0.rgb, r0, r5 diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh new file mode 100644 index 00000000..7c88013f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh @@ -0,0 +1,39 @@ +ps.1.4 +;------------------------------------------------------------------------------ +; Phase 1 +;------------------------------------------------------------------------------ +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) +; Alpha gets lost after phase marker, so store it here +mov r5, r0.a +;------------------------------------------------------------------------------ +; Phase 2 +;------------------------------------------------------------------------------ +phase +; Sample environment map +texld r3, r2 +; Result goes in output color (multiply by constant color c0) +mul r0.rgb, r3, c0 ++mov r0.a, c0.a + +mul r1.rgb, r0, r0 +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color +dp3 r1.rgb, r0, c3 +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale + diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh new file mode 100644 index 00000000..576e31cf --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh @@ -0,0 +1,93 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; Shader specific constant: +; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$worldTangentS ); +&AllocateRegister( \$worldTangentT ); + +&SkinPositionNormalAndTangentSpace( $worldPos, $worldNormal, + $worldTangentS, $worldTangentT ); + +;------------------------------------------------------------------------------ +; Transform the position from world to proj space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +; svect +mov oT1.x, $worldTangentS.x +mov oT2.x, $worldTangentS.y +mov oT3.x, $worldTangentS.z +&FreeRegister( \$worldTangentS ); + +; tvect +mov oT1.y, $worldTangentT.x +mov oT2.y, $worldTangentT.y +mov oT3.y, $worldTangentT.z +&FreeRegister( \$worldTangentT ); + +; normal +mov oT1.z, $worldNormal.x +mov oT2.z, $worldNormal.y +mov oT3.z, $worldNormal.z + +&FreeRegister( \$worldNormal ); + +; Compute the vector from vertex to camera +&AllocateRegister( \$eyeVector ); +sub $eyeVector.xyz, $cEyePos, $worldPos + +&FreeRegister( \$worldPos ); + +; Move it into the w component of the texture coords, as the wacky +; pixel shader wants it there. +mov oT1.w, $eyeVector.x +mov oT2.w, $eyeVector.y +mov oT3.w, $eyeVector.z + +&FreeRegister( \$eyeVector ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + + diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh new file mode 100644 index 00000000..2ac66164 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh @@ -0,0 +1,90 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; Shader specific constant: +; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$worldTangentS ); +&AllocateRegister( \$worldTangentT ); + +&SkinPositionNormalAndTangentSpace( $worldPos, $worldNormal, + $worldTangentS, $worldTangentT ); + +;------------------------------------------------------------------------------ +; Transform the position from world to proj space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +; svect +mov oT1.x, $worldTangentS.x +mov oT2.x, $worldTangentS.y +mov oT3.x, $worldTangentS.z +&FreeRegister( \$worldTangentS ); + +; tvect +mov oT1.y, $worldTangentT.x +mov oT2.y, $worldTangentT.y +mov oT3.y, $worldTangentT.z +&FreeRegister( \$worldTangentT ); + +; normal +mov oT1.z, $worldNormal.x +mov oT2.z, $worldNormal.y +mov oT3.z, $worldNormal.z + +&FreeRegister( \$worldNormal ); + +; Compute the vector from vertex to camera +&AllocateRegister( \$eyeVector ); +sub $eyeVector.xyz, $cEyePos, $worldPos + +&FreeRegister( \$worldPos ); + +; eye vector +mov oT4.xyz, $eyeVector + +&FreeRegister( \$eyeVector ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + + diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh new file mode 100644 index 00000000..4c65d906 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh @@ -0,0 +1,15 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t1 ; cube map +tex t2 ; envmap mask + +mul r1, t1, t2 ; Envmap * mask +mul r0.rgb, r1, c2 ; envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 + ; * 2 * (overbrightFactor/2) +mul r0.a, c3.a, t2.a ; alpha = modulation * mask alpha + +#if WRITEONETODESTALPHA +mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh new file mode 100644 index 00000000..ffa3f1e0 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh @@ -0,0 +1,16 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, t2 ; Envmap * mask +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh new file mode 100644 index 00000000..b98b9396 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh @@ -0,0 +1,9 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +mul r0, v0, c3 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh new file mode 100644 index 00000000..86710123 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh @@ -0,0 +1,5 @@ +ps.1.1 + +tex t0 + +mul r0.rgba, c0, t0 diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh new file mode 100644 index 00000000..40eb8d28 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh @@ -0,0 +1,41 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&SkinPosition( $worldPos ); + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +&CalcFog( $worldPos, $projPos ); +&FreeRegister( \$projPos ); +&FreeRegister( \$worldPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh new file mode 100644 index 00000000..c837e9af --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh @@ -0,0 +1,19 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 + +; interpolate between illuminated + non-selfilluminated +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh new file mode 100644 index 00000000..2d280f5c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh @@ -0,0 +1,21 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t1 + +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh new file mode 100644 index 00000000..da6b77c3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh @@ -0,0 +1,23 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 ; base +tex t1 ; env map +tex t2 ; mask + +mul r0.rgb, t0, c3 + ; base times modulation +mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +mul r1, t2, t1 ; envmapmask * envmap +mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/mp/src/materialsystem/stdshaders/VertexLitTexture.psh b/mp/src/materialsystem/stdshaders/VertexLitTexture.psh new file mode 100644 index 00000000..7a692c92 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitTexture.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 + +mul r0, t0, v0 + diff --git a/mp/src/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh b/mp/src/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh new file mode 100644 index 00000000..a69250bf --- /dev/null +++ b/mp/src/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh @@ -0,0 +1,16 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 + +mul_x2 r0.rgb, t0, v0 ++ mul r0.a, t0, v0 + diff --git a/mp/src/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh b/mp/src/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh new file mode 100644 index 00000000..08438dcb --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh @@ -0,0 +1,40 @@ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +phase + +; Sample environment map +texld r3, r2 +texld r4, t5 ; Normalize the tangent-space eye vector + +; dot eye-vector with per-pixel normal from r0 +dp3_sat r1, r4_bx2, r0_bx2 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +mul r0.a, 1-r1.a, 1-r1.a ; squared +mul r0.a, r0.a, r0.a ; quartic +mul_sat r1.a, r0.a, 1-r1.a ; quintic + +; multiply color by reflecttint +mul r0, r3, c1 + +; blend between reflected color and fog color based on fresnel +lrp r0.rgb, r1.a, r0, c0 \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh b/mp/src/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh new file mode 100644 index 00000000..5ebb39f4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh @@ -0,0 +1,39 @@ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +phase + +; Sample environment map +texld r3, r2 +texld r4, t5 ; Normalize the tangent-space eye vector + +; dot eye-vector with per-pixel normal from r0 +dp3_sat r1, r4_bx2, r0_bx2 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +mul r0.a, 1-r1.a, 1-r1.a ; squared +mul r0.a, r0.a, r0.a ; quartic +mul_sat r1.a, r0.a, 1-r1.a ; quintic + +; multiply color by reflecttint +mul r0.rgb, r3, c1 ++mov_sat r0.a, v0.a +add_sat r0.a, r1.a, r0.a diff --git a/mp/src/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh b/mp/src/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh new file mode 100644 index 00000000..60502016 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh @@ -0,0 +1,19 @@ +ps.1.1 + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +mul r0, t3, c1 ; multiply color by reflecttint +lrp r0.rgb, c1.a, r0, c0 ; blend between reflected color and fog color based on constant factor + + + + + diff --git a/mp/src/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh b/mp/src/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh new file mode 100644 index 00000000..fe76d772 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh @@ -0,0 +1,18 @@ +ps.1.1 + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +mul r0.rgb, t3, c1 ; multiply color by reflecttint ++mov_sat r0.a, v0.a ; NOTE: This is necessary since v0.a can be outside 0 - 1! +add_sat r0.a, c1.a, r0.a ; cheap water blend factor + constant blend factor + + + diff --git a/mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh b/mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh new file mode 100644 index 00000000..50d7f803 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh @@ -0,0 +1,26 @@ +ps.1.1 + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +mul r0, t3, c1 ; envmap color * envmaptint + +dp3_sat t2, v0_bx2, t0_bx2 ; dot eye-vector with per-pixel normal from t0 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +; NOTE: This is not perspective-correct and results in strange artifacts +mul r1.a, 1-t2.a, 1-t2.a ; squared +mul r1.a, r1.a, r1.a ; quartic +mul_sat r1.a, r1.a, 1-t2.a ; quintic + +; t1.a is now the fresnel factor +lrp r0.rgb, r1.a, r0, c0 ; blend between reflected color and fog color based on fresnel + + diff --git a/mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh b/mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh new file mode 100644 index 00000000..bd491d58 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh @@ -0,0 +1,31 @@ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +phase + +; Sample environment map +texld r3, r2 + +; multiply color by reflecttint +mul r0, r3, c1 + +; blend between reflected color and fog color based on constant factor +lrp r0.rgb, c1.a, r0, c0 diff --git a/mp/src/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh b/mp/src/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh new file mode 100644 index 00000000..6ca504cf --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh @@ -0,0 +1,100 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; Move it into the w component of the texture coords, as the wacky +; pixel shader wants it there. +mov oT1.w, $worldEyeVect.x +mov oT2.w, $worldEyeVect.y +mov oT3.w, $worldEyeVect.z + +&AllocateRegister( \$tangentEyeVect ); + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal + +&Normalize( $tangentEyeVect ); +mov oD0.xyz, $tangentEyeVect + +&FreeRegister( \$tangentEyeVect ); + +; Get the magnitude of worldEyeVect +dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect +rsq $worldEyeVect.w, $worldEyeVect.w +rcp $worldEyeVect.w, $worldEyeVect.w + +; calculate the cheap water blend factor and stick it into oD0.a +; NOTE: This won't be perspective correct!!!!! +; OPTIMIZE: This could turn into a mad. +add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_2.x +mul oD0.w, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_2.y + +&FreeRegister( \$worldEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/mp/src/materialsystem/stdshaders/WaterCheap_ps11.psh b/mp/src/materialsystem/stdshaders/WaterCheap_ps11.psh new file mode 100644 index 00000000..34178d28 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheap_ps11.psh @@ -0,0 +1,26 @@ +ps.1.1 + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +mul r0.rgb, t3, c1 ; envmap color * envmaptint ++mov_sat r0.a, v0.a ; Put the cheap water blend factor here + +dp3_sat t2, v0_bx2, t0_bx2 ; dot eye-vector with per-pixel normal from t0 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +; NOTE: This is not perspective-correct and results in strange artifacts +mul r1.a, 1-t2.a, 1-t2.a ; squared +mul r1.a, r1.a, r1.a ; quartic +mul_sat r1.a, r1.a, 1-t2.a ; quintic + +; t1.a is now the fresnel factor +add_sat r0.a, r1.a, r0.a ; Now we have the final blend factor between cheap water + refraction + diff --git a/mp/src/materialsystem/stdshaders/WaterCheap_ps14.psh b/mp/src/materialsystem/stdshaders/WaterCheap_ps14.psh new file mode 100644 index 00000000..2c452539 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheap_ps14.psh @@ -0,0 +1,30 @@ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +phase + +; Sample environment map +texld r3, r2 + +; multiply color by reflecttint +mul r0.rgb, r3, c1 ++mov_sat r0.a, v0.a ; Necessary since v0.a may be negative +add_sat r0.a, c1.a, r0.a diff --git a/mp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc b/mp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc new file mode 100644 index 00000000..4ca66570 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc @@ -0,0 +1,152 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "MULTITEXTURE" "0..1" +// STATIC: "FRESNEL" "0..1" +// STATIC: "BLEND" "0..1" +// STATIC: "REFRACTALPHA" "0..1" +// STATIC: "HDRTYPE" "0..2" +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] + +// DYNAMIC: "HDRENABLED" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" + +const HALF3 g_WaterFogColor : register( c0 ); +const HALF4 g_CheapWaterParams : register( c1 ); +const HALF4 g_ReflectTint : register( c2 ); +const float4 g_PixelFogParams : register( c3 ); + +#define g_CheapWaterStart g_CheapWaterParams.x +#define g_CheapWaterEnd g_CheapWaterParams.y +#define g_CheapWaterDeltaRecip g_CheapWaterParams.z +#define g_CheapWaterStartDivDelta g_CheapWaterParams.w + +sampler EnvmapSampler : register( s0 ); +sampler NormalMapSampler : register( s1 ); +#if REFRACTALPHA +sampler RefractSampler : register( s2 ); +#endif +sampler NormalizeSampler : register( s6 ); + +struct PS_INPUT +{ + float2 normalMapTexCoord : TEXCOORD0; + HALF3 worldSpaceEyeVect : TEXCOORD1; + HALF3x3 tangentSpaceTranspose : TEXCOORD2; + float4 vRefract_W_ProjZ : TEXCOORD5; + +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bBlend = BLEND ? true : false; + +#if MULTITEXTURE + float3 vNormal = tex2D( NormalMapSampler, i.normalMapTexCoord ); + float3 vNormal1 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.xy ); + float3 vNormal2 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.zw ); + vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 ); + +#if ( NORMAL_DECODE_MODE == NORM_DECODE_ATI2N ) + vNormal.xy = vNormal.xy * 2.0f - 1.0f; + vNormal.z = sqrt( 1.0f - dot(vNormal.xy, vNormal.xy) ); +#else + vNormal = 2.0 * vNormal - 1.0; +#endif + +#else + float3 vNormal = DecompressNormal( NormalMapSampler, i.normalMapTexCoord, NORMAL_DECODE_MODE ); +#endif + + HALF3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); + HALF3 worldSpaceEye; + + HALF flWorldSpaceDist = 1.0f; + +#ifdef NV3X + // for some reason, fxc doesn't convert length( half3 v ) into all _pp opcodes. + if (bBlend) + { + worldSpaceEye = i.worldSpaceEyeVect; + HALF worldSpaceDistSqr = dot( worldSpaceEye, worldSpaceEye ); + HALF rcpWorldSpaceDist = rsqrt( worldSpaceDistSqr ); + worldSpaceEye *= rcpWorldSpaceDist; + flWorldSpaceDist = worldSpaceDistSqr * rcpWorldSpaceDist; + } + else + { + worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); + } +#else // !NV3X + if (bBlend) + { + worldSpaceEye = i.worldSpaceEyeVect; + flWorldSpaceDist = length( worldSpaceEye ); + worldSpaceEye /= flWorldSpaceDist; + } + else + { + worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); + } +#endif + + HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldSpaceEye ); + HALF3 specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= g_ReflectTint; + +#if FRESNEL + // FIXME: It's unclear that we want to do this for cheap water + // but the code did this previously and I didn't want to change it + HALF flDotResult = dot( worldSpaceEye, worldSpaceNormal ); + flDotResult = 1.0f - max( 0.0f, flDotResult ); + + HALF flFresnelFactor = flDotResult * flDotResult; + flFresnelFactor *= flFresnelFactor; + flFresnelFactor *= flDotResult; +#else + HALF flFresnelFactor = g_ReflectTint.a; +#endif + + HALF flAlpha; + if (bBlend) + { + HALF flReflectAmount = saturate( flWorldSpaceDist * g_CheapWaterDeltaRecip - g_CheapWaterStartDivDelta ); + flAlpha = saturate( flFresnelFactor + flReflectAmount ); + +#if REFRACTALPHA + // Perform division by W only once + float ooW = 1.0f / i.vRefract_W_ProjZ.z; + float2 unwarpedRefractTexCoord = i.vRefract_W_ProjZ * ooW; + float fogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a; + // Fade on the border between the water and land. + flAlpha *= saturate( ( fogDepthValue - .05f ) * 20.0f ); +#endif + } + else + { + flAlpha = 1.0f; +#if HDRTYPE == 0 || HDRENABLED == 0 + specularLighting = lerp( g_WaterFogColor, specularLighting, flFresnelFactor ); +#else + specularLighting = lerp( GammaToLinear( g_WaterFogColor ), specularLighting, flFresnelFactor ); +#endif + } + + // multiply the color by alpha.since we are using alpha blending to blend against dest alpha for borders. + + + +#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE) + float fogFactor = CalcRangeFog( i.vRefract_W_ProjZ.w, g_PixelFogParams.x, g_PixelFogParams.z, g_PixelFogParams.w ); +#else + float fogFactor = 0; +#endif + + return FinalOutput( float4( specularLighting, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} diff --git a/mp/src/materialsystem/stdshaders/WaterCheap_vs11.vsh b/mp/src/materialsystem/stdshaders/WaterCheap_vs11.vsh new file mode 100644 index 00000000..b1cdd61f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheap_vs11.vsh @@ -0,0 +1,88 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; Move it into the w component of the texture coords, as the wacky +; pixel shader wants it there. +mov oT1.w, $worldEyeVect.x +mov oT2.w, $worldEyeVect.y +mov oT3.w, $worldEyeVect.z + +; Get the magnitude of worldEyeVect +dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect +rsq $worldEyeVect.w, $worldEyeVect.w +rcp $worldEyeVect.w, $worldEyeVect.w + +; calculate the cheap water blend factor and stick it into oD0.a +; NOTE: This won't be perspective correct!!!!! +; OPTIMIZE: This could turn into a mad. +add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_2.x +mul oD0, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_2.y + +&FreeRegister( \$worldEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/mp/src/materialsystem/stdshaders/WaterCheap_vs14.vsh b/mp/src/materialsystem/stdshaders/WaterCheap_vs14.vsh new file mode 100644 index 00000000..0e5a1074 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheap_vs14.vsh @@ -0,0 +1,96 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; eye vector +mov oT4.xyz, $worldEyeVect + +alloc $tangentEyeVect + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal + +; Get the magnitude of worldEyeVect +dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect +rsq $worldEyeVect.w, $worldEyeVect.w +rcp $worldEyeVect.w, $worldEyeVect.w + +; calculate the cheap water blend factor and stick it into oD0.a +; NOTE: This won't be perspective correct!!!!! +; OPTIMIZE: This could turn into a mad. +add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_2.x +mul oD0, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_2.y + +; stick the tangent space eye vector into oT5.xyz +mov oT5.xyz, $tangentEyeVect + +&FreeRegister( \$worldEyeVect ); +&FreeRegister( \$tangentEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/mp/src/materialsystem/stdshaders/WaterCheap_vs20.fxc b/mp/src/materialsystem/stdshaders/WaterCheap_vs20.fxc new file mode 100644 index 00000000..bae02380 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterCheap_vs20.fxc @@ -0,0 +1,84 @@ +// STATIC: "BLEND" "0..1" +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vNormal : NORMAL; + float2 vNormalMapCoord : TEXCOORD0; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 normalMapTexCoord : TEXCOORD0; + float3 worldVertToEyeVector : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + float4 vRefract_W_ProjZ : TEXCOORD5; + float4 vExtraBumpTexCoord : TEXCOORD6; + float4 fogFactorW : COLOR1; +}; + +const float4 cNormalMapTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 ); + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float4 projPos; + float3 worldPos; + + projPos = mul( v.vPos, cModelViewProj ); + o.projPos = projPos; + +#if BLEND + // Map projected position to the reflection texture + o.vRefract_W_ProjZ.x = projPos.x; + o.vRefract_W_ProjZ.y = -projPos.y; // invert Y + o.vRefract_W_ProjZ.xy = (o.vRefract_W_ProjZ + projPos.w) * 0.5f; + o.vRefract_W_ProjZ.z = projPos.w; +#endif + + o.vRefract_W_ProjZ.w = projPos.z; + + worldPos = mul( v.vPos, cModel[0] ); + + float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + o.tangentSpaceTranspose[0] = worldTangentS; + o.tangentSpaceTranspose[1] = worldTangentT; + o.tangentSpaceTranspose[2] = worldNormal; + + float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + o.worldVertToEyeVector = worldVertToEyeVector; + + // FIXME: need to add a normalMapTransform to all of the water shaders. + //o.normalMapTexCoord.x = dot( v.vNormalMapCoord, cNormalMapTransform[0] ) + cNormalMapTransform[0].w; + //o.normalMapTexCoord.y = dot( v.vNormalMapCoord, cNormalMapTransform[1] ) + cNormalMapTransform[1].w; + o.normalMapTexCoord = v.vNormalMapCoord; + + float f45x=v.vNormalMapCoord.x+v.vNormalMapCoord.y; + float f45y=v.vNormalMapCoord.y-v.vNormalMapCoord.x; + o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x; + o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y; + o.vExtraBumpTexCoord.z=v.vNormalMapCoord.y*0.45+TexOffsets.z; + o.vExtraBumpTexCoord.w=v.vNormalMapCoord.x*0.45+TexOffsets.w; + + o.fogFactorW = CalcFog( worldPos, projPos, FOGTYPE_RANGE ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/WaterReflect_ps11.psh b/mp/src/materialsystem/stdshaders/WaterReflect_ps11.psh new file mode 100644 index 00000000..d31ab49c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterReflect_ps11.psh @@ -0,0 +1,27 @@ +ps.1.1 + +; t0: +; texture: dudv map +; texcoords: dudvmap texcoords +; t1: +; texture: reflection render target +; texcoords: +; t2: +; texture: normal map (usef for fresnel calculation) +; texcoords: +; t4: texture: normalization cube map +; texcoords: eye vect + +tex t0 ; sample dudv map +texbem t1, t0 ; reflection +tex t2 ; normal map +tex t3 ; eye vector (through normalization cubemap) + +; dot eye-vector with per-pixel normal from t2 +dp3_sat r1.rgba, t3_bx2, t2_bx2 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 +mul r0.a, 1-r1.a, 1-r1.a // squared +mul r0.a, r0.a, r0.a // quartic +mul r0.rgb, t1, c0 // shove color from reflection render target into r0 ++mul_sat r0.a, r0.a, 1-r1.a // quintic \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh b/mp/src/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh new file mode 100644 index 00000000..88d1f8dc --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh @@ -0,0 +1,24 @@ +ps.1.1 + +; t0: +; texture: dudv map +; texcoords: dudvmap texcoords +; t1: +; texture: refraction render target +; texcoords: + +tex t0 ; sample dudv map +texbem t1, t0 ; refraction +tex t2 ; The normal map +tex t3 ; Normalize the tangent-space vector to the eye + +; dot eye-vector with per-pixel normal from t2 +dp3_sat r1.rgba, t2_bx2, t3_bx2 + +mul r0.a, 1-r1.a, 1-r1.a ; squared +mul r0.a, r0.a, r0.a ; quartic + +mul r0.rgb, t1, c0 ++mul_sat r0.a, r0.a, 1-r1.a ; quintic + +add_sat r0.a, r0.a, v0.a ; cheap water distance diff --git a/mp/src/materialsystem/stdshaders/WaterRefract_ps11.psh b/mp/src/materialsystem/stdshaders/WaterRefract_ps11.psh new file mode 100644 index 00000000..7e3ee733 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WaterRefract_ps11.psh @@ -0,0 +1,13 @@ +ps.1.1 + +; t0: +; texture: dudv map +; texcoords: dudvmap texcoords +; t1: +; texture: refraction render target +; texcoords: + +tex t0 ; sample dudv map +texbem t1, t0 ; refraction + +mul r0, t1, c0 diff --git a/mp/src/materialsystem/stdshaders/Water_ps14.psh b/mp/src/materialsystem/stdshaders/Water_ps14.psh new file mode 100644 index 00000000..e9daecd1 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Water_ps14.psh @@ -0,0 +1,96 @@ +; STATIC: "REFLECT" "0..1" +; STATIC: "REFRACT" "0..1" +ps.1.4 +; T2 - refraction +; T3 - normal map +; T4 - reflection +; TC0 - normal map coords +; TC1 - proj tex coords (reflection) +; TC2 - proj tex coords (refraction) +; TC3 - tangent space view vec +; TC4 - displacement scale + +; sample normal map +texld r3, t0 + +#if REFLECT +; reflection coords +texcrd r4.xy, t1_dw.xyw +#endif +#if REFRACT +; refraction coords +texcrd r2.xy, t2_dw.xyw +#endif +; tangent space eye vector +texld r1, t5 ; <---- Normalizing CUBE MAP here!!! +; reflection/refraction scale (x,y) +texcrd r0.xyz, t4.xyz + +; perturb coords by constant displacement +; and by normal map alpha (which has 1/(2**miplevel in it) +mul r0.rg, r0, r3.a +#if REFLECT +mad r4.rg, r3_bx2, r0.x, r4 +#endif + +#if REFRACT +mad r2.rg, r3_bx2, r0.y, r2 +#endif + +; stuff something into z so that texld will deal +#if REFLECT +mov r4.b, c5 +#endif +#if REFRACT +mov r2.b, c5 +#endif + +phase + +#if REFLECT +; reflection +texld r4, r4 +#endif +#if REFRACT +; refraction +texld r2, r2 +#endif + +#if REFLECT +; N.V +dp3_sat r1.a, r3_bx2, r1_bx2 +#endif + +#if REFRACT +; tint refraction +mul r2.rgb, r2, c1 +#endif + +#if REFLECT +; tint reflction +mul r4.rgb, r4, c4 + +; (1-N.V) ^ 5 ++mul r0.a, 1-r1.a, 1-r1.a +mul r0.a, r0.a, r0.a +mul_sat r0.a, r0.a, 1-r1.a +#endif + +#if !REFLECT && !REFRACT +; This is wrong!!!! +mov r0.rgba, c0 +#endif + +#if !REFLECT && REFRACT +mov r0.rgba, r2 +#endif + +#if REFLECT && !REFRACT +mov r0.rgba, r4 +#endif + +#if REFLECT && REFRACT +; reflection * fresnel + refraction * ( 1 - fresnel ) +lrp r0.rgba, r0.a, r4, r2 +#endif + diff --git a/mp/src/materialsystem/stdshaders/Water_ps14.vsh b/mp/src/materialsystem/stdshaders/Water_ps14.vsh new file mode 100644 index 00000000..0ec30aa7 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Water_ps14.vsh @@ -0,0 +1,95 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; c0 = (0, 1, 2, 0.5) +; c1 = (1/2.2, 0, 0, 0) +; c2 = camera position *in world space* +; c4-c7 = modelViewProj matrix (transpose) +; c8-c11 = ViewProj matrix (transpose) +; c12-c15 = model->view matrix (transpose) +; c16 = [fogStart, fogEnd, fogRange, undefined] +; +; $SHADER_SPECIFIC_CONST_0..$SHADER_SPECIFIC_CONST_3 - special proj matrix +; +; Vertex components (as specified in the vertex DECL) +; $vPos = Position +; $vTexCoord0.xy = TexCoord0 +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +; Vertex components +; $vPos = Position +; $vNormal = normal +; $vTexCoord0.xy = TexCoord0 +; $vTangentS = S axis of Texture space +; $vTangentT = T axis of Texture space + + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + + +alloc $projPos + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +alloc $worldPos + +; Transform position from object to world space +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +alloc $worldEyeVect + +; Get the eye vector in world space +add $worldEyeVect.xyz, -$worldPos, $cEyePos + +alloc $tangentEyeVect + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal +mov $tangentEyeVect.w, $cZero + +mov oT5, $tangentEyeVect + +; base coordinates +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + +; reflection +alloc $projPosReflect + +mov $projPosReflect, $projPos +add $projPosReflect.xy, $projPosReflect, $projPosReflect.w +mul $projPosReflect.xy, $projPosReflect, $cHalf +mov oT1, $projPosReflect + +; refraction +mov $projPos.y, -$projPos.y +add $projPos.xy, $projPos, $projPos.w +mul $projPos.xy, $projPos, $cHalf +mov oT2, $projPos + +; reflectionscale, refractionscale +mov oT4, $SHADER_SPECIFIC_CONST_4 + +free $worldEyeVect +free $tangentEyeVect +free $projPosReflect +free $worldPos +free $projPos \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/Water_vs11.vsh b/mp/src/materialsystem/stdshaders/Water_vs11.vsh new file mode 100644 index 00000000..3b0131b8 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Water_vs11.vsh @@ -0,0 +1,102 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; c0 = (0, 1, 2, 0.5) +; c1 = (1/2.2, 0, 0, 0) +; c2 = camera position *in world space* +; c4-c7 = modelViewProj matrix (transpose) +; c8-c11 = ViewProj matrix (transpose) +; c12-c15 = model->view matrix (transpose) +; c16 = [fogStart, fogEnd, fogRange, undefined] +; +; Vertex components (as specified in the vertex DECL) +; $vPos = Position +; $vTexCoord0.xy = TexCoord0 +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +; Vertex components +; $vPos = Position +; $vNormal = normal +; $vTexCoord0.xy = TexCoord0 +; $vTangentS = S axis of Texture space +; $vTangentT = T axis of Texture space + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +alloc $projPos + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +alloc $worldPos + +; Transform position from object to world space +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +alloc $worldEyeVect + +; Get the eye vector in world space +add $worldEyeVect.xyz, -$worldPos, $cEyePos + +; transform the eye vector to tangent space +dp3 oT3.x, $worldEyeVect, $vTangentS +dp3 oT3.y, $worldEyeVect, $vTangentT +dp3 oT3.z, $worldEyeVect, $vNormal + +; Get the magnitude of worldEyeVect +dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect +rsq $worldEyeVect.w, $worldEyeVect.w +rcp $worldEyeVect.w, $worldEyeVect.w + +; calculate the cheap water blend factor and stick it into oD0.a +; NOTE: This won't be perspective correct!!!!! +; OPTIMIZE: This could turn into a mad. +add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_3.x +mul oD0, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_3.y + +; dudv map +alloc $bumpTexCoord + +dp4 $bumpTexCoord.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 $bumpTexCoord.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + +mov oT0.xy, $bumpTexCoord + +; normal map +mov oT2.xy, $bumpTexCoord + +free $bumpTexCoord + +alloc $newProjPos + +mov oPos, $projPos + +; special case perspective correct texture projection so that the texture fits exactly on the screen +mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_4.w +add $projPos.xy, $projPos.xy, $projPos.w +mul $projPos.xy, $projPos.xy, $cHalf + +mov oT1.xy, $projPos.xy +mov oT1.z, $cZero +mov oT1.w, $projPos.w + +free $projPos +free $worldPos +free $worldEyeVect +free $projTangentS +free $projTangentT +free $newProjPos diff --git a/mp/src/materialsystem/stdshaders/Water_vs20.fxc b/mp/src/materialsystem/stdshaders/Water_vs20.fxc new file mode 100644 index 00000000..8f3a7a81 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/Water_vs20.fxc @@ -0,0 +1,117 @@ +// STATIC: "BASETEXTURE" "0..1" +// STATIC: "MULTITEXTURE" "0..1" + +// SKIP: $MULTITEXTURE && $BASETEXTURE + +#include "common_vs_fxc.h" + +const float4 cBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); +const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vNormal : NORMAL; + float4 vBaseTexCoord : TEXCOORD0; + float2 vLightmapTexCoord : TEXCOORD1; + float2 vLightmapTexCoordOffset : TEXCOORD2; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos_POSITION : POSITION; +#if !defined( _X360 ) + float vFog : FOG; +#endif + float2 vBumpTexCoord : TEXCOORD0; + float3 vTangentEyeVect : TEXCOORD1; + float4 vReflectXY_vRefractYX : TEXCOORD2; + float W : TEXCOORD3; + float4 vProjPos : TEXCOORD4; + float screenCoord : TEXCOORD5; +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif +#if BASETEXTURE + HALF4 lightmapTexCoord1And2 : TEXCOORD6; + HALF4 lightmapTexCoord3 : TEXCOORD7; +#endif + float4 fogFactorW : COLOR1; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + // Projected position + float4 vProjPos = mul( v.vPos, cModelViewProj ); + o.vProjPos = o.vProjPos_POSITION = vProjPos; + + // Project tangent basis + float2 vProjTangentS = mul( v.vTangentS, cViewProj ); + float2 vProjTangentT = mul( v.vTangentT, cViewProj ); + + // Map projected position to the reflection texture + float2 vReflectPos; + vReflectPos = (vProjPos.xy + vProjPos.w) * 0.5f; + + // Map projected position to the refraction texture + float2 vRefractPos; + vRefractPos.x = vProjPos.x; + vRefractPos.y = -vProjPos.y; // invert Y + vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; + + // Reflection transform + o.vReflectXY_vRefractYX = float4( vReflectPos.x, vReflectPos.y, vRefractPos.y, vRefractPos.x ); + o.W = vProjPos.w; + + o.screenCoord = vProjPos.x; + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + o.fogFactorW = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE ); +#if !defined( _X360 ) + o.vFog = o.fogFactorW; +#endif + + // Eye vector + float3 vWorldEyeVect = cEyePos - vWorldPos; + // Transform to the tangent space + o.vTangentEyeVect.x = dot( vWorldEyeVect, v.vTangentS ); + o.vTangentEyeVect.y = dot( vWorldEyeVect, v.vTangentT ); + o.vTangentEyeVect.z = dot( vWorldEyeVect, vObjNormal ); + + // Tranform bump coordinates + o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); + o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); + float f45x=v.vBaseTexCoord.x+v.vBaseTexCoord.y; + float f45y=v.vBaseTexCoord.y-v.vBaseTexCoord.x; +#if MULTITEXTURE + o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x; + o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y; + o.vExtraBumpTexCoord.z=v.vBaseTexCoord.y*0.45+TexOffsets.z; + o.vExtraBumpTexCoord.w=v.vBaseTexCoord.x*0.45+TexOffsets.w; +#endif + +#if BASETEXTURE + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; + + float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; + float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; + + // reversed component order + o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; + o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; + + o.lightmapTexCoord3.xy = lightmapTexCoord3; +#endif + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/WorldTexture.psh b/mp/src/materialsystem/stdshaders/WorldTexture.psh new file mode 100644 index 00000000..6144fdf2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldTexture.psh @@ -0,0 +1,14 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 +mov r0, t0 + diff --git a/mp/src/materialsystem/stdshaders/WorldTwoTextureBlend.psh b/mp/src/materialsystem/stdshaders/WorldTwoTextureBlend.psh new file mode 100644 index 00000000..b9494b02 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldTwoTextureBlend.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mov r0.rgb, t0 + +mul r0.a, t0.a, v0.a ; Grab alpha from vertex color + +lrp r0.rgb, t2.a, t2, r0 ; Base = base * (1 - detail alpha) + detail * detail alpha +mul r0.rgb, r0, v0 ; modulate by vertex color +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh b/mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh new file mode 100644 index 00000000..033730bb --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh @@ -0,0 +1,25 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c1, 1.0f, 1.0f, 1.0f, 1.0f + +tex t0 +tex t1 +tex t2 + +mov_x2_sat r0.rgb, t0 + ; r0 = sat( t0 * 2 ) +mul r0.a, t0.a, v0.a ; Grab alpha from vertex color + +lrp_sat r0.rgb, t2.a, r0, c1 ; r0 = B*Da + (1-Da) + +mul r0.rgb, r0, t2 ; modulate by detail color +mul r0.rgb, r0, v0 ; modulate by vertex color +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh b/mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh new file mode 100644 index 00000000..2f5a8ca5 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mov r0.rgb, t0 + +mov r0.a, v0.a ; Grab alpha from vertex color + +lrp r0.rgb, t2.a, t2, r0 ; Base = base * (1 - detail alpha) + detail * detail alpha +mul r0.rgb, r0, v0 ; modulate by vertex color +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1.rgb, c1, t0 ; Self illum * tint ++ mul r1.a, t0.a, 1-t2.a ; Reduce self-illum amount based on 1 - detailalpha + +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lightmap + diff --git a/mp/src/materialsystem/stdshaders/WorldVertexAlpha.psh b/mp/src/materialsystem/stdshaders/WorldVertexAlpha.psh new file mode 100644 index 00000000..e610452e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexAlpha.psh @@ -0,0 +1,10 @@ +ps.1.1 + +tex t0 ; basetexture +tex t1 ; lightmap + +mov r0.a, 1-t1.a +;mov r0.rgb, t0 ; * 2 * (overbrightFactor/2) +;mov_x2 r0.rgb, t0 ; * 2 * (overbrightFactor/2) +mul r0.rgb, t0, t1; +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/WorldVertexAlpha.vsh b/mp/src/materialsystem/stdshaders/WorldVertexAlpha.vsh new file mode 100644 index 00000000..ae2566a6 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexAlpha.vsh @@ -0,0 +1,37 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +&AllocateRegister( \$worldPos ); + +; garymcthack +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$worldPos ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +; base texcoords +mov oT0, $vTexCoord0 + +; lightmap texcoords +mov oT1, $vTexCoord1 + +&FreeRegister( \$worldPos ); # garymcthack + diff --git a/mp/src/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc b/mp/src/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc new file mode 100644 index 00000000..7ccc584a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc @@ -0,0 +1,43 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "PASS" "0..1" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +// CENTROID: TEXCOORD1 + +sampler BaseSampler : register( s0 ); +sampler LightmapSampler: register( s1 ); +sampler LightmapAlphaSampler: register( s2 ); + +struct PS_INPUT +{ + float2 baseCoord : TEXCOORD0; + float2 lightmapCoord : TEXCOORD1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bAlphaPass = PASS ? true : false; + + float4 base = tex2D( BaseSampler, i.baseCoord ); + float4 lightmap = tex2D( LightmapSampler, i.lightmapCoord ); + float4 alpha = tex2D( LightmapAlphaSampler, i.lightmapCoord ); + + float4 color; + + base.a = dot( base, HALF3( HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f) ) ); + color = 2.0f * base * lightmap; // The 2x is for an assumed overbright 2 (it's always 2 on dx9) + + if( bAlphaPass ) + { + // Don't care about color, just return pre-multiplied alpha + return FinalOutput( float4( 0.0f, 0.0f, 1.0f, (1.0f - alpha.a) * color.a ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); + } + else + { + return FinalOutput( float4( color.rgb, (1.0f - alpha.a) ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); + } +} + diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition.psh b/mp/src/materialsystem/stdshaders/WorldVertexTransition.psh new file mode 100644 index 00000000..4fd2882b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition.psh @@ -0,0 +1,18 @@ +; STATIC: "DETAIL" "0..1" +ps.1.1 + +tex t0 ; basetexture +tex t1 ; basetexture2 +tex t2 ; lightmap +#if DETAIL +tex t3 ; detail +#endif + +mov_sat r1.a, v0.a +lrp r0, r1.a, t1, t0 + +mul r0, r0, t2 +#if DETAIL +mul_x2 r0.rgb, r0, t3 +#endif +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition.vsh b/mp/src/materialsystem/stdshaders/WorldVertexTransition.vsh new file mode 100644 index 00000000..81e56dbe --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition.vsh @@ -0,0 +1,48 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +&AllocateRegister( \$worldPos ); + +; garymcthack +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$worldPos ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +; base texcoords +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + +dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + +; lightmap texcoords +mov oT2, $vTexCoord1 + +; detail +dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + +; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. +mov oD0, $vColor + +&FreeRegister( \$worldPos ); # garymcthack + diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh b/mp/src/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh new file mode 100644 index 00000000..d4a5c623 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh @@ -0,0 +1,16 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +mul r0.rgb, t1, t0 ; fold in lightmap (color) ++mov r0.a, v0.a ; fold in lightmap (alpha) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition_Editor.psh b/mp/src/materialsystem/stdshaders/WorldVertexTransition_Editor.psh new file mode 100644 index 00000000..936edc9e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition_Editor.psh @@ -0,0 +1,10 @@ +ps.1.1 + +tex t0 ; basetexture +tex t1 ; basetexture2 +tex t2 ; lightmap + +; The editor uses vertex alpha as the blend factor +lrp r0, 1-v0.a, t1, t0 +mul r0, r0, t2 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh b/mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh new file mode 100644 index 00000000..8d4edad0 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh @@ -0,0 +1,23 @@ +ps.1.1 + +def c0, 1.0f, 0.0f, 0.0f, 0.0f +def c1, 0.0f, 1.0f, 0.0f, 0.0f +def c2, 0.0f, 0.0f, 1.0f, 0.0f + +tex t0 ; basetexture zy +tex t1 ; basetexture xz +tex t2 ; basetexture xy +tex t3 ; lightmap + +dp3_sat r1, v0, c0 +mul r0, t0, r1 + +dp3_sat r1, v0, c1 +mad r0, t1, r1, r0 + +dp3_sat r1, v0, c2 +mad r0, t2, r1, r0 + +; multiply by lightmap +mul_x2 r0.rgb, r0, t3 ++mov r0.a, v0 ; $vColor diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh b/mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh new file mode 100644 index 00000000..dd0cc99c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh @@ -0,0 +1,54 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + +alloc $projPos + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +alloc $worldPos +alloc $worldNormal + +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +dp3 $worldNormal.x, $vNormal, $cModel0 +dp3 $worldNormal.y, $vNormal, $cModel1 +dp3 $worldNormal.z, $vNormal, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +free $projPos + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +; base texcoords +alloc $texcoord +mul $texcoord.xyz, $worldPos, $SHADER_SPECIFIC_CONST_0 + +mov oT0.xy, $texcoord.zy; +mov oT1.xy, $texcoord.xz; +mov oT2.xy, $texcoord.xy; + +free $texcoord + +; lightmap texcoords +mov oT3, $vTexCoord1 + +mul oD0.rgb, $worldNormal, $worldNormal + +; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. +mov oD0.a, $vColor + +free $worldPos +free $worldNormal diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp b/mp/src/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp new file mode 100644 index 00000000..331f8f17 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp @@ -0,0 +1,537 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "convar.h" + +#include "worldvertextransition.inc" +#include "worldvertextransition_vs14.inc" +#include "worldvertextransition_seamless.inc" +#include "lightmappedgeneric_vs11.inc" +#include "writevertexalphatodestalpha_vs11.inc" +#include "worldvertextransition_dx8_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( WorldVertexTransition, WorldVertexTransition_DX8 ) + +ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); + +BEGIN_VS_SHADER( WorldVertexTransition_DX8, + "Help for WorldVertexTransition_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture2", "base texture2 help" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $baseTexture" ) + SHADER_PARAM( BASETEXTURETRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$baseTexture texcoord transform" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map for BASETEXTURE" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( BUMPBASETEXTURE2WITHBUMPMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "0.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) + SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "WorldVertexTransition_DX6"; + return 0; + } + + void SetupVars( WorldVertexTransitionEditor_DX8_Vars_t& info ) + { + info.m_nBaseTextureVar = BASETEXTURE; + info.m_nBaseTextureFrameVar = FRAME; + info.m_nBaseTextureTransformVar = BASETEXTURETRANSFORM; + info.m_nBaseTexture2Var = BASETEXTURE2; + info.m_nBaseTexture2FrameVar = FRAME2; + info.m_nBaseTexture2TransformVar = BASETEXTURETRANSFORM2; + } + + SHADER_INIT_PARAMS() + { + // Initializes FLASHLIGHTTEXTURE + MATERIAL_VAR2_LIGHTING_LIGHTMAP + WorldVertexTransitionEditor_DX8_Vars_t info; + SetupVars( info ); + InitParamsWorldVertexTransitionEditor_DX8( params, info ); + + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + if( IsUsingGraphics() && params[ENVMAP]->IsDefined() && !CanUseEditorMaterials() ) + { + if( stricmp( params[ENVMAP]->GetStringValue(), "env_cubemap" ) == 0 ) + { + Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); + params[ENVMAP]->SetUndefined(); + } + } + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + { + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + } + + if( !params[ENVMAPTINT]->IsDefined() ) + { + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[SELFILLUMTINT]->IsDefined() ) + { + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[DETAILSCALE]->IsDefined() ) + { + params[DETAILSCALE]->SetFloatValue( 4.0f ); + } + + if( !params[FRESNELREFLECTION]->IsDefined() ) + { + params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); + } + + if( !params[ENVMAPMASKFRAME]->IsDefined() ) + { + params[ENVMAPMASKFRAME]->SetIntValue( 0 ); + } + + if( !params[ENVMAPFRAME]->IsDefined() ) + { + params[ENVMAPFRAME]->SetIntValue( 0 ); + } + + if( !params[BUMPFRAME]->IsDefined() ) + { + params[BUMPFRAME]->SetIntValue( 0 ); + } + + if( !params[ENVMAPCONTRAST]->IsDefined() ) + { + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + } + + if( !params[ENVMAPSATURATION]->IsDefined() ) + { + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + + if( !params[BUMPBASETEXTURE2WITHBUMPMAP]->IsDefined() ) + { + params[BUMPBASETEXTURE2WITHBUMPMAP]->SetIntValue( 0 ); + } + + if( !params[DETAILSCALE]->IsDefined() ) + { + params[DETAILSCALE]->SetFloatValue( 4.0f ); + } + + if( !params[DETAILFRAME]->IsDefined() ) + { + params[DETAILFRAME]->SetIntValue( 0 ); + } + + if( params[SEAMLESS_SCALE]->IsDefined() && params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) + { + // seamless scale is going to be used, so kill some other features. . might implement with these features later. + params[DETAIL]->SetUndefined(); + params[BUMPMAP]->SetUndefined(); + params[ENVMAP]->SetUndefined(); + } + + if ( !params[SEAMLESS_SCALE]->IsDefined() ) + { + // zero means don't do seamless mapping. + params[SEAMLESS_SCALE]->SetFloatValue( 0.0f ); + } + + if( params[SSBUMP]->IsDefined() && params[SSBUMP]->GetIntValue() != 0 ) + { + // turn of normal mapping since we have ssbump defined, which + // means that we didn't make a dx8 fallback for this material. + params[BUMPMAP]->SetUndefined(); + } + } + SHADER_INIT + { + // Loads BASETEXTURE, BASETEXTURE2 + WorldVertexTransitionEditor_DX8_Vars_t info; + SetupVars( info ); + InitWorldVertexTransitionEditor_DX8( this, params, info ); + + // FLASHLIGHTFIXME + if ( params[FLASHLIGHTTEXTURE]->IsDefined() ) + { + LoadTexture( FLASHLIGHTTEXTURE ); + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + if ( g_pHardwareConfig->SupportsPixelShaders_1_4() && params[BLENDMODULATETEXTURE]->IsDefined() ) + { + LoadTexture( BLENDMODULATETEXTURE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( params[ENVMAP]->IsDefined() && !params[BUMPMAP]->IsDefined() ) + { + Warning( "must have $bumpmap if you have $envmap for worldvertextransition\n" ); + params[ENVMAP]->SetUndefined(); + params[BUMPMAP]->SetUndefined(); + } + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + LoadBumpMap( BUMPMAP ); + } + if( params[ENVMAP]->IsDefined() ) + { + if( !IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ) ) + { + LoadCubeMap( ENVMAP ); + } + else + { + Warning( "$envmapsphere not supported by worldvertextransition\n" ); + params[ENVMAP]->SetUndefined(); + } + } + } + + void WriteVertexAlphaToDestAlpha( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + if( pShaderShadow ) + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableColorWrites( false ); + + writevertexalphatodestalpha_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "writevertexalphatodestalpha_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "writevertexalphatodestalpha_ps11" ); + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_COLOR, 2, 0, 0 ); + } + else + { + writevertexalphatodestalpha_vs11_Dynamic_Index vshIndex; + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + void DrawFlashlightPass( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, int passID ) + { + bool bBump = ( passID == 0 ) && ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture(); + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, true, passID, BASETEXTURE2, FRAME2 ); + } + + bool ShouldUseBumpmapping( IMaterialVar **params ) + { + return g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined(); + } + + void DrawFlashlight( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + WriteVertexAlphaToDestAlpha( params, pShaderAPI, pShaderShadow ); + DrawFlashlightPass( params, pShaderAPI, pShaderShadow, 0 ); + DrawFlashlightPass( params, pShaderAPI, pShaderShadow, 1 ); + } + + SHADER_DRAW + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + bool bSupports14 = g_pHardwareConfig->SupportsPixelShaders_1_4(); + + // FLASHLIGHTFIXME: need to make these the same. + bool hasFlashlight = UsingFlashlight( params ); + if( hasFlashlight ) + { + DrawFlashlight( params, pShaderAPI, pShaderShadow ); + } + else if ( params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) + { + // This is the seamless_scale version, which doesn't use $detail or $bumpmap + SHADOW_STATE + { + // three copies of the base texture for seamless blending + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // lightmap + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + worldvertextransition_seamless_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition_Seamless", vshIndex.GetIndex() ); + + int pshIndex = 0; + pShaderShadow->SetPixelShader( "WorldVertexTransition_Seamless", pshIndex ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + // Texture 0..2 + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); + } + + // Texture 3 = lightmap + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); + + EnablePixelShaderOverbright( 0, true, true ); + + float fSeamlessScale = params[SEAMLESS_SCALE]->GetFloatValue(); + float map_scale[4]= { fSeamlessScale, fSeamlessScale, fSeamlessScale, fSeamlessScale }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale ); + + worldvertextransition_seamless_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + SHADOW_STATE + { + // inherit state from previous pass + + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + DYNAMIC_STATE + { + if( !bLightingOnly ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE2, FRAME2 ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE2, FRAME2 ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE2, FRAME2 ); + } + } + Draw(); + } + else if( !params[BUMPMAP]->IsTexture() || !g_pConfig->UseBumpmapping() ) + { + bool bDetail = params[DETAIL]->IsTexture(); + bool bBlendModulate = params[BLENDMODULATETEXTURE]->IsTexture(); + SHADOW_STATE + { + // This is the dx8, non-worldcraft version, non-bumped version + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if( bDetail ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + if ( bSupports14 && bBlendModulate ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + + int fmt = VERTEX_POSITION | VERTEX_COLOR; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + if ( !bSupports14 ) + { + worldvertextransition_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition", vshIndex.GetIndex() ); + + int pshIndex = bDetail ? 1 : 0; + pShaderShadow->SetPixelShader( "WorldVertexTransition", pshIndex ); + } + else + { + worldvertextransition_vs14_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition_vs14", vshIndex.GetIndex() ); + + int pshIndex = bDetail ? 1 : 0; + pshIndex += bBlendModulate ? 2 : 0; + pShaderShadow->SetPixelShader( "WorldVertexTransition_ps14", pshIndex ); + } + + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Texture 1 + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE2, FRAME2 ); + } + if( bDetail ) + { + BindTexture( SHADER_SAMPLER3, DETAIL, DETAILFRAME ); + } + if ( bSupports14 && bBlendModulate ) + { + BindTexture( SHADER_SAMPLER4, BLENDMODULATETEXTURE ); + } + + // always set the transform for detail textures since I'm assuming that you'll + // always have a detailscale. + // go ahead and set this even if we don't have a detail texture so the vertex shader doesn't + // barf chunks with unitialized data. + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); + + if ( bSupports14 ) + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BLENDMASKTRANSFORM ); + } + + // Texture 3 = lightmap + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_LIGHTMAP ); + + EnablePixelShaderOverbright( 0, true, true ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM2 ); + if ( !bSupports14 ) + { + worldvertextransition_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + else + { + worldvertextransition_vs14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + Draw(); + } + else + { + if( params[BUMPBASETEXTURE2WITHBUMPMAP]->GetIntValue() ) + { + DrawWorldBumpedUsingVertexShader( BASETEXTURE, BASETEXTURETRANSFORM, + BUMPMAP, BUMPFRAME, BUMPTRANSFORM, ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP, + ENVMAPFRAME, ENVMAPTINT, COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, + FRESNELREFLECTION, true, BASETEXTURE2, BASETEXTURETRANSFORM2, FRAME2, false ); + } + else + { + // draw the base texture with everything else you normally would for + // bumped world materials + DrawWorldBumpedUsingVertexShader( + BASETEXTURE, BASETEXTURETRANSFORM, + BUMPMAP, BUMPFRAME, BUMPTRANSFORM, + ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP, ENVMAPFRAME, ENVMAPTINT, + COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, + FRESNELREFLECTION, + false, -1, -1, -1, false ); + + // blend basetexture 2 on top of everything using lightmap alpha. + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_COLOR, 2, 0, 0 ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( false ); + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + vshIndex.SetVERTEXCOLOR( true ); + pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WorldVertexTransition_BlendBase2" ); + FogToFogColor(); + } + DYNAMIC_STATE + { + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE2, FRAME2 ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + float half[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; + pShaderAPI->SetPixelShaderConstant( 4, half ); + EnablePixelShaderOverbright( 0, true, true ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM2 ); + + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + } + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition_ps14.psh b/mp/src/materialsystem/stdshaders/WorldVertexTransition_ps14.psh new file mode 100644 index 00000000..763a5d11 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition_ps14.psh @@ -0,0 +1,32 @@ +; STATIC: "DETAIL" "0..1" +; STATIC: "BLENDMODULATETEXTURE" "0..1" +ps.1.4 + +def c1, 3.0, -2.0, 0.5, 0.5 + +texld r0, t0 +texld r1, t1 +texld r2, t2 +#if DETAIL +texld r3, t3 ; detail +#endif +#if BLENDMODULATETEXTURE +texld r4, t4 ; detail +#endif + +#if BLEND_MODULATETEXTURE +sub r5.a, v0.a, r4.g +add_sat r5.a, r5.a, c1.a +mad r6.a, c1.g, r5.a, c1.r +mul r6.a, r6.a, r5.a +mul r5.a, r6.a, r5.a +#else +mov_sat r5.a, v0.a +#endif +lrp r0, r5.a, r1, r0 + +mul r0, r0, r2 +#if DETAIL +mul_x2 r0.rgb, r0, r3 +#endif +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc b/mp/src/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc new file mode 100644 index 00000000..f27e870d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc @@ -0,0 +1,47 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "MACROS" "0..1" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + + +sampler BaseSampler : register( s0 ); +// NOTE: LightmapSampler is at the same place as the lightmap sampler in lightmappedgeneric so that we have +// generally the same texture state here. +// CENTROID: TEXCOORD1 +sampler LightmapSampler: register( s1 ); +sampler BaseSampler2: register( s2 ); +sampler LightmapAlphaSampler: register( s3 ); +sampler MacrosSampler: register( s4 ); + +struct PS_INPUT +{ + float2 baseCoord : TEXCOORD0; + float2 baseCoord2 : TEXCOORD1; + float2 lightmapCoord : TEXCOORD2; + float2 macrosCoord : TEXCOORD3; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bMacros = MACROS ? true : false; + + float4 base = tex2D( BaseSampler, i.baseCoord ); + float4 base2 = tex2D( BaseSampler2, i.baseCoord2 ); + + float4 lightmap = tex2D( LightmapSampler, i.lightmapCoord ); + float blendFactor = lightmap.a; + + float4 color = 2.0f * lightmap * lerp( base2, base, blendFactor ); + if( bMacros ) + { + float4 macros = tex2D( MacrosSampler, i.macrosCoord ); + + // Not sure what to do with macro alpha + color.rgb *= 2.0f * lerp( macros.a, macros.b, blendFactor ); + } + + return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} + diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh b/mp/src/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh new file mode 100644 index 00000000..eecc1c89 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh @@ -0,0 +1,52 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +&AllocateRegister( \$worldPos ); + +; garymcthack +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$worldPos ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +; base texcoords +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + +dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + +; lightmap texcoords +mov oT2, $vTexCoord1 + +; detail +dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + +; mask +dp4 oT4.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_6 +dp4 oT4.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_7 + +; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. +mov oD0, $vColor + +&FreeRegister( \$worldPos ); # garymcthack + diff --git a/mp/src/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc b/mp/src/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc new file mode 100644 index 00000000..5f18ca81 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc @@ -0,0 +1,64 @@ +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cBaseTexCoordTransform2[2] : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cMacrosTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vColor : COLOR0; + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 baseCoord : TEXCOORD0; + float2 baseCoord2 : TEXCOORD1; + float2 lightmapCoord : TEXCOORD2; + float2 macrosCoord : TEXCOORD3; + float4 color : COLOR0; + float4 fogFactorW : COLOR1; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldNormal, worldPos; + float2 texCoord; + worldPos = mul( v.vPos, cModel[0] ); + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + o.color = v.vColor; + + o.baseCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + + o.baseCoord2.x = dot( v.vTexCoord0, cBaseTexCoordTransform2[0] ); + o.baseCoord2.y = dot( v.vTexCoord0, cBaseTexCoordTransform2[1] ); + + o.lightmapCoord = v.vTexCoord1; + + o.macrosCoord.x = dot( v.vTexCoord0, cMacrosTexCoordTransform[0] ); + o.macrosCoord.y = dot( v.vTexCoord0, cMacrosTexCoordTransform[1] ); + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/cable_dx6.cpp b/mp/src/materialsystem/stdshaders/cable_dx6.cpp new file mode 100644 index 00000000..9b11551f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cable_dx6.cpp @@ -0,0 +1,62 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Cable, Cable_DX6 ) + +BEGIN_SHADER( Cable_DX6, + "Help for Cable_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.25", "Minimum amount of light (0-1 value)" ) + SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.25", "Maximum amount of light" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + int GetDrawFlagsPass1(IMaterialVar** params ) + { + int flags = SHADER_DRAW_POSITION; + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + flags |= SHADER_DRAW_COLOR; + flags |= SHADER_DRAW_TEXCOORD0; + return flags; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableConstantColor( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + SetNormalBlendingShadowState( BASETEXTURE, true ); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params) ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + Vector min, max; + params[MINLIGHT]->GetVecValue( &min.x, 3 ); + params[MAXLIGHT]->GetVecValue( &max.x, 3 ); + Vector avg = ( min + max ) * 0.5f; + pShaderAPI->Color3fv( &avg.x ); + } + Draw( ); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/cable_dx8.cpp b/mp/src/materialsystem/stdshaders/cable_dx8.cpp new file mode 100644 index 00000000..9e3c98dd --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cable_dx8.cpp @@ -0,0 +1,132 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: A wet version of base * lightmap +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "cable.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Cable, Cable_DX8 ) + +BEGIN_VS_SHADER( Cable_DX8, + "Help for Cable shader" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "cable/cablenormalmap", "bumpmap texture" ) + SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.1", "Minimum amount of light (0-1 value)" ) + SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.3", "Maximum amount of light" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && !g_pHardwareConfig->SupportsVertexAndPixelShaders()) + { + return "UnlitGeneric_DX6"; + } + return 0; + } + + SHADER_INIT + { + LoadBumpMap( BUMPMAP ); + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + // Enable blending? + if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) ) + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + + int tCoordDimensions[] = {2,2}; + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_COLOR | VERTEX_TANGENT_S | VERTEX_TANGENT_T, + 2, tCoordDimensions, 0 ); + + cable_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Cable", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "Cable" ); + + // we are writing linear values from this shader. + // This is kinda wrong. We are writing linear or gamma depending on "IsHDREnabled" below. + // The COLOR really decides if we are gamma or linear. + if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + pShaderShadow->EnableSRGBWrite( true ); + } + + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BUMPMAP ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE ); + + + // The dot product with the light is remapped from the range + // [-1,1] to [MinLight, MaxLight]. + + // Given: + // -A + B = MinLight + // A + B = MaxLight + // then A = (MaxLight - MinLight) / 2 + // and B = (MaxLight + MinLight) / 2 + + // So here, we multiply the light direction by A to scale the dot product. + // Then in the pixel shader we add by B. + float flMinLight = params[MINLIGHT]->GetFloatValue(); + float flMaxLight = params[MAXLIGHT]->GetFloatValue(); + + float A = (flMaxLight - flMinLight) * 0.5f; + float B = (flMaxLight + flMinLight) * 0.5f; + + float b4[4] = {B,B,B,B}; + if( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + SetPixelShaderConstantGammaToLinear( 0, b4 ); + } + else + { + pShaderAPI->SetPixelShaderConstant( 0, b4 ); + } + + // This is the light direction [0,1,0,0] * A * 0.5 + float lightDir[4] = {0, A*0.5, 0, 0}; + if( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + SetVertexShaderConstantGammaToLinear( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lightDir ); + } + else + { + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lightDir ); + } + + cable_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/cable_dx9.cpp b/mp/src/materialsystem/stdshaders/cable_dx9.cpp new file mode 100644 index 00000000..5b25ed61 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cable_dx9.cpp @@ -0,0 +1,141 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: A wet version of base * lightmap +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "cable_vs20.inc" +#include "cable_ps20.inc" +#include "cable_ps20b.inc" +#include "cpp_shader_constant_register_map.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern ConVar mat_fullbright; + +DEFINE_FALLBACK_SHADER( Cable, Cable_DX9 ) + +BEGIN_VS_SHADER( Cable_DX9, + "Help for Cable shader" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "cable/cablenormalmap", "bumpmap texture" ) + SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.1", "Minimum amount of light (0-1 value)" ) + SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.3", "Maximum amount of light" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( !(g_pHardwareConfig->SupportsPixelShaders_2_0() && g_pHardwareConfig->SupportsVertexShaders_2_0()) || + (g_pHardwareConfig->GetDXSupportLevel() < 90) ) + { + return "Cable_DX8"; + } + return 0; + } + + SHADER_INIT + { + LoadBumpMap( BUMPMAP ); + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + } + + SHADER_DRAW + { + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + // Enable blending? + if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) ) + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + + int tCoordDimensions[] = {2,2}; + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_COLOR | VERTEX_TANGENT_S | VERTEX_TANGENT_T, + 2, tCoordDimensions, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( cable_vs20 ); + SET_STATIC_VERTEX_SHADER( cable_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( cable_ps20b ); + SET_STATIC_PIXEL_SHADER( cable_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( cable_ps20 ); + SET_STATIC_PIXEL_SHADER( cable_ps20 ); + } + + // we are writing linear values from this shader. + // This is kinda wrong. We are writing linear or gamma depending on "IsHDREnabled" below. + // The COLOR really decides if we are gamma or linear. + pShaderShadow->EnableSRGBWrite( true ); + + FogToFogColor(); + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + + BindTexture( SHADER_SAMPLER0, BUMPMAP ); + if ( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + + } + else + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( cable_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER( cable_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( cable_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( cable_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( cable_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( cable_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/cable_ps2x.fxc b/mp/src/materialsystem/stdshaders/cable_ps2x.fxc new file mode 100644 index 00000000..a3c7ff13 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cable_ps2x.fxc @@ -0,0 +1,54 @@ +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler NormalSampler : register( s0 ); +sampler BaseTextureSampler : register( s1 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +struct PS_INPUT +{ + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + + float4 directionalLightColor : COLOR0; + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 vNormalMapDir = tex2D( NormalSampler, i.vTexCoord0 ); // Get the 3-vector from the normal map + float4 textureColor = tex2D( BaseTextureSampler, i.vTexCoord1 ); // Interpret tcoord t1 as color data. + + //Expand compacted vectors + //TODO: find if there's a better way to expand a color normal to a full vector ( _bx2 was used in the assembly code ) + vNormalMapDir = (vNormalMapDir - 0.5) * 2.0; + float3 vLightDir = float3( 0.0f, 0.0f, 1.0f ); + + float lightDirDotNormalMap = dot( vNormalMapDir, vLightDir ); //normalMap dot dirLightDir + + // do half-lambert on the dot + lightDirDotNormalMap = lightDirDotNormalMap * 0.5 + 0.5; + lightDirDotNormalMap = lightDirDotNormalMap * lightDirDotNormalMap; + + float4 resultColor; + resultColor.xyz = lightDirDotNormalMap * ( textureColor.rgb * i.directionalLightColor.rgb ); + resultColor.a = textureColor.a * i.directionalLightColor.a; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/mp/src/materialsystem/stdshaders/cable_vs20.fxc b/mp/src/materialsystem/stdshaders/cable_vs20.fxc new file mode 100644 index 00000000..adb3559e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cable_vs20.fxc @@ -0,0 +1,80 @@ +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 directionalLightColor : COLOR0; + + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + + float4 directionalLightColor : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul( v.vPos, cModel[0] ); + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + //------------------------------------------------------------------------------ + // Setup the tangent space + //------------------------------------------------------------------------------ + + // Get S crossed with T (call it R) + float3 r = cross( v.vTangentS, v.vTangentT ); + + // Normalize S (into s) + float3 s = normalize( v.vTangentS ); + + // Normalize R (into r) + r = normalize( r ); + + // Regenerate T (into t) + float3 t = cross( r, v.vTangentS ); + + //------------------------------------------------------------------------------ + // Copy texcoords for the normal map and base texture + //------------------------------------------------------------------------------ + o.vTexCoord0 = v.vTexCoord0; + o.vTexCoord1 = v.vTexCoord1; + + // Pass the dirlight color through + o.directionalLightColor = v.directionalLightColor; + + return o; +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/cloud.cpp b/mp/src/materialsystem/stdshaders/cloud.cpp new file mode 100644 index 00000000..810e6c4d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cloud.cpp @@ -0,0 +1,76 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_SHADER( Cloud, + "Help for Cloud" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 ) + SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" ) + SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" ) + SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" ) + END_SHADER_PARAMS + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + LoadTexture( CLOUDALPHATEXTURE ); + if( !params[CLOUDSCALE]->IsDefined() ) + { + params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f ); + } + if( !params[MASKSCALE]->IsDefined() ) + { + params[MASKSCALE]->SetVecValue( 1.0f, 1.0f ); + } + } + + SHADER_DRAW + { + if( g_pHardwareConfig->GetSamplerCount() >= 2 ) + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + { + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + else + { + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | + SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_TEXCOORD1 ); + DefaultFog(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); + + // handle scrolling of base texture + SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE0, + BASETEXTURETRANSFORM, CLOUDSCALE ); + SetFixedFunctionTextureScale( MATERIAL_TEXTURE1, MASKSCALE ); + } + Draw(); + } + else + { + ShaderWarning("Cloud not supported for single-texturing boards!\n"); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/cloud_dx8.cpp b/mp/src/materialsystem/stdshaders/cloud_dx8.cpp new file mode 100644 index 00000000..d3bc2530 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cloud_dx8.cpp @@ -0,0 +1,77 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "cloud_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Cloud_dx8, "Help for Cloud" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 ) + SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" ) + SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" ) + SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" ) + END_SHADER_PARAMS + + SHADER_INIT + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( CLOUDALPHATEXTURE, TEXTUREFLAGS_SRGB ); + if ( !params[CLOUDSCALE]->IsDefined() ) + { + params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f ); + } + if ( !params[MASKSCALE]->IsDefined() ) + { + params[MASKSCALE]->SetVecValue( 1.0f, 1.0f ); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + { + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + else + { + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); + + cloud_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "cloud_vs11", vshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( "cloud_ps11" ); + + DefaultFog(); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); + + // handle scrolling of base texture + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM, CLOUDSCALE ); + SetVertexShaderTextureScale( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, MASKSCALE ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/cloud_dx9.cpp b/mp/src/materialsystem/stdshaders/cloud_dx9.cpp new file mode 100644 index 00000000..4b04b8b4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cloud_dx9.cpp @@ -0,0 +1,94 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// DirectX 9 Cloud shader +// +//=============================================================================== + +#include "BaseVSShader.h" +#include "cloud_vs20.inc" +#include "cloud_ps20.inc" + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Cloud, Cloud_dx9 ) + +BEGIN_VS_SHADER( Cloud_dx9, "Help for Cloud" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 ) + SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" ) + SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" ) + SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "Cloud_dx8"; + + return 0; + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( CLOUDALPHATEXTURE, TEXTUREFLAGS_SRGB ); + if ( !params[CLOUDSCALE]->IsDefined() ) + { + params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f ); + } + if ( !params[MASKSCALE]->IsDefined() ) + { + params[MASKSCALE]->SetVecValue( 1.0f, 1.0f ); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + { + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + else + { + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( cloud_vs20 ); + SET_STATIC_VERTEX_SHADER( cloud_vs20 ); + + DECLARE_STATIC_PIXEL_SHADER( cloud_ps20 ); + SET_STATIC_PIXEL_SHADER( cloud_ps20 ); + + DefaultFog(); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); + + // Handle scrolling of base texture + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM, CLOUDSCALE ); + SetVertexShaderTextureScale( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, MASKSCALE ); + + DECLARE_DYNAMIC_VERTEX_SHADER( cloud_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( cloud_vs20 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( cloud_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( cloud_ps20 ); + } + + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/cloud_ps11.psh b/mp/src/materialsystem/stdshaders/cloud_ps11.psh new file mode 100644 index 00000000..8e5627cb --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cloud_ps11.psh @@ -0,0 +1,6 @@ +ps.1.1 + +tex t0 +tex t1 + +mul r0, t0, t1 diff --git a/mp/src/materialsystem/stdshaders/cloud_ps20.fxc b/mp/src/materialsystem/stdshaders/cloud_ps20.fxc new file mode 100644 index 00000000..31f8bbd2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cloud_ps20.fxc @@ -0,0 +1,26 @@ +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler CloudAlphaSampler : register( s1 ); + +struct PS_INPUT +{ + float2 baseCoords : TEXCOORD0; + float2 cloudAlphaCoords : TEXCOORD1; + float fogFactor : TEXCOORD2; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 vBase = tex2D( BaseTextureSampler, i.baseCoords ); + float4 vCloudAlpha = tex2D( CloudAlphaSampler, i.cloudAlphaCoords ); + + float fogFactor = 2.0f * smoothstep( 0.3f, 0.6f, i.fogFactor ); + + float4 result = vBase * vCloudAlpha; + result.a *= fogFactor; + + // No actual fog. Use the "fog factor" to modulate alpha (after some smoothstep mojo) + return FinalOutput( result, 1.0f, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +} diff --git a/mp/src/materialsystem/stdshaders/cloud_vs11.vsh b/mp/src/materialsystem/stdshaders/cloud_vs11.vsh new file mode 100644 index 00000000..6348937e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cloud_vs11.vsh @@ -0,0 +1,26 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..0" + +#include "macros.vsh" + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +&AllocateRegister( \$worldPos ); +; $worldPos unused, for above water, range fog calcs +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); +&FreeRegister( \$worldPos ); + +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 oT1.x, $vTexCoord1, $SHADER_SPECIFIC_CONST_2 +dp4 oT1.y, $vTexCoord1, $SHADER_SPECIFIC_CONST_3 + diff --git a/mp/src/materialsystem/stdshaders/cloud_vs20.fxc b/mp/src/materialsystem/stdshaders/cloud_vs20.fxc new file mode 100644 index 00000000..3655e9fa --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cloud_vs20.fxc @@ -0,0 +1,37 @@ +#include "common_vs_fxc.h" + +const float4 g_matBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 g_matCloudTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseCoords : TEXCOORD0; + float2 cloudAlphaCoords : TEXCOORD1; + float fogFactor : TEXCOORD2; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + o.projPos = mul( v.vPos, cModelViewProj ); + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + o.fogFactor = CalcFog( vWorldPos, o.projPos, FOGTYPE_RANGE ); + + // Texture coordinate transforms + o.baseCoords.x = dot( v.vTexCoord0.xyzw, g_matBaseTexCoordTransform[0] ); + o.baseCoords.y = dot( v.vTexCoord0.xyzw, g_matBaseTexCoordTransform[1] ); + o.cloudAlphaCoords.x = dot( v.vTexCoord1.xyzw, g_matCloudTexCoordTransform[0] ); + o.cloudAlphaCoords.y = dot( v.vTexCoord1.xyzw, g_matCloudTexCoordTransform[1] ); + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/debugdepth.cpp b/mp/src/materialsystem/stdshaders/debugdepth.cpp new file mode 100644 index 00000000..65e55e0c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugdepth.cpp @@ -0,0 +1,113 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "shaderlib/cshader.h" +#include "convar.h" +#include "debugdrawdepth_vs20.inc" +#include "debugdrawdepth_ps20.inc" +#include "debugdrawdepth_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_debugdepthmode( "mat_debugdepthmode", "0" ); +static ConVar mat_debugdepthval( "mat_debugdepthval", "128.0f" ); +static ConVar mat_debugdepthvalmax( "mat_debugdepthvalmax", "256.0f" ); + +BEGIN_SHADER_FLAGS( DebugDepth, "Help for DebugDepth", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_INIT + { + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { +// Assert( 0 ); + return "WireFrame"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( debugdrawdepth_vs20 ); + SET_STATIC_VERTEX_SHADER( debugdrawdepth_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( debugdrawdepth_ps20b ); + SET_STATIC_PIXEL_SHADER( debugdrawdepth_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( debugdrawdepth_ps20 ); + SET_STATIC_PIXEL_SHADER( debugdrawdepth_ps20 ); + } + } + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( debugdrawdepth_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, s_pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( debugdrawdepth_vs20 ); + + Vector4D vecZFilter( 0, 0, 0, 1 ); + int nDepthMode = mat_debugdepthmode.GetInt(); + if ( nDepthMode > 1 ) + { + nDepthMode = 0; + } + + vecZFilter[nDepthMode] = 1; + s_pShaderAPI->SetPixelShaderConstant( 1, vecZFilter.Base() ); + + Vector4D vecModulationColor( 0, 0, 0, 1 ); + if ( IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) + { + vecModulationColor[0] = 0; + vecModulationColor[1] = 1; + vecModulationColor[2] = 1; + } + else + { + vecModulationColor[0] = 1; + vecModulationColor[1] = 1; + vecModulationColor[2] = 1; + } + s_pShaderAPI->SetPixelShaderConstant( 2, vecModulationColor.Base() ); + + float flDepthFactor = mat_debugdepthval.GetFloat(); + float flDepthFactorMax = mat_debugdepthvalmax.GetFloat(); + if ( flDepthFactor == 0 ) + { + flDepthFactor = 1.0f; + } + Vector4D vecZFactor( (flDepthFactorMax - flDepthFactor), flDepthFactor, 1, 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, vecZFactor.Base() ); + } + Draw(); + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/debugluxel.cpp b/mp/src/materialsystem/stdshaders/debugluxel.cpp new file mode 100644 index 00000000..b3135fcb --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugluxel.cpp @@ -0,0 +1,140 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "shaderlib/cshader.h" + +#define USE_NEW_SHADER //Updating assembly shaders to fxc, this is for A/B testing. + +#ifdef USE_NEW_SHADER + +#include "unlitgeneric_vs20.inc" +#include "unlitgeneric_ps20.inc" +#include "unlitgeneric_ps20b.inc" + +#endif + + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_SHADER_FLAGS( DebugLuxels, "Help for DebugLuxels", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( NOSCALE, SHADER_PARAM_TYPE_BOOL, "0", "fixme" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } +#endif +} + +SHADER_INIT +{ + LoadTexture( BASETEXTURE ); +} + +SHADER_DRAW +{ + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + if (IS_FLAG_SET(MATERIAL_VAR_TRANSLUCENT)) + { + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + else + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + bool bVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); + + DECLARE_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bVertexColor ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); + } + } +#endif + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + int texCoordScaleX = 1, texCoordScaleY = 1; + if (!params[NOSCALE]->GetIntValue()) + { + pShaderAPI->GetLightmapDimensions( &texCoordScaleX, &texCoordScaleY ); + } + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + float vVertexColor[4] = { IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) ? 1.0f : 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, vVertexColor, 1 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); + } + + //texture scale transform + Vector4D transformation[2]; + transformation[0].Init( (float)texCoordScaleX, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, (float)texCoordScaleY, 0.0f, 0.0f ); + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, transformation[0].Base(), 2 ); + } + else +#endif + { + if (!params[NOSCALE]->GetIntValue()) + { + pShaderAPI->MatrixMode( MATERIAL_TEXTURE0 ); + pShaderAPI->LoadIdentity( ); + pShaderAPI->ScaleXY( texCoordScaleX, texCoordScaleY ); + } + } + } + Draw(); +} +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/debugmodifyvertex.cpp b/mp/src/materialsystem/stdshaders/debugmodifyvertex.cpp new file mode 100644 index 00000000..c497ca95 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugmodifyvertex.cpp @@ -0,0 +1,93 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: This is an example of a material that modifies vertex data +// in the shader. NOTE: Every pass is given a clean set of vertex data. +// Modifications made in the first pass are *not* carried over to the next pass +// Modifications must take place during the DYNAMIC_STATE block. +// Use the function MeshBuilder() to build the mesh +// +// Also note: Using thie feature is *really expensive*! It makes a copy of +// the vertex data *per pass!* If you wish to modify vertex data to be used +// with all passes, your best bet is to construct a dynamic mesh instead. +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_SHADER_FLAGS( DebugModifyVertex, "Help for DebugModifyVertex", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( WAVE, SHADER_PARAM_TYPE_FLOAT, "1.0", "wave amplitude" ) + END_SHADER_PARAMS + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + if( g_pHardwareConfig->GetSamplerCount() >= 2 ) + { + // lightmap + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableVertexDataPreprocess( true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + float amp = params[WAVE]->GetFloatValue(); + float currTime = pShaderAPI->CurrentTime(); + for (int i = 0; i < MeshBuilder()->NumVertices(); ++i) + { + float const* pPos = MeshBuilder()->Position(); + MeshBuilder()->Position3f( pPos[0] + amp * sin( currTime + pPos[2] / 4 ), + pPos[1] + amp * sin( currTime + pPos[2] / 4 + 2 * 3.14 / 3 ), + pPos[2] + amp * sin( currTime + pPos[2] / 4 + 4 * 3.14 / 3 ) ); + MeshBuilder()->AdvanceVertex(); + } + } + Draw(); + + // base * vertex color + SHADOW_STATE + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | + SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + // Notice here that since we didn't modify the position, and this is a second + // pass, the position has been reset to it's initial, unmodified position + float currTime = pShaderAPI->CurrentTime(); + for (int i = 0; i < MeshBuilder()->NumVertices(); ++i) + { + float const* pPos = MeshBuilder()->Position(); + MeshBuilder()->Color3f( ( sin( currTime + pPos[0] ) + 1.0F) * 0.5, + ( sin( currTime + pPos[1] ) + 1.0F) * 0.5, + ( sin( currTime + pPos[2] ) + 1.0F) * 0.5 ); + MeshBuilder()->AdvanceVertex(); + } + } + Draw(); + } + else + { + ShaderWarning( "DebugModifyVertex: not " + "implemented for single-texturing hardware\n" ); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp b/mp/src/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp new file mode 100644 index 00000000..2f5c6a8e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp @@ -0,0 +1,64 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "debugmorphaccumulator_ps30.inc" +#include "debugmorphaccumulator_vs30.inc" + +BEGIN_VS_SHADER_FLAGS( DebugMorphAccumulator, "Help for Debug Morph Accumulator", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthTest( false ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableCulling( false ); + pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBWrite( false ); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); + SET_STATIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); + SET_STATIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + + DECLARE_DYNAMIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); + } + Draw( ); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc b/mp/src/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc new file mode 100644 index 00000000..b479085c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc @@ -0,0 +1,16 @@ +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float2 vTexCoord : TEXCOORD0; +}; + +sampler MorphAccumulator : register( s0 ); + +HALF4 main( PS_INPUT i ) : COLOR +{ + float4 vDeltas = tex2D( MorphAccumulator, i.vTexCoord ); + return float4( abs( vDeltas.x ), abs( vDeltas.z ), abs( vDeltas.y ) + abs( vDeltas.w ), 1.0f ); +} + diff --git a/mp/src/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc b/mp/src/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc new file mode 100644 index 00000000..4ff8a742 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc @@ -0,0 +1,23 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.vProjPos = mul( v.vPos, cModelViewProj ); + o.vTexCoord = v.vTexCoord; + + return o; +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/debugmrttexture.cpp b/mp/src/materialsystem/stdshaders/debugmrttexture.cpp new file mode 100644 index 00000000..04a1128e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugmrttexture.cpp @@ -0,0 +1,86 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "debugmrttexture_ps20.inc" +#include "debugmrttexture_ps20b.inc" +#include "debugmrttexture_vs20.inc" + +BEGIN_VS_SHADER_FLAGS( DebugMRTTexture, "Help for DebugMRTTexture", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( MRTINDEX, SHADER_PARAM_TYPE_INTEGER, "", "" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { +// if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) +// { +// return "UnlitGeneric_DX8"; +// } + return 0; + } + + SHADER_INIT_PARAMS() + { + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + DECLARE_STATIC_VERTEX_SHADER( debugmrttexture_vs20 ); + SET_STATIC_VERTEX_SHADER( debugmrttexture_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( debugmrttexture_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( MRTINDEX, params[MRTINDEX]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER( debugmrttexture_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( debugmrttexture_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( MRTINDEX, params[MRTINDEX]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER( debugmrttexture_ps20 ); + } + + int numTexCoords = 2; + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, numTexCoords, 0, 0 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + DECLARE_DYNAMIC_VERTEX_SHADER( debugmrttexture_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( debugmrttexture_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20 ); + } + } + Draw(); + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/debugmrttexture_ps2x.fxc b/mp/src/materialsystem/stdshaders/debugmrttexture_ps2x.fxc new file mode 100644 index 00000000..7764e529 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugmrttexture_ps2x.fxc @@ -0,0 +1,26 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "MRTINDEX" "0..1" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; +}; + +sampler BaseTextureSampler1 : register( s0 ); +sampler BaseTextureSampler2 : register( s1 ); + +float4 main( PS_INPUT i ) : COLOR +{ +#if MRTINDEX == 0 + float4 result = tex2D( BaseTextureSampler1, i.baseTexCoord ); +#else + float4 result = tex2D( BaseTextureSampler2, i.baseTexCoord ); +#endif + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} + diff --git a/mp/src/materialsystem/stdshaders/debugmrttexture_vs20.fxc b/mp/src/materialsystem/stdshaders/debugmrttexture_vs20.fxc new file mode 100644 index 00000000..db5c4863 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugmrttexture_vs20.fxc @@ -0,0 +1,29 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 projPos; + float3 worldPos; + + projPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + o.projPos = projPos; + + o.baseTexCoord = v.vBaseTexCoord; + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/debugnormalmap.cpp b/mp/src/materialsystem/stdshaders/debugnormalmap.cpp new file mode 100644 index 00000000..0be5246a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugnormalmap.cpp @@ -0,0 +1,148 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#define USE_NEW_SHADER //Updating assembly shaders to fxc, this is for A/B testing. + + + +#ifdef USE_NEW_SHADER + +#include "unlitgeneric_vs20.inc" +#include "unlitgeneric_ps20.inc" +#include "unlitgeneric_ps20b.inc" + +#endif + +#include "unlitgeneric_vs11.inc" + + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( DebugNormalMap, "Help for DebugNormalMap", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldDiffuseBumpMap_bump", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_INIT + { + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + { +// Assert( 0 ); + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + DECLARE_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, 0 ); + SET_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); + } + } + else +#endif + { + unlitgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( false ); + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + vshIndex.SetVERTEXCOLOR( false ); + vshIndex.SetSEPARATEDETAILUVS( false ); + pShaderShadow->SetVertexShader( "unlitgeneric_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "unlitgeneric" ); + } + } + DYNAMIC_STATE + { + if ( params[BUMPMAP]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT ); + } + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BUMPTRANSFORM ); +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + float vVertexColor[4] = { 0, 0, 0, 0 }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, vVertexColor, 1 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); + } + } + else +#endif + { + unlitgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + Draw(); + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/debugsoftwarevertexshader.cpp b/mp/src/materialsystem/stdshaders/debugsoftwarevertexshader.cpp new file mode 100644 index 00000000..be7cedf3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugsoftwarevertexshader.cpp @@ -0,0 +1,56 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ) +{ + float t = pShaderAPI->CurrentTime(); + for( int i = 0; i < meshBuilder.NumVertices(); i++ ) + { + const float *pPos = meshBuilder.Position(); + meshBuilder.Position3f( pPos[0], pPos[1], pPos[2] + 10.0f * sin( t + pPos[0] ) ); + meshBuilder.AdvanceVertex(); + } +} + +FORWARD_DECLARE_SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ); + +BEGIN_SHADER_FLAGS( DebugSoftwareVertexShader, "blah", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/basetexture", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( FRAME, SHADER_PARAM_TYPE_INTEGER, "0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( BASETEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_INIT + { + if( g_pHardwareConfig->SupportsVertexAndPixelShaders() ) + { + USE_SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ); + } + else + { + USE_SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ); + } + } + SHADER_DRAW + { + SHADOW_STATE + { + } + DYNAMIC_STATE + { + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/debugtangentspace.cpp b/mp/src/materialsystem/stdshaders/debugtangentspace.cpp new file mode 100644 index 00000000..30279012 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugtangentspace.cpp @@ -0,0 +1,133 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +#define USE_NEW_SHADER //Updating assembly shaders to fxc, this is for A/B testing. + +#ifdef USE_NEW_SHADER +#include "debugtangentspace_vs11.inc" +#include "debugtangentspace_vs20.inc" +#include "unlitgeneric_notexture_ps11.inc" +#include "unlitgeneric_notexture_ps20.inc" +#include "unlitgeneric_notexture_ps20b.inc" + +#else +#include "debugtangentspace.inc" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_SHADER( DebugTangentSpace, "Help for DebugTangentSpace" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/basetexture", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( FRAME, SHADER_PARAM_TYPE_INTEGER, "0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( BASETEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + if (g_pHardwareConfig->SupportsVertexAndPixelShaders()) + { + SHADOW_STATE + { + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 0; + int userDataSize = 4; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + DECLARE_STATIC_VERTEX_SHADER( debugtangentspace_vs20 ); + SET_STATIC_VERTEX_SHADER( debugtangentspace_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); + } + } + else + { + DECLARE_STATIC_VERTEX_SHADER( debugtangentspace_vs11 ); + SET_STATIC_VERTEX_SHADER( debugtangentspace_vs11 ); + + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); + } +#else + debugtangentspace_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "DebugTangentSpace", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "UnlitGeneric_NoTexture" ); +#endif + } + DYNAMIC_STATE + { + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); + } + } + else // legacy hardware + { + DECLARE_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs11 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs11 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); + } +#else + debugtangentspace_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); +#endif + } + Draw(); + } + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/debugtangentspace.vsh b/mp/src/materialsystem/stdshaders/debugtangentspace.vsh new file mode 100644 index 00000000..cb38a23b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugtangentspace.vsh @@ -0,0 +1,34 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&SkinPositionAndNormal( $worldPos, $worldNormal ); + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +&FreeRegister( \$worldPos ); + +; stick the normal in the color channel +mov oD0.xyz, $worldNormal.xyz +mov oD0.w, $cOne ; make sure all components are defined + +&FreeRegister( \$projPos ); +&FreeRegister( \$worldNormal ); diff --git a/mp/src/materialsystem/stdshaders/debugtangentspace_vs11.fxc b/mp/src/materialsystem/stdshaders/debugtangentspace_vs11.fxc new file mode 100644 index 00000000..1584ef26 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugtangentspace_vs11.fxc @@ -0,0 +1,51 @@ +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float3 vNormal : NORMAL; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + + float4 vDiffuse : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, v.vPos, v.vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + + o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + + o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + // stick the normal in the color channel + o.vDiffuse.rgb = worldNormal; + o.vDiffuse.a = 1.0f; + + return o; +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/debugtangentspace_vs20.fxc b/mp/src/materialsystem/stdshaders/debugtangentspace_vs20.fxc new file mode 100644 index 00000000..f829bde9 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/debugtangentspace_vs20.fxc @@ -0,0 +1,55 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + + float4 vDiffuse : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, v.vPos, vObjNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + + o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + + o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + // stick the normal in the color channel + o.vDiffuse.rgb = worldNormal; + o.vDiffuse.a = 1.0f; + + return o; +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc b/mp/src/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc new file mode 100644 index 00000000..61daa238 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc @@ -0,0 +1,11 @@ +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float projPosZ : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return FinalOutput( float4( 0, 0, 0, 1.0f ), 0.0f, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE, true, i.projPosZ ); +} diff --git a/mp/src/materialsystem/stdshaders/depthtodestalpha_vs20.fxc b/mp/src/materialsystem/stdshaders/depthtodestalpha_vs20.fxc new file mode 100644 index 00000000..9891502e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/depthtodestalpha_vs20.fxc @@ -0,0 +1,23 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float projPosZ : TEXCOORD0; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.vProjPos = mul( v.vPos, cModelViewProj ); + o.projPosZ = o.vProjPos.z; + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/depthwrite.cpp b/mp/src/materialsystem/stdshaders/depthwrite.cpp new file mode 100644 index 00000000..06d7690f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/depthwrite.cpp @@ -0,0 +1,207 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "depthwrite_ps20.inc" +#include "depthwrite_ps20b.inc" +#include "depthwrite_vs20.inc" + +#if !defined( _X360 ) +#include "depthwrite_ps30.inc" +#include "depthwrite_vs30.inc" +#endif + +BEGIN_VS_SHADER_FLAGS( DepthWrite, "Help for Depth Write", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "", "Alpha reference value" ) + SHADER_PARAM( COLOR_DEPTH, SHADER_PARAM_TYPE_BOOL, "0", "Write depth as color") + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Wireframe"; + } + return 0; + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + bool bAlphaClip = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ); + int nColorDepth = GetIntParam( COLOR_DEPTH, params, 0 ); + + SHADOW_STATE + { + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + if ( nColorDepth == 0 ) + { + // Bias primitives when rendering into shadow map so we get slope-scaled depth bias + // rather than having to apply a constant bias in the filtering shader later + pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_SHADOW_BIAS ); + } + + // Turn off writes to color buffer since we always sample shadows from the DEPTH texture later + // This gives us double-speed fill when rendering INTO the shadow map + pShaderShadow->EnableColorWrites( ( nColorDepth == 1 ) ); + pShaderShadow->EnableAlphaWrites( false ); + + // Don't backface cull unless alpha clipping, since this can cause artifacts when the + // geometry is clipped by the flashlight near plane + // If a material was already marked nocull, don't cull it + pShaderShadow->EnableCulling( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) && !IS_FLAG_SET(MATERIAL_VAR_NOCULL) ); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_STATIC_VERTEX_SHADER( depthwrite_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( ONLY_PROJECT_POSITION, !bAlphaClip && IsX360() && !nColorDepth ); //360 needs to know if it *shouldn't* output texture coordinates to avoid shader patches + SET_STATIC_VERTEX_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_VERTEX_SHADER( depthwrite_vs20 ); + + if ( bAlphaClip || g_pHardwareConfig->PlatformRequiresNonNullPixelShaders() || nColorDepth ) + { + if( bAlphaClip ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( depthwrite_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_PIXEL_SHADER( depthwrite_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( depthwrite_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_PIXEL_SHADER( depthwrite_ps20 ); + } + } + } +#ifndef _X360 + else + { + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( depthwrite_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( ONLY_PROJECT_POSITION, 0 ); //360 only combo, and this is a PC path + SET_STATIC_VERTEX_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_VERTEX_SHADER( depthwrite_vs30 ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + DECLARE_STATIC_PIXEL_SHADER( depthwrite_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_PIXEL_SHADER( depthwrite_ps30 ); + } +#endif + } + DYNAMIC_STATE + { + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + depthwrite_vs20_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetCOMPRESSED_VERTS( (int)vertexCompression ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if ( bAlphaClip ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + float vAlphaThreshold[4] = {0.7f, 0.7f, 0.7f, 0.7f}; + if ( ALPHATESTREFERENCE != -1 && ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) ) + { + vAlphaThreshold[0] = vAlphaThreshold[1] = vAlphaThreshold[2] = vAlphaThreshold[3] = params[ALPHATESTREFERENCE]->GetFloatValue(); + } + + pShaderAPI->SetPixelShaderConstant( 0, vAlphaThreshold, 1 ); + } + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( depthwrite_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); + SET_DYNAMIC_PIXEL_SHADER( depthwrite_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( depthwrite_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); + SET_DYNAMIC_PIXEL_SHADER( depthwrite_ps20 ); + } + } +#ifndef _X360 + else // 3.0 shader case (PC only) + { + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + depthwrite_vs30_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetMORPHING( pShaderAPI->IsHWMorphingEnabled() ); + vshIndex.SetCOMPRESSED_VERTS( (int)vertexCompression ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if ( bAlphaClip ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + float vAlphaThreshold[4] = {0.7f, 0.7f, 0.7f, 0.7f}; + if ( ALPHATESTREFERENCE != -1 && ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) ) + { + vAlphaThreshold[0] = vAlphaThreshold[1] = vAlphaThreshold[2] = vAlphaThreshold[3] = params[ALPHATESTREFERENCE]->GetFloatValue(); + } + + pShaderAPI->SetPixelShaderConstant( 0, vAlphaThreshold, 1 ); + } + + DECLARE_DYNAMIC_PIXEL_SHADER( depthwrite_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); + SET_DYNAMIC_PIXEL_SHADER( depthwrite_ps30 ); + } +#endif + + Vector4D vParms; + + // set up arbitrary far planes, as the real ones are too far ( 30,000 ) +// pShaderAPI->SetPSNearAndFarZ( 1 ); + vParms.x = 7.0f; // arbitrary near + vParms.y = 4000.0f; // arbitrary far + vParms.z = 0.0f; + vParms.w = 0.0f; + pShaderAPI->SetPixelShaderConstant( 1, vParms.Base(), 2 ); + + } // DYNAMIC_STATE + + Draw( ); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/depthwrite_ps2x.fxc b/mp/src/materialsystem/stdshaders/depthwrite_ps2x.fxc new file mode 100644 index 00000000..1baabcf3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/depthwrite_ps2x.fxc @@ -0,0 +1,44 @@ +// STATIC: "COLOR_DEPTH" "0..1" + +// DYNAMIC: "ALPHACLIP" "0..1" + +const float g_AlphaThreshold : register( c0 ); + +const float2 g_vNearFarPlanes : register( c1 ); + #define g_flNearPlane g_vNearFarPlanes.x + #define g_flFarPlane g_vNearFarPlanes.y + +struct PS_INPUT +{ +#if ALPHACLIP + float2 texCoord0 : TEXCOORD0; +#endif + +#if COLOR_DEPTH + float4 vWorldPos_projPosZ : TEXCOORD1; +#endif +}; + +sampler BaseTextureSampler : register( s0 ); + +float4 main( PS_INPUT i ) : COLOR +{ + float4 color = float4( 1, 0, 0, 1 ); // opaque alpha....the color doesn't matter for this shader + +#if ALPHACLIP + color = tex2D( BaseTextureSampler, i.texCoord0 ); + + clip( color.a - g_AlphaThreshold ); + +#endif + +#if ( COLOR_DEPTH == 1 ) + + return float4( i.vWorldPos_projPosZ.w / g_flFarPlane, 0.0, 0.0, 1.0 ); + +#else + + return color; + +#endif +} diff --git a/mp/src/materialsystem/stdshaders/depthwrite_vs20.fxc b/mp/src/materialsystem/stdshaders/depthwrite_vs20.fxc new file mode 100644 index 00000000..f98e40e2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/depthwrite_vs20.fxc @@ -0,0 +1,83 @@ +// STATIC: "ONLY_PROJECT_POSITION" "0..1" [XBOX] +// STATIC: "ONLY_PROJECT_POSITION" "0..0" [PC] +// STATIC: "COLOR_DEPTH" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord : TEXCOORD0; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + + // Position delta stream + float3 vPosFlex : POSITION1; + +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + +#if (ONLY_PROJECT_POSITION == 0) //360 sometimes runs without the pixel shader component, but has to patch this output if it does. + float2 texCoord : TEXCOORD0; +#endif + +#if COLOR_DEPTH + float4 vWorldPos_projPosZ : TEXCOORD1; +#endif + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + float3 vWorldPos; + float4 vPosition = v.vPos; + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, vPosition.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, float3(0, 0, 0), vPosition.xyz ); +#endif + + SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, vWorldPos ); + + float4 vProjPos = mul( float4( vWorldPos, 1.0f ), cViewProj ); + + o.vProjPos = vProjPos; + +#if (ONLY_PROJECT_POSITION == 0) + o.texCoord = v.vTexCoord; +#endif + +#if ( COLOR_DEPTH && !ONLY_PROJECT_POSITION ) + o.vWorldPos_projPosZ.z = vProjPos.z; + o.vWorldPos_projPosZ.w = vProjPos.w; +#endif + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/detail.cpp b/mp/src/materialsystem/stdshaders/detail.cpp new file mode 100644 index 00000000..956bf518 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/detail.cpp @@ -0,0 +1,37 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Detail, "Help for Detail" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + } + + SHADER_FALLBACK + { + return "UnlitGeneric"; + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + } + +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/detail_ps11.psh b/mp/src/materialsystem/stdshaders/detail_ps11.psh new file mode 100644 index 00000000..fb5916ab --- /dev/null +++ b/mp/src/materialsystem/stdshaders/detail_ps11.psh @@ -0,0 +1,12 @@ +ps.1.1 + +tex t0 +tex t1 + +mul r0.rgb, t0, v0 + + +; handle distance fade +sub r0.a, t0.a, 1-v0.a + +sub r0.a, r0.a, t1_bias.a +cnd r0.a, r0.a, c0.a, c1.a diff --git a/mp/src/materialsystem/stdshaders/detail_vs11.vsh b/mp/src/materialsystem/stdshaders/detail_vs11.vsh new file mode 100644 index 00000000..28dee2fd --- /dev/null +++ b/mp/src/materialsystem/stdshaders/detail_vs11.vsh @@ -0,0 +1,56 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 +mov $worldPos.w, $cOne + + +;------------------------------------------------------------------------------ +; Transform the position from world to proj space +;------------------------------------------------------------------------------ +&AllocateRegister( \$projPos ); +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); +&FreeRegister( \$worldPos ); + + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +mov oT0.xy, $vTexCoord0.xy + +; special case perspective correct texture projection so that the texture fits exactly on the screen +mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_0.w +add $projPos.xy, $projPos.xy, $projPos.w +mul $projPos.xy, $projPos.xy, $cHalf +mul $projPos.xy, $projPos.xy, $SHADER_SPECIFIC_CONST_0.xy +mad $projPos.xy, $projPos.w, $SHADER_SPECIFIC_CONST_1.xy, $projPos.xy + +mov oT1.xy, $projPos.xy +mov oT1.z, $projPos.w +mov oT1.w, $projPos.w + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Modulation color +;------------------------------------------------------------------------------ +mov oD0, $vColor diff --git a/mp/src/materialsystem/stdshaders/eye_refract.cpp b/mp/src/materialsystem/stdshaders/eye_refract.cpp new file mode 100644 index 00000000..87528028 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eye_refract.cpp @@ -0,0 +1,253 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "eye_refract_helper.h" +#include "cloak_blended_pass_helper.h" +#include "emissive_scroll_blended_pass_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( EyeRefract, EyeRefract_dx9 ) +BEGIN_VS_SHADER( EyeRefract_dx9, "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( CORNEATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "cornea texture" ) + SHADER_PARAM( AMBIENTOCCLTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "reflection texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + + SHADER_PARAM( EYEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "origin 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( DILATION, SHADER_PARAM_TYPE_FLOAT, "0", "Pupil dilation (0 is none, 1 is maximal)" ) + SHADER_PARAM( GLOSSINESS, SHADER_PARAM_TYPE_FLOAT, "1", "Glossiness of eye (1 is default, 0 is not glossy at all)" ) + SHADER_PARAM( SPHERETEXKILLCOMBO, SHADER_PARAM_TYPE_BOOL, "1", "texkill pixels not on sphere" ) + SHADER_PARAM( RAYTRACESPHERE, SHADER_PARAM_TYPE_BOOL, "1", "Raytrace sphere" ) + SHADER_PARAM( PARALLAXSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1", "Parallax strength" ) + SHADER_PARAM( CORNEABUMPSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1", "Cornea strength" ) + + SHADER_PARAM( AMBIENTOCCLCOLOR, SHADER_PARAM_TYPE_VEC3, "[1 1 1]", "Ambient occlusion color" ) + SHADER_PARAM( EYEBALLRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Eyeball radius for ray casting" ) + + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is eyes in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + + // Emissive Scroll Pass + SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) + SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) + SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) + SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( EMISSIVEBLENDFLOWTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "flow map" ) + END_SHADER_PARAMS + + void SetupVarsEyeRefract( Eye_Refract_Vars_t &info ) + { + info.m_nFrame = FRAME; + info.m_nIris = IRIS; + info.m_nIrisFrame = IRISFRAME; + info.m_nEyeOrigin = EYEORIGIN; + info.m_nIrisU = IRISU; + info.m_nIrisV = IRISV; + info.m_nDilation = DILATION; + info.m_nGlossiness = GLOSSINESS; + info.m_nIntro = INTRO; + info.m_nEntityOrigin = ENTITYORIGIN; + info.m_nWarpParam = WARPPARAM; + info.m_nCorneaTexture = CORNEATEXTURE; + info.m_nAmbientOcclTexture = AMBIENTOCCLTEXTURE; + info.m_nEnvmap = ENVMAP; + info.m_nSphereTexKillCombo = SPHERETEXKILLCOMBO; + info.m_nRaytraceSphere = RAYTRACESPHERE; + info.m_nParallaxStrength = PARALLAXSTRENGTH; + info.m_nCorneaBumpStrength = CORNEABUMPSTRENGTH; + info.m_nAmbientOcclColor = AMBIENTOCCLCOLOR; + info.m_nEyeballRadius = EYEBALLRADIUS; + info.m_nDiffuseWarpTexture = LIGHTWARPTEXTURE; + } + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + // Emissive Scroll Pass + void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) + { + info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; + info.m_nBaseTexture = IRIS; + info.m_nFlowTexture = EMISSIVEBLENDFLOWTEXTURE; + info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; + info.m_nEmissiveTint = EMISSIVEBLENDTINT; + info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; + } + + SHADER_INIT_PARAMS() + { + Eye_Refract_Vars_t info; + SetupVarsEyeRefract( info ); + InitParams_Eyes_Refract( this, params, pMaterialName, info ); + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + + // Emissive Scroll Pass + if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) + { + params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); + } + else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Eyes_dx8"; + } + + return 0; + } + + SHADER_INIT + { + Eye_Refract_Vars_t info; + SetupVarsEyeRefract( info ); + Init_Eyes_Refract( this, params, info ); + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitEmissiveScrollBlendedPass( this, params, info ); + } + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardEye = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + bDrawStandardEye = false; + } + } + + // Standard rendering pass + if ( bDrawStandardEye ) + { + Eye_Refract_Vars_t info; + SetupVarsEyeRefract( info ); + Draw_Eyes_Refract( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/eye_refract_helper.cpp b/mp/src/materialsystem/stdshaders/eye_refract_helper.cpp new file mode 100644 index 00000000..af4d2c08 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eye_refract_helper.cpp @@ -0,0 +1,461 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "eye_refract_helper.h" + +#include "cpp_shader_constant_register_map.h" + +#include "eyes_flashlight_vs11.inc" +#include "eyes_flashlight_ps11.inc" + +#include "eye_refract_vs20.inc" +#include "eye_refract_ps20.inc" +#include "eye_refract_ps20b.inc" + +#ifndef _X360 +#include "eye_refract_vs30.inc" +#include "eye_refract_ps30.inc" +#endif + +#include "convar.h" + +static ConVar r_lightwarpidentity( "r_lightwarpidentity","0", FCVAR_CHEAT ); + +void InitParams_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Eye_Refract_Vars_t &info ) +{ + // FLASHLIGHTFIXME + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + + // Set material flags + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + // Set material parameter default values + if ( ( info.m_nIntro >= 0 ) && ( !params[info.m_nIntro]->IsDefined() ) ) + { + params[info.m_nIntro]->SetIntValue( kDefaultIntro ); + } + + if ( ( info.m_nDilation >= 0 ) && ( !params[info.m_nDilation]->IsDefined() ) ) + { + params[info.m_nDilation]->SetFloatValue( kDefaultDilation ); + } + + if ( ( info.m_nGlossiness >= 0 ) && ( !params[info.m_nGlossiness]->IsDefined() ) ) + { + params[info.m_nGlossiness]->SetFloatValue( kDefaultGlossiness ); + } + + if ( ( info.m_nSphereTexKillCombo >= 0 ) && ( !params[info.m_nSphereTexKillCombo]->IsDefined() ) ) + { + params[info.m_nSphereTexKillCombo]->SetIntValue( kDefaultSphereTexKillCombo ); + } + + if ( ( info.m_nRaytraceSphere >= 0 ) && ( !params[info.m_nRaytraceSphere]->IsDefined() ) ) + { + params[info.m_nRaytraceSphere]->SetIntValue( kDefaultRaytraceSphere ); + } + + if ( ( info.m_nAmbientOcclColor >= 0 ) && ( !params[info.m_nAmbientOcclColor]->IsDefined() ) ) + { + params[info.m_nAmbientOcclColor]->SetVecValue( kDefaultAmbientOcclColor, 4 ); + } + + if ( ( info.m_nEyeballRadius >= 0 ) && ( !params[info.m_nEyeballRadius]->IsDefined() ) ) + { + params[info.m_nEyeballRadius]->SetFloatValue( kDefaultEyeballRadius ); + } + + if ( ( info.m_nParallaxStrength >= 0 ) && ( !params[info.m_nParallaxStrength]->IsDefined() ) ) + { + params[info.m_nParallaxStrength]->SetFloatValue( kDefaultParallaxStrength ); + } + + if ( ( info.m_nCorneaBumpStrength >= 0 ) && ( !params[info.m_nCorneaBumpStrength]->IsDefined() ) ) + { + params[info.m_nCorneaBumpStrength]->SetFloatValue( kDefaultCorneaBumpStrength ); + } +} + +void Init_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, Eye_Refract_Vars_t &info ) +{ + pShader->LoadTexture( info.m_nCorneaTexture ); // SHADER_SAMPLER0 (this is a normal, hence not sRGB) + pShader->LoadTexture( info.m_nIris, TEXTUREFLAGS_SRGB ); // SHADER_SAMPLER1 + pShader->LoadCubeMap( info.m_nEnvmap, TEXTUREFLAGS_SRGB ); // SHADER_SAMPLER2 + pShader->LoadTexture( info.m_nAmbientOcclTexture, TEXTUREFLAGS_SRGB ); // SHADER_SAMPLER3 + + if ( IS_PARAM_DEFINED( info.m_nDiffuseWarpTexture ) ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); // SHADER_SAMPLER4 + } + + pShader->LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); // SHADER_SAMPLER5 +} + +void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, bool bDrawFlashlightAdditivePass, Eye_Refract_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + bool bDiffuseWarp = IS_PARAM_DEFINED( info.m_nDiffuseWarpTexture ); + bool bIntro = IS_PARAM_DEFINED( info.m_nIntro ) ? ( params[info.m_nIntro]->GetIntValue() ? true : false ) : false; + + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Cornea normal + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Iris + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Cube reflection + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Ambient occlusion + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + if ( bDiffuseWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Light warp + } + + int nShadowFilterMode = 0; + if ( bDrawFlashlightAdditivePass == true ) + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + + pShaderShadow->EnableDepthWrites( false ); + pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Write over the eyes that were already there + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Flashlight cookie + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_STATIC_VERTEX_SHADER( eye_refract_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, bIntro ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( eye_refract_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + bool bSphereTexKillCombo = IS_PARAM_DEFINED( info.m_nSphereTexKillCombo ) ? ( params[info.m_nSphereTexKillCombo]->GetIntValue() ? true : false ) : ( kDefaultSphereTexKillCombo ? true : false ); + bool bRayTraceSphere = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? ( params[info.m_nRaytraceSphere]->GetIntValue() ? true : false ) : ( kDefaultRaytraceSphere ? true : false ); + + DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( SPHERETEXKILLCOMBO, bSphereTexKillCombo ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( RAYTRACESPHERE, bRayTraceSphere ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( eye_refract_ps20b ); + + if ( bDrawFlashlightAdditivePass == true ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER6 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Noise map + } + } + else + { + DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER( eye_refract_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( eye_refract_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, bIntro ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( eye_refract_vs30 ); + + bool bSphereTexKillCombo = IS_PARAM_DEFINED( info.m_nSphereTexKillCombo ) ? ( params[info.m_nSphereTexKillCombo]->GetIntValue() ? true : false ) : ( kDefaultSphereTexKillCombo ? true : false ); + bool bRayTraceSphere = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? ( params[info.m_nRaytraceSphere]->GetIntValue() ? true : false ) : ( kDefaultRaytraceSphere ? true : false ); + + DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( SPHERETEXKILLCOMBO, bSphereTexKillCombo ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( RAYTRACESPHERE, bRayTraceSphere ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( eye_refract_ps30 ); + + if ( bDrawFlashlightAdditivePass == true ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Shadow depth map + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Noise map + } + } +#endif + + // On DX9, get the gamma read and write correct + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // Iris + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); // Cube map reflection + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); // Ambient occlusion + pShaderShadow->EnableSRGBWrite( true ); + + if ( bDrawFlashlightAdditivePass == true ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true ); // Flashlight cookie + } + + // Fog + if ( bDrawFlashlightAdditivePass == true ) + { + pShader->FogToBlack(); + } + else + { + pShader->FogToFogColor(); + } + } + DYNAMIC_STATE + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture = NULL; + FlashlightState_t flashlightState; + bool bFlashlightShadows = false; + if ( bDrawFlashlightAdditivePass == true ) + { + flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + } + + pShader->BindTexture( SHADER_SAMPLER0, info.m_nCorneaTexture ); // Cornea normal + pShader->BindTexture( SHADER_SAMPLER1, info.m_nIris, info.m_nIrisFrame ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nEnvmap ); + pShader->BindTexture( SHADER_SAMPLER3, info.m_nAmbientOcclTexture ); + + if ( bDiffuseWarp ) + { + if ( r_lightwarpidentity.GetBool() ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_IDENTITY_LIGHTWARP ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER4, info.m_nDiffuseWarpTexture ); + } + } + + if ( bDrawFlashlightAdditivePass == true ) + pShader->BindTexture( SHADER_SAMPLER5, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + pShader->SetAmbientCubeDynamicStateVertexShader(); + + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nEyeOrigin ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nIrisU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nIrisV ); + + if ( bDrawFlashlightAdditivePass == true ) + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, flashlightState.m_vecLightOrigin.Base(), 1 ); + + LightState_t lightState = { 0, false, false }; + if ( bDrawFlashlightAdditivePass == false ) + { + pShaderAPI->GetDX9LightState( &lightState ); + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_DYNAMIC_VERTEX_SHADER( eye_refract_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eye_refract_vs20 ); + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( eye_refract_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eye_refract_vs30 ); + } +#endif + + // Get luminance of ambient cube and saturate it + float fAverageAmbient = max(0.0f, min( pShaderAPI->GetAmbientLightCubeLuminance(), 1.0f ) ); + + // Special constant for DX9 eyes: { Dilation, Glossiness, x, x }; + float vPSConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPSConst[0] = IS_PARAM_DEFINED( info.m_nDilation ) ? params[info.m_nDilation]->GetFloatValue() : kDefaultDilation; + vPSConst[1] = IS_PARAM_DEFINED( info.m_nGlossiness ) ? params[info.m_nGlossiness]->GetFloatValue() : kDefaultGlossiness; + vPSConst[2] = fAverageAmbient; + vPSConst[3] = IS_PARAM_DEFINED( info.m_nCorneaBumpStrength ) ? params[info.m_nCorneaBumpStrength]->GetFloatValue() : kDefaultCorneaBumpStrength; + pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); + + pShaderAPI->SetPixelShaderConstant( 1, IS_PARAM_DEFINED( info.m_nEyeOrigin ) ? params[info.m_nEyeOrigin]->GetVecValue() : kDefaultEyeOrigin, 1 ); + pShaderAPI->SetPixelShaderConstant( 2, IS_PARAM_DEFINED( info.m_nIrisU ) ? params[info.m_nIrisU]->GetVecValue() : kDefaultIrisU, 1 ); + pShaderAPI->SetPixelShaderConstant( 3, IS_PARAM_DEFINED( info.m_nIrisV ) ? params[info.m_nIrisV]->GetVecValue() : kDefaultIrisV, 1 ); + + float vEyePos[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + pShaderAPI->SetPixelShaderConstant( 4, vEyePos, 1 ); + pShaderAPI->SetPixelShaderConstant( 5, IS_PARAM_DEFINED( info.m_nAmbientOcclColor ) ? params[info.m_nAmbientOcclColor]->GetVecValue() : kDefaultAmbientOcclColor, 1 ); + + float vPackedConst6[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + //vPackedConst6[0] Unused + vPackedConst6[1] = IS_PARAM_DEFINED( info.m_nEyeballRadius ) ? params[info.m_nEyeballRadius]->GetFloatValue() : kDefaultEyeballRadius; + //vPackedConst6[2] = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? params[info.m_nRaytraceSphere]->GetFloatValue() : kDefaultRaytraceSphere; + vPackedConst6[3] = IS_PARAM_DEFINED( info.m_nParallaxStrength ) ? params[info.m_nParallaxStrength]->GetFloatValue() : kDefaultParallaxStrength; + pShaderAPI->SetPixelShaderConstant( 6, vPackedConst6, 1 ); + + float fPixelFogType = pShaderAPI->GetPixelFogCombo() == 1 ? 1 : 0; + + // Controls for lerp-style paths through shader code + float vShaderControls[4] = { fPixelFogType, 0, 0, 0 }; + pShaderAPI->SetPixelShaderConstant( 10, vShaderControls, 1 ); + + if ( bDrawFlashlightAdditivePass == true ) + { + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + if ( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER6, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER7, TEXTURE_SHADOW_NOISE_2D ); + } + } + + // Flashlight tax +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps20b ); + } + else // ps.2.0 + { + DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps20 ); + } + } +#ifndef _X360 + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps30 ); + } +#endif + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + if ( bDrawFlashlightAdditivePass == true ) + { + float atten[4], pos[4], tweaks[4]; + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( 7, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( 8, pos, 1 ); + + //pShaderAPI->SetPixelShaderConstant( 9, worldToTexture.Base(), 4 ); + //10 + //11 + //12 + + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture[0], 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, worldToTexture[1], 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, worldToTexture[2], 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, worldToTexture[3], 1 ); + + // Tweaks associated with a given flashlight + tweaks[0] = flashlightState.m_flShadowFilterSize / flashlightState.m_flShadowMapResolution; + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( 9, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + } + else // Lighting constants when not drawing flashlight + { + pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); + } + + // Intro tax + if ( bIntro ) + { + float curTime = params[info.m_nWarpParam]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + if ( IS_PARAM_DEFINED( info.m_nEntityOrigin ) ) + { + params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, timeVec, 1 ); + } + } + pShader->Draw(); +} + + +extern ConVar r_flashlight_version2; +void Draw_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eye_Refract_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + Draw_Eyes_Refract_Internal( pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression ); + if ( pShaderShadow ) + { + pShader->SetInitialShadowState( ); + } + } + Draw_Eyes_Refract_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression ); +} diff --git a/mp/src/materialsystem/stdshaders/eye_refract_helper.h b/mp/src/materialsystem/stdshaders/eye_refract_helper.h new file mode 100644 index 00000000..ce62a33b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eye_refract_helper.h @@ -0,0 +1,69 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef EYE_REFRACT_HELPER_H +#define EYE_REFRACT_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct Eye_Refract_Vars_t +{ + Eye_Refract_Vars_t() { memset( this, 0xFF, sizeof(Eye_Refract_Vars_t) ); } + + int m_nFrame; + int m_nIris; + int m_nIrisFrame; + int m_nEyeOrigin; + int m_nIrisU; + int m_nIrisV; + int m_nDilation; + int m_nGlossiness; + int m_nIntro; + int m_nEntityOrigin; // Needed for intro + int m_nWarpParam; + int m_nCorneaTexture; + int m_nAmbientOcclTexture; + int m_nEnvmap; + int m_nSphereTexKillCombo; + int m_nRaytraceSphere; + int m_nParallaxStrength; + int m_nCorneaBumpStrength; + int m_nAmbientOcclColor; + int m_nEyeballRadius; + int m_nDiffuseWarpTexture; +}; + +// Default values (Arrays should only be vec[4]) +static const int kDefaultIntro = 0; +static const float kDefaultEyeOrigin[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; +static const float kDefaultIrisU[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; +static const float kDefaultIrisV[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; +static const float kDefaultDilation = 0.5f; +static const float kDefaultGlossiness = 1.0f; +static const float kDefaultWarpParam = 0.0f; +static const int kDefaultSphereTexKillCombo = 0; +static const int kDefaultRaytraceSphere = 0; +static const float kDefaultParallaxStrength = 0.25f; +static const float kDefaultCorneaBumpStrength = 1.0f; +static const float kDefaultAmbientOcclColor[4] = { 0.33f, 0.33f, 0.33f, 0.0f }; +static const float kDefaultEyeballRadius = 0.5f; + +void InitParams_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Eye_Refract_Vars_t &info ); +void Init_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, Eye_Refract_Vars_t &info ); +void Draw_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eye_Refract_Vars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // EYES_DX8_DX9_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/eye_refract_ps2x.fxc b/mp/src/materialsystem/stdshaders/eye_refract_ps2x.fxc new file mode 100644 index 00000000..da053d22 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eye_refract_ps2x.fxc @@ -0,0 +1,494 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =========================== + +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" + +// STATIC: "SPHERETEXKILLCOMBO" "0..1" [ps20b] +// STATIC: "SPHERETEXKILLCOMBO" "0..1" [ps30] + +// STATIC: "RAYTRACESPHERE" "0..1" [ps20b] +// STATIC: "RAYTRACESPHERE" "0..1" [ps30] + +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] + +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] + +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +// We don't use other lights when doing the flashlight +// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// SKIP: ( $RAYTRACESPHERE == 0 ) && ( $SPHERETEXKILLCOMBO == 1 ) [ps30] +// SKIP: ( $RAYTRACESPHERE == 0 ) && ( $SPHERETEXKILLCOMBO == 1 ) [ps20b] + +// Debug 2.0 shader locally +//#ifdef SHADER_MODEL_PS_2_B +//#undef SHADER_MODEL_PS_2_B +//#define SHADER_MODEL_PS_2_0 +//#endif + + +// Includes ======================================================================================= +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +// Texture Samplers =============================================================================== +sampler g_tCorneaSampler : register( s0 ); +sampler g_tIrisSampler : register( s1 ); +sampler g_tEyeReflectionCubemapSampler : register( s2 ); +sampler g_tEyeAmbientOcclSampler : register( s3 ); +sampler g_tLightwarpSampler : register( s4 ); // 1D texture for TF NPR lighting + +sampler g_tFlashlightCookieSampler : register( s5 ); +sampler g_tFlashlightDepthSampler : register( s6 ); +sampler g_tRandomRotationSampler : register( s7 ); + +// Shaders Constants and Globals ================================================================== +const float4 g_vPackedConst0 : register( c0 ); +#define g_flDilationFactor g_vPackedConst0.x +#define g_flGlossiness g_vPackedConst0.y +#define g_flAverageAmbient g_vPackedConst0.z +#define g_flCorneaBumpStrength g_vPackedConst0.w + +const float3 g_vEyeOrigin : register( c1 ); +const float4 g_vIrisProjectionU : register( c2 ); +const float4 g_vIrisProjectionV : register( c3 ); +const float4 g_vCameraPosition : register( c4 ); +const float3 g_cAmbientOcclColor : register( c5 ); + +const float4 g_vPackedConst6 : register( c6 ); +#define g_flEyeballRadius g_vPackedConst6.y //0.51f +//#define g_bRaytraceSphere g_vPackedConst6.z //1.0f +#define g_flParallaxStrength g_vPackedConst6.w //0.25f + +// Flashlight constants +const float4 g_vFlashlightAttenuationFactors : register( c7 ); // FarZ in w +const float3 g_vFlashlightPos : register( c8 ); +const float4 g_vShadowTweaks : register( c9 ); +const float4 g_ShaderControls : register( c10 ); +#define g_fPixelFogType g_ShaderControls.x + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); + +PixelShaderLightInfo g_sLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float4 vAmbientOcclUv_fallbackCorneaUv : TEXCOORD0; + float4 cVertexLight : TEXCOORD1; // w is used for the flashlight pass + float4 vTangentViewVector : TEXCOORD2; // Tangent view vector (Note: w is used for flashlight pass) + float4 vWorldPosition_ProjPosZ : TEXCOORD3; + float3 vWorldNormal : TEXCOORD4; // World-space normal + float3 vWorldTangent : TEXCOORD5; // World-space tangent + float4 vLightFalloffCosine01 : TEXCOORD6; // Light falloff and cosine terms for first two local lights + float4 vLightFalloffCosine23 : TEXCOORD7; // Light falloff and cosine terms for next two local lights + + float3 vWorldBinormal : COLOR0; // World-space normal +}; + +// Ray sphere intersect returns distance along ray to intersection ================================ +float IntersectRaySphere ( float3 cameraPos, float3 ray, float3 sphereCenter, float sphereRadius) +{ + float3 dst = cameraPos.xyz - sphereCenter.xyz; + float B = dot(dst, ray); + float C = dot(dst, dst) - (sphereRadius * sphereRadius); + float D = B*B - C; + return (D > 0) ? (-B - sqrt(D)) : 0; +} + +// Calculate both types of Fog and lerp to get result +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); + return lerp( fRangeFog, fHeightFog, fPixelFogType ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + pixelFogFactor = saturate( pixelFogFactor ); + float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + return lerp( fRangeResult, fHeightResult, fPixelFogType ); +} + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + // Set bools to compile out code + bool bFlashlight = ( FLASHLIGHT != 0 ) ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + int nNumLights = FLASHLIGHT ? 1 : NUM_LIGHTS; // Flashlight is considered one light, otherwise, use numlights combo + +#if !defined( SHADER_MODEL_PS_2_0 ) + bool bRayCast = RAYTRACESPHERE ? true : false; + bool bRayCastTexKill = SPHERETEXKILLCOMBO ? true : false; +#endif + + float flFlashlightNDotL = i.vTangentViewVector.w; + float4 vFlashlightTexCoord = { 0.0f, 0.0f, 0.0f, 0.0f }; + if ( bFlashlight ) + { + vFlashlightTexCoord.xyzw = i.cVertexLight.xyzw; // This was hidden in this interpolator + i.cVertexLight.rgba = float4( 0.0f, 0.0f, 0.0f, 0.0f ); + } + + // Interpolated vectors + float3 vWorldNormal = i.vWorldNormal.xyz; + float3 vWorldTangent = i.vWorldTangent.xyz; + float3 vWorldBinormal = ( i.vWorldBinormal.xyz * 2.0f ) - 1.0f; // normalize( cross( vWorldNormal.xyz, vWorldTangent.xyz ) ); + + float3 vTangentViewVector = i.vTangentViewVector.xyz; + + // World position + float3 vWorldPosition = i.vWorldPosition_ProjPosZ.xyz; + + // World view vector to pixel + float3 vWorldViewVector = normalize( vWorldPosition.xyz - g_vCameraPosition.xyz ); + + //=================// + // TF NPR lighting // + //=================// + if ( bDoDiffuseWarp ) + { + // Replace the interpolated vertex light + if ( bFlashlight == true ) + { + // Deal with this below in the flashlight section + } + else + { + if ( nNumLights > 0 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine01.z ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ) * cWarpedLight.rgb; + } + + if ( nNumLights > 1 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine01.w ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ) * cWarpedLight.rgb; + } + + if ( nNumLights > 2 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine23.z ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ) * cWarpedLight.rgb; + } + + if ( nNumLights > 3 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine23.w ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ) * cWarpedLight.rgb; + } + } + } + + //==========================================================================================================// + // Ray cast against sphere representing eyeball to reduce artifacts from non-spherical morphed eye geometry // + //==========================================================================================================// +#if !defined( SHADER_MODEL_PS_2_0 ) + if ( bRayCast ) + { + float fSphereRayCastDistance = IntersectRaySphere( g_vCameraPosition.xyz, vWorldViewVector.xyz, g_vEyeOrigin.xyz, g_flEyeballRadius ); + vWorldPosition.xyz = g_vCameraPosition.xyz + ( vWorldViewVector.xyz * fSphereRayCastDistance ); + if (fSphereRayCastDistance == 0) + { + if ( bRayCastTexKill ) + clip(-1); // texkill to get a better silhouette + vWorldPosition.xyz = g_vEyeOrigin.xyz + ( vWorldNormal.xyz * g_flEyeballRadius ); + } + } +#endif + + //=================================// + // Generate sphere and cornea uv's // + //=================================// +#if !defined( SHADER_MODEL_PS_2_0 ) + float2 vCorneaUv; // Note: Cornea texture is a cropped version of the iris texture + vCorneaUv.x = dot( g_vIrisProjectionU, float4( vWorldPosition, 1.0f ) ); + vCorneaUv.y = dot( g_vIrisProjectionV, float4( vWorldPosition, 1.0f ) ); + float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; +#else // ps_20 + float2 vCorneaUv = i.vAmbientOcclUv_fallbackCorneaUv.wz; // Note: Cornea texture is a cropped version of the iris texture + float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; +#endif + + //=================================// + // Hacked parallax mapping on iris // + //=================================// + float fIrisOffset = tex2D( g_tCorneaSampler, vCorneaUv.xy ).b; + +#if !defined( SHADER_MODEL_PS_2_0 ) + float2 vParallaxVector = ( ( vTangentViewVector.xy * fIrisOffset * g_flParallaxStrength ) / ( 1.0f - vTangentViewVector.z ) ); // Note: 0.25 is a magic number + vParallaxVector.x = -vParallaxVector.x; //Need to flip x...not sure why. + //vParallaxVector.x *= -1.0; //Need to flip x...not sure why. + //vParallaxVector = 0.0f; //Disable parallax for debugging +#else // Disable parallax effect in 2.0 version + float2 vParallaxVector = { 0.0f, 0.0f }; +#endif + + float2 vIrisUv = vSphereUv.xy - vParallaxVector.xy; + + // Note: We fetch from this texture twice right now with different uv's for the color and alpha + float2 vCorneaNoiseUv = vSphereUv.xy + ( vParallaxVector.xy * 0.5 ); + float fCorneaNoise = tex2D( g_tIrisSampler, vCorneaNoiseUv.xy ).a; + + //===============// + // Cornea normal // + //===============// + // Sample 2D normal from texture + float3 vCorneaTangentNormal = { 0.0, 0.0, 1.0 }; + float4 vCorneaSample = tex2D( g_tCorneaSampler, vCorneaUv.xy ); + vCorneaTangentNormal.xy = vCorneaSample.rg - 0.5f; // Note: This scales the bump to 50% strength + + // Scale strength of normal + vCorneaTangentNormal.xy *= g_flCorneaBumpStrength; + + // Add in surface noise and imperfections (NOTE: This should be baked into the normal map!) + vCorneaTangentNormal.xy += fCorneaNoise * 0.1f; + + // Normalize tangent vector +#if !defined( SHADER_MODEL_PS_2_0 ) + // Since this isn't used later in 2.0, skip the normalize to save shader instructions + vCorneaTangentNormal.xyz = normalize( vCorneaTangentNormal.xyz ); +#endif + + // Transform into world space + float3 vCorneaWorldNormal = Vec3TangentToWorldNormalized( vCorneaTangentNormal.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + //============// + // Flashlight // + //============// + float3 vFlashlightVector = { 0.0f, 0.0f, 0.0f }; + float3 cFlashlightColorFalloff = { 0.0f, 0.0f, 0.0f }; + if ( bFlashlight == true ) + { + // Flashlight vector + vFlashlightVector.xyz = normalize( g_vFlashlightPos.xyz - i.vWorldPosition_ProjPosZ.xyz ); + + // Distance attenuation for flashlight and to fade out shadow over distance + float3 vDelta = g_vFlashlightPos.xyz - i.vWorldPosition_ProjPosZ.xyz; + float flDistSquared = dot( vDelta, vDelta ); + float flDist = sqrt( flDistSquared ); + float flFlashlightAttenuation = dot( g_vFlashlightAttenuationFactors.xyz, float3( 1.0f, 1.0f/flDist, 1.0f/flDistSquared ) ); + + // Flashlight cookie +#if !defined( SHADER_MODEL_PS_2_0 ) + float3 vProjCoords = vFlashlightTexCoord.xyz / vFlashlightTexCoord.w; + float3 cFlashlightCookieColor = tex2D( g_tFlashlightCookieSampler, vProjCoords ); +#else + float3 cFlashlightCookieColor = tex2Dproj( g_tFlashlightCookieSampler, vFlashlightTexCoord.xyzw ); +#endif + + // Shadow depth map +#if FLASHLIGHTSHADOWS && !defined( SHADER_MODEL_PS_2_0 ) + int nShadowLevel = FLASHLIGHTDEPTHFILTERMODE; + float flShadow = DoFlashlightShadow( g_tFlashlightDepthSampler, g_tRandomRotationSampler, vProjCoords, float2(0,0), nShadowLevel, g_vShadowTweaks, false ); + float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = lerp( flAttenuated, flShadow, flFlashlightAttenuation ); // Blend between shadow and above, according to light attenuation + cFlashlightCookieColor *= flShadow; // Apply shadow term to cookie color +#endif + + // Flashlight color intensity (needs to be multiplied by global flashlight color later) + cFlashlightColorFalloff.rgb = flFlashlightAttenuation * cFlashlightCookieColor.rgb; + + // Add this into the interpolated lighting + if ( bDoDiffuseWarp ) + { + //float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, flFlashlightNDotL ).rgb; + //i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * cWarpedLight.rgb; + i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * flFlashlightNDotL; // No light warp for now + } + else + { + i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * flFlashlightNDotL; + } + } + + //==============// + // Dilate pupil // + //==============// +#if !defined( SHADER_MODEL_PS_2_0 ) + vIrisUv.xy -= 0.5f; // Center around (0,0) + float fPupilCenterToBorder = saturate( length( vIrisUv.xy ) / 0.2f ); //Note: 0.2 is the uv radius of the iris + float fPupilDilateFactor = g_flDilationFactor; // This value should be between 0-1 + vIrisUv.xy *= lerp (1.0f, fPupilCenterToBorder, saturate( fPupilDilateFactor ) * 2.5f - 1.25f ); + vIrisUv.xy += 0.5f; +#endif + + //============// + // Iris color // + //============// + float4 cIrisColor = tex2D( g_tIrisSampler, vIrisUv.xy ); + + //==========================// + // Iris lighting highlights // + //==========================// + float3 cIrisLighting = float3( 0.0f, 0.0f, 0.0f ); + +#if !defined( SHADER_MODEL_PS_2_0 ) + // Mask off everything but the iris pixels + float fIrisHighlightMask = tex2D( g_tCorneaSampler, vCorneaUv.xy ).a; + + // Generate the normal + float3 vIrisTangentNormal = vCorneaTangentNormal.xyz; + vIrisTangentNormal.xy *= -2.5f; // I'm not normalizing on purpose + + for ( int j=0; j < nNumLights; j++ ) + { + // World light vector + float3 vWorldLightVector; + if ( ( j == 0 ) && ( bFlashlight == true ) ) + vWorldLightVector = vFlashlightVector.xyz; + else + vWorldLightVector = PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, j ); + + // Tangent light vector + float3 vTangentLightVector = Vec3WorldToTangent( vWorldLightVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + // Adjust the tangent light vector to generate the iris lighting + float3 tmpv = -vTangentLightVector.xyz; + tmpv.xy *= -0.5f; //Flatten tangent view + tmpv.z = max( tmpv.z, 0.5f ); //Clamp z of tangent view to help maintain highlight + tmpv.xyz = normalize( tmpv.xyz ); + + // Core iris lighting math + float fIrisFacing = pow( abs( dot( vIrisTangentNormal.xyz, tmpv.xyz ) ), 6.0f ) * 0.5f; // Yes, 6.0 and 0.5 are magic numbers + + // Cone of darkness to darken iris highlights when light falls behind eyeball past a certain point + float flConeOfDarkness = pow( 1.0f - saturate( ( -vTangentLightVector.z - 0.25f ) / 0.75f ), 4.0f ); + //float flConeOfDarkness = pow( 1.0f - saturate( ( -dot( vIrisTangentNormal.xyz, vTangentLightVector.xyz ) - 0.15f ) / 0.85f ), 8.0f ); + + // Tint by iris color and cone of darkness + float3 cIrisLightingTmp = fIrisFacing * fIrisHighlightMask * flConeOfDarkness; + + // Attenuate by light color and light falloff + if ( ( j == 0 ) && ( bFlashlight == true ) ) + cIrisLightingTmp.rgb *= cFlashlightColorFalloff.rgb * cFlashlightColor.rgb; + else if ( j == 0 ) + cIrisLightingTmp.rgb *= i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ); + else if ( j == 1 ) + cIrisLightingTmp.rgb *= i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ); + else if ( j == 2 ) + cIrisLightingTmp.rgb *= i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ); + else + cIrisLightingTmp.rgb *= i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ); + + // Sum into final variable + cIrisLighting.rgb += cIrisLightingTmp.rgb; + } + + // Add slight view dependent iris lighting based on ambient light intensity to enhance situations with no local lights (0.5f is to help keep it subtle) + cIrisLighting.rgb += saturate( dot( vIrisTangentNormal.xyz, -vTangentViewVector.xyz ) ) * g_flAverageAmbient * fIrisHighlightMask * 0.5f; +#else + // Else, intensify light over cornea to simulate the brightening that happens above + cIrisLighting.rgb += i.cVertexLight.rgb * vCorneaSample.a; +#endif + + //===================// + // Ambient occlusion // + //===================// + float3 cAmbientOcclFromTexture = tex2D( g_tEyeAmbientOcclSampler, i.vAmbientOcclUv_fallbackCorneaUv.xy ).rgb; + float3 cAmbientOcclColor = lerp( g_cAmbientOcclColor, 1.0f, cAmbientOcclFromTexture.rgb ); // Color the ambient occlusion + i.cVertexLight.rgb *= cAmbientOcclColor.rgb; + + //==========================// + // Reflection from cube map // + //==========================// + float3 vCorneaReflectionVector = reflect ( vWorldViewVector.xyz, vCorneaWorldNormal.xyz ); + + //float3 cReflection = ENV_MAP_SCALE * texCUBE( g_tEyeReflectionCubemapSampler, vCorneaReflectionVector.xyz ).rgb; + float3 cReflection = g_flGlossiness * texCUBE( g_tEyeReflectionCubemapSampler, vCorneaReflectionVector.xyz ).rgb; + + // Hack: Only add in half of the env map for the flashlight pass. This looks reasonable. + if ( bFlashlight ) + { + cReflection.rgb *= 0.5f; + } + + //===========================// + // Glint specular highlights // + //===========================// + float3 cSpecularHighlights = 0.0f; + if ( bFlashlight ) + { + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, vFlashlightVector.xyz ) ), 128.0f ) * cFlashlightColorFalloff.rgb * cFlashlightColor.rgb; + } + else // no flashlight + { + if ( nNumLights > 0 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 0 ) ) ), 128.0f ) * i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ); + + if ( nNumLights > 1 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 1 ) ) ), 128.0f ) * i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ); + + if ( nNumLights > 2 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 2 ) ) ), 128.0f ) * i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ); + + if ( nNumLights > 3 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 3 ) ) ), 128.0f ) * i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ); + } + + //===============// + // Combine terms // + //===============// + float4 result; + + // Unlit iris, pupil, and sclera color + result.rgb = cIrisColor.rgb; + + // Add in slight cornea noise to help define raised cornea layer for close-ups + result.rgb += fCorneaNoise * 0.1f; + + // Diffuse light (Vertex lighting + extra iris caustic lighting) + result.rgb *= i.cVertexLight.rgb + cIrisLighting.rgb; + + // Environment map + result.rgb += cReflection.rgb * i.cVertexLight.rgb; + + // Local light glints + result.rgb += cSpecularHighlights.rgb; + + // Set alpha to 1.0 by default + result.a = 1.0; + +#if !defined( SHADER_MODEL_PS_2_0 ) + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_vCameraPosition.z, i.vWorldPosition_ProjPosZ.z, i.vWorldPosition_ProjPosZ.w ); + return FinalOutputConst( result, fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR ); +#else + float fogFactor = CalcPixelFogFactor( PIXEL_FOG_TYPE_NONE, g_FogParams, g_vCameraPosition.z, i.vWorldPosition_ProjPosZ.z, i.vWorldPosition_ProjPosZ.w ); + return FinalOutput( result, fogFactor, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +#endif + +} diff --git a/mp/src/materialsystem/stdshaders/eye_refract_vs20.fxc b/mp/src/materialsystem/stdshaders/eye_refract_vs20.fxc new file mode 100644 index 00000000..af975f99 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eye_refract_vs20.fxc @@ -0,0 +1,217 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "INTRO" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..4" +// DYNAMIC: "MORPHING" "0..1" [vs30] + +#include "vortwarp_vs20_helper.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_iFogType = DOWATERFOG; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; + +const float3 g_cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 ); +const float4 g_vIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 ); +const float4 g_vIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 ); +const float4 g_vFlashlightPosition : register( SHADER_SPECIFIC_CONST_4 ); + +#if INTRO +const float4 g_vConst4 : register( SHADER_SPECIFIC_CONST_5 ); +#define g_vModelOrigin g_vConst4.xyz +#define g_flTime g_vConst4.w +#endif + +const float4 g_vFlashlightMatrixRow1 : register( SHADER_SPECIFIC_CONST_6 ); +const float4 g_vFlashlightMatrixRow2 : register( SHADER_SPECIFIC_CONST_7 ); +const float4 g_vFlashlightMatrixRow3 : register( SHADER_SPECIFIC_CONST_8 ); +const float4 g_vFlashlightMatrixRow4 : register( SHADER_SPECIFIC_CONST_9 ); + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates + + // Position deltas + float3 vPosFlex : POSITION1; + +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; // Fixed-function fog factor +#endif + float4 vAmbientOcclUv_fallbackCorneaUv : TEXCOORD0; // Base texture coordinate + float4 cVertexLight : TEXCOORD1; // Vertex-lit color (Note: w is used for flashlight pass) + float4 vTangentViewVector : TEXCOORD2; // Tangent view vector (Note: w is used for flashlight pass) + float4 vWorldPosition_ProjPosZ : TEXCOORD3; + float3 vWorldNormal : TEXCOORD4; // World-space normal + float3 vWorldTangent : TEXCOORD5; // World-space tangent + float4 vLightFalloffCosine01 : TEXCOORD6; // Light falloff and cosine terms for first two local lights + float4 vLightFalloffCosine23 : TEXCOORD7; // Light falloff and cosine terms for next two local lights + + float3 vWorldBinormal : COLOR0; // World-space normal +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + int nNumLights = NUM_LIGHTS; + + float4 vPosition = v.vPos; + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, vPosition.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz ); +#endif + + // Transform the position + float3 vWorldPosition; + SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, vWorldPosition ); + + // Note: I'm relying on the iris projection vector math not changing or this will break + float3 vEyeSocketUpVector = normalize( -g_vIrisProjectionV.xyz ); + float3 vEyeSocketLeftVector = normalize( -g_vIrisProjectionU.xyz ); + +#if INTRO + float3 dummy = float3( 0.0f, 0.0f, 0.0f ); + WorldSpaceVertexProcess( g_flTime, g_vModelOrigin, vWorldPosition, dummy, dummy, dummy ); +#endif + + o.vWorldPosition_ProjPosZ.xyz = vWorldPosition.xyz; + + // Transform into projection space + //vWorldPosition -= ( vWorldPosition - g_cEyeOrigin ) * 0.9; //Debug to visualize eye origin + float4 vProjPos = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( vWorldPosition, 1.0f ), cViewProjZ ); + + + o.vWorldPosition_ProjPosZ.w = vProjPos.z; + +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( vWorldPosition, vProjPos, g_iFogType ); +#endif + + // Normal = (Pos - Eye origin) + float3 vWorldNormal = normalize( vWorldPosition.xyz - g_cEyeOrigin.xyz ); + o.vWorldNormal.xyz = vWorldNormal.xyz; + + // Tangent & binormal + /* + float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vEyeSocketLeftVector.xyz ) ); + o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f; + + float3 vWorldTangent = normalize( cross( vWorldBinormal.xyz, vWorldNormal.xyz ) ); + o.vWorldTangent.xyz = vWorldTangent.xyz; + //*/ + + //* + float3 vWorldTangent = normalize( cross( vEyeSocketUpVector.xyz, vWorldNormal.xyz ) ); + o.vWorldTangent.xyz = vWorldTangent.xyz; + + float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vWorldTangent.xyz ) ); + o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f; + //*/ + + float3 vWorldViewVector = normalize (vWorldPosition.xyz - cEyePos.xyz); + o.vTangentViewVector.xyz = Vec3WorldToTangentNormalized (vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz); + + // AV - I think this will effectively make the eyeball less rounded left to right to help vertext lighting quality + // AV - Note: This probably won't look good if put on an exposed eyeball + //float vNormalDotSideVec = -dot( vWorldNormal, g_vEyeballUp ) * 0.5f; + float vNormalDotSideVec = -dot( vWorldNormal, vEyeSocketLeftVector) * 0.5f; + float3 vBentWorldNormal = normalize(vNormalDotSideVec * vEyeSocketLeftVector + vWorldNormal); + + // Compute vertex lighting + o.cVertexLight.a = 0.0f; //Only used for flashlight pass + o.cVertexLight.rgb = DoLightingUnrolled( vWorldPosition, vBentWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, nNumLights ); + + // Only interpolate ambient light for TF NPR lighting + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + if ( bDoDiffuseWarp ) + { + if( bDynamicLight ) + { + o.cVertexLight.rgb = AmbientLight( vBentWorldNormal.xyz ); + } + else + { + o.cVertexLight.rgb = float3( 0.0f, 0.0f, 0.0f ); + } + } + +// NOTE: it appears that o.vLightFalloffCosine01 and o.vLightFalloffCosine23 are filled in even if +// we don't have enough lights, meaning we pass garbage to the pixel shader which then throws it away + + // Light falloff for first two local lights + o.vLightFalloffCosine01.x = VertexAttenInternal( vWorldPosition.xyz, 0 ); + o.vLightFalloffCosine01.y = VertexAttenInternal( vWorldPosition.xyz, 1 ); + o.vLightFalloffCosine01.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 0, g_bHalfLambert ); + o.vLightFalloffCosine01.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 1, g_bHalfLambert ); + + // Light falloff for next two local lights + o.vLightFalloffCosine23.x = VertexAttenInternal( vWorldPosition.xyz, 2 ); + o.vLightFalloffCosine23.y = VertexAttenInternal( vWorldPosition.xyz, 3 ); + o.vLightFalloffCosine23.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 2, g_bHalfLambert ); + o.vLightFalloffCosine23.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 3, g_bHalfLambert ); + + // Texture coordinates set by artists for ambient occlusion + o.vAmbientOcclUv_fallbackCorneaUv.xy = v.vTexCoord0.xy; + + // Cornea uv for ps.2.0 fallback + float2 vCorneaUv; // Note: Cornea texture is a cropped version of the iris texture + vCorneaUv.x = dot( g_vIrisProjectionU, float4( vWorldPosition, 1.0f ) ); + vCorneaUv.y = dot( g_vIrisProjectionV, float4( vWorldPosition, 1.0f ) ); + float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; + o.vAmbientOcclUv_fallbackCorneaUv.wz = vCorneaUv.xy; // Note: wz unpacks faster than zw in ps.2.0! + + // Step on the vertex light interpolator for the flashlight tex coords + bool bFlashlight = ( FLASHLIGHT != 0 ) ? true : false; + o.vTangentViewVector.w = 0.0f; + if ( bFlashlight ) + { + o.cVertexLight.x = dot( g_vFlashlightMatrixRow1.xyzw, float4( vWorldPosition, 1.0f ) ); + o.cVertexLight.y = dot( g_vFlashlightMatrixRow2.xyzw, float4( vWorldPosition, 1.0f ) ); + o.cVertexLight.z = dot( g_vFlashlightMatrixRow3.xyzw, float4( vWorldPosition, 1.0f ) ); + o.cVertexLight.w = dot( g_vFlashlightMatrixRow4.xyzw, float4( vWorldPosition, 1.0f ) ); + + o.vTangentViewVector.w = saturate( dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ) ); // Flashlight N.L with modified normal + + // Half lambert version + //o.cVertexLight.z = dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ); // Flashlight N.L with modified normal + //o.cVertexLight.z = ( o.cVertexLight.z * 0.5f ) + 0.5f; + //o.cVertexLight.z *= o.cVertexLight.z; + } + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/eyeball.cpp b/mp/src/materialsystem/stdshaders/eyeball.cpp new file mode 100644 index 00000000..7113585d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyeball.cpp @@ -0,0 +1,37 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Eyeball shader +// +//=============================================================================// + +#include "BaseVSShader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Eyeball, "Help for EyeBall" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/alyx/pupil_l", "iris texture", 0 ) + SHADER_PARAM_OVERRIDE( BASETEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + // This should be a dead shader... + return "Wireframe"; + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + } + +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/eyeglint_dx9.cpp b/mp/src/materialsystem/stdshaders/eyeglint_dx9.cpp new file mode 100644 index 00000000..d2662e6d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyeglint_dx9.cpp @@ -0,0 +1,66 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Run procedural glint generation inner loop in pixel shader +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "shaderlib/cshader.h" + +#include "eyeglint_vs20.inc" +#include "eyeglint_ps20.inc" +#include "eyeglint_ps20b.inc" + +DEFINE_FALLBACK_SHADER( EyeGlint, EyeGlint_dx9 ) +BEGIN_VS_SHADER( EyeGlint_dx9, "Help for EyeGlint" ) + +BEGIN_SHADER_PARAMS +END_SHADER_PARAMS + +SHADER_INIT +{ +} + +SHADER_FALLBACK +{ + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Wireframe"; + } + return 0; +} + +SHADER_DRAW +{ + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Additive blending + + int pTexCoords[3] = { 2, 2, 3 }; + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, pTexCoords, 0 ); + + pShaderShadow->EnableCulling( false ); + + pShaderShadow->EnableSRGBWrite( false ); // linear texture + + DECLARE_STATIC_VERTEX_SHADER( eyeglint_vs20 ); + SET_STATIC_VERTEX_SHADER( eyeglint_vs20 ); + + SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( eyeglint ); + } + + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( eyeglint_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( eyeglint_vs20 ); + + SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( eyeglint ); + } + Draw(); +} +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/eyeglint_ps2x.fxc b/mp/src/materialsystem/stdshaders/eyeglint_ps2x.fxc new file mode 100644 index 00000000..bc39f079 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyeglint_ps2x.fxc @@ -0,0 +1,32 @@ +// ======= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====== +// +// Run procedural glint generation inner loop in pixel shader (ps_2_0) +// +// ============================================================================= + +struct PS_INPUT +{ + float2 tc : TEXCOORD0; // Interpolated coordinate of current texel + float2 glintCenter : TEXCOORD1; // Uniform value containing center of glint + float3 glintColor : TEXCOORD2; // Uniform value of color of glint +}; + +float GlintGaussSpotCoefficient( float2 d ) +{ + return saturate( exp( -25.0f * dot(d, d) ) ); +} + +float4 main( PS_INPUT i ) : COLOR +{ + float2 uv = i.tc - i.glintCenter; // This texel relative to glint center + + float intensity = GlintGaussSpotCoefficient( uv + float2(-0.25f, -0.25f) ) + + GlintGaussSpotCoefficient( uv + float2( 0.25f, -0.25f) ) + + 5 * GlintGaussSpotCoefficient( uv ) + + GlintGaussSpotCoefficient( uv + float2(-0.25f, 0.25f) ) + + GlintGaussSpotCoefficient( uv + float2( 0.25f, 0.25f) ); + + intensity *= 4.0f/9.0f; + + return float4( intensity * i.glintColor, 1.0f ); +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/eyeglint_vs20.fxc b/mp/src/materialsystem/stdshaders/eyeglint_vs20.fxc new file mode 100644 index 00000000..cf1ccb9b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyeglint_vs20.fxc @@ -0,0 +1,38 @@ +//===== Copyright © 1996-2007, Valve Corporation, All rights reserved. ======// +// +// Vertex shader to pass through texcoords needed to run the +// procedural glint generation inner loop in the pixel shader +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 tc : TEXCOORD0; // Interpolated coordinate of current texel in 3x3 quad + float2 glintCenter : TEXCOORD1; // Uniform value containing center of glint in local 3x3 quad + float3 glintColor : TEXCOORD2; // Uniform value of color of glint +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 tc : TEXCOORD0; // Interpolated coordinate of current texel in 3x3 quad + float2 glintCenter : TEXCOORD1; // Uniform value containing center of glint in local 3x3 quad + float3 glintColor : TEXCOORD2; // Uniform value of color of glint +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + o.projPos = float4( v.vPos, 1.0f ); + o.tc = v.tc; + o.glintCenter = v.glintCenter; + o.glintColor = v.glintColor; + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/eyes.cpp b/mp/src/materialsystem/stdshaders/eyes.cpp new file mode 100644 index 00000000..7aa4738f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes.cpp @@ -0,0 +1,186 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: eye renderer +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "eyes_dx8_dx9_helper.h" +#include "cloak_blended_pass_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( eyes, Eyes_dx8 ) + +BEGIN_VS_SHADER( Eyes_dx8, + "Help for Eyes" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/alyx/eyeball_l", "iris texture", 0 ) + SHADER_PARAM( IRIS, SHADER_PARAM_TYPE_TEXTURE, "models/alyx/pupil_l", "iris texture" ) + SHADER_PARAM( IRISFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame for the iris texture" ) + SHADER_PARAM( GLINT, SHADER_PARAM_TYPE_TEXTURE, "models/humans/male/glint", "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" ) + SHADER_PARAM( DILATION, SHADER_PARAM_TYPE_FLOAT, "0", "Iris dilation" ) + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is eyes in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + END_SHADER_PARAMS + + void SetupVars( Eyes_DX8_DX9_Vars_t &info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nFrame = FRAME; + info.m_nIris = IRIS; + info.m_nIrisFrame = IRISFRAME; + info.m_nGlint = GLINT; + info.m_nEyeOrigin = EYEORIGIN; + info.m_nEyeUp = EYEUP; + info.m_nIrisU = IRISU; + info.m_nIrisV = IRISV; + info.m_nGlintU = GLINTU; + info.m_nGlintV = GLINTV; + info.m_nDilation = DILATION; + info.m_nIntro = INTRO; + info.m_nEntityOrigin = ENTITYORIGIN; + info.m_nWarpParam = WARPPARAM; + } + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + SHADER_INIT_PARAMS() + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + InitParamsEyes_DX8_DX9( this, params, pMaterialName, info ); + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + } + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "Eyes_dx6"; + + return 0; + } + + SHADER_INIT + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + InitEyes_DX8_DX9( this, params, info ); + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + // There is some strangeness in DX8 when trying to skip the main pass, so leave this alone for now + //bDrawStandardPass = false; + } + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + DrawEyes_DX8_DX9( false, this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/eyes.vsh b/mp/src/materialsystem/stdshaders/eyes.vsh new file mode 100644 index 00000000..58ae021d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes.vsh @@ -0,0 +1,80 @@ +vs.1.1 +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0 = eyeball origin +; $SHADER_SPECIFIC_CONST_1 = eyeball up * 0.5 +; $SHADER_SPECIFIC_CONST_2 = iris projection U +; $SHADER_SPECIFIC_CONST_3 = iris projection V +; $SHADER_SPECIFIC_CONST_4 = glint projection U +; $SHADER_SPECIFIC_CONST_5 = glint projection V +;------------------------------------------------------------------------------ + +# STATIC: "HALF_LAMBERT" "0..1" +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "LIGHT_COMBO" "0..21" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending (whacks r1-r7, positions in r7) +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&SkinPosition( $worldPos ); + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Normal is based on vertex position +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$normalDotUp ); + +sub $worldNormal, $worldPos, $SHADER_SPECIFIC_CONST_0 ; Normal = (Pos - Eye origin) +dp3 $normalDotUp, $worldNormal, $SHADER_SPECIFIC_CONST_1 ; Normal -= 0.5f * (Normal dot Eye Up) * Eye Up +mul $normalDotUp, $normalDotUp, $cHalf +mad $worldNormal, -$normalDotUp, $SHADER_SPECIFIC_CONST_1, $worldNormal + +&FreeRegister( \$normalDotUp ); + +; normalize the normal +&Normalize( $worldNormal ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ +&DoLighting( $worldPos, $worldNormal ); + +&FreeRegister( \$worldNormal ); + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +; Texture 0 is the base texture +; Texture 1 is a planar projection used for the iris +; Texture 2 is a planar projection used for the glint +;------------------------------------------------------------------------------ + +mov oT0, $vTexCoord0 +dp4 oT1.x, $SHADER_SPECIFIC_CONST_2, $worldPos +dp4 oT1.y, $SHADER_SPECIFIC_CONST_3, $worldPos +dp4 oT2.x, $SHADER_SPECIFIC_CONST_4, $worldPos +dp4 oT2.y, $SHADER_SPECIFIC_CONST_5, $worldPos + +&FreeRegister( \$worldPos ); diff --git a/mp/src/materialsystem/stdshaders/eyes_dx6.cpp b/mp/src/materialsystem/stdshaders/eyes_dx6.cpp new file mode 100644 index 00000000..f5454595 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_dx6.cpp @@ -0,0 +1,251 @@ +//========= 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 + diff --git a/mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp b/mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp new file mode 100644 index 00000000..97e6ed32 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp @@ -0,0 +1,550 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "BaseVSShader.h" +#include "tier1/convar.h" +#include "mathlib/vmatrix.h" +#include "eyes_dx8_dx9_helper.h" +#include "cpp_shader_constant_register_map.h" +#include "Eyes.inc" +#include "eyes_flashlight_vs11.inc" +#include "eyes_flashlight_ps11.inc" + +#ifdef STDSHADER_DX9_DLL_EXPORT + +#include "eyes_vs20.inc" +#include "eyes_ps20.inc" +#include "eyes_ps20b.inc" +#include "eyes_flashlight_vs20.inc" +#include "eyes_flashlight_ps20.inc" +#include "eyes_flashlight_ps20b.inc" + +#ifndef _X360 +#include "eyes_vs30.inc" +#include "eyes_ps30.inc" +#include "eyes_flashlight_vs30.inc" +#include "eyes_flashlight_ps30.inc" +#endif + +#endif + +ConVar r_flashlight_version2( "r_flashlight_version2", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ); + +void InitParamsEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, + Eyes_DX8_DX9_Vars_t &info ) +{ + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + Assert( info.m_nIntro != -1 ); + if( info.m_nIntro != -1 && !params[info.m_nIntro]->IsDefined() ) + { + params[info.m_nIntro]->SetIntValue( 0 ); + } +} + +void InitEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, Eyes_DX8_DX9_Vars_t &info ) +{ + pShader->LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nIris, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nGlint ); + + // Be sure dilation is zeroed if undefined + if( !params[info.m_nDilation]->IsDefined() ) + { + params[info.m_nDilation]->SetFloatValue( 0.0f ); + } +} + +static void SetDepthFlashlightParams( CBaseVSShader *pShader, IShaderDynamicAPI *pShaderAPI, const VMatrix& worldToTexture, const FlashlightState_t& flashlightState ) +{ + float atten[4], pos[4], tweaks[4]; + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + + if ( IsX360() ) + { + pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); + } +} + + +static void DrawFlashlight( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + if( pShaderShadow ) + { + pShaderShadow->EnableDepthWrites( false ); + + pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Write over the eyes that were already there + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Spot + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Base + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Normalizing cubemap + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Iris + + // Set stream format (note that this shader supports compression) + int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + +#ifdef STDSHADER_DX9_DLL_EXPORT + if ( bDX9 ) + { + int nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_STATIC_VERTEX_SHADER( eyes_flashlight_vs20 ); + SET_STATIC_VERTEX_SHADER( eyes_flashlight_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( eyes_flashlight_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( eyes_flashlight_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( eyes_flashlight_ps20 ); + SET_STATIC_PIXEL_SHADER( eyes_flashlight_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( eyes_flashlight_vs30 ); + SET_STATIC_VERTEX_SHADER( eyes_flashlight_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( eyes_flashlight_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( eyes_flashlight_ps30 ); + } +#endif + + // On DX9, get the gamma read and write correct + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Spot + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // Base + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); // Iris + pShaderShadow->EnableSRGBWrite( true ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Shadow noise rotation map + } + } + else +#endif + { + // DX8 uses old asm shaders + eyes_flashlight_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "eyes_flashlight_vs11", vshIndex.GetIndex() ); + + eyes_flashlight_ps11_Static_Index pshIndex; + pShaderShadow->SetPixelShader( "eyes_flashlight_ps11", pshIndex.GetIndex() ); + } + + pShader->FogToBlack(); + } + else + { + // 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. + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + if ( !bDX9 ) + { + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 0, true ); + } + + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + pShader->BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture, info.m_nFrame ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); + pShader->BindTexture( SHADER_SAMPLER3, info.m_nIris, info.m_nIrisFrame ); + +#ifdef STDSHADER_DX9_DLL_EXPORT + if ( bDX9 ) + { + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs20 ); + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs30 ); + } +#endif + +// float vPSConst[4] = {params[info.m_nDilation]->GetFloatValue(), 0.0f, 0.0f, 0.0f}; +// pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); + + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); + SET_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20b ); + + SetDepthFlashlightParams( pShader, pShaderAPI, worldToTexture, flashlightState ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20 ); + } + } +#ifndef _X360 + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); + SET_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps30 ); + + SetDepthFlashlightParams( pShader, pShaderAPI, worldToTexture, flashlightState ); + } +#endif + } + else // older asm shaders for DX8 +#endif + { + eyes_flashlight_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + eyes_flashlight_ps11_Dynamic_Index pshIndex; + pShaderAPI->SetPixelShaderIndex( pshIndex.GetIndex() ); + } + + // This uses from VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 to VERTEX_SHADER_SHADER_SPECIFIC_CONST_5 + pShader->SetFlashlightVertexShaderConstants( false, -1, false, -1, false ); + + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, info.m_nEyeOrigin ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, info.m_nEyeUp ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, info.m_nIrisU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, info.m_nIrisV ); + } + pShader->Draw(); +} + +static void DrawUsingVertexShader( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Iris + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Glint + + // Set stream format (note that this shader supports compression) + int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + pShaderShadow->EnableAlphaWrites( true ); //we end up hijacking destination alpha for opaques most of the time. + +#ifdef STDSHADER_DX9_DLL_EXPORT + if ( bDX9 ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( eyes_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[info.m_nIntro]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( eyes_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( eyes_ps20b ); + SET_STATIC_PIXEL_SHADER( eyes_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( eyes_ps20 ); + SET_STATIC_PIXEL_SHADER( eyes_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( eyes_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[info.m_nIntro]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( eyes_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( eyes_ps30 ); + SET_STATIC_PIXEL_SHADER( eyes_ps30 ); + } +#endif + // On DX9, get the gamma read and write correct + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Base + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // White + pShaderShadow->EnableSRGBWrite( true ); + } + else +#endif + { + eyes_Static_Index vshIndex; + vshIndex.SetHALF_LAMBERT( IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + pShaderShadow->SetVertexShader( "Eyes", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "Eyes_Overbright2" ); + } + + pShader->FogToFogColor(); + } + DYNAMIC_STATE + { + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nFrame ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nIris, info.m_nIrisFrame ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nGlint ); + pShader->SetAmbientCubeDynamicStateVertexShader(); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nEyeOrigin ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nEyeUp ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nIrisU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nIrisV ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nGlintU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, info.m_nGlintV ); + +#ifdef STDSHADER_DX9_DLL_EXPORT + if( bDX9 ) + { + LightState_t lightState; + pShaderAPI->GetDX9LightState( &lightState ); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( eyes_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( eyes_vs20 ); + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( eyes_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eyes_vs30 ); + } +#endif + + // Get luminance of ambient cube and saturate it + float fGlintDamping = max(0.0f, min( pShaderAPI->GetAmbientLightCubeLuminance(), 1.0f ) ); + const float fDimGlint = 0.01f; + + // Remap so that glint damping smooth steps to zero for low luminances + if ( fGlintDamping > fDimGlint ) + fGlintDamping = 1.0f; + else + fGlintDamping *= SimpleSplineRemapVal( fGlintDamping, 0.0f, fDimGlint, 0.0f, 1.0f ); + + // Special constant for DX9 eyes: { Dilation, ambient, x, x }; + float vPSConst[4] = {params[info.m_nDilation]->GetFloatValue(), fGlintDamping, 0.0f, 0.0f}; + pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( eyes_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( eyes_ps20 ); + } + } +#ifndef _X360 + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( eyes_ps30 ); + } +#endif + + Assert( info.m_nIntro != -1 ); + if( params[info.m_nIntro]->GetIntValue() ) + { + float curTime = params[info.m_nWarpParam]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + Assert( params[info.m_nEntityOrigin]->IsDefined() ); + params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, timeVec, 1 ); + } + } + else +#endif + { + eyes_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetLIGHT_COMBO( pShaderAPI->GetCurrentLightCombo() ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + pShader->Draw(); +} + +static void DrawEyes_DX8_DX9_Internal( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, bool bHasFlashlight, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + if( !bHasFlashlight ) + { + DrawUsingVertexShader( bDX9, pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + DrawFlashlight( bDX9, pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } +} + +extern ConVar r_flashlight_version2; +void DrawEyes_DX8_DX9( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + DrawEyes_DX8_DX9_Internal( bDX9, pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression ); + if ( pShaderShadow ) + { + pShader->SetInitialShadowState( ); + } + } + DrawEyes_DX8_DX9_Internal( bDX9, pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression ); +} + + diff --git a/mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.h b/mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.h new file mode 100644 index 00000000..daf7c124 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.h @@ -0,0 +1,54 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef EYES_DX8_DX9_HELPER_H +#define EYES_DX8_DX9_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct Eyes_DX8_DX9_Vars_t +{ + Eyes_DX8_DX9_Vars_t() { memset( this, 0xFF, sizeof(Eyes_DX8_DX9_Vars_t) ); } + + int m_nBaseTexture; + int m_nFrame; + int m_nIris; + int m_nIrisFrame; + int m_nGlint; + int m_nEyeOrigin; + int m_nEyeUp; + int m_nIrisU; + int m_nIrisV; + int m_nGlintU; + int m_nGlintV; + int m_nDilation; + int m_nIntro; + int m_nEntityOrigin; + int m_nWarpParam; +}; + +void InitParamsEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Eyes_DX8_DX9_Vars_t &info ); +void InitEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, Eyes_DX8_DX9_Vars_t &info ); +void DrawEyes_DX8_DX9( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // EYES_DX8_DX9_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/eyes_dx9.cpp b/mp/src/materialsystem/stdshaders/eyes_dx9.cpp new file mode 100644 index 00000000..b33ec804 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_dx9.cpp @@ -0,0 +1,84 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: eye renderer +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "eyes_dx8_dx9_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( eyes, Eyes_dx9 ) + +BEGIN_VS_SHADER( Eyes_dx9, "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" ) + SHADER_PARAM( DILATION, SHADER_PARAM_TYPE_FLOAT, "0", "Pupil dilation (0 is none, 1 is maximal)" ) + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is eyes in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + END_SHADER_PARAMS + + void SetupVars( Eyes_DX8_DX9_Vars_t &info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nFrame = FRAME; + info.m_nIris = IRIS; + info.m_nIrisFrame = IRISFRAME; + info.m_nGlint = GLINT; + info.m_nEyeOrigin = EYEORIGIN; + info.m_nEyeUp = EYEUP; + info.m_nIrisU = IRISU; + info.m_nIrisV = IRISV; + info.m_nGlintU = GLINTU; + info.m_nGlintV = GLINTV; + info.m_nDilation = DILATION; + info.m_nIntro = INTRO; + info.m_nEntityOrigin = ENTITYORIGIN; + info.m_nWarpParam = WARPPARAM; + } + + SHADER_INIT_PARAMS() + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + InitParamsEyes_DX8_DX9( this, params, pMaterialName, info ); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "Eyes_dx8"; + + return 0; + } + + SHADER_INIT + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + InitEyes_DX8_DX9( this, params, info ); + } + + + SHADER_DRAW + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + DrawEyes_DX8_DX9( true, this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/eyes_flashlight2_ps11.psh b/mp/src/materialsystem/stdshaders/eyes_flashlight2_ps11.psh new file mode 100644 index 00000000..3b02fbb3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_flashlight2_ps11.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw stuff +;------------------------------------------------------------------------------ + +tex t0 ; Contains spotlight +tex t1 ; Contains base texture +tex t2 ; Normalize world pos to light +tex t3 ; Sample iris + +dp3 r0, t2_bx2, v0_bx2 ; r0 = N dot L +lrp r1.rgb, t3.a, t3, t1 ; r1 = lerp( baseColor, irisSample.xyz, irisSample.a ) +mul r0.rgb, r0_sat, r1 ; Saturate ( N dot L )* lerp +mul r0.rgb, r0, v0.a ; *= attenuation +mul_x2 r0.rgb, r0, t0 + ; *= 2 * spotlight +mov r0.a, t1.a diff --git a/mp/src/materialsystem/stdshaders/eyes_flashlight_inc.fxc b/mp/src/materialsystem/stdshaders/eyes_flashlight_inc.fxc new file mode 100644 index 00000000..7629f72f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_flashlight_inc.fxc @@ -0,0 +1,92 @@ +//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + + +const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); + +sampler SpotSampler : register( s0 ); +sampler BaseTextureSampler : register( s1 ); +sampler IrisSampler : register( s3 ); + +#if FLASHLIGHTSHADOWS && (!SHADER_MODEL_PS_1_1) && (!SHADER_MODEL_PS_1_4) && (!SHADER_MODEL_PS_2_0) +sampler FlashlightDepthSampler : register( s4 ); +sampler RandomRotationSampler : register( s5 ); +#endif + +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + +#else + const float4 g_FogParams : register( PSREG_FOG_PARAMS ); + const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +#endif + +struct PS_INPUT +{ + float4 spotTexCoord : TEXCOORD0; + float2 baseTexCoord : TEXCOORD1; + float2 irisTexCoord : TEXCOORD3; +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + float3 vertAtten : COLOR0; +#else + float3 vertAtten : TEXCOORD4; + float3 worldPos : TEXCOORD5; + float3 projPos : TEXCOORD7; +#endif +}; + +float4 main( PS_INPUT i ) : COLOR +{ +#if defined(SHADER_MODEL_PS_2_0) + float3 spotColor = tex2Dproj( SpotSampler, i.spotTexCoord.xyzw ) * cFlashlightColor; +#elif ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; + float3 spotColor = tex2D( SpotSampler, vProjCoords ) * cFlashlightColor; +#else + float3 spotColor = tex2D( SpotSampler, i.spotTexCoord ); +#endif + + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + float4 irisSample = tex2D( IrisSampler, i.irisTexCoord ); + + float3 outcolor = float3(1,1,1); + +#if !defined( SHADER_MODEL_PS_1_1 ) && !defined( SHADER_MODEL_PS_1_4 ) + if( i.spotTexCoord.w <= 0.0f ) + { + outcolor = float3(0,0,0); + } +#endif + + // Composite the iris and sclera together +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + float3 albedo = lerp( baseSample.xyz, irisSample.xyz, irisSample.a ); +#else + float3 albedo = lerp( baseSample.xyz, irisSample.xyz * 0.5f, irisSample.a ); // dim down the iris in HDR +#endif + + // Do shadow depth mapping... +#if FLASHLIGHTSHADOWS && ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_vShadowTweaks, true ); + float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = lerp( flAttenuated, flShadow, dot(i.vertAtten, float3(0.30f, 0.59f, 0.11f) ) ); // Blend between shadow and above, according to light attenuation + outcolor *= flShadow * spotColor * albedo; +#else + outcolor *= spotColor * albedo; +#endif + + // NOTE!! This has to be last to avoid loss of range. + outcolor *= i.vertAtten; +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + return float4( outcolor, baseSample.a ); +#else + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos.z, i.projPos.z ); + return FinalOutput( float4( outcolor, 1.0f ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +#endif + +} diff --git a/mp/src/materialsystem/stdshaders/eyes_flashlight_ps11.fxc b/mp/src/materialsystem/stdshaders/eyes_flashlight_ps11.fxc new file mode 100644 index 00000000..25e0702e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_flashlight_ps11.fxc @@ -0,0 +1,9 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +#define HDRTYPE HDR_TYPE_NONE + +#include "eyes_flashlight_inc.fxc" diff --git a/mp/src/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc b/mp/src/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc new file mode 100644 index 00000000..eb00fc04 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc @@ -0,0 +1,15 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +#include "eyes_flashlight_inc.fxc" diff --git a/mp/src/materialsystem/stdshaders/eyes_flashlight_vs11.vsh b/mp/src/materialsystem/stdshaders/eyes_flashlight_vs11.vsh new file mode 100644 index 00000000..48c4cd57 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_flashlight_vs11.vsh @@ -0,0 +1,115 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos ); + +alloc $worldPos +alloc $projPos + + +&SkinPosition( $worldPos ); + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 + +;------------------------------------------------------------------------------ +; Normal is based on vertex position +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$normalDotUp ); + +sub $worldNormal, $worldPos, $SHADER_SPECIFIC_CONST_6 ; Normal = (Pos - Eye origin) +dp3 $normalDotUp, $worldNormal, $SHADER_SPECIFIC_CONST_7 ; Normal -= 0.5f * (Normal dot Eye Up) * Eye Up +mul $normalDotUp, $normalDotUp, $cHalf +mad $worldNormal, -$normalDotUp, $SHADER_SPECIFIC_CONST_7, $worldNormal + +&FreeRegister( \$normalDotUp ); + +; normalize the normal +&Normalize( $worldNormal ); + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +; base tex coords +mov oT1.xy, $vTexCoord0 + +; spotlight texcoords +dp4 oT0.x, $worldPos, $SHADER_SPECIFIC_CONST_1 +dp4 oT0.y, $worldPos, $SHADER_SPECIFIC_CONST_2 +dp4 oT0.z, $worldPos, $SHADER_SPECIFIC_CONST_3 +dp4 oT0.w, $worldPos, $SHADER_SPECIFIC_CONST_4 + +local( $worldPosToLightVector, $distFactors ); + +alloc $worldPosToLightVector + +sub $worldPosToLightVector, $SHADER_SPECIFIC_CONST_0.xyz, $worldPos + +local( $distatten ); +alloc $distatten +; $distatten = [ 1, 1/dist, 1/distsquared ] + +; dist squared +dp3 $distatten.z, $worldPosToLightVector, $worldPosToLightVector + +; oodist +rsq $distatten.y, $distatten.z + +mov $distatten.x, $cOne + +local( $dist ); +alloc $dist +mul $dist.x, $distatten.z, $distatten.y + +rcp $distatten.z, $distatten.z ; 1/distsquared + +local( $endFalloffFactor ); +alloc $endFalloffFactor + +; ( dist - farZ ) +sub $endFalloffFactor.x, $dist.x, $SHADER_SPECIFIC_CONST_5.w +; 1 / ( (0.6f * farZ) - farZ) +mul $endFalloffFactor, $endFalloffFactor.x, $SHADER_SPECIFIC_CONST_0.w +max $endFalloffFactor, $endFalloffFactor, $cZero +min $endFalloffFactor, $endFalloffFactor, $cOne + +local( $vertAtten ); +alloc $vertAtten +dp3 $vertAtten, $distatten, $SHADER_SPECIFIC_CONST_5 +mul $vertAtten, $vertAtten, $endFalloffFactor + +; Normalize L +&Normalize( $worldPosToLightVector ); + +; N.L +dp3 $worldNormal, $worldNormal, $worldPosToLightVector + +; Modulate distance attenuation with N.L +mul oD0, $vertAtten, $worldNormal + +; iris +dp4 oT3.x, $SHADER_SPECIFIC_CONST_8, $worldPos +dp4 oT3.y, $SHADER_SPECIFIC_CONST_9, $worldPos + +free $dist +free $endFalloffFactor +free $worldPos +free $worldNormal +free $projPos +free $worldPosToLightVector +free $distatten +free $vertAtten diff --git a/mp/src/materialsystem/stdshaders/eyes_flashlight_vs20.fxc b/mp/src/materialsystem/stdshaders/eyes_flashlight_vs20.fxc new file mode 100644 index 00000000..e2e37dc1 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_flashlight_vs20.fxc @@ -0,0 +1,145 @@ +// ------------------------------------------------------------------------------ +// $cLight0Pos = world space light position +// $SHADER_SPECIFIC_CONST_1 = spotlight projection +// $SHADER_SPECIFIC_CONST_2 = spotlight projection +// $SHADER_SPECIFIC_CONST_3 = spotlight projection +// $SHADER_SPECIFIC_CONST_4 = spotlight projection +// $SHADER_SPECIFIC_CONST_5 = far z +// $SHADER_SPECIFIC_CONST_6 = eyeball origin +// $SHADER_SPECIFIC_CONST_7 = eyeball up * 0.5 +// $SHADER_SPECIFIC_CONST_8 = iris projection U +// $SHADER_SPECIFIC_CONST_9 = iris projection V +// ------------------------------------------------------------------------------ + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cLightPosition : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cSpotlightProj1 : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cSpotlightProj2 : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cSpotlightProj3 : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cSpotlightProj4 : register( SHADER_SPECIFIC_CONST_4 ); +const float4 cFlashlighAtten : register( SHADER_SPECIFIC_CONST_5 ); // const, linear, quadratic & farZ +const float4 cIrisProjectionU : register( SHADER_SPECIFIC_CONST_8 ); +const float4 cIrisProjectionV : register( SHADER_SPECIFIC_CONST_9 ); + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vNormal : NORMAL; + float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; // Fixed-function fog factor +#endif + float4 spotTexCoord : TEXCOORD0; // Spotlight texture coordinates + float2 baseTexCoord : TEXCOORD1; // Base texture coordinates + float2 irisTexCoord : TEXCOORD3; // Iris texture coordinates + float3 vertAtten : TEXCOORD4; // vertex attenuation + float3 worldPos : TEXCOORD5; + float3 projPosXYZ : TEXCOORD7; +}; + + +float RemapValClamped_01( float val, float A, float B ) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + return cVal; +} + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + DecompressVertex_Normal( v.vNormal, vNormal ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); +#endif + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, vNormal, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + + worldNormal = normalize( worldNormal ); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + o.projPosXYZ = projPos.xyz; + o.worldPos = worldPos.xyz; + +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, o.projPos, g_FogType ); +#endif + + // Base texture coordinates + o.baseTexCoord = v.vTexCoord0; + + // Spotlight texture coordinates + o.spotTexCoord.x = dot( cSpotlightProj1, float4(worldPos, 1) ); + o.spotTexCoord.y = dot( cSpotlightProj2, float4(worldPos, 1) ); + o.spotTexCoord.z = dot( cSpotlightProj3, float4(worldPos, 1) ); + o.spotTexCoord.w = dot( cSpotlightProj4, float4(worldPos, 1) ); + + // Compute vector to light + float3 vWorldPosToLightVector = cLightPosition.xyz - worldPos; + + float3 vDistAtten = float3(1, 1, 1); + vDistAtten.z = dot( vWorldPosToLightVector, vWorldPosToLightVector ); // distsquared + vDistAtten.y = rsqrt( vDistAtten.z ); // 1 / dist + + float flDist = vDistAtten.z * vDistAtten.y; // dist + vDistAtten.z = 1.0f / vDistAtten.z; // 1 / distsquared + + float fFarZ = cFlashlighAtten.w; + + float endFalloffFactor = RemapValClamped_01( flDist, fFarZ, 0.6 * fFarZ ); + o.vertAtten.xyz = endFalloffFactor * dot( vDistAtten, cFlashlighAtten.xyz ); + + o.vertAtten *= dot( normalize( vWorldPosToLightVector ), worldNormal ); + + o.irisTexCoord.x = dot( cIrisProjectionU, float4(worldPos, 1) ); + o.irisTexCoord.y = dot( cIrisProjectionV, float4(worldPos, 1) ); + + return o; +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/eyes_ps2x.fxc b/mp/src/materialsystem/stdshaders/eyes_ps2x.fxc new file mode 100644 index 00000000..d71d813f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/eyes_ps2x.fxc @@ -0,0 +1,68 @@ +//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); +sampler IrisSampler : register( s1 ); +sampler GlintSampler : register( s2 ); +const float4 cEyeScalars : register( c0 ); // { Dilation, ambient, x, x } + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float2 irisTexCoord : TEXCOORD1; + float2 glintTexCoord : TEXCOORD2; + float3 vertAtten : TEXCOORD3; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +#define fDilationFactor cEyeScalars.x +#define fGlintDamping cEyeScalars.y + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + float4 glintSample = tex2D( GlintSampler, i.glintTexCoord ); +/* + // Dilate the pupil/iris texture (1 is max dilation, 0 is none) + float2 biasedCoords = i.irisTexCoord * 2.0f - 1.0f; // -1 to +1 range + float fDilatability = saturate(0.8f - sqrt(dot(biasedCoords, biasedCoords) )); // 1 in the center, fading out to 0 at 0.8 from center, since irises are inset into maps + float2 scaledCoords = biasedCoords * (1 + fDilatability); // Maximal dilation + + // Blend undilated and maximally dilated based upon dilation factor + float2 dilatedCoords = lerp( scaledCoords, biasedCoords, 1.0f-saturate(cDilationFactor.x)); + dilatedCoords = dilatedCoords * 0.5f + 0.5f; // Back to 0..1 range +*/ + + float4 irisSample = tex2D( IrisSampler, i.irisTexCoord ); // Sample the iris map using dilated coordinates + + float4 result; + result.rgb = lerp( baseSample.rgb, irisSample.rgb, irisSample.a ); + result.rgb *= i.vertAtten; + result.rgb += glintSample.rgb * fGlintDamping; + result.a = baseSample.a; + + bool bWriteDepthToAlpha = false; + + // ps_2_b and beyond +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) + bWriteDepthToAlpha = WRITE_DEPTH_TO_DESTALPHA != 0; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w ); +} diff --git a/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp new file mode 100644 index 00000000..9b02330a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp @@ -0,0 +1,271 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +/* Example how to plug this into an existing shader: + + In the VMT: + // Flesh Interior Pass + "$FleshInteriorEnabled" "1" // Enables effect + "$FleshInteriorTexture" "models/Alyx/alyx_flesh_color" // Mask in alpha + "$FleshNormalTexture" "models/Alyx/alyx_flesh_normal" + "$FleshBorderTexture1D" "models/Alyx/alyx_flesh_border" + "$FleshInteriorNoiseTexture" "Engine/noise-blur-256x256" + "$FleshSubsurfaceTexture" "models/Alyx/alyx_flesh_subsurface" + "$FleshBorderNoiseScale" "1.5" // Flesh Noise UV scalar for border + "$FleshBorderWidth" "0.3" // Width of flesh border + "$FleshBorderSoftness" "0.42" // Border softness must be greater than 0.0 and up tp 0.5 + "$FleshBorderTint" "[1 1 1]" // Tint / brighten the border 1D texture + "$FleshGlossBrightness" "0.66" // Change the brightness of the glossy layer + "$FleshDebugForceFleshOn" "0" // DEBUG: This will force on full flesh for testing + "$FleshScrollSpeed" "1.0" + "Proxies" + { + "FleshInterior" + { + } + } + + #include "flesh_interior_blended_pass_helper.h" + + In BEGIN_SHADER_PARAMS: + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + Add this above SHADER_INIT_PARAMS() + // Flesh Interior Pass + void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) + { + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + } + + In SHADER_INIT_PARAMS() + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } + + In SHADER_INIT + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } + + At the very end of SHADER_DRAW + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + +==================================================================================================== */ + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "convar.h" +#include "flesh_interior_blended_pass_helper.h" + +// Auto generated inc files +#include "flesh_interior_blended_pass_dx8_vs11.inc" + +void InitParamsFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, FleshInteriorBlendedPassVars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + SET_PARAM_STRING_IF_NOT_DEFINED( info.m_nFleshCubeTexture, "env_cubemap" ); // Default to in-game env map + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderNoiseScale, kDefaultBorderNoiseScale ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflDebugForceFleshOn, kDefaultDebugForceFleshOn ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius1, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius2, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius3, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius4, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncSubsurfaceTint, kDefaultSubsurfaceTint, 4 ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderWidth, kDefaultBorderWidth ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderSoftness, kDefaultBorderSoftness ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncBorderTint, kDefaultBorderTint, 4 ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlobalOpacity, kDefaultGlobalOpacity ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlossBrightness, kDefaultGlossBrightness ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflScrollSpeed, kDefaultScrollSpeed ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nTime, 0.0f ); +} + +void InitFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, FleshInteriorBlendedPassVars_t &info ) +{ + // Load textures + pShader->LoadTexture( info.m_nFleshTexture ); + //pShader->LoadTexture( info.m_nFleshNoiseTexture ); + //pShader->LoadTexture( info.m_nFleshBorderTexture1D ); + //pShader->LoadTexture( info.m_nFleshNormalTexture ); + //pShader->LoadTexture( info.m_nFleshSubsurfaceTexture ); + //pShader->LoadCubeMap( info.m_nFleshCubeTexture ); +} + +void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, FleshInteriorBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + // Reset shadow state manually since we're drawing from two materials + pShader->SetInitialShadowState(); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // Vertex Shader + flesh_interior_blended_pass_dx8_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "flesh_interior_blended_pass_dx8_vs11", vshIndex.GetIndex() ); + + // Pixel Shader + pShaderShadow->SetPixelShader( "flesh_interior_blended_pass_dx8_ps11", 0 ); + + // Textures + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Blending + pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableAlphaTest( true ); + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); + } + DYNAMIC_STATE + { + // Reset render state manually since we're drawing from two materials + pShaderAPI->SetDefaultState(); + + // Set Vertex Shader Combos + flesh_interior_blended_pass_dx8_vs11_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + // Set Vertex Shader Constants + + // Time % 1000 + float flCurrentTime = IS_PARAM_DEFINED( info.m_nTime ) && params[info.m_nTime]->GetFloatValue() > 0.0f ? params[info.m_nTime]->GetFloatValue() : pShaderAPI->CurrentTime(); + flCurrentTime *= IS_PARAM_DEFINED( info.m_nflScrollSpeed ) ? params[info.m_nflScrollSpeed]->GetFloatValue() : kDefaultScrollSpeed; // This is a dirty hack, but it works well enough + + float vVsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vVsConst0[0] = flCurrentTime; + vVsConst0[0] -= (float)( (int)( vVsConst0[0] / 1000.0f ) ) * 1000.0f; + + // Flesh effect centers and radii + float vVsConst1[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius1 ) ) + { + params[info.m_nvEffectCenterRadius1]->GetVecValue( vVsConst1, 4 ); + if ( vVsConst1[3] < 0.001f ) + vVsConst1[3] = 0.001f; + vVsConst1[3] = 1.0f / vVsConst1[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, vVsConst1, 1 ); + + float vVsConst2[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius2 ) ) + { + params[info.m_nvEffectCenterRadius2]->GetVecValue( vVsConst2, 4 ); + if ( vVsConst2[3] < 0.001f ) + vVsConst2[3] = 0.001f; + vVsConst2[3] = 1.0f / vVsConst2[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, vVsConst2, 2 ); + + float vVsConst3[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius3 ) ) + { + params[info.m_nvEffectCenterRadius3]->GetVecValue( vVsConst3, 4 ); + if ( vVsConst3[3] < 0.001f ) + vVsConst3[3] = 0.001f; + vVsConst3[3] = 1.0f / vVsConst3[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vVsConst3, 3 ); + + float vVsConst4[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius4 ) ) + { + params[info.m_nvEffectCenterRadius4]->GetVecValue( vVsConst4, 4 ); + if ( vVsConst4[3] < 0.001f ) + vVsConst4[3] = 0.001f; + vVsConst4[3] = 1.0f / vVsConst4[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, vVsConst4, 4 ); + + // Set Pixel Shader Combos + /* None */ + + // Bind textures + pShader->BindTexture( SHADER_SAMPLER0, info.m_nFleshTexture ); + + // Set Pixel Shader Constants + + // Border color tint + pShaderAPI->SetPixelShaderConstant( 3, IS_PARAM_DEFINED( info.m_ncBorderTint ) ? params[info.m_ncBorderTint]->GetVecValue() : kDefaultBorderTint, 1 ); + + // Global opacity + float vPsConst4[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst4[0] = IS_PARAM_DEFINED( info.m_nflGlobalOpacity ) ? params[info.m_nflGlobalOpacity]->GetFloatValue() : kDefaultGlobalOpacity; + pShaderAPI->SetPixelShaderConstant( 4, vPsConst4, 1 ); + + float vPsConst5[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + pShaderAPI->SetPixelShaderConstant( 5, vPsConst5, 1 ); + } + pShader->Draw(); +} diff --git a/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh new file mode 100644 index 00000000..fc7e32a9 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; c5 1, 1, 1, 1 +;------------------------------------------------------------------------------ + +tex t0 ; Base color + +mul r0, v0, v0 ; // Mask^2 +mul r0, r0, r0 ; // Mask^4 +sub r0, c5, r0 ; // 1.0 - Mask^4 + +mul r0.rgb, r0, t0 ; // * Flesh texture color +mul r0.a, r0.a, t0.a ; // * Flesh X-rated mask +mul r0.a, r0.a, v1.a ; // * Fresnel mask diff --git a/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh new file mode 100644 index 00000000..53b6d87d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh @@ -0,0 +1,114 @@ +# DYNAMIC: "SKINNING" "0..1" + +vs.1.1 +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$projPos ); + +&SkinPositionAndNormal( $worldPos, $worldNormal ); + +if( $SKINNING == 1 ) +{ + &Normalize( $worldNormal ); +} + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog - don't bother with water fog for intro effects +;------------------------------------------------------------------------------ +&DepthFog( $projPos, "oFog" ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Flesh area +;------------------------------------------------------------------------------ +; // Store the closest effect intensity +; o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance +; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius1.xyz ) * g_vEffectCenterOoRadius1.w ); +; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius2.xyz ) * g_vEffectCenterOoRadius2.w ); +; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius3.xyz ) * g_vEffectCenterOoRadius3.w ); +; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius4.xyz ) * g_vEffectCenterOoRadius4.w ); + +alloc $tmp1 +alloc $flEffect + +mov $flEffect, $cTwo +mad $flEffect, $flEffect, $cTwo, $cTwo + +sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_1 +dp3 $tmp1.w, $tmp1, $tmp1 +rsq $tmp1.w, $tmp1.w +rcp $tmp1.w, $tmp1.w +mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_1.w +min $flEffect, $flEffect, $tmp1.w + +sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_2 +dp3 $tmp1.w, $tmp1, $tmp1 +rsq $tmp1.w, $tmp1.w +rcp $tmp1.w, $tmp1.w +mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_2.w +min $flEffect, $flEffect, $tmp1.w + +sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_3 +dp3 $tmp1.w, $tmp1, $tmp1 +rsq $tmp1.w, $tmp1.w +rcp $tmp1.w, $tmp1.w +mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_3.w +min $flEffect, $flEffect, $tmp1.w + +sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_4 +dp3 $tmp1.w, $tmp1, $tmp1 +rsq $tmp1.w, $tmp1.w +rcp $tmp1.w, $tmp1.w +mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_4.w +min $flEffect, $flEffect, $tmp1.w + +mov oD0, $flEffect + +; float3 vWorldViewVector = normalize( vWorldPosition.xyz - cEyePos.xyz ); +; o.flDistanceToEffectCenter_flFresnelEffect.y = pow( saturate( dot( -vWorldViewVector.xyz, vWorldNormal.xyz ) ), 1.5f ); + +sub $tmp1, $worldPos, $cEyePos +&Normalize( $tmp1 ); +dp3 $tmp1, -$tmp1, $worldNormal +max $tmp1, $tmp1, $cZero +mul $tmp1, $tmp1, $tmp1 +mov oD1, $tmp1 + +free $tmp1 +free $flEffect + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +mov oT0.xy, $vTexCoord0 + +alloc $tmp2 + +dp4 $tmp2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 $tmp2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + +add oT1.xy, $tmp2, $SHADER_SPECIFIC_CONST_4 + +free $tmp2 + +; YUCK! This is to make texcoords continuous for mat_softwaretl +mov oT2, $cZero + +&FreeRegister( \$worldPos ); +&FreeRegister( \$worldNormal ); diff --git a/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp new file mode 100644 index 00000000..03ae509d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp @@ -0,0 +1,355 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +/* Example how to plug this into an existing shader: + + In the VMT: + // Flesh Interior Pass + "$FleshInteriorEnabled" "1" // Enables effect + "$FleshInteriorTexture" "models/Alyx/alyx_flesh_color" // Mask in alpha + "$FleshNormalTexture" "models/Alyx/alyx_flesh_normal" + "$FleshBorderTexture1D" "models/Alyx/alyx_flesh_border" + "$FleshInteriorNoiseTexture" "Engine/noise-blur-256x256" + "$FleshSubsurfaceTexture" "models/Alyx/alyx_flesh_subsurface" + "$FleshBorderNoiseScale" "1.5" // Flesh Noise UV scalar for border + "$FleshBorderWidth" "0.3" // Width of flesh border + "$FleshBorderSoftness" "0.42" // Border softness must be greater than 0.0 and up tp 0.5 + "$FleshBorderTint" "[1 1 1]" // Tint / brighten the border 1D texture + "$FleshGlossBrightness" "0.66" // Change the brightness of the glossy layer + "$FleshDebugForceFleshOn" "0" // DEBUG: This will force on full flesh for testing + "$FleshScrollSpeed" "1.0" + "Proxies" + { + "FleshInterior" + { + } + } + + #include "flesh_interior_blended_pass_helper.h" + + In BEGIN_SHADER_PARAMS: + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + Add this above SHADER_INIT_PARAMS() + // Flesh Interior Pass + void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) + { + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + } + + In SHADER_INIT_PARAMS() + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } + + In SHADER_INIT + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } + + At the very end of SHADER_DRAW + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + +==================================================================================================== */ + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "convar.h" +#include "flesh_interior_blended_pass_helper.h" + +// Auto generated inc files +#include "flesh_interior_blended_pass_vs20.inc" +#include "flesh_interior_blended_pass_ps20.inc" +#include "flesh_interior_blended_pass_ps20b.inc" + +void InitParamsFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, FleshInteriorBlendedPassVars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + SET_PARAM_STRING_IF_NOT_DEFINED( info.m_nFleshCubeTexture, "env_cubemap" ); // Default to in-game env map + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderNoiseScale, kDefaultBorderNoiseScale ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflDebugForceFleshOn, kDefaultDebugForceFleshOn ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius1, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius2, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius3, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius4, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncSubsurfaceTint, kDefaultSubsurfaceTint, 4 ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderWidth, kDefaultBorderWidth ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderSoftness, kDefaultBorderSoftness ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncBorderTint, kDefaultBorderTint, 4 ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlobalOpacity, kDefaultGlobalOpacity ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlossBrightness, kDefaultGlossBrightness ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflScrollSpeed, kDefaultScrollSpeed ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nTime, 0.0f ); +} + +void InitFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, FleshInteriorBlendedPassVars_t &info ) +{ + // Load textures + pShader->LoadTexture( info.m_nFleshTexture, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nFleshNoiseTexture ); + pShader->LoadTexture( info.m_nFleshBorderTexture1D, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nFleshNormalTexture ); + pShader->LoadTexture( info.m_nFleshSubsurfaceTexture, TEXTUREFLAGS_SRGB ); + pShader->LoadCubeMap( info.m_nFleshCubeTexture, TEXTUREFLAGS_SRGB ); +} + +void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, FleshInteriorBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + // Reset shadow state manually since we're drawing from two materials + pShader->SetInitialShadowState(); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + // Vertex Shader + DECLARE_STATIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + + // Pixel Shader + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); + SET_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); + SET_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); + } + + // Textures + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); // Noise texture not sRGB + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false ); // Normal texture not sRGB + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true ); + pShaderShadow->EnableSRGBWrite( true ); + + // Blending + pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableAlphaTest( true ); + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); + } + DYNAMIC_STATE + { + // Reset render state manually since we're drawing from two materials + pShaderAPI->SetDefaultState(); + + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + // Set Vertex Shader Combos + LightState_t lightState = { 0, false, false }; + pShaderAPI->GetDX9LightState( &lightState ); + DECLARE_DYNAMIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + + // Set Vertex Shader Constants + pShader->SetAmbientCubeDynamicStateVertexShader(); + + // Time % 1000 + float flCurrentTime = IS_PARAM_DEFINED( info.m_nTime ) && params[info.m_nTime]->GetFloatValue() > 0.0f ? params[info.m_nTime]->GetFloatValue() : pShaderAPI->CurrentTime(); + flCurrentTime *= IS_PARAM_DEFINED( info.m_nflScrollSpeed ) ? params[info.m_nflScrollSpeed]->GetFloatValue() : kDefaultScrollSpeed; // This is a dirty hack, but it works well enough + + float vVsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vVsConst0[0] = flCurrentTime; + vVsConst0[0] -= (float)( (int)( vVsConst0[0] / 1000.0f ) ) * 1000.0f; + + // Noise UV scroll + vVsConst0[1] = flCurrentTime / 100.0f; + vVsConst0[1] -= (float)( (int)( vVsConst0[1] ) ); + + // Border noise scale + vVsConst0[2] = IS_PARAM_DEFINED( info.m_nflBorderNoiseScale ) ? params[info.m_nflBorderNoiseScale]->GetFloatValue() : kDefaultBorderNoiseScale; + + // Debug force flesh on + vVsConst0[3] = IS_PARAM_DEFINED( info.m_nflDebugForceFleshOn ) ? params[info.m_nflDebugForceFleshOn]->GetFloatValue() : kDefaultDebugForceFleshOn; + + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, vVsConst0, 1 ); + + // Flesh effect centers and radii + float vVsConst1[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius1 ) ) + { + params[info.m_nvEffectCenterRadius1]->GetVecValue( vVsConst1, 4 ); + if ( vVsConst1[3] < 0.001f ) + vVsConst1[3] = 0.001f; + vVsConst1[3] = 1.0f / vVsConst1[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, vVsConst1, 1 ); + + float vVsConst2[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius2 ) ) + { + params[info.m_nvEffectCenterRadius2]->GetVecValue( vVsConst2, 4 ); + if ( vVsConst2[3] < 0.001f ) + vVsConst2[3] = 0.001f; + vVsConst2[3] = 1.0f / vVsConst2[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, vVsConst2, 2 ); + + float vVsConst3[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius3 ) ) + { + params[info.m_nvEffectCenterRadius3]->GetVecValue( vVsConst3, 4 ); + if ( vVsConst3[3] < 0.001f ) + vVsConst3[3] = 0.001f; + vVsConst3[3] = 1.0f / vVsConst3[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vVsConst3, 3 ); + + float vVsConst4[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius4 ) ) + { + params[info.m_nvEffectCenterRadius4]->GetVecValue( vVsConst4, 4 ); + if ( vVsConst4[3] < 0.001f ) + vVsConst4[3] = 0.001f; + vVsConst4[3] = 1.0f / vVsConst4[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, vVsConst4, 4 ); + + // Set Pixel Shader Combos + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); + } + + // Bind textures + pShader->BindTexture( SHADER_SAMPLER0, info.m_nFleshTexture ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nFleshNoiseTexture ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nFleshBorderTexture1D ); + pShader->BindTexture( SHADER_SAMPLER3, info.m_nFleshNormalTexture ); + pShader->BindTexture( SHADER_SAMPLER4, info.m_nFleshSubsurfaceTexture ); + pShader->BindTexture( SHADER_SAMPLER5, info.m_nFleshCubeTexture ); + + // Set Pixel Shader Constants + + // Subsurface tint + pShaderAPI->SetPixelShaderConstant( 0, IS_PARAM_DEFINED( info.m_ncSubsurfaceTint ) ? params[info.m_ncSubsurfaceTint]->GetVecValue() : kDefaultSubsurfaceTint, 1 ); + + // Border width + float vPsConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst1[0] = IS_PARAM_DEFINED( info.m_nflBorderWidth ) ? params[info.m_nflBorderWidth]->GetFloatValue() : kDefaultBorderWidth; + vPsConst1[0] = 1.0f / vPsConst1[0]; // ( 1.0f / g_flBorderWidthFromVmt ) + vPsConst1[1] = vPsConst1[0] - 1.0f; // ( 1.0f / g_flBorderWidthFromVmt ) - 1.0f + pShaderAPI->SetPixelShaderConstant( 1, vPsConst1, 1 ); + + // Border softness + float vPsConst2[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst2[0] = IS_PARAM_DEFINED( info.m_nflBorderSoftness ) ? params[info.m_nflBorderSoftness]->GetFloatValue() : kDefaultBorderSoftness; + if ( vPsConst2[0] < 0.01f ) + vPsConst2[0] = 0.01f; + else if ( vPsConst2[0] > 0.5f ) + vPsConst2[0] = 0.5f; + pShaderAPI->SetPixelShaderConstant( 2, vPsConst2, 1 ); + + // Border color tint + pShaderAPI->SetPixelShaderConstant( 3, IS_PARAM_DEFINED( info.m_ncBorderTint ) ? params[info.m_ncBorderTint]->GetVecValue() : kDefaultBorderTint, 1 ); + + // Global opacity + float vPsConst4[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst4[0] = IS_PARAM_DEFINED( info.m_nflGlobalOpacity ) ? params[info.m_nflGlobalOpacity]->GetFloatValue() : kDefaultGlobalOpacity; + pShaderAPI->SetPixelShaderConstant( 4, vPsConst4, 1 ); + + // Gloss brightness + float vPsConst5[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst5[0] = IS_PARAM_DEFINED( info.m_nflGlossBrightness ) ? params[info.m_nflGlossBrightness]->GetFloatValue() : kDefaultGlossBrightness; + pShaderAPI->SetPixelShaderConstant( 5, vPsConst5, 1 ); + } + pShader->Draw(); +} diff --git a/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.h b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.h new file mode 100644 index 00000000..92b8d57a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.h @@ -0,0 +1,68 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef FLESH_INTERIOR_BLENDED_PASS_HELPER_H +#define FLESH_INTERIOR_BLENDED_PASS_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct FleshInteriorBlendedPassVars_t +{ + FleshInteriorBlendedPassVars_t() { memset( this, 0xFF, sizeof(FleshInteriorBlendedPassVars_t) ); } + + int m_nFleshTexture; + int m_nFleshNoiseTexture; + int m_nFleshBorderTexture1D; + int m_nFleshNormalTexture; + int m_nFleshSubsurfaceTexture; + int m_nFleshCubeTexture; + + int m_nflBorderNoiseScale; + int m_nflDebugForceFleshOn; + int m_nvEffectCenterRadius1; + int m_nvEffectCenterRadius2; + int m_nvEffectCenterRadius3; + int m_nvEffectCenterRadius4; + + int m_ncSubsurfaceTint; + int m_nflBorderWidth; + int m_nflBorderSoftness; // > 0.0f && < 0.5f ! + int m_ncBorderTint; + int m_nflGlobalOpacity; + int m_nflGlossBrightness; + int m_nflScrollSpeed; + + int m_nTime; +}; + +// Default values (Arrays should only be vec[4]) +static const float kDefaultBorderNoiseScale = 1.5f; +static const float kDefaultDebugForceFleshOn = 0.0f; +static const float kDefaultEffectCenterRadius[4] = { 0.0f, 0.0f, 0.0f, 0.0001f }; // Disabled by default +static const float kDefaultSubsurfaceTint[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; // Disabled by default +static const float kDefaultBorderWidth = 0.3f; +static const float kDefaultBorderSoftness = 0.42f; // > 0.0f && < 0.5f ! +static const float kDefaultBorderTint[4] = { 1.0f, 1.0f, 1.0f, 0.0f }; +static const float kDefaultGlobalOpacity = 1.0f; +static const float kDefaultGlossBrightness = 0.66f; +static const float kDefaultScrollSpeed = 1.0f; + +void InitParamsFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, FleshInteriorBlendedPassVars_t &info ); +void InitFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, FleshInteriorBlendedPassVars_t &info ); +void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, FleshInteriorBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // FLESH_INTERIOR_BLENDED_PASS_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc new file mode 100644 index 00000000..3e288e56 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc @@ -0,0 +1,127 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// +// Includes ======================================================================================= +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +#include "common_vertexlitgeneric_dx9.h" + +// Texture Samplers =============================================================================== +sampler g_tBaseSampler : register( s0 ); +sampler g_tNoiseSampler : register( s1 ); +sampler g_tBorder1DSampler : register( s2 ); +sampler g_tNormalSampler : register( s3 ); +sampler g_tSubsurfaceSampler: register( s4 ); +sampler g_tCubeSampler : register( s5 ); + +// Shaders Constants and Globals ================================================================== +const float3 g_cSubsurfaceTint : register( c0 ); +const float2 g_flBorderWidth : register( c1 ); //{ 1.0f / g_flBorderWidthFromVmt, ( 1.0f / g_flBorderWidthFromVmt ) - 1.0f }; +const float g_flBorderSoftness : register( c2 ); +const float3 g_cBorderTint : register( c3 ); +const float g_flGlobalOpacity : register( c4 ); +const float g_flGlossBrightness : register( c5 ); + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float2 vTexCoord0 : TEXCOORD0; + float2 flDistanceToEffectCenter_flFresnelEffect : TEXCOORD1; + float4 vNoiseTexCoord : TEXCOORD2; + float3 vTangentViewVector : TEXCOORD3; + float3 cVertexLight : TEXCOORD4; + float3x3 mTangentSpaceTranspose : TEXCOORD5; + // second row : TEXCOORD6; + // third row : TEXCOORD7; +}; + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + // Color texture + float4 cBaseColor = tex2D( g_tBaseSampler, i.vTexCoord0.xy ); + float flFleshMaskFromTexture = cBaseColor.a; + + // Subsurface colors + float4 cSubsurfaceColor = tex2D( g_tSubsurfaceSampler, i.vTexCoord0.xy ); + cBaseColor.rgb += cBaseColor.rgb * cSubsurfaceColor.rgb * g_cSubsurfaceTint.rgb; + + // Scroll noise textures to ripple border of opening + float flNoise0 = tex2D( g_tNoiseSampler, i.vNoiseTexCoord.xy ).g; // Use green so we can DXT1 if we want + float flNoise1 = tex2D( g_tNoiseSampler, i.vNoiseTexCoord.wz ).g; // Use green so we can DXT1 if we want + float flNoise = ( flNoise0 + flNoise1 ) * 0.5f; + + // Generate 0-1 mask from distance computed in the VS + float flClampedInputMask = 0.0f; + flClampedInputMask = 1.0f - saturate( i.flDistanceToEffectCenter_flFresnelEffect.x ); + flClampedInputMask *= i.flDistanceToEffectCenter_flFresnelEffect.y; + flClampedInputMask *= flFleshMaskFromTexture; + + // Noise mask - Only apply noise around border of sphere + float flBorderMask = saturate( ( 1.0f - flClampedInputMask ) * g_flBorderWidth.x - g_flBorderWidth.y ); + float flNoiseMask = 1.0f - abs( ( flBorderMask * 2.0f ) - 1.0f ); + + // This is used to lerp in the 1D border texture over the flesh color + float flBorderMaskWithNoise = ( 1.0f - smoothstep( flNoiseMask - g_flBorderSoftness, flNoiseMask + g_flBorderSoftness, flNoise.r ) ) * flNoiseMask; + + // Border color + float vBorderUv = ( sign( flBorderMask - 0.5 ) * (1.0f - pow( flBorderMaskWithNoise, 4.0f )) * 0.5f ) + 0.5f; + float4 cBorderColor = 2.0f * tex2D( g_tBorder1DSampler, vBorderUv ); + cBorderColor.rgb *= g_cBorderTint; + cBorderColor.rgb *= flNoise; + + // Normal map + float4 vNormalMapValue = tex2D( g_tNormalSampler, i.vTexCoord0.xy ); + float3 vTangentNormal = ( vNormalMapValue.xyz * 2.0f ) - 1.0f; + vTangentNormal.xy += ( flNoise * 1.5f ) - 0.75f; // NOTE: This will denormalize the normal. + //float3 vWorldNormal = mul( i.mTangentSpaceTranspose, vTangentNormal.xyz ); + + // Specular gloss layer + float3 vTangentReflectionVector = reflect( i.vTangentViewVector.xyz, vTangentNormal.xyz ); + //vTangentReflectionVector.xy += ( flNoise * 1.5f ) - 0.75f; + float3 vWorldReflectionVector = mul( i.mTangentSpaceTranspose, vTangentReflectionVector.xyz ); + float3 cGlossLayer = ENV_MAP_SCALE * texCUBE( g_tCubeSampler, vWorldReflectionVector.xyz ).rgb; + cGlossLayer.rgb *= g_flGlossBrightness; + + // Gloss mask is just hard-coded fresnel for now + float flGlossMask = pow( saturate( dot( vTangentNormal.xyz, -i.vTangentViewVector.xyz ) ), 8.0f ); + + // Opacity + float flOpacity = 1.0f; + flOpacity = max( flBorderMaskWithNoise, step( flBorderMask, 0.5f ) ); + + // Apply global opacity + flOpacity *= g_flGlobalOpacity; + + //===============// + // Combine terms // + //===============// + float4 result; + result.rgb = cBaseColor.rgb * i.cVertexLight.rgb; + result.rgb += cGlossLayer.rgb * flGlossMask; + result.rgb *= pow( 1.0f - flBorderMaskWithNoise, 2.0f ); // Darken near border + result.rgb = lerp( result.rgb, cBorderColor.rgb, saturate( vBorderUv * 2.0f ) ); // bring in transition 1D texture + + //result.rgb = flClampedInputMask; + //result.rgb = flBorderMask; + //result.rgb = saturate( flClampedInputMask * 2.0f ); + //result.rgb = i.flDistanceToEffectCenter_flFresnelEffect.x;// * i.flDistanceToEffectCenter_flFresnelEffect.y; + //result.rgb = i.flDistanceToEffectCenter_flFresnelEffect.y * g_flBorderWidth.x - g_flBorderWidth.y; + //result.rgb = flNoiseMask; + //result.rgb = flBorderMaskWithNoise; + //result.rgb = flOpacity; + //result.rgb = flBorderUv; + //result.rgb = cBorderColor; + //result.rgb = -i.vTangentViewVector.z; + //result.rgb = vNormalMapValue.xyz; + //result.rgb = vTangentNormal.xyz; + //result.rgb = flGlossLayer; + //result.rgb = i.cVertexLight.rgb; + //result.rgb = texCUBE( g_tCubeSampler, vTangentNormal.xyz ).rgb; + //result.rgb = i.vTangentViewVector.x; + //result.rgb = cGlossLayer.rgb; + + // Set alpha for blending + result.a = flOpacity; + //result.a = 1.0f; + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +} diff --git a/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc new file mode 100644 index 00000000..2a361b01 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc @@ -0,0 +1,155 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +// Includes +#include "common_vs_fxc.h" + +// Globals +static const int g_iFogType = DOWATERFOG; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 g_vConst0 : register( SHADER_SPECIFIC_CONST_0 ); +#define g_flTime g_vConst0.x +#define g_flNoiseUvScroll g_vConst0.y +#define g_flBorderNoiseScale g_vConst0.z +#define g_flDebugForceFleshOn g_vConst0.w + +const float4 g_vEffectCenterOoRadius1 : register( SHADER_SPECIFIC_CONST_1 ); //= { -295.0f, -5.0f, 40.0f, 1.0f/20.0f }; +const float4 g_vEffectCenterOoRadius2 : register( SHADER_SPECIFIC_CONST_2 ); //= { -295.0f, 15.0f, 40.0f, 1.0f/10.0f }; +const float4 g_vEffectCenterOoRadius3 : register( SHADER_SPECIFIC_CONST_3 ); //= { -295.0f, 35.0f, 40.0f, 1.0f/10.0f }; +const float4 g_vEffectCenterOoRadius4 : register( SHADER_SPECIFIC_CONST_4 ); //= { -295.0f, 55.0f, 40.0f, 1.0f/10.0f }; + +// Structs +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vNormal : NORMAL; // Normal + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base texture coordinates + float3 vPosFlex : POSITION1; // Delta positions for flexing + float4 vTangent : TANGENT; +}; + +struct VS_OUTPUT +{ + float4 vProjPosition : POSITION; // Projection-space position + float2 vTexCoord0 : TEXCOORD0; + float2 flDistanceToEffectCenter_flFresnelEffect : TEXCOORD1; + float4 vNoiseTexCoord : TEXCOORD2; + float3 vTangentViewVector : TEXCOORD3; + float3 cVertexLight : TEXCOORD4; + float3x3 mTangentSpaceTranspose : TEXCOORD5; + // second row : TEXCOORD6; + // third row : TEXCOORD7; + +}; + +// Main +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + + // Flexes coming in from a separate stream (contribution masked by cFlexScale.x) + float4 vObjPosition = i.vPos; + vObjPosition.xyz += i.vPosFlex.xyz * cFlexScale.x; + + float3 vObjNormal; + float4 vObjTangent; + DecompressVertex_NormalTangent( i.vNormal, i.vTangent, vObjNormal, vObjTangent ); + + // Transform the position + float3 vWorldPosition = { 0.0f, 0.0f, 0.0f }; + float3 vWorldNormal = { 0.0f, 0.0f, 0.0f }; + float3 vWorldTangent = { 0.0f, 0.0f, 0.0f }; + float3 vWorldBinormal = { 0.0f, 0.0f, 0.0f }; + SkinPositionNormalAndTangentSpace( g_bSkinning, vObjPosition, vObjNormal, vObjTangent, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal, vWorldTangent, vWorldBinormal ); + + // Transform into projection space + float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.vProjPosition = vProjPosition; + + // Pass through tex coords + o.vTexCoord0.xy = i.vTexCoord0.xy; + + // Store the closest effect intensity + o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius1.xyz ) * g_vEffectCenterOoRadius1.w ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius2.xyz ) * g_vEffectCenterOoRadius2.w ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius3.xyz ) * g_vEffectCenterOoRadius3.w ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius4.xyz ) * g_vEffectCenterOoRadius4.w ); + + /* + // Test values for development in Alyx_interior map + o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance + float3 vTestPosition = { -295.0f, -5.0f, 40.0f }; + float flMinY = -5.0f; + float flMaxY = 66.0f; + vTestPosition.y = lerp( flMinY, flMaxY, ( abs( frac( g_flTime / 20.0f ) * 2.0 - 1.0 ) ) ); + //vTestPosition.y = lerp( flMinY, flMaxY, 0.65f ); + + //1.0f - saturate( i.flDistanceToEffectCenter_flFresnelEffect.x * 4.0f - 3.0f ) + + //o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance + + const float g_flInteriorRadius = 20.0f; + if ( g_flInteriorRadius ) + { + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - vTestPosition.xyz ) / g_flInteriorRadius ); + } + + const float g_flInteriorRadius2 = 14.0f; + if ( g_flInteriorRadius2 ) + { + vTestPosition.y = lerp( flMinY, flMaxY, 0.65f ); + //vTestPosition.z = lerp( 37, 45, ( abs( frac( g_flTime / 4.0f ) * 2.0 - 1.0 ) ) ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - vTestPosition.xyz ) / g_flInteriorRadius2 ); + } + //*/ + + if ( g_flDebugForceFleshOn ) + { + o.flDistanceToEffectCenter_flFresnelEffect.x = 0.0f; + } + + // Fresnel mask + float3 vWorldViewVector = normalize( vWorldPosition.xyz - cEyePos.xyz ); + o.flDistanceToEffectCenter_flFresnelEffect.y = pow( saturate( dot( -vWorldViewVector.xyz, vWorldNormal.xyz ) ), 1.5f ); + + // Noise UV + o.vNoiseTexCoord.xy = o.vTexCoord0.xy * g_flBorderNoiseScale + g_flNoiseUvScroll; + o.vNoiseTexCoord.zw = o.vTexCoord0.xy * g_flBorderNoiseScale - g_flNoiseUvScroll; // Will fetch as wz to avoid matching layers + + // Tangent view vector + o.vTangentViewVector.xyz = Vec3WorldToTangentNormalized( vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + // Compute vertex lighting + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + +#if ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) + o.cVertexLight.rgb = DoLighting( vWorldPosition, vWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert ); +#else + o.cVertexLight.rgb = DoLightingUnrolled( vWorldPosition, vWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); +#endif + + // Tangent space transform + o.mTangentSpaceTranspose[0] = float3( vWorldTangent.x, vWorldBinormal.x, vWorldNormal.x ); + o.mTangentSpaceTranspose[1] = float3( vWorldTangent.y, vWorldBinormal.y, vWorldNormal.y ); + o.mTangentSpaceTranspose[2] = float3( vWorldTangent.z, vWorldBinormal.z, vWorldNormal.z ); + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh new file mode 100644 index 00000000..fbb4393f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r1, t2, 1-t3.a ; envmap * envmapmask alpha +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh new file mode 100644 index 00000000..9380ec63 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh @@ -0,0 +1,9 @@ +ps.1.1 + +tex t0 ; base 1 +tex t1 ; base 2 + +mov r1, t1 +lrp r0, 1-v0.a, t0, r1 +mul r0, r0, c0 + diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_decal.cpp b/mp/src/materialsystem/stdshaders/lightmappedgeneric_decal.cpp new file mode 100644 index 00000000..9e74b5cf --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_decal.cpp @@ -0,0 +1,135 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "lightmappedgeneric_decal.inc" +#include "mathlib/bumpvects.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +BEGIN_VS_SHADER( LightmappedGeneric_Decal, + "Help for LightmappedGeneric_Decal" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + SET_FLAGS( MATERIAL_VAR_DECAL ); + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); + + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if ( !params[BASETEXTURE]->GetTextureValue()->IsTranslucent() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + } + + void DrawDecal( IMaterialVar **params, IShaderDynamicAPI *pShaderAPI, IShaderShadow *pShaderShadow ) + { + if( IsSnapshotting() ) + { + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + SetNormalBlendingShadowState( BASETEXTURE, true ); + + int pTexCoords[3] = { 2, 2, 1 }; + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION | VERTEX_COLOR, 3, pTexCoords, 0 ); + + lightmappedgeneric_decal_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "LightmappedGeneric_Decal", vshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( "LightmappedGeneric_Decal" ); + FogToFogColor(); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + // Load the z^2 components of the lightmap coordinate axes only + // This is (N dot basis)^2 + Vector vecZValues( g_localBumpBasis[0].z, g_localBumpBasis[1].z, g_localBumpBasis[2].z ); + vecZValues *= vecZValues; + + Vector4D basis[3]; + basis[0].Init( vecZValues.x, vecZValues.x, vecZValues.x, 0.0f ); + basis[1].Init( vecZValues.y, vecZValues.y, vecZValues.y, 0.0f ); + basis[2].Init( vecZValues.z, vecZValues.z, vecZValues.z, 0.0f ); + pShaderAPI->SetPixelShaderConstant( 0, (float*)basis, 3 ); + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + SetModulationPixelShaderDynamicState( 3 ); + + lightmappedgeneric_decal_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + SHADER_DRAW + { + if( UsingFlashlight( params ) ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, false, -1, -1, -1, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 ); + } + else + { + DrawDecal( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc b/mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc new file mode 100644 index 00000000..fd457be8 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc @@ -0,0 +1,59 @@ +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); +sampler LightMap0Sampler : register( s1 ); +sampler LightMap1Sampler : register( s2 ); +sampler LightMap2Sampler : register( s3 ); + +const float4 g_LightMap0Color : register( c0 ); +const float4 g_LightMap1Color : register( c1 ); +const float4 g_LightMap2Color : register( c2 ); +const float4 g_ModulationColor : register( c3 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + + +struct PS_INPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + float2 vTexCoord3 : TEXCOORD3; + float4 worldPos_projPosZ : TEXCOORD4; // Necessary for pixel fog + + float4 vColor : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 resultColor; + + // output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + + // lightmapColor[1] * ( ( N dot basis[1] )^2 ) + + // lightmapColor[2] * ( ( N dot basis[2] )^2 ) + + resultColor = tex2D( LightMap0Sampler, i.vTexCoord1 ) * g_LightMap0Color; + resultColor = (tex2D( LightMap1Sampler, i.vTexCoord2 ) * g_LightMap1Color) + resultColor; + resultColor = (tex2D( LightMap2Sampler, i.vTexCoord3 ) * g_LightMap2Color) + resultColor; + + // Modulate by decal texture + float4 decalColor = tex2D( BaseTextureSampler, i.vTexCoord0 ); + resultColor.rgb = resultColor * decalColor; + resultColor.a = decalColor.a; + + // Modulate by constant color + resultColor = resultColor * g_ModulationColor; + + // Modulate by per-vertex factor + resultColor = resultColor * i.vColor; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc b/mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc new file mode 100644 index 00000000..0b7db284 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc @@ -0,0 +1,74 @@ +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; + +const float4 cShaderConst0 : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cShaderConst1 : register( SHADER_SPECIFIC_CONST_1 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + + float4 vColor : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + float2 vTexCoord3 : TEXCOORD3; + + float4 worldPos_projPosZ : TEXCOORD4; // Necessary for pixel fog + + float4 vColor : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul( v.vPos, cModel[0] ); + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + + // Compute the texture coordinates given the offset between + // each bumped lightmap + float2 offset; + offset.x = v.vTexCoord2.x; + offset.y = 0.0f; + + o.vTexCoord0.x = dot( v.vTexCoord0, cShaderConst0 ); + o.vTexCoord0.y = dot( v.vTexCoord0, cShaderConst1 ); + + o.vTexCoord1 = offset + v.vTexCoord1.xy; + o.vTexCoord2 = (offset * 2.0) + v.vTexCoord1.xy; + o.vTexCoord3 = (offset * 3.0) + v.vTexCoord1.xy; + + o.vColor = v.vColor; + + return o; +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp new file mode 100644 index 00000000..f55f8883 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp @@ -0,0 +1,288 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( LightmappedGeneric, LightmappedGeneric_DX6 ) + +BEGIN_SHADER( LightmappedGeneric_DX6, + "Help for LightmappedGeneric_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "90", "Do specular pass only on dxlevel or higher (ie.80, 81, 90)" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + if( params[BASETEXTURE]->IsDefined() ) + { + if( !IS_FLAG_SET(MATERIAL_VAR_MULTIPASS) ) + { + params[ENVMAP]->SetUndefined(); + params[ENVMAPMASK]->SetUndefined(); + } + } + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + + SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + LoadCubeMap( ENVMAP ); + } + else + { + LoadTexture( ENVMAP ); + } + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + { + LoadTexture( ENVMAPMASK ); + } + } + } + + SHADER_FALLBACK + { + return 0; + } + + int GetDrawFlagsPass1(IMaterialVar** params) + { + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD0; + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + flags |= SHADER_DRAW_COLOR; + if (params[BASETEXTURE]->IsTexture()) + flags |= SHADER_DRAW_TEXCOORD1; + return flags; + } + + void DrawLightmapOnly( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); + + SetModulationShadowState(); + SetDefaultBlendingShadowState( ); + pShaderShadow->DrawFlags( GetDrawFlagsPass1( params ) ); + DefaultFog(); + } + DYNAMIC_STATE + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + SetModulationDynamicState(); + } + Draw(); + } + + void DrawBaseTimesLightmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // Base times lightmap + SHADOW_STATE + { + // alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // Alpha blending + SetDefaultBlendingShadowState( BASETEXTURE, true ); + + // Independenly configure alpha and color + pShaderShadow->EnableAlphaPipe( true ); + + // color channel + + // base + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // lightmap + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); + + pShaderShadow->EnableConstantColor( IsColorModulating() ); + + // alpha channel + pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); + if ((! IsColorModulating()) && ( ! IsAlphaModulating())) + pShaderShadow->EnableVertexAlpha( IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA) ); + pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, TextureIsTranslucent(BASETEXTURE, true) ); + pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE1, false ); + + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD1; + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + { + if ( (! IsColorModulating()) && ( ! IsAlphaModulating())) + flags |= SHADER_DRAW_COLOR; + + } + if (params[BASETEXTURE]->IsTexture()) + { + flags |= SHADER_DRAW_TEXCOORD0; + } + + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + } + DYNAMIC_STATE + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + SetModulationDynamicState(); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableAlphaPipe( false ); + } + } + + void DrawMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // Pass 1 : Base * lightmap or just lightmap + if ( params[BASETEXTURE]->IsTexture() ) + { + DrawBaseTimesLightmap( params, pShaderAPI, pShaderShadow ); + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + + // Draw the selfillum pass + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) + { + FixedFunctionSelfIlluminationPass( + SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); + } + } + else + { + DrawLightmapOnly( params, pShaderAPI, pShaderShadow ); + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + + // Pass 2 : Masked environment map + if (params[ENVMAP]->IsTexture()) + { + FixedFunctionAdditiveMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + } + + SHADER_DRAW + { + bool hasFlashlight = UsingFlashlight( params ); + + if( hasFlashlight ) + { + DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + } + else + { + // Base * Lightmap + env + DrawMode1( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER + + +//----------------------------------------------------------------------------- +// This allows us to use a block labelled 'Water_DX60' in the water materials +//----------------------------------------------------------------------------- +BEGIN_INHERITED_SHADER( Water_DX60, LightmappedGeneric_DX6, "Help for Water_DX60" ) +END_INHERITED_SHADER + diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp new file mode 100644 index 00000000..8464f94f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp @@ -0,0 +1,802 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + + +#include "lightmappedgeneric_vs11.inc" +#include "unlitgeneric_vs11.inc" +#include "worldvertextransition_seamless.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); + +DEFINE_FALLBACK_SHADER( LightmappedGeneric, LightmappedGeneric_DX8 ) + +BEGIN_VS_SHADER( LightmappedGeneric_DX8, + "Help for LightmappedGeneric_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "amount of detail texture to apply" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_INTEGER, "90", "Do specular pass only on dxlevel or higher (ie.80, 81, 90)" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_BOOL, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( FORCEBUMP, SHADER_PARAM_TYPE_BOOL, "0", "0 == Do bumpmapping if the card says it can handle it. 1 == Always do bumpmapping." ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + END_SHADER_PARAMS + + virtual bool ShouldUseBumpmapping( IMaterialVar **params ) + { + return g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined(); + } + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. + if( ShouldUseBumpmapping( params ) && params[ALBEDO]->IsDefined() && + params[BASETEXTURE]->IsDefined() && + !( params[NODIFFUSEBUMPLIGHTING]->IsDefined() && params[NODIFFUSEBUMPLIGHTING]->GetIntValue() ) ) + { + params[BASETEXTURE]->SetStringValue( params[ALBEDO]->GetStringValue() ); + } + + if( IsUsingGraphics() && params[ENVMAP]->IsDefined() && !CanUseEditorMaterials() ) + { + if( stricmp( params[ENVMAP]->GetStringValue(), "env_cubemap" ) == 0 ) + { + Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); + params[ENVMAP]->SetUndefined(); + } + } + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + { + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + } + + if( !params[ENVMAPTINT]->IsDefined() ) + { + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[SELFILLUMTINT]->IsDefined() ) + { + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[DETAILSCALE]->IsDefined() ) + { + params[DETAILSCALE]->SetFloatValue( 4.0f ); + } + + if( !params[DETAILBLENDFACTOR]->IsDefined() ) + { + params[DETAILBLENDFACTOR]->SetFloatValue( 1.0f ); + } + + if( !params[FRESNELREFLECTION]->IsDefined() ) + { + params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); + } + + if( !params[ENVMAPMASKFRAME]->IsDefined() ) + { + params[ENVMAPMASKFRAME]->SetIntValue( 0 ); + } + + if( !params[ENVMAPFRAME]->IsDefined() ) + { + params[ENVMAPFRAME]->SetIntValue( 0 ); + } + + if( !params[BUMPFRAME]->IsDefined() ) + { + params[BUMPFRAME]->SetIntValue( 0 ); + } + + if( !params[ENVMAPCONTRAST]->IsDefined() ) + { + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + } + + if( !params[ENVMAPSATURATION]->IsDefined() ) + { + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + } + + if( !params[ALPHATESTREFERENCE]->IsDefined() ) + { + params[ALPHATESTREFERENCE]->SetFloatValue( 0.0f ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( ShouldUseBumpmapping( params ) && (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0) ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && (params[ENVMAPOPTIONAL]->GetIntValue() > g_pHardwareConfig->GetDXSupportLevel()) ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + + if( params[SEAMLESS_SCALE]->IsDefined() && params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) + { + if( params[BUMPMAP]->IsDefined() ) + { + Warning( "Can't use $bumpmap with $seamless_scale for lightmappedgeneric_dx8. Implicitly disabling $bumpmap: %s\n", pMaterialName ); + params[BUMPMAP]->SetUndefined(); + } + if( params[ENVMAP]->IsDefined() ) + { + Warning( "Can't use $envmap with $seamless_scale for lightmappedgeneric_dx8. Implicitly disabling $envmap: %s\n", pMaterialName ); + params[ENVMAP]->SetUndefined(); + } + } + + if ( !params[SEAMLESS_SCALE]->IsDefined() ) + { + // zero means don't do seamless mapping. + params[SEAMLESS_SCALE]->SetFloatValue( 0.0f ); + } + + // Get rid of envmap if we aren't using bumpmapping + // *and* we have normalmapalphaenvmapmask *and* we don't have envmapmask elsewhere + if ( params[ENVMAP]->IsDefined() && params[BUMPMAP]->IsDefined() && IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ) && !ShouldUseBumpmapping( params ) ) + { + if ( !IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) && !params[ENVMAPMASK]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + } + } + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80) + return "LightmappedGeneric_DX6"; + + if ( IsPC() && g_pHardwareConfig->PreferReducedFillrate() ) + return "LightmappedGeneric_NoBump_DX8"; + + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + + if( ShouldUseBumpmapping( params ) ) + { + LoadBumpMap( BUMPMAP ); + } + + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + LoadCubeMap( ENVMAP ); + else + LoadTexture( ENVMAP ); + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + LoadTexture( ENVMAPMASK ); + } + + if( ShouldUseBumpmapping( params ) ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + } + +#ifndef USE_HLSL_PIXEL_SHADERS + inline const char *GetPixelShaderName( IMaterialVar** params, bool bBumpedEnvMap ) + { + static char const* s_pPixelShaders[] = + { + // Unmasked + "LightmappedGeneric_EnvMapV2", + "LightmappedGeneric_SelfIlluminatedEnvMapV2", + + "LightmappedGeneric_BaseAlphaMaskedEnvMapV2", + "LightmappedGeneric_SelfIlluminatedEnvMapV2", + + // Env map mask + "LightmappedGeneric_MaskedEnvMapV2", + "LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2", + + "LightmappedGeneric_MaskedEnvMapV2", + "LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2", + }; + + if (!params[BASETEXTURE]->IsTexture()) + { + if (params[ENVMAP]->IsTexture() && !bBumpedEnvMap ) + { + if (!params[ENVMAPMASK]->IsDefined() ) + { + return "LightmappedGeneric_EnvmapNoTexture"; + } + else + { + return "LightmappedGeneric_MaskedEnvmapNoTexture"; + } + } + else + { + return "LightmappedGeneric_NoTexture"; + } + } + else + { + if (params[ENVMAP]->IsTexture() && !bBumpedEnvMap ) + { + int pshIndex = 0; + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + pshIndex |= 0x1; + if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + pshIndex |= 0x2; + if (params[ENVMAPMASK]->IsTexture()) + pshIndex |= 0x4; + return s_pPixelShaders[pshIndex]; + } + else + { + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + return "LightmappedGeneric_SelfIlluminated"; + else + return "LightmappedGeneric"; + } + } + } +#endif + + void DrawUnbumpedUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap ) + { + bool hasEnvmap = params[ENVMAP]->IsTexture() && !bBumpedEnvMap; + bool hasBaseTexture = params[BASETEXTURE]->IsTexture(); + bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool hasEnvmapCameraSpace = IS_FLAG_SET( MATERIAL_VAR_ENVMAPCAMERASPACE ); + bool hasEnvmapSphere = IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ); + + if ( hasEnvmap || hasBaseTexture || hasVertexColor || !bBumpedEnvMap ) + { + SHADOW_STATE + { + // Alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + if ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); + } + + // Base texture on stage 0 + if (params[BASETEXTURE]->IsTexture()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + } + + // Lightmap on stage 1 + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + int fmt = VERTEX_POSITION; + + if ( hasEnvmap ) + { + fmt |= VERTEX_NORMAL; + + // envmap on stage 2 + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // envmapmask on stage 3 + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + } + + if (params[BASETEXTURE]->IsTexture() || bBumpedEnvMap) + { + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + else + { + SetDefaultBlendingShadowState( ENVMAPMASK, false ); + } + + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + { + fmt |= VERTEX_COLOR; + } + + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( false ); + vshIndex.SetENVMAP( hasEnvmap ); + vshIndex.SetENVMAPCAMERASPACE( hasEnvmap && hasEnvmapCameraSpace ); + vshIndex.SetENVMAPSPHERE( hasEnvmap && hasEnvmapSphere ); + vshIndex.SetVERTEXCOLOR( hasVertexColor ); + pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + const char *pshName = GetPixelShaderName( params, bBumpedEnvMap ); + pShaderShadow->SetPixelShader( pshName ); + DefaultFog(); + } + DYNAMIC_STATE + { + if (hasBaseTexture) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + if ( hasEnvmap ) + { + BindTexture( SHADER_SAMPLER2, ENVMAP, ENVMAPFRAME ); + + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + if (params[ENVMAPMASK]->IsTexture() ) + BindTexture( SHADER_SAMPLER3, ENVMAPMASK, ENVMAPMASKFRAME ); + else + BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME ); + + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); + } + + if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || + IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) + { + LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); + } + SetEnvMapTintPixelShaderDynamicState( 2, ENVMAPTINT, -1 ); + } + + if ( !hasEnvmap || hasBaseTexture || hasVertexColor ) + { + SetModulationVertexShaderDynamicState(); + } + EnablePixelShaderOverbright( 0, true, true ); + SetPixelShaderConstant( 1, SELFILLUMTINT ); + + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + if ( bBumpedEnvMap ) + { + DrawWorldBumpedSpecularLighting( + BUMPMAP, ENVMAP, BUMPFRAME, ENVMAPFRAME, + ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, + BUMPTRANSFORM, FRESNELREFLECTION, + hasEnvmap || hasBaseTexture || hasVertexColor ); + } + } + + void DrawDetailNoEnvmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doSelfIllum ) + { + SHADOW_STATE + { + // Alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // Base texture on stage 0 + if (params[BASETEXTURE]->IsTexture()) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Lightmap on stage 1 + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + // Detail on stage 2 + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + int fmt = VERTEX_POSITION; + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + fmt |= VERTEX_COLOR; + + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( true ); + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + vshIndex.SetVERTEXCOLOR( IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); + pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + if (!params[BASETEXTURE]->IsTexture()) + { + pShaderShadow->SetPixelShader("LightmappedGeneric_DetailNoTexture"); + } + else + { + if (!IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || (!doSelfIllum)) + { + pShaderShadow->SetPixelShader("LightmappedGeneric_Detail"); + } + else + { + pShaderShadow->SetPixelShader("LightmappedGeneric_DetailSelfIlluminated"); + } + } + DefaultFog(); + } + DYNAMIC_STATE + { + if (params[BASETEXTURE]->IsTexture()) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + BindTexture( SHADER_SAMPLER2, DETAIL, FRAME ); + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); + + SetModulationVertexShaderDynamicState(); + EnablePixelShaderOverbright( 0, true, true ); + + if (doSelfIllum) + { + SetPixelShaderConstant( 1, SELFILLUMTINT ); + } + float c2[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + c2[0] = c2[1] = c2[2] = c2[3] = params[DETAILBLENDFACTOR]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); + + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + inline const char *GetAdditiveEnvmapPixelShaderName( bool usingMask, + bool usingBaseTexture, bool usingBaseAlphaEnvmapMask ) + { + static char const* s_pPixelShaders[] = + { + "LightmappedGeneric_AddEnvmapNoTexture", + "LightmappedGeneric_AddEnvmapMaskNoTexture", + }; + + if ( !usingMask && usingBaseTexture && usingBaseAlphaEnvmapMask ) + return "LightmappedGeneric_AddBaseAlphaMaskedEnvMap"; + + int pshIndex = 0; + if (usingMask) + pshIndex |= 0x1; + return s_pPixelShaders[pshIndex]; + } + + void DrawAdditiveEnvmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + bool usingBaseTexture = params[BASETEXTURE]->IsTexture(); + bool usingMask = params[ENVMAPMASK]->IsTexture(); + bool usingBaseAlphaEnvmapMask = IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK); + SHADOW_STATE + { + // Alpha test + pShaderShadow->EnableAlphaTest( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); + + // envmap on stage 2 + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // envmapmask on stage 3 + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + + if (params[BASETEXTURE]->IsTexture()) + { + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + } + else + { + SetAdditiveBlendingShadowState( ENVMAPMASK, false ); + } + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + // Compute the vertex shader index. + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( false ); + vshIndex.SetENVMAP( true ); + vshIndex.SetENVMAPCAMERASPACE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) ); + vshIndex.SetENVMAPSPHERE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ); + vshIndex.SetVERTEXCOLOR( false ); + s_pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + const char *pshName = GetAdditiveEnvmapPixelShaderName( usingMask, + usingBaseTexture, usingBaseAlphaEnvmapMask ); + pShaderShadow->SetPixelShader( pshName ); + FogToBlack(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER2, ENVMAP, ENVMAPFRAME ); + + if (usingMask || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + { + if (usingMask) + BindTexture( SHADER_SAMPLER3, ENVMAPMASK, ENVMAPMASKFRAME ); + else + BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME ); + + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); + } + + SetPixelShaderConstant( 2, ENVMAPTINT ); + + if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) + { + LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); + } + + SetModulationVertexShaderDynamicState(); + + // Compute the vertex shader index. + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + void DrawDetailMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap ) + { + // Mode 1 : + // Pass 1 : B * L * D + Self Illum + // Pass 2 : Add E * M + + // Draw the detail w/ no envmap + DrawDetailNoEnvmap( params, pShaderAPI, pShaderShadow, true ); + + if ( !bBumpedEnvMap ) + { + DrawAdditiveEnvmap( params, pShaderAPI, pShaderShadow ); + } + else + { + DrawWorldBumpedSpecularLighting( + BUMPMAP, ENVMAP, BUMPFRAME, ENVMAPFRAME, + ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, + BUMPTRANSFORM, FRESNELREFLECTION, + true ); + } + } + + void DrawDetailUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap ) + { + // We don't have enough textures; gotta do this in two passes if there's envmapping + if (!params[ENVMAP]->IsTexture()) + { + DrawDetailNoEnvmap( params, pShaderAPI, pShaderShadow, IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) ); + } + else + { + if (!params[BASETEXTURE]->IsTexture()) + { + // If there's an envmap but no base texture, ignore detail + DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); + } + else + { + DrawDetailMode1( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); + } + } + } + + void DrawUnbumpedSeamlessUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // This is the seamless_scale version, which doesn't use $detail or $bumpmap + SHADOW_STATE + { + // three copies of the base texture for seamless blending + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // lightmap + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + worldvertextransition_seamless_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition_Seamless", vshIndex.GetIndex() ); + + int pshIndex = 0; + pShaderShadow->SetPixelShader( "WorldVertexTransition_Seamless", pshIndex ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + // Texture 0..2 + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); + } + + // Texture 3 = lightmap + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); + + EnablePixelShaderOverbright( 0, true, true ); + + float fSeamlessScale = params[SEAMLESS_SCALE]->GetFloatValue(); + float map_scale[4]= { fSeamlessScale, fSeamlessScale, fSeamlessScale, fSeamlessScale }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale ); + + worldvertextransition_seamless_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + SHADER_DRAW + { + bool hasFlashlight = UsingFlashlight( params ); + bool bBump = ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture() && + (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0); + bool bSSBump = bBump && ( params[SSBUMP]->GetIntValue() != 0 ); + + if( hasFlashlight ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 ); + } + else if( bBump ) + { + DrawWorldBumpedUsingVertexShader( + BASETEXTURE, BASETEXTURETRANSFORM, + BUMPMAP, BUMPFRAME, BUMPTRANSFORM, ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP, + ENVMAPFRAME, ENVMAPTINT, COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, FRESNELREFLECTION, + false, -1, -1, -1, bSSBump ); + } + else + { + bool bBumpedEnvMap = ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture() && params[ENVMAP]->IsTexture(); + if (!params[DETAIL]->IsTexture()) + { + if( params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) + { + DrawUnbumpedSeamlessUsingVertexShader( params, pShaderAPI, pShaderShadow ); + } + else + { + DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); + } + } + else + { + DrawDetailUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); + } + } + } +END_SHADER + + +//----------------------------------------------------------------------------- +// Version that doesn't do bumpmapping +//----------------------------------------------------------------------------- +BEGIN_INHERITED_SHADER( LightmappedGeneric_NoBump_DX8, LightmappedGeneric_DX8, + "Help for LightmappedGeneric_NoBump_DX8" ) + + SHADER_FALLBACK + { + if (g_pHardwareConfig->GetDXSupportLevel() < 80) + return "LightmappedGeneric_DX6"; + + return 0; + } + + virtual bool ShouldUseBumpmapping( IMaterialVar **params ) + { + if ( !g_pConfig->UseBumpmapping() ) + return false; + + if ( !params[BUMPMAP]->IsDefined() ) + return false; + + return ( params[FORCEBUMP]->GetIntValue() != 0 ); + } + +END_INHERITED_SHADER diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp new file mode 100644 index 00000000..bac124a8 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp @@ -0,0 +1,164 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "convar.h" +#include "lightmappedgeneric_dx9_helper.h" + +static LightmappedGeneric_DX9_Vars_t s_info; + + +BEGIN_VS_SHADER( LightmappedGeneric, + "Help for LightmappedGeneric" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + + SHADER_PARAM( ALPHA2, SHADER_PARAM_TYPE_FLOAT, "1", "" ) + + // detail (multi-) texturing + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( BUMPMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( BUMPMASK, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/lightmappedtexture", "Blended texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $basetexture2" ) + SHADER_PARAM( BASETEXTURENOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( BASETEXTURE2NOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "light munging lookup texture" ) + SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) + SHADER_PARAM( MASKEDBLENDING, SHADER_PARAM_TYPE_INTEGER, "0", "blend using texture with no vertex alpha. For using texture blending on non-displacements" ) + SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + + SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.") + SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha."); + SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha."); + + SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") + SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) + SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline") + SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") + SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") + SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") + SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") +END_SHADER_PARAMS + + void SetupVars( LightmappedGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + + info.m_nAlpha2 = ALPHA2; + + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTint = DETAILTINT; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nFresnelReflection = FRESNELREFLECTION; + info.m_nNoDiffuseBumpLighting = NODIFFUSEBUMPLIGHTING; + info.m_nBumpmap2 = BUMPMAP2; + info.m_nBumpFrame2 = BUMPFRAME2; + info.m_nBumpTransform2 = BUMPTRANSFORM2; + info.m_nBumpMask = BUMPMASK; + info.m_nBaseTexture2 = BASETEXTURE2; + info.m_nBaseTexture2Frame = FRAME2; + info.m_nBaseTextureNoEnvmap = BASETEXTURENOENVMAP; + info.m_nBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP; + info.m_nDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nLightWarpTexture = LIGHTWARPTEXTURE; + info.m_nBlendModulateTexture = BLENDMODULATETEXTURE; + info.m_nMaskedBlending = MASKEDBLENDING; + info.m_nBlendMaskTransform = BLENDMASKTRANSFORM; + info.m_nSelfShadowedBumpFlag = SSBUMP; + info.m_nSeamlessMappingScale = SEAMLESS_SCALE; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + + info.m_nSoftEdges = SOFTEDGES; + info.m_nEdgeSoftnessStart = EDGESOFTNESSSTART; + info.m_nEdgeSoftnessEnd = EDGESOFTNESSEND; + info.m_nOutline = OUTLINE; + info.m_nOutlineColor = OUTLINECOLOR; + info.m_nOutlineAlpha = OUTLINEALPHA; + info.m_nOutlineStart0 = OUTLINESTART0; + info.m_nOutlineStart1 = OUTLINESTART1; + info.m_nOutlineEnd0 = OUTLINEEND0; + info.m_nOutlineEnd1 = OUTLINEEND1; + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "LightmappedGeneric_DX8"; + + return 0; + } + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { + SetupVars( s_info ); + InitParamsLightmappedGeneric_DX9( this, params, pMaterialName, s_info ); + } + + SHADER_INIT + { + SetupVars( s_info ); + InitLightmappedGeneric_DX9( this, params, s_info ); + } + + SHADER_DRAW + { + DrawLightmappedGeneric_DX9( this, params, pShaderAPI, pShaderShadow, s_info, pContextDataPtr ); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp new file mode 100644 index 00000000..9da6716d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp @@ -0,0 +1,1085 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//============================================================================= + +#include "lightmappedgeneric_dx9_helper.h" +#include "BaseVSShader.h" +#include "commandbuilder.h" +#include "convar.h" +#include "lightmappedgeneric_ps20.inc" +#include "lightmappedgeneric_vs20.inc" +#include "lightmappedgeneric_ps20b.inc" + +#include "tier0/memdbgon.h" + +ConVar mat_disable_lightwarp( "mat_disable_lightwarp", "0" ); +ConVar mat_disable_fancy_blending( "mat_disable_fancy_blending", "0" ); +ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); +ConVar my_mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); +extern ConVar r_flashlight_version2; + +class CLightmappedGeneric_DX9_Context : public CBasePerMaterialContextData +{ +public: + uint8 *m_pStaticCmds; + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; + + bool m_bVertexShaderFastPath; + bool m_bPixelShaderFastPath; + bool m_bPixelShaderForceFastPathBecauseOutline; + bool m_bFullyOpaque; + bool m_bFullyOpaqueWithoutAlphaTest; + + void ResetStaticCmds( void ) + { + if ( m_pStaticCmds ) + { + delete[] m_pStaticCmds; + m_pStaticCmds = NULL; + } + } + + CLightmappedGeneric_DX9_Context( void ) + { + m_pStaticCmds = NULL; + } + + ~CLightmappedGeneric_DX9_Context( void ) + { + ResetStaticCmds(); + } + +}; + + +void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info ) +{ + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. + if( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() && + !( params[info.m_nNoDiffuseBumpLighting]->IsDefined() && params[info.m_nNoDiffuseBumpLighting]->GetIntValue() ) ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + if( pShader->IsUsingGraphics() && params[info.m_nEnvmap]->IsDefined() && !pShader->CanUseEditorMaterials() ) + { + if( stricmp( params[info.m_nEnvmap]->GetStringValue(), "env_cubemap" ) == 0 ) + { + Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + } + + if ( (mat_disable_lightwarp.GetBool() ) && + (info.m_nLightWarpTexture != -1) ) + { + params[info.m_nLightWarpTexture]->SetUndefined(); + } + if ( (mat_disable_fancy_blending.GetBool() ) && + (info.m_nBlendModulateTexture != -1) ) + { + params[info.m_nBlendModulateTexture]->SetUndefined(); + } + + if( !params[info.m_nEnvmapTint]->IsDefined() ) + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[info.m_nNoDiffuseBumpLighting]->IsDefined() ) + params[info.m_nNoDiffuseBumpLighting]->SetIntValue( 0 ); + + if( !params[info.m_nSelfIllumTint]->IsDefined() ) + params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[info.m_nDetailScale]->IsDefined() ) + params[info.m_nDetailScale]->SetFloatValue( 4.0f ); + + if ( !params[info.m_nDetailTint]->IsDefined() ) + params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f, 1.0f ); + + InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + InitIntParam( info.m_nDetailTextureCombineMode, params, 0 ); + + if( !params[info.m_nFresnelReflection]->IsDefined() ) + params[info.m_nFresnelReflection]->SetFloatValue( 1.0f ); + + if( !params[info.m_nEnvmapMaskFrame]->IsDefined() ) + params[info.m_nEnvmapMaskFrame]->SetIntValue( 0 ); + + if( !params[info.m_nEnvmapFrame]->IsDefined() ) + params[info.m_nEnvmapFrame]->SetIntValue( 0 ); + + if( !params[info.m_nBumpFrame]->IsDefined() ) + params[info.m_nBumpFrame]->SetIntValue( 0 ); + + if( !params[info.m_nDetailFrame]->IsDefined() ) + params[info.m_nDetailFrame]->SetIntValue( 0 ); + + if( !params[info.m_nEnvmapContrast]->IsDefined() ) + params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f ); + + if( !params[info.m_nEnvmapSaturation]->IsDefined() ) + params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f ); + + InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if( params[info.m_nBumpmap]->IsDefined() ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0) ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nEnvmap]->SetUndefined(); + } + + if( !params[info.m_nBaseTextureNoEnvmap]->IsDefined() ) + { + params[info.m_nBaseTextureNoEnvmap]->SetIntValue( 0 ); + } + if( !params[info.m_nBaseTexture2NoEnvmap]->IsDefined() ) + { + params[info.m_nBaseTexture2NoEnvmap]->SetIntValue( 0 ); + } + + if( ( info.m_nSelfShadowedBumpFlag != -1 ) && + ( !params[info.m_nSelfShadowedBumpFlag]->IsDefined() ) + ) + { + params[info.m_nSelfShadowedBumpFlag]->SetIntValue( 0 ); + } + // handle line art parms + InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); + InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); + InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); +} + +void InitLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedGeneric_DX9_Vars_t &info ) +{ + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + } + + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap2]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap2 ); + } + + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpMask]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpMask ); + } + + if (params[info.m_nBaseTexture]->IsDefined()) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + + if (!params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[info.m_nBaseTexture2]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture2, TEXTUREFLAGS_SRGB ); + } + + if (params[info.m_nLightWarpTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nLightWarpTexture ); + } + + if ((info.m_nBlendModulateTexture != -1) && + (params[info.m_nBlendModulateTexture]->IsDefined()) ) + { + pShader->LoadTexture( info.m_nBlendModulateTexture ); + } + + if (params[info.m_nDetail]->IsDefined()) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; + + pShader->LoadTexture( info.m_nDetail, nDetailBlendMode != 0 ? TEXTUREFLAGS_SRGB : 0 ); + } + + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if (params[info.m_nEnvmap]->IsDefined()) + { + if ( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + else + { + pShader->LoadTexture( info.m_nEnvmap ); + } + + if ( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if ( params[info.m_nEnvmapMask]->IsDefined() ) + { + pShader->LoadTexture( info.m_nEnvmapMask ); + } + } + else + { + params[info.m_nEnvmapMask]->SetUndefined(); + } + + // We always need this because of the flashlight. + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); +} + +void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar** params, bool hasFlashlight, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + LightmappedGeneric_DX9_Vars_t &info, + CBasePerMaterialContextData **pContextDataPtr + ) +{ + CLightmappedGeneric_DX9_Context *pContextData = reinterpret_cast< CLightmappedGeneric_DX9_Context *> ( *pContextDataPtr ); + if ( pShaderShadow || ( ! pContextData ) || pContextData->m_bMaterialVarsChanged || hasFlashlight ) + { + bool hasBaseTexture = params[info.m_nBaseTexture]->IsTexture(); + int nAlphaChannelTextureVar = hasBaseTexture ? (int)info.m_nBaseTexture : (int)info.m_nEnvmapMask; + BlendType_t nBlendType = pShader->EvaluateBlendRequirements( nAlphaChannelTextureVar, hasBaseTexture ); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bFullyOpaqueWithoutAlphaTest = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && (!hasFlashlight || IsX360()); //dest alpha is free for special use + bool bFullyOpaque = bFullyOpaqueWithoutAlphaTest && !bIsAlphaTested; + bool bNeedRegenStaticCmds = (! pContextData ) || pShaderShadow; + + if ( ! pContextData ) // make sure allocated + { + pContextData = new CLightmappedGeneric_DX9_Context; + *pContextDataPtr = pContextData; + } + + bool hasBump = ( params[info.m_nBumpmap]->IsTexture() ) && ( !g_pHardwareConfig->PreferReducedFillrate() ); + bool hasSSBump = hasBump && (info.m_nSelfShadowedBumpFlag != -1) && ( params[info.m_nSelfShadowedBumpFlag]->GetIntValue() ); + bool hasBaseTexture2 = hasBaseTexture && params[info.m_nBaseTexture2]->IsTexture(); + bool hasLightWarpTexture = params[info.m_nLightWarpTexture]->IsTexture(); + bool hasBump2 = hasBump && params[info.m_nBumpmap2]->IsTexture(); + bool hasDetailTexture = params[info.m_nDetail]->IsTexture(); + bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + bool hasBumpMask = hasBump && hasBump2 && params[info.m_nBumpMask]->IsTexture() && !hasSelfIllum && + !hasDetailTexture && !hasBaseTexture2 && (params[info.m_nBaseTextureNoEnvmap]->GetIntValue() == 0); + bool bHasBlendModulateTexture = + (info.m_nBlendModulateTexture != -1) && + (params[info.m_nBlendModulateTexture]->IsTexture() ); + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + + if ( hasFlashlight && !IsX360() ) + { + // !!speed!! do this in the caller so we don't build struct every time + CBaseVSShader::DrawFlashlight_dx90_Vars_t vars; + vars.m_bBump = hasBump; + vars.m_nBumpmapVar = info.m_nBumpmap; + vars.m_nBumpmapFrame = info.m_nBumpFrame; + vars.m_nBumpTransform = info.m_nBumpTransform; + vars.m_nFlashlightTextureVar = info.m_nFlashlightTexture; + vars.m_nFlashlightTextureFrameVar = info.m_nFlashlightTextureFrame; + vars.m_bLightmappedGeneric = true; + vars.m_bWorldVertexTransition = hasBaseTexture2; + vars.m_nBaseTexture2Var = info.m_nBaseTexture2; + vars.m_nBaseTexture2FrameVar = info.m_nBaseTexture2Frame; + vars.m_nBumpmap2Var = info.m_nBumpmap2; + vars.m_nBumpmap2Frame = info.m_nBumpFrame2; + vars.m_nBump2Transform = info.m_nBumpTransform2; + vars.m_nAlphaTestReference = info.m_nAlphaTestReference; + vars.m_bSSBump = hasSSBump; + vars.m_nDetailVar = info.m_nDetail; + vars.m_nDetailScale = info.m_nDetailScale; + vars.m_nDetailTextureCombineMode = info.m_nDetailTextureCombineMode; + vars.m_nDetailTextureBlendFactor = info.m_nDetailTextureBlendFactor; + vars.m_nDetailTint = info.m_nDetailTint; + + if ( ( info.m_nSeamlessMappingScale != -1 ) ) + vars.m_fSeamlessScale = params[info.m_nSeamlessMappingScale]->GetFloatValue(); + else + vars.m_fSeamlessScale = 0.0; + pShader->DrawFlashlight_dx90( params, pShaderAPI, pShaderShadow, vars ); + return; + } + + pContextData->m_bFullyOpaque = bFullyOpaque; + pContextData->m_bFullyOpaqueWithoutAlphaTest = bFullyOpaqueWithoutAlphaTest; + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( hasBump && g_pHardwareConfig->SupportsNormalMapCompression() && g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + ITexture *pBumpTex = params[info.m_nBumpmap]->GetTextureValue(); + if ( pBumpTex ) + { + nNormalDecodeMode = pBumpTex->GetNormalDecodeMode(); + + if ( hasBump2 ) // Check encoding of secondary normal if there is oneg + { + ITexture *pBumpTex2 = params[info.m_nBumpmap]->GetTextureValue(); + if ( pBumpTex2 && ( pBumpTex2->GetNormalDecodeMode() != nNormalDecodeMode ) ) + { + DevMsg("LightmappedGeneric: Primary and Secondary normal map compression formats don't match. This is unsupported!\n"); + Assert(0); + } + } + } + } + + int nNormalMaskDecodeMode = 0; + if ( hasBumpMask && g_pHardwareConfig->SupportsNormalMapCompression() && g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + ITexture *pBumpMaskTex = params[info.m_nBumpMask]->GetTextureValue(); + if ( pBumpMaskTex ) + { + nNormalMaskDecodeMode = pBumpMaskTex->GetNormalDecodeMode(); + } + } + + bool bHasOutline = IsBoolSet( info.m_nOutline, params ); + pContextData->m_bPixelShaderForceFastPathBecauseOutline = bHasOutline; + bool bHasSoftEdges = IsBoolSet( info.m_nSoftEdges, params ); + bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); + + + float fDetailBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + + if ( pShaderShadow || bNeedRegenStaticCmds ) + { + bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool hasDiffuseBumpmap = hasBump && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0); + + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + + bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && + ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); + + if ( bNeedRegenStaticCmds ) + { + pContextData->ResetStaticCmds(); + CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; + + + if( !hasBaseTexture ) + { + if( hasEnvmap ) + { + // if we only have an envmap (no basetexture), then we want the albedo to be black. + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); + } + else + { + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + } + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + if ( bSeamlessMapping ) + { + staticCmdsBuf.SetVertexShaderConstant4( + VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, + params[info.m_nSeamlessMappingScale]->GetFloatValue(),0,0,0 ); + } + staticCmdsBuf.StoreEyePosInPixelShaderConstant( 10 ); + staticCmdsBuf.SetPixelShaderFogParams( 11 ); + staticCmdsBuf.End(); + // now, copy buf + pContextData->m_pStaticCmds = new uint8[staticCmdsBuf.Size()]; + memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); + } + if ( pShaderShadow ) + { + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + pShader->SetDefaultBlendingShadowState( nAlphaChannelTextureVar, hasBaseTexture ); + + unsigned int flags = VERTEX_POSITION; + + // base texture + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + if ( hasLightWarpTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false ); + } + if ( bHasBlendModulateTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false ); + } + + if ( hasBaseTexture2 ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true ); + } +// if( hasLightmap ) + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + else + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + } + + if( hasEnvmap || ( IsX360() && hasFlashlight ) ) + { + if( hasEnvmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + } + } + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL; + } + + int nDetailBlendMode = 0; + if ( hasDetailTexture ) + { + nDetailBlendMode = GetIntParam( info.m_nDetailTextureCombineMode, params ); + ITexture *pDetailTexture = params[info.m_nDetail]->GetTextureValue(); + if ( pDetailTexture->GetFlags() & TEXTUREFLAGS_SSBUMP ) + { + if ( hasBump ) + nDetailBlendMode = 10; // ssbump + else + nDetailBlendMode = 11; // ssbump_nobump + } + } + + if( hasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); + bool bSRGBState = ( nDetailBlendMode == 1 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER12, bSRGBState ); + } + + if( hasBump || hasNormalMapAlphaEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Normal map alpha, in the compressed normal case + } + } + if( hasBump2 ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // Secondary normal alpha, in the compressed normal case + } + } + if( hasBumpMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); + if ( nNormalMaskDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Normal mask alpha, in the compressed normal case + } + } + if( hasEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + } + + if( hasFlashlight && IsX360() ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER14 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER15, true ); + } + + if( hasVertexColor || hasBaseTexture2 || hasBump2 ) + { + flags |= VERTEX_COLOR; + } + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 2; + if( hasBump ) + { + numTexCoords = 3; + } + + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + // Pre-cache pixel shaders + bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + + int bumpmap_variant=(hasSSBump) ? 2 : hasBump; + bool bMaskedBlending=( (info.m_nMaskedBlending != -1) && + (params[info.m_nMaskedBlending]->GetIntValue() != 0) ); + + DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask ); + SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, params[info.m_nEnvmap]->IsTexture() ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, hasBaseTexture2 || hasBump2 ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, hasBumpMask ); + + bool bReliefMapping = false; //( bumpmap_variant == 2 ) && ( ! bSeamlessMapping ); + SET_STATIC_VERTEX_SHADER_COMBO( RELIEF_MAPPING, false );//bReliefMapping ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); +#ifdef _X360 + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight); +#endif + SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); + SET_STATIC_PIXEL_SHADER_COMBO( RELIEF_MAPPING, bReliefMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, (int) nNormalMaskDecodeMode ); +#ifdef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight); +#endif + SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, 0 ); // No normal compression with ps_2_0 (yikes!) + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, 0 ); // No normal compression with ps_2_0 + SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20 ); + } + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff and writing depth to dest alpha + // But only do it if we're not using the alpha already for translucency + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + + pShaderShadow->EnableSRGBWrite( true ); + + pShader->DefaultFog(); + + + } // end shadow state + } // end shadow || regen display list + if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) + { + // need to regenerate the semistatic cmds + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_bMaterialVarsChanged = false; + + bool bHasBlendMaskTransform= ( + (info.m_nBlendMaskTransform != -1) && + (info.m_nMaskedBlending != -1) && + (params[info.m_nMaskedBlending]->GetIntValue() ) && + ( ! (params[info.m_nBumpTransform]->MatrixIsIdentity() ) ) ); + + // If we don't have a texture transform, we don't have + // to set vertex shader constants or run vertex shader instructions + // for the texture transform. + bool bHasTextureTransform = + !( params[info.m_nBaseTextureTransform]->MatrixIsIdentity() && + params[info.m_nBumpTransform]->MatrixIsIdentity() && + params[info.m_nBumpTransform2]->MatrixIsIdentity() && + params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ); + + bHasTextureTransform |= bHasBlendMaskTransform; + + pContextData->m_bVertexShaderFastPath = !bHasTextureTransform; + + if( params[info.m_nDetail]->IsTexture() ) + { + pContextData->m_bVertexShaderFastPath = false; + } + if (bHasBlendMaskTransform) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( + VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, info.m_nBlendMaskTransform ); + } + + if ( ! pContextData->m_bVertexShaderFastPath ) + { + bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && + ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); + bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); + if (!bSeamlessMapping ) + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + // If we have a detail texture, then the bump texcoords are the same as the base texcoords. + if( hasBump && !hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); + } + if( hasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform ); + } + else if ( hasBump2 ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBumpTransform2 ); + } + } + pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicState( 0, info.m_nEnvmapTint ); + // set up shader modulation color + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + pShader->ComputeModulationColor( color ); + float flLScale = pShaderAPI->GetLightMapScaleFactor(); + color[0] *= flLScale; + color[1] *= flLScale; + color[2] *= flLScale; + + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + color[3] *= ( IS_PARAM_DEFINED( info.m_nAlpha2 ) && params[ info.m_nAlpha2 ]->GetFloatValue() > 0.0f ) ? params[ info.m_nAlpha2 ]->GetFloatValue() : 1.0f; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 12, color ); + + if ( hasDetailTexture ) + { + float detailTintAndBlend[4] = {1, 1, 1, 1}; + + if ( info.m_nDetailTint != -1 ) + { + params[info.m_nDetailTint]->GetVecValue( detailTintAndBlend, 3 ); + } + + detailTintAndBlend[3] = fDetailBlendFactor; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 8, detailTintAndBlend ); + } + + float envmapTintVal[4]; + float selfIllumTintVal[4]; + params[info.m_nEnvmapTint]->GetVecValue( envmapTintVal, 3 ); + params[info.m_nSelfIllumTint]->GetVecValue( selfIllumTintVal, 3 ); + float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); + float envmapSaturation = params[info.m_nEnvmapSaturation]->GetFloatValue(); + float fresnelReflection = params[info.m_nFresnelReflection]->GetFloatValue(); + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + + pContextData->m_bPixelShaderFastPath = true; + bool bUsingContrast = hasEnvmap && ( (envmapContrast != 0.0f) && (envmapContrast != 1.0f) ) && (envmapSaturation != 1.0f); + bool bUsingFresnel = hasEnvmap && (fresnelReflection != 1.0f); + bool bUsingSelfIllumTint = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && (selfIllumTintVal[0] != 1.0f || selfIllumTintVal[1] != 1.0f || selfIllumTintVal[2] != 1.0f); + if ( bUsingContrast || bUsingFresnel || bUsingSelfIllumTint || !g_pConfig->bShowSpecular ) + { + pContextData->m_bPixelShaderFastPath = false; + } + if( !pContextData->m_bPixelShaderFastPath ) + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstants( 2, 3 ); + pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapContrast]->GetVecValue() ); + pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapSaturation]->GetVecValue() ); + float flFresnel = params[info.m_nFresnelReflection]->GetFloatValue(); + // [ 0, 0, 1-R(0), R(0) ] + pContextData->m_SemiStaticCmdsOut.OutputConstantData4( 0., 0., 1.0 - flFresnel, flFresnel ); + + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, params[info.m_nSelfIllumTint]->GetVecValue() ); + } + else + { + if ( bHasOutline ) + { + float flOutlineParms[8] = { GetFloatParam( info.m_nOutlineStart0, params ), + GetFloatParam( info.m_nOutlineStart1, params ), + GetFloatParam( info.m_nOutlineEnd0, params ), + GetFloatParam( info.m_nOutlineEnd1, params ), + 0,0,0, + GetFloatParam( info.m_nOutlineAlpha, params ) }; + if ( info.m_nOutlineColor != -1 ) + { + params[info.m_nOutlineColor]->GetVecValue( flOutlineParms + 4, 3 ); + } + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 2, flOutlineParms, 2 ); + } + + if ( bHasSoftEdges ) + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( + 4, GetFloatParam( info.m_nEdgeSoftnessStart, params ), + GetFloatParam( info.m_nEdgeSoftnessEnd, params ), + 0,0 ); + } + } + // texture binds + if( hasBaseTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + // handle mat_fullbright 2 + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + if( bLightingOnly ) + { + // BASE TEXTURE + if( hasSelfIllum ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + // BASE TEXTURE 2 + if( hasBaseTexture2 ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER7, TEXTURE_GREY ); + } + + // DETAIL TEXTURE + if( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_GREY ); + } + + // disable color modulation + float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + // turn off environment mapping + envmapTintVal[0] = 0.0f; + envmapTintVal[1] = 0.0f; + envmapTintVal[2] = 0.0f; + } + + // always set the transform for detail textures since I'm assuming that you'll + // always have a detailscale. + if( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBaseTextureTransform, info.m_nDetailScale ); + } + + if( hasBaseTexture2 ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER7, info.m_nBaseTexture2, info.m_nBaseTexture2Frame ); + } + if( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER12, info.m_nDetail, info.m_nDetailFrame ); + } + + if( hasBump || hasNormalMapAlphaEnvmapMask ) + { + if( !g_pConfig->m_bFastNoBump ) + { + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pContextData->m_SemiStaticCmdsOut.BindMultiTexture( pShader, SHADER_SAMPLER4, SHADER_SAMPLER9, info.m_nBumpmap, info.m_nBumpFrame ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nBumpmap, info.m_nBumpFrame ); + } + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALMAP_FLAT ); + } + } + if( hasBump2 ) + { + if( !g_pConfig->m_bFastNoBump ) + { + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pContextData->m_SemiStaticCmdsOut.BindMultiTexture( pShader, SHADER_SAMPLER5, SHADER_SAMPLER10, info.m_nBumpmap2, info.m_nBumpFrame2 ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nBumpmap2, info.m_nBumpFrame2 ); + } + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALMAP_FLAT ); + } + } + if( hasBumpMask ) + { + if( !g_pConfig->m_bFastNoBump ) + { + if ( nNormalMaskDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + Assert(0); + //pContextData->m_SemiStaticCmdsOut.BindTexture( SHADER_SAMPLER8, SHADER_SAMPLER11, info.m_nBumpMask ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER8, info.m_nBumpMask, -1 ); + } + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER8, TEXTURE_NORMALMAP_FLAT ); + } + } + + if( hasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); + } + + if ( hasLightWarpTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER6, info.m_nLightWarpTexture, -1 ); + } + + if ( bHasBlendModulateTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBlendModulateTexture, -1 ); + } + + pContextData->m_SemiStaticCmdsOut.End(); + } + } + DYNAMIC_STATE + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + + if( hasEnvmap ) + { + DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + int nFixedLightingMode = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ); + + bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath; + + if( nFixedLightingMode != 0 ) + { + if ( pContextData->m_bPixelShaderForceFastPathBecauseOutline ) + nFixedLightingMode = 0; + else + bVertexShaderFastPath = false; + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( + LIGHTING_PREVIEW, + (nFixedLightingMode)?1:0 + ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_vs20 ); + + bool bPixelShaderFastPath = pContextData->m_bPixelShaderFastPath; + if( nFixedLightingMode !=0 ) + { + bPixelShaderFastPath = false; + } + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if( pContextData->m_bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedgeneric_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath || pContextData->m_bPixelShaderForceFastPathBecauseOutline ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nFixedLightingMode ); + + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedgeneric_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nFixedLightingMode ); + + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_ps20 ); + } + + if( hasFlashlight && IsX360() ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + DynamicCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture.Base(), 4 ); + + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + float atten[4], pos[4]; + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + DynamicCmdsOut.SetPixelShaderConstant( 13, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + DynamicCmdsOut.SetPixelShaderConstant( 14, pos, 1 ); + + pShader->BindTexture( SHADER_SAMPLER13, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER14, pFlashlightDepthTexture, 0 ); + DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER15, TEXTURE_SHADOW_NOISE_2D ); + + // Tweaks associated with a given flashlight + float tweaks[4]; + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + DynamicCmdsOut.SetPixelShaderConstant( 19, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + DynamicCmdsOut.SetPixelShaderConstant( 31, vScreenScale, 1 ); + } + } + + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + pShader->Draw(); + + if( IsPC() && (IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0) && pContextData->m_bFullyOpaqueWithoutAlphaTest ) + { + //Alpha testing makes it so we can't write to dest alpha + //Writing to depth makes it so later polygons can't write to dest alpha either + //This leads to situations with garbage in dest alpha. + + //Fix it now by converting depth to dest alpha for any pixels that just wrote. + pShader->DrawEqualDepthToDestAlpha(); + } +} + +void DrawLightmappedGeneric_DX9(CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + LightmappedGeneric_DX9_Vars_t &info, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool hasFlashlight = pShader->UsingFlashlight( params ); + if ( !IsX360() && !r_flashlight_version2.GetInt() ) + { + DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); + return; + } + + DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); +} diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h new file mode 100644 index 00000000..00375b9f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h @@ -0,0 +1,99 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef LIGHTMAPPEDGENERIC_DX9_HELPER_H +#define LIGHTMAPPEDGENERIC_DX9_HELPER_H + +#include +#include "BaseVSShader.h" + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct LightmappedGeneric_DX9_Vars_t +{ + LightmappedGeneric_DX9_Vars_t() { memset( this, 0xFF, sizeof(LightmappedGeneric_DX9_Vars_t) ); } + + int m_nBaseTexture; + int m_nBaseTextureFrame; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nSelfIllumTint; + + int m_nAlpha2; // Hack for DoD srgb blend issues on overlays + + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + int m_nDetailTint; + + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nBumpFrame; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nFresnelReflection; + int m_nNoDiffuseBumpLighting; + int m_nBumpmap2; + int m_nBumpFrame2; + int m_nBumpTransform2; + int m_nBumpMask; + int m_nBaseTexture2; + int m_nBaseTexture2Frame; + int m_nBaseTextureNoEnvmap; + int m_nBaseTexture2NoEnvmap; + int m_nDetailAlphaMaskBaseTexture; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + int m_nLightWarpTexture; + int m_nBlendModulateTexture; + int m_nMaskedBlending; + int m_nBlendMaskTransform; + int m_nSelfShadowedBumpFlag; + int m_nSeamlessMappingScale; + int m_nAlphaTestReference; + + int m_nSoftEdges; + int m_nEdgeSoftnessStart; + int m_nEdgeSoftnessEnd; + + int m_nOutline; + int m_nOutlineColor; + int m_nOutlineAlpha; + int m_nOutlineStart0; + int m_nOutlineStart1; + int m_nOutlineEnd0; + int m_nOutlineEnd1; + +}; + +void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info ); +void InitLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedGeneric_DX9_Vars_t &info ); +void DrawLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + LightmappedGeneric_DX9_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr ); + + +#endif // LIGHTMAPPEDGENERIC_DX9_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_envmap.psh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_envmap.psh new file mode 100644 index 00000000..1e4a2bc4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_envmap.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc b/mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc new file mode 100644 index 00000000..3a0d059d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc @@ -0,0 +1,122 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "NORMALMAP" "0..1" +// STATIC: "WORLDVERTEXTRANSITION" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +const float3 g_FlashlightPos : register( SHADER_SPECIFIC_CONST_0 ); +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_1 ); +const float4 g_FlashlightAttenuationFactors : register( SHADER_SPECIFIC_CONST_5 ); + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cNormalMapTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_8 ); + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + // If this is float4, and the input is float3, the w component default to one. + float4 vPos : POSITION; + float3 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; +#if NORMALMAP + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +#endif + float4 vColor : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float4 spotTexCoord : TEXCOORD0; + float2 baseTexCoord : TEXCOORD1; +#if NORMALMAP + float3 tangentPosToLightVector : TEXCOORD2; + float2 normalMapTexCoord : TEXCOORD3; +#else + float3 worldPosToLightVector : TEXCOORD2; + float3 normal : TEXCOORD3; +#endif + float4 vertAtten : COLOR0; +}; + +float RemapValClamped( float val, float A, float B ) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + return cVal; +} + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + float4 projPos; + float3 worldPos; + float3 worldNormal; + float3 eyeVector; + + projPos = mul( v.vPos, cModelViewProj ); + o.projPos = projPos; + + worldPos = mul( v.vPos, cModel[0] ); + worldNormal = mul( v.vNormal, ( float3x3 )cModel[0] ); + +#if NORMALMAP + float3 worldTangentS = mul( v.vTangentS, cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, cModel[0] ); +#endif + +#if !defined( _X360 ) + o.fog = CalcFog( worldPos, projPos, g_FogType ); +#endif + + o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; + o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; + + float4 spotTexCoord = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); + o.spotTexCoord = spotTexCoord.xyzw; + + float3 worldPosToLightVector = g_FlashlightPos - worldPos; +#if NORMALMAP + o.normalMapTexCoord.x = dot( v.vBaseTexCoord, cNormalMapTexCoordTransform[0] ) + cNormalMapTexCoordTransform[0].w; + o.normalMapTexCoord.y = dot( v.vBaseTexCoord, cNormalMapTexCoordTransform[1] ) + cNormalMapTexCoordTransform[1].w; + + o.tangentPosToLightVector.x = dot( worldPosToLightVector, worldTangentS ); + o.tangentPosToLightVector.y = dot( worldPosToLightVector, worldTangentT ); + o.tangentPosToLightVector.z = dot( worldPosToLightVector, worldNormal ); +#else + o.worldPosToLightVector = worldPosToLightVector; + o.normal = worldNormal; +#endif + + float3 delta = worldPosToLightVector; + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); + float farZ = g_FlashlightAttenuationFactors.w; + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6 * farZ ); + o.vertAtten.xyz = saturate( endFalloffFactor * dot( g_FlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + +#if WORLDVERTEXTRANSITION + o.vertAtten.w = 1 - v.vColor.w; +#else +#if VERTEXCOLOR + o.vertAtten.w = v.vColor.w; +#else + o.vertAtten.w = 1.0f; +#endif +#endif + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc b/mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc new file mode 100644 index 00000000..7d23bb95 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc @@ -0,0 +1,184 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "NORMALMAP" "0..1" +// STATIC: "WORLDVERTEXTRANSITION" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "DETAIL" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +const float3 g_FlashlightPos : register( SHADER_SPECIFIC_CONST_0 ); +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_1 ); +const float4 g_FlashlightAttenuationFactors : register( SHADER_SPECIFIC_CONST_5 ); + +#if SEAMLESS +const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_6 ); +#define SEAMLESS_SCALE (SeamlessScale.x) +#endif +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cNormalMapOrDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_8 ); + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + float3 vPos : POSITION; //This HAS to match lightmappedgeneric_vs20.fxc's position input. Otherwise depth fighting errors occur on the 360 + float4 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; +#if WORLDVERTEXTRANSITION + float2 vLightmapTexCoord : TEXCOORD1; + float4 vColor : COLOR0; +#endif +#if NORMALMAP + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + + float4 spotTexCoord : TEXCOORD0; + +#if SEAMLESS + float3 SeamlessTexCoord : TEXCOORD1; +#else + float2 baseTexCoord : TEXCOORD1; +#endif + +#if NORMALMAP + float3 tangentPosToLightVector : TEXCOORD2; + float2 normalMapTexCoord : TEXCOORD3; +#else + float3 worldPosToLightVector : TEXCOORD2; + float3 normal : TEXCOORD3; +#endif + + float2 detailCoords : TEXCOORD4; + float4 worldPos_worldTransition : TEXCOORD5; + float3 vProjPos : TEXCOORD6; + float4 fogFactorW : TEXCOORD7; +}; + +float RemapValClamped( float val, float A, float B, float C, float D) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + + return C + (D - C) * cVal; +} + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float4 projPos; + float3 worldPos; + float3 worldNormal; + float3 eyeVector; + + //Projection math HAS to match lightmappedgeneric_vs20.fxc's math exactly. Otherwise depth fighting errors occur on the 360 + projPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + o.projPos = projPos; + o.vProjPos.xyz = projPos.xyw; + + worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); + worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + + o.worldPos_worldTransition = float4( worldPos.xyz, 1.0f ); + + o.fogFactorW = CalcFog( worldPos, projPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW.w; +#endif + +#if NORMALMAP + float3 worldTangentS = mul( v.vTangentS, cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, cModel[0] ); +#endif +#if SEAMLESS + float3 vNormal=normalize( worldNormal ); + o.fogFactorW.xyz = vNormal * vNormal; // sums to 1. + o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos; + + // Generate new tangent and binormal with seamless projection + #if NORMALMAP + // Brute-force for prototype - This must match the projection in the pixel shader! + //float3 vVecX = { 1.0f, 0.0f, 0.0f }; + //float3 vVecY = { 0.0f, 1.0f, 0.0f }; + //float3 vVecZ = { 0.0f, 0.0f, 1.0f }; + //worldTangentS.xyz = normalize( ( o.fogFactorW.x * vVecZ.xyz ) + ( o.fogFactorW.y * vVecX.xyz ) + ( o.fogFactorW.z * vVecX.xyz ) ); + //worldTangentT.xyz = normalize( ( o.fogFactorW.x * vVecY.xyz ) + ( o.fogFactorW.y * vVecZ.xyz ) + ( o.fogFactorW.z * vVecY.xyz ) ); + + // Optimized version - This must match the projection in the pixel shader! + worldTangentS.xyz = normalize( float3( o.fogFactorW.y + o.fogFactorW.z, 0.0f, o.fogFactorW.x ) ); + worldTangentT.xyz = normalize( float3( 0.0f, o.fogFactorW.x + o.fogFactorW.z, o.fogFactorW.y ) ); + #endif +#else +#if (SEAMLESS == 0 ) + o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; + o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; +#endif +#endif + + float4 spotTexCoord = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); + o.spotTexCoord = spotTexCoord.xyzw; + + float3 worldPosToLightVector = g_FlashlightPos - worldPos; +#if NORMALMAP + +#if (DETAIL == 0) + o.normalMapTexCoord.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w; + o.normalMapTexCoord.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w; +#else + +#if SEAMLESS + o.normalMapTexCoord = v.vBaseTexCoord; +#else + o.normalMapTexCoord = o.baseTexCoord; +#endif + +#endif + + o.tangentPosToLightVector.x = dot( worldPosToLightVector, worldTangentS ); + o.tangentPosToLightVector.y = dot( worldPosToLightVector, worldTangentT ); + o.tangentPosToLightVector.z = dot( worldPosToLightVector, worldNormal ); +#else + o.worldPosToLightVector = worldPosToLightVector; + o.normal = worldNormal; +#endif + +#if DETAIL + o.detailCoords.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w; + o.detailCoords.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w; +#else + o.detailCoords = float2(0,0); +#endif + + //float3 delta = worldPosToLightVector; + //float distSquared = dot( delta, delta ); + //float dist = sqrt( distSquared ); + //float farZ = g_FlashlightAttenuationFactors.w; + //float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + //o.projPos_atten.w = endFalloffFactor * dot( g_FlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ); + //o.projPos_atten.w = saturate( o.projPos_atten.w ); + +#if WORLDVERTEXTRANSITION + o.worldPos_worldTransition.w = v.vColor.w; +#endif + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_inc.vsh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_inc.vsh new file mode 100644 index 00000000..a5d12a81 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_inc.vsh @@ -0,0 +1,110 @@ +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform +; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform +; $SHADER_SPECIFIC_CONST_4 = Modulation color +;------------------------------------------------------------------------------ + +sub LightmappedGeneric +{ + local( $detail ) = shift; + local( $envmap ) = shift; + local( $envmapcameraspace ) = shift; + local( $envmapsphere ) = shift; + local( $vertexcolor ) = shift; + + local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + + &AllocateRegister( \$projPos ); + + dp4 $projPos.x, $vPos, $cModelViewProj0 + dp4 $projPos.y, $vPos, $cModelViewProj1 + dp4 $projPos.z, $vPos, $cModelViewProj2 + dp4 $projPos.w, $vPos, $cModelViewProj3 + mov oPos, $projPos + + &AllocateRegister( \$worldPos ); + + if( $DOWATERFOG == 1 ) + { + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 + } + &CalcFog( $worldPos, $projPos ); + &FreeRegister( \$projPos ); + + ;------------------------------------------------------------------------------ + ; Texture coordinates + ;------------------------------------------------------------------------------ + ; base texcoords + dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 + dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + ; lightmap texcoords + mov oT1, $vTexCoord1 + + if( $envmap ) + { + &AllocateRegister( \$worldNormal ); + + ; Transform the position + normal to world space + dp4 $worldPos.x, $vPos, $cModel0 + dp4 $worldPos.y, $vPos, $cModel1 + if( $DOWATERFOG ne 1 ) + { + dp4 $worldPos.z, $vPos, $cModel2 + } + + dp3 $worldNormal.x, $vNormal, $cModel0 + dp3 $worldNormal.y, $vNormal, $cModel1 + dp3 $worldNormal.z, $vNormal, $cModel2 + + if( $envmapcameraspace ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + ; transform reflection vector into view space + dp3 oT2.x, $reflectionVector, $cViewModel0 + dp3 oT2.y, $reflectionVector, $cViewModel1 + dp3 oT2.z, $reflectionVector, $cViewModel2 + &FreeRegister( \$reflectionVector ); + } + elsif( $envmapsphere ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + &ComputeSphereMapTexCoords( $reflectionVector, "oT2" ); + &FreeRegister( \$reflectionVector ); + } + else + { + &ComputeReflectionVector( $worldPos, $worldNormal, "oT2" ); + } + ; envmap mask + dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 ; FIXME + dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 ; FIXME + +# &FreeRegister( \$worldPos ); + &FreeRegister( \$worldNormal ); + } + + &FreeRegister( \$worldPos ); # garymcthack + + if( $detail ) + { + dp4 oT2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 ; FIXME + dp4 oT2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 ; FIXME + } + + if( $vertexcolor ) + { + ; Modulation color + mul oD0, $vColor, $cModulationColor + } + else + { + ; Modulation color + mov oD0, $cModulationColor + } +} diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc b/mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc new file mode 100644 index 00000000..1dbb8b2f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc @@ -0,0 +1,12 @@ +sampler TextureSampler : register( s1 ); + +struct PS_INPUT +{ + float4 vColor0 : COLOR0; + float2 vTexCoord1 : TEXCOORD1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return tex2D( TextureSampler, i.vTexCoord1 ); +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc b/mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc new file mode 100644 index 00000000..afee6c9c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc @@ -0,0 +1,51 @@ +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord1 : TEXCOORD1; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 vDiffuse : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul4x3( v.vPos, cModel[0] ); + + o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + + o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + // YUCK! This is to make texcoords continuous for mat_softwaretl + o.vTexCoord0 = 0.0f; + o.vTexCoord1 = v.vTexCoord1; + + o.vDiffuse = 1.0f; + + return o; +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh new file mode 100644 index 00000000..4f72286f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r1, t2, t3 ; envmap * envmapmask +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh new file mode 100644 index 00000000..a525a7b2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh @@ -0,0 +1,24 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 + +; Blend between grey and lightmap color based on total alpha + +def c0 0.5f 0.5f 0.5f 1.0f + +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mul r1.a, t0, v0 ; base times vertex alpha +; GR - workaround for const/lerp issues +mul r0.rgb, c1, t0 ; Self illum * tint ++mul_sat r0.a, c1, t0 +lrp r1.rgb, t0.a, r1, r0 ; Blend between self-illum + lightmap +lrp r0, r1.a, r1, c0 ; interpolate between grey + color diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh new file mode 100644 index 00000000..77b05b9f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 + +; Blend between grey and lightmap color based on total alpha + +def c2, 0.5f, 0.5f, 0.5f, 1.0f + +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mov r1.a, v0 ; vertex alpha +lrp r0, r1.a, r1, c2 ; interpolate between grey + color diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc b/mp/src/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc new file mode 100644 index 00000000..d5be9e5f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc @@ -0,0 +1,122 @@ +// STATIC: "BASETEXTURE" "0..1" +// STATIC: "ENVMAP" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" + +// SKIP: !$ENVMAP && ( $BASEALPHAENVMAPMASK || $ENVMAPMASK ) +// SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK +// SKIP: $SELFILLUM && $BASEALPHAENVMAPMASK +// SKIP: !$BASETEXTURE && $SELFILLUM + +const float3 g_OverbrightFactor : register( c0 ); +const float3 g_SelfIllumTint : register( c1 ); +const float3 g_EnvmapTint : register( c2 ); + +sampler BaseTextureSampler : register( s0 ); +sampler LightmapSampler : register( s1 ); +sampler EnvmapSampler : register( s2 ); +sampler EnvmapMaskSampler : register( s3 ); + +//sampler DetailSampler : register( s3 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float2 lightmapTexCoord : TEXCOORD1; + float3 envmapTexCoord : TEXCOORD2; + float2 envmapMaskTexCoord : TEXCOORD3; + float4 vertexColor : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bBaseTexture = BASETEXTURE ? true : false; + bool bEnvmap = ENVMAP ? true : false; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + +#if 1 + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + if( bBaseTexture ) + { + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); + } + + float3 specularFactor = 1.0f; + + if( bEnvmapMask ) + { + specularFactor *= tex2D( EnvmapMaskSampler, i.envmapMaskTexCoord ).xyz; + } + if( bBaseAlphaEnvmapMask ) + { + specularFactor *= 1.0 - baseColor.a; // this blows! + } + + float3 diffuseLighting = tex2D( LightmapSampler, i.lightmapTexCoord ); + + float3 albedo = float3( 1.0f, 1.0f, 1.0f ); + float alpha = 1.0f; + if( bBaseTexture ) + { + albedo *= baseColor; + if( !bBaseAlphaEnvmapMask && !bSelfIllum ) + { + alpha *= baseColor.a; + } + } + + // The vertex color contains the modulation color + vertex color combined + albedo *= i.vertexColor; + alpha *= i.vertexColor.a; // not sure about this one + + float3 diffuseComponent = ( albedo * diffuseLighting * 2.0f ) * g_OverbrightFactor; + + if( bSelfIllum ) + { + float3 selfIllumComponent = g_SelfIllumTint * albedo; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + } + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); + + if( bEnvmap ) + { + specularLighting = tex2D( EnvmapSampler, i.envmapTexCoord ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint; + } + + float3 result = diffuseComponent + specularLighting; + return float4( result, alpha ); +#endif + +#if 0 + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + float3 diffuseLighting = tex2D( LightmapSampler, i.lightmapTexCoord ); + + float3 albedo = float3( 1.0f, 1.0f, 1.0f ); + float alpha = 1.0f; + albedo *= i.vertexColor; + alpha *= i.vertexColor.a; // not sure about this one + + float3 diffuseComponent = ( albedo * diffuseLighting * 2.0f ) * g_OverbrightFactor; + float3 result = diffuseComponent; + return float4( result, alpha ); +#endif + +#if 0 + float4 result; + + result.rgb = tex2D( LightmapSampler, i.lightmapTexCoord ).rgb * i.vertexColor.rgb; + result.a = i.vertexColor.a; + result.rgb = ( result.rgb * g_OverbrightFactor ) * 2.0f; + return result; +#endif +} + + diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h b/mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h new file mode 100644 index 00000000..585ea1f6 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h @@ -0,0 +1,583 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// SKIP: $BUMPMAP2 && $WARPLIGHTING +// SKIP: $WARPLIGHTING && $DETAILTEXTURE +// SKIP: $ENVMAPMASK && $BUMPMAP +// SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK +// SKIP: $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM +// SKIP: !$FASTPATH && $FASTPATHENVMAPCONTRAST +// SKIP: !$FASTPATH && $FASTPATHENVMAPTINT +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: !$BUMPMAP && $BUMPMAP2 +// SKIP: $ENVMAPMASK && $BUMPMAP2 +// SKIP: $BASETEXTURENOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) +// SKIP: $BASETEXTURE2NOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) +// SKIP: $BASEALPHAENVMAPMASK && $BUMPMAP +// SKIP: $PARALLAXMAP && $DETAILTEXTURE +// SKIP: $SEAMLESS && $RELIEF_MAPPING +// SKIP: $SEAMLESS && $DETAILTEXTURE +// SKIP: $SEAMLESS && $MASKEDBLENDING +// SKIP: $BUMPMASK && ( $SEAMLESS || $DETAILTEXTURE || $SELFILLUM || $BASETEXTURENOENVMAP || $BASETEXTURE2 ) +// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 1) +// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 2) +// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 1) +// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 2) +// NOSKIP: $FANCY_BLENDING && (!$FASTPATH) + +// 360 compiler craps out on some combo in this family. Content doesn't use blendmode 10 anyway +// SKIP: $FASTPATH && $PIXELFOGTYPE && $BASETEXTURE2 && $DETAILTEXTURE && $CUBEMAP && ($DETAIL_BLEND_MODE == 10 ) [XBOX] + +// debug crap: +// NOSKIP: $DETAILTEXTURE +// NOSKIP: $CUBEMAP +// NOSKIP: $ENVMAPMASK +// NOSKIP: $BASEALPHAENVMAPMASK +// NOSKIP: $SELFILLUM + +#define USE_32BIT_LIGHTMAPS_ON_360 //uncomment to use 32bit lightmaps, be sure to keep this in sync with the same #define in materialsystem/cmatlightmaps.cpp + +#include "common_ps_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_lightmappedgeneric_fxc.h" + +#if SEAMLESS +#define USE_FAST_PATH 1 +#else +#define USE_FAST_PATH FASTPATH +#endif + +const HALF4 g_EnvmapTint : register( c0 ); + +#if USE_FAST_PATH == 1 + +# if FASTPATHENVMAPCONTRAST == 0 +static const HALF3 g_EnvmapContrast = { 0.0f, 0.0f, 0.0f }; +# else +static const HALF3 g_EnvmapContrast = { 1.0f, 1.0f, 1.0f }; +# endif +static const HALF3 g_EnvmapSaturation = { 1.0f, 1.0f, 1.0f }; +static const HALF g_FresnelReflection = 1.0f; +static const HALF g_OneMinusFresnelReflection = 0.0f; +static const HALF4 g_SelfIllumTint = { 1.0f, 1.0f, 1.0f, 1.0f }; +# if OUTLINE +const float4 g_OutlineParams : register( c2 ); +#define OUTLINE_MIN_VALUE0 g_OutlineParams.x +#define OUTLINE_MIN_VALUE1 g_OutlineParams.y +#define OUTLINE_MAX_VALUE0 g_OutlineParams.z +#define OUTLINE_MAX_VALUE1 g_OutlineParams.w + +const float4 g_OutlineColor : register( c3 ); +#define OUTLINE_COLOR g_OutlineColor + +# endif +# if SOFTEDGES +const float4 g_EdgeSoftnessParms : register( c4 ); +#define SOFT_MASK_MIN g_EdgeSoftnessParms.x +#define SOFT_MASK_MAX g_EdgeSoftnessParms.y +# endif +#else + +const HALF3 g_EnvmapContrast : register( c2 ); +const HALF3 g_EnvmapSaturation : register( c3 ); +const HALF4 g_FresnelReflectionReg : register( c4 ); +#define g_FresnelReflection g_FresnelReflectionReg.a +#define g_OneMinusFresnelReflection g_FresnelReflectionReg.b +const HALF4 g_SelfIllumTint : register( c7 ); +#endif + +const float4 g_DetailTint_and_BlendFactor : register( c8 ); +#define g_DetailTint (g_DetailTint_and_BlendFactor.rgb) +#define g_DetailBlendFactor (g_DetailTint_and_BlendFactor.w) + +const HALF3 g_EyePos : register( c10 ); +const HALF4 g_FogParams : register( c11 ); +const float4 g_TintValuesAndLightmapScale : register( c12 ); + +#define g_flAlpha2 g_TintValuesAndLightmapScale.w + +const float4 g_FlashlightAttenuationFactors : register( c13 ); +const float3 g_FlashlightPos : register( c14 ); +const float4x4 g_FlashlightWorldToTexture : register( c15 ); // through c18 +const float4 g_ShadowTweaks : register( c19 ); + + +sampler BaseTextureSampler : register( s0 ); +sampler LightmapSampler : register( s1 ); +sampler EnvmapSampler : register( s2 ); +#if FANCY_BLENDING +sampler BlendModulationSampler : register( s3 ); +#endif + +#if DETAILTEXTURE +sampler DetailSampler : register( s12 ); +#endif + +sampler BumpmapSampler : register( s4 ); +#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA +sampler AlphaMapSampler : register( s9 ); // alpha +#else +#define AlphaMapSampler BumpmapSampler +#endif + +#if BUMPMAP2 == 1 +sampler BumpmapSampler2 : register( s5 ); +#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA +sampler AlphaMapSampler2 : register( s10 ); // alpha +#else +#define AlphaMapSampler2 BumpmapSampler2 +#endif +#else +sampler EnvmapMaskSampler : register( s5 ); +#endif + + +#if WARPLIGHTING +sampler WarpLightingSampler : register( s6 ); +#endif +sampler BaseTextureSampler2 : register( s7 ); + +#if BUMPMASK == 1 +sampler BumpMaskSampler : register( s8 ); +#if NORMALMASK_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA +sampler AlphaMaskSampler : register( s11 ); // alpha +#else +#define AlphaMaskSampler BumpMaskSampler +#endif +#endif + +#if defined( _X360 ) && FLASHLIGHT +sampler FlashlightSampler : register( s13 ); +sampler ShadowDepthSampler : register( s14 ); +sampler RandRotSampler : register( s15 ); +#endif + +struct PS_INPUT +{ +#if SEAMLESS + float3 SeamlessTexCoord : TEXCOORD0; // zy xz + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask +#else + HALF2 baseTexCoord : TEXCOORD0; + // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. +#if ( RELIEF_MAPPING == 0 ) + HALF4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; +#endif +#endif +// CENTROID: TEXCOORD2 + HALF4 lightmapTexCoord1And2 : TEXCOORD2; +// CENTROID: TEXCOORD3 + HALF4 lightmapTexCoord3 : TEXCOORD3; + HALF4 worldPos_projPosZ : TEXCOORD4; + HALF3x3 tangentSpaceTranspose : TEXCOORD5; + // tangentSpaceTranspose : TEXCOORD6 + // tangentSpaceTranspose : TEXCOORD7 + HALF4 vertexColor : COLOR; + float4 vertexBlendX_fogFactorW : COLOR1; + + // Extra iterators on 360, used in flashlight combo +#if defined( _X360 ) && FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; + float4 vProjPos : TEXCOORD9; +#endif +}; + +#if LIGHTING_PREVIEW == 2 +LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR +#else +HALF4 main( PS_INPUT i ) : COLOR +#endif +{ + bool bBaseTexture2 = BASETEXTURE2 ? true : false; + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBumpmap = BUMPMAP ? true : false; + bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; + bool bBaseTextureNoEnvmap = BASETEXTURENOENVMAP ? true : false; + bool bBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP ? true : false; + + float4 baseColor = 0.0f; + float4 baseColor2 = 0.0f; + float4 vNormal = float4(0, 0, 1, 1); + float3 baseTexCoords = float3(0,0,0); + +#if SEAMLESS + baseTexCoords = i.SeamlessTexCoord.xyz; +#else + baseTexCoords.xy = i.baseTexCoord.xy; +#endif + + GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpmapSampler, bBaseTexture2, bBumpmap || bNormalMapAlphaEnvmapMask, + baseTexCoords, i.vertexColor.rgb, baseColor, baseColor2, vNormal ); + +#if BUMPMAP == 1 // not ssbump + vNormal.xyz = vNormal.xyz * 2.0f - 1.0f; // make signed if we're not ssbump +#endif + + HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); +#if LIGHTING_PREVIEW == 0 + if( bBumpmap && bDiffuseBumpmap ) + { + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); + lightmapColor2 = LightMapSample( LightmapSampler, bumpCoord2 ); + lightmapColor3 = LightMapSample( LightmapSampler, bumpCoord3 ); + } + else + { + HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); + lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); + } +#endif + +#if RELIEF_MAPPING + // in the parallax case, all texcoords must be the same in order to free + // up an iterator for the tangent space view vector + HALF2 detailTexCoord = i.baseTexCoord.xy; + HALF2 bumpmapTexCoord = i.baseTexCoord.xy; + HALF2 envmapMaskTexCoord = i.baseTexCoord.xy; +#else + + #if ( DETAILTEXTURE == 1 ) + HALF2 detailTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; + HALF2 bumpmapTexCoord = i.baseTexCoord.xy; + #elif ( BUMPMASK == 1 ) + HALF2 detailTexCoord = 0.0f; + HALF2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; + HALF2 bumpmap2TexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz; + #else + HALF2 detailTexCoord = 0.0f; + HALF2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; + #endif + + HALF2 envmapMaskTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz; +#endif // !RELIEF_MAPPING + + HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); +#if DETAILTEXTURE + +#if SHADER_MODEL_PS_2_0 + detailColor = tex2D( DetailSampler, detailTexCoord ); +#else + detailColor = float4( g_DetailTint, 1.0f ) * tex2D( DetailSampler, detailTexCoord ); +#endif + +#endif + +#if ( OUTLINE || SOFTEDGES ) + float distAlphaMask = baseColor.a; + +# if OUTLINE + if ( ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && + ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) + { + float oFactor=1.0; + if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) + { + oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); + } + else + { + oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); + } + baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); + } +# endif +# if SOFTEDGES + baseColor.a *= smoothstep( SOFT_MASK_MAX, SOFT_MASK_MIN, distAlphaMask ); +# else + baseColor.a *= distAlphaMask >= 0.5; +# endif +#endif + + +#if LIGHTING_PREVIEW == 2 + baseColor.xyz=GammaToLinear(baseColor.xyz); +#endif + + float blendedAlpha = baseColor.a; + +#if MASKEDBLENDING + float blendfactor=0.5; +#else + float blendfactor=i.vertexBlendX_fogFactorW.r; +#endif + + if( bBaseTexture2 ) + { +#if (SELFILLUM == 0) && (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (FANCY_BLENDING) + float4 modt=tex2D(BlendModulationSampler,i.lightmapTexCoord3.zw); +#if MASKEDBLENDING + // FXC is unable to optimize this, despite blendfactor=0.5 above + //float minb=modt.g-modt.r; + //float maxb=modt.g+modt.r; + //blendfactor=smoothstep(minb,maxb,blendfactor); + blendfactor=modt.g; +#else + float minb=saturate(modt.g-modt.r); + float maxb=saturate(modt.g+modt.r); + blendfactor=smoothstep(minb,maxb,blendfactor); +#endif +#endif + baseColor.rgb = lerp( baseColor, baseColor2.rgb, blendfactor ); + blendedAlpha = lerp( baseColor.a, baseColor2.a, blendfactor ); + } + + HALF3 specularFactor = 1.0f; + float4 vNormalMask = float4(0, 0, 1, 1); + if( bBumpmap ) + { + if( bBaseTextureNoEnvmap ) + { + vNormal.a = 0.0f; + } + +#if ( BUMPMAP2 == 1 ) + { + #if ( BUMPMASK == 1 ) + HALF2 b2TexCoord = bumpmap2TexCoord; + #else + HALF2 b2TexCoord = bumpmapTexCoord; + #endif + + HALF4 vNormal2; + if ( BUMPMAP == 2 ) + vNormal2 = tex2D( BumpmapSampler2, b2TexCoord ); + else + vNormal2 = DecompressNormal( BumpmapSampler2, b2TexCoord, NORMAL_DECODE_MODE, AlphaMapSampler2 ); // Bump 2 coords + + if( bBaseTexture2NoEnvmap ) + { + vNormal2.a = 0.0f; + } + + #if ( BUMPMASK == 1 ) + float3 vNormal1 = DecompressNormal( BumpmapSampler, i.detailOrBumpAndEnvmapMaskTexCoord.xy, NORMALMASK_DECODE_MODE, AlphaMapSampler ); + + vNormal.xyz = normalize( vNormal1.xyz + vNormal2.xyz ); + + // Third normal map...same coords as base + vNormalMask = DecompressNormal( BumpMaskSampler, i.baseTexCoord.xy, NORMALMASK_DECODE_MODE, AlphaMaskSampler ); + + vNormal.xyz = lerp( vNormalMask.xyz, vNormal.xyz, vNormalMask.a ); // Mask out normals from vNormal + specularFactor = vNormalMask.a; + #else // BUMPMASK == 0 + if ( FANCY_BLENDING && bNormalMapAlphaEnvmapMask ) + { + vNormal = lerp( vNormal, vNormal2, blendfactor); + } + else + { + vNormal.xyz = lerp( vNormal.xyz, vNormal2.xyz, blendfactor); + } + + #endif + + } + +#endif // BUMPMAP2 == 1 + + if( bNormalMapAlphaEnvmapMask ) + { + specularFactor *= vNormal.a; + } + } + else if ( bNormalMapAlphaEnvmapMask ) + { + specularFactor *= vNormal.a; + } + +#if ( BUMPMAP2 == 0 ) + if( bEnvmapMask ) + { + specularFactor *= tex2D( EnvmapMaskSampler, envmapMaskTexCoord ).xyz; + } +#endif + + if( bBaseAlphaEnvmapMask ) + { + specularFactor *= 1.0 - blendedAlpha; // Reversing alpha blows! + } + float4 albedo = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + float alpha = 1.0f; + albedo *= baseColor; + if( !bBaseAlphaEnvmapMask && !bSelfIllum ) + { + alpha *= baseColor.a; + } + + if( bDetailTexture ) + { + albedo = TextureCombine( albedo, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); + } + + // The vertex color contains the modulation color + vertex color combined +#if ( SEAMLESS == 0 ) + albedo.xyz *= i.vertexColor; +#endif + alpha *= i.vertexColor.a * g_flAlpha2; // not sure about this one + + // Save this off for single-pass flashlight, since we'll still need the SSBump vector, not a real normal + float3 vSSBumpVector = vNormal.xyz; + + HALF3 diffuseLighting; + if( bBumpmap && bDiffuseBumpmap ) + { + +// ssbump +#if ( BUMPMAP == 2 ) + diffuseLighting = vNormal.x * lightmapColor1 + + vNormal.y * lightmapColor2 + + vNormal.z * lightmapColor3; + diffuseLighting *= g_TintValuesAndLightmapScale.rgb; + + // now, calculate vNormal for reflection purposes. if vNormal isn't needed, hopefully + // the compiler will eliminate these calculations + vNormal.xyz = normalize( bumpBasis[0]*vNormal.x + bumpBasis[1]*vNormal.y + bumpBasis[2]*vNormal.z); +#else + float3 dp; + dp.x = saturate( dot( vNormal, bumpBasis[0] ) ); + dp.y = saturate( dot( vNormal, bumpBasis[1] ) ); + dp.z = saturate( dot( vNormal, bumpBasis[2] ) ); + dp *= dp; + +#if ( DETAIL_BLEND_MODE == TCOMBINE_SSBUMP_BUMP ) + dp *= 2*detailColor; +#endif + diffuseLighting = dp.x * lightmapColor1 + + dp.y * lightmapColor2 + + dp.z * lightmapColor3; + float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); + diffuseLighting *= g_TintValuesAndLightmapScale.rgb / sum; +#endif + } + else + { + diffuseLighting = lightmapColor1 * g_TintValuesAndLightmapScale.rgb; + } + +#if WARPLIGHTING && ( SEAMLESS == 0 ) + float len=0.5*length(diffuseLighting); + // FIXME: 8-bit lookup textures like this need a "nice filtering" VTF option, which converts + // them to 16-bit on load or does filtering in the shader (since most hardware - 360 + // included - interpolates 8-bit textures at 8-bit precision, which causes banding) + diffuseLighting *= 2.0*tex2D(WarpLightingSampler,float2(len,0)); +#endif + +#if CUBEMAP || LIGHTING_PREVIEW || ( defined( _X360 ) && FLASHLIGHT ) + float3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); +#endif + + float3 diffuseComponent = albedo.xyz * diffuseLighting; + +#if defined( _X360 ) && FLASHLIGHT + + // ssbump doesn't pass a normal to the flashlight...it computes shadowing a different way +#if ( BUMPMAP == 2 ) + bool bHasNormal = false; + + float3 worldPosToLightVector = g_FlashlightPos - i.worldPos_projPosZ.xyz; + + float3 tangentPosToLightVector; + tangentPosToLightVector.x = dot( worldPosToLightVector, i.tangentSpaceTranspose[0] ); + tangentPosToLightVector.y = dot( worldPosToLightVector, i.tangentSpaceTranspose[1] ); + tangentPosToLightVector.z = dot( worldPosToLightVector, i.tangentSpaceTranspose[2] ); + + tangentPosToLightVector = normalize( tangentPosToLightVector ); + + float nDotL = saturate( vSSBumpVector.x*dot( tangentPosToLightVector, bumpBasis[0]) + + vSSBumpVector.y*dot( tangentPosToLightVector, bumpBasis[1]) + + vSSBumpVector.z*dot( tangentPosToLightVector, bumpBasis[2]) ); +#else + bool bHasNormal = true; + float nDotL = 1.0f; +#endif + + float fFlashlight = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, i.flashlightSpacePos, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, 0, true, false, i.vProjPos.xy / i.vProjPos.w, false, g_ShadowTweaks, bHasNormal ); + + diffuseComponent = albedo.xyz * ( diffuseLighting + ( fFlashlight * nDotL ) ); +#endif + + if( bSelfIllum ) + { + float3 selfIllumComponent = g_SelfIllumTint * albedo.xyz; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + } + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); +#if CUBEMAP + if( bCubemap ) + { + float3 worldVertToEyeVector = g_EyePos - i.worldPos_projPosZ.xyz; + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldVertToEyeVector ); + + // Calc Fresnel factor + half3 eyeVect = normalize(worldVertToEyeVector); + HALF fresnel = 1.0 - dot( worldSpaceNormal, eyeVect ); + fresnel = pow( fresnel, 5.0 ); + fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection; + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + + specularLighting *= g_EnvmapTint; +#if FANCY_BLENDING == 0 + HALF3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); + HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); +#endif + specularLighting *= fresnel; + } +#endif + + HALF3 result = diffuseComponent + specularLighting; + +#if LIGHTING_PREVIEW + worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); +# if LIGHTING_PREVIEW == 1 + float dotprod = 0.7+0.25 * dot( worldSpaceNormal, normalize( float3( 1, 2, -.5 ) ) ); + return FinalOutput( HALF4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +# else + LPREVIEW_PS_OUT ret; + ret.color = float4( albedo.xyz,alpha ); + ret.normal = float4( worldSpaceNormal,alpha ); + ret.position = float4( i.worldPos_projPosZ.xyz, alpha ); + ret.flags = float4( 1, 1, 1, alpha ); + + return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +# endif +#else // == end LIGHTING_PREVIEW == + + bool bWriteDepthToAlpha = false; + + // ps_2_b and beyond +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) + bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + +#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; +#endif + + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w ); + +#endif +} + diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc b/mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc new file mode 100644 index 00000000..599d16a4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc @@ -0,0 +1,59 @@ +// STATIC: "MASKEDBLENDING" "0..1" +// STATIC: "BASETEXTURE2" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "BUMPMAP" "0..2" +// STATIC: "BUMPMAP2" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "BASETEXTURENOENVMAP" "0..1" +// STATIC: "BASETEXTURE2NOENVMAP" "0..1" +// STATIC: "WARPLIGHTING" "0..1" +// STATIC: "FANCY_BLENDING" "0..1" +// STATIC: "RELIEF_MAPPING" "0..0" [ps20b] +// STATIC: "SEAMLESS" "0..1" +// STATIC: "OUTLINE" "0..1" +// STATIC: "SOFTEDGES" "0..1" +// STATIC: "BUMPMASK" "0..1" +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] +// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [PC] +// STATIC: "DETAIL_BLEND_MODE" "0..11" +// STATIC: "FLASHLIGHT" "0..1" [ps20b] [XBOX] + +// DYNAMIC: "FASTPATHENVMAPCONTRAST" "0..1" +// DYNAMIC: "FASTPATH" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// SKIP: $SEAMLESS && $RELIEF_MAPPING [ps20b] + +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// SKIP: $SEAMLESS && ( $OUTLINE || $SOFTEDGES) +// SKIP: $BASETEXTURE2 && ( $OUTLINE || $SOFTEDGES) +// SKIP: $BUMPMAP2 && ( $OUTLINE || $SOFTEDGES) +// SKIP: $SELFILLUM && ( $OUTLINE || $SOFTEDGES) +// SKIP: $MASKEDBLENDING && ( $OUTLINE || $SOFTEDGES) +// SKIP: $FANCY_BLENDING && ( $OUTLINE || $SOFTEDGES) +// SKIP: $LIGHTING_PREVIEW && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($FASTPATH == 0) && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($DETAILTEXTURE && $BUMPMAP) && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($WARPLIGHTING) && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($BUMPMAP) && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($DETAIL_BLEND_MODE == 2 ) || ($DETAIL_BLEND_MODE == 3 ) || ($DETAIL_BLEND_MODE == 4 ) +// SKIP: ($DETAIL_BLEND_MODE == 5 ) || ($DETAIL_BLEND_MODE == 6 ) || ($DETAIL_BLEND_MODE == 7 ) +// SKIP: ($DETAIL_BLEND_MODE == 8 ) || ($DETAIL_BLEND_MODE == 9 ) +// SKIP ($DETAIL_BLEND_MODE == 10 ) && ($BUMPMAP == 0 ) +// SKIP ($DETAIL_BLEND_MODE == 11 ) && ($BUMPMAP != 0 ) + +#include "lightmappedgeneric_ps2_3_x.h" + diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh new file mode 100644 index 00000000..84b56437 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) + +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh new file mode 100644 index 00000000..b4893363 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0.rgb, t0, v0 + ; base times vertex color (with alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r1, t2, t3 ; envmap * envmapmask +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) + +mul r1, c1, t0.a ; Self illum alpha * tint +mad r1, t0, r1, t1 ; Self illum * tint + lightmap +mul r0.rgb, r1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh b/mp/src/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh new file mode 100644 index 00000000..cc1dd1f8 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh @@ -0,0 +1,20 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# STATIC: "DETAIL" "0..1" +# STATIC: "ENVMAP" "0..1" +# STATIC: "ENVMAPCAMERASPACE" "0..0" +# STATIC: "ENVMAPSPHERE" "0..1" +# STATIC: "VERTEXCOLOR" "0..1" + +# can't have envmapshere or envmapcameraspace without envmap +# SKIP: !$ENVMAP && ( $ENVMAPSPHERE || $ENVMAPCAMERASPACE ) + +# can't have both envmapsphere and envmapcameraspace +# SKIP: $ENVMAPSPHERE && $ENVMAPCAMERASPACE + +#include "LightmappedGeneric_inc.vsh" + +&LightmappedGeneric( $DETAIL, $ENVMAP, $ENVMAPCAMERASPACE, $ENVMAPSPHERE, + $VERTEXCOLOR ); + diff --git a/mp/src/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc b/mp/src/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc new file mode 100644 index 00000000..362eb668 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc @@ -0,0 +1,254 @@ +// STATIC: "ENVMAP_MASK" "0..1" +// STATIC: "TANGENTSPACE" "0..1" +// STATIC: "BUMPMAP" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "VERTEXALPHATEXBLENDFACTOR" "0..1" +// STATIC: "RELIEF_MAPPING" "0..0" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "BUMPMASK" "0..1" +// STATIC: "FLASHLIGHT" "0..1" [XBOX] + +// DYNAMIC: "FASTPATH" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] + +// This should not be a combo since I'm a moron with the tangent space and the flashlight. +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: $SEAMLESS && $RELIEF_MAPPING +// SKIP: $BUMPMASK && $RELIEF_MAPPING +// SKIP: $BUMPMASK && $SEAMLESS + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_UseSeparateEnvmapMask = ENVMAP_MASK; +static const bool g_bTangentSpace = TANGENTSPACE; +static const bool g_bBumpmap = BUMPMAP; +static const bool g_bBumpmapDiffuseLighting = DIFFUSEBUMPMAP; +static const bool g_bVertexColor = VERTEXCOLOR; +static const bool g_bVertexAlphaTexBlendFactor = VERTEXALPHATEXBLENDFACTOR; +static const bool g_BumpMask = BUMPMASK; + +#if SEAMLESS +const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_0 ); +#define SEAMLESS_SCALE (SeamlessScale.x) +#else +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cDetailOrBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); +#endif +// This should be identity if we are bump mapping, otherwise we'll screw up the lightmapTexCoordOffset. +const float4 cEnvmapMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cBlendMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_10 ); // not contiguous with the rest! + +struct VS_INPUT +{ + float3 vPos : POSITION; + float4 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; + float2 vLightmapTexCoord : TEXCOORD1; + float2 vLightmapTexCoordOffset : TEXCOORD2; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vColor : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + +#if SEAMLESS + float3 SeamlessTexCoord : TEXCOORD0; // x y z + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask +#else + float2 baseTexCoord : TEXCOORD0; + // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. +#if RELIEF_MAPPING + float3 TangentSpaceViewRay : TEXCOORD1; +#else + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; +#endif +#endif + float4 lightmapTexCoord1And2 : TEXCOORD2; + float4 lightmapTexCoord3 : TEXCOORD3; // and basetexcoord*mask_scale + float4 worldPos_projPosZ : TEXCOORD4; + +#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) + float3x3 tangentSpaceTranspose : TEXCOORD5; // and 6 and 7 +#endif + + float4 vertexColor : COLOR; // in seamless, r g b = blend weights + float4 vertexBlendX_fogFactorW : COLOR1; + + // Extra iterators on 360, used in flashlight combo +#if defined( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; + float4 vProjPos : TEXCOORD9; +#endif +#endif + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float3 worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); + + float4 vProjPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( v.vPos, 1 ), cModelViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); + + float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + +#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) + float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + + #if SEAMLESS && BUMPMAP && defined( _X360 ) + float3 n = normalize( worldNormal ); + float3 n2 = n * n; // sums to 1. + + o.tangentSpaceTranspose[0] = normalize( float3( n2.y + n2.z, 0.0f, n2.x ) ); + o.tangentSpaceTranspose[1] = normalize( float3( 0.0f, n2.x + n2.z, n2.y ) ); + o.tangentSpaceTranspose[2] = worldNormal; + #else + o.tangentSpaceTranspose[0] = worldTangentS; + o.tangentSpaceTranspose[1] = worldTangentT; + o.tangentSpaceTranspose[2] = worldNormal; + #endif + +#endif + + float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + +#if SEAMLESS + { + // we need to fill in the texture coordinate projections + o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos; + } +#else + { + if (FASTPATH) + { + o.baseTexCoord.xy = v.vBaseTexCoord; + } + else + { + o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; + o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; + } +#if ( RELIEF_MAPPING == 0 ) + { + // calculate detailorbumptexcoord + if ( FASTPATH ) + o.detailOrBumpAndEnvmapMaskTexCoord.xy = v.vBaseTexCoord.xy; + else + { + o.detailOrBumpAndEnvmapMaskTexCoord.x = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[0] ) + cDetailOrBumpTexCoordTransform[0].w; + o.detailOrBumpAndEnvmapMaskTexCoord.y = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[1] ) + cDetailOrBumpTexCoordTransform[1].w; + } + } +#endif + } +#endif + if ( FASTPATH ) + { + o.lightmapTexCoord3.zw = v.vBaseTexCoord; + } + else + { + o.lightmapTexCoord3.z = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[0] ) + cBlendMaskTexCoordTransform[0].w; + o.lightmapTexCoord3.w = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[1] ) + cBlendMaskTexCoordTransform[1].w; + } + + // compute lightmap coordinates + if( g_bBumpmap && g_bBumpmapDiffuseLighting ) + { + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; + + float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; + float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; + + // reversed component order + o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; + o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; + + o.lightmapTexCoord3.xy = lightmapTexCoord3; + } + else + { + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord; + } + +#if ( RELIEF_MAPPING == 0) + if( g_UseSeparateEnvmapMask || g_BumpMask ) + { + // reversed component order +# if FASTPATH + o.detailOrBumpAndEnvmapMaskTexCoord.wz = v.vBaseTexCoord.xy; +# else + o.detailOrBumpAndEnvmapMaskTexCoord.w = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[0] ) + cEnvmapMaskTexCoordTransform[0].w; + o.detailOrBumpAndEnvmapMaskTexCoord.z = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[1] ) + cEnvmapMaskTexCoordTransform[1].w; +# endif + } +#endif + + o.vertexBlendX_fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.vertexBlendX_fogFactorW; +#endif + + if (!g_bVertexColor) + { + o.vertexColor = float4( 1.0f, 1.0f, 1.0f, cModulationColor.a ); + } + else + { +#if FASTPATH + o.vertexColor = v.vColor; +#else + if ( g_bVertexAlphaTexBlendFactor ) + { + o.vertexColor.rgb = v.vColor.rgb; + o.vertexColor.a = cModulationColor.a; + } + else + { + o.vertexColor = v.vColor; + o.vertexColor.a *= cModulationColor.a; + } +#endif + } +#if SEAMLESS + // compute belnd weights in rgb + float3 vNormal=normalize( worldNormal ); + o.vertexColor.xyz = vNormal * vNormal; // sums to 1. +#endif + +// On 360, we have extra iterators and can fold the flashlight into this shader +#if defined( _X360 ) + #if FLASHLIGHT + o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); + o.vProjPos = vProjPos; + #endif +#endif + + if ( g_bVertexAlphaTexBlendFactor ) + { + o.vertexBlendX_fogFactorW.r = v.vColor.a; + } + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/refract.cpp b/mp/src/materialsystem/stdshaders/refract.cpp new file mode 100644 index 00000000..852e93a5 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/refract.cpp @@ -0,0 +1,111 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "convar.h" +#include "refract_dx9_helper.h" + +DEFINE_FALLBACK_SHADER( Refract, Refract_DX90 ) + +BEGIN_VS_SHADER( Refract_DX90, "Help for Refract" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" ) + SHADER_PARAM( NORMALMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $normalmap" ) + SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $normalmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$normalmap texcoord transform" ) + SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$normalmap texcoord transform" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0f", "" ) + SHADER_PARAM( BLURAMOUNT, SHADER_PARAM_TYPE_INTEGER, "1", "0, 1, or 2 for how much blur you want" ) + SHADER_PARAM( FADEOUTONSILHOUETTE, SHADER_PARAM_TYPE_BOOL, "1", "0 for no fade out on silhouette, 1 for fade out on sillhouette" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( REFRACTTINTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shield", "" ) + SHADER_PARAM( REFRACTTINTTEXTUREFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( NOWRITEZ, SHADER_PARAM_TYPE_INTEGER, "0", "0 == write z, 1 = no write z" ) + SHADER_PARAM( MASKED, SHADER_PARAM_TYPE_BOOL, "0", "mask using dest alpha" ) + SHADER_PARAM( VERTEXCOLORMODULATE, SHADER_PARAM_TYPE_BOOL, "0","Use the vertex color to effect refract color. alpha will adjust refract amount" ) + SHADER_PARAM( FORCEALPHAWRITE, SHADER_PARAM_TYPE_BOOL, "0","Force the material to write alpha to the dest buffer" ) + END_SHADER_PARAMS +// FIXME: doesn't support Fresnel! + + void SetupVars( Refract_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nFrame = FRAME; + info.m_nRefractAmount = REFRACTAMOUNT; + info.m_nRefractTint = REFRACTTINT; + info.m_nNormalMap = NORMALMAP; + info.m_nNormalMap2 = NORMALMAP2; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpFrame2 = BUMPFRAME2; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nBumpTransform2 = BUMPTRANSFORM2; + info.m_nBlurAmount = BLURAMOUNT; + info.m_nFadeOutOnSilhouette = FADEOUTONSILHOUETTE; + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nRefractTintTexture = REFRACTTINTTEXTURE; + info.m_nRefractTintTextureFrame = REFRACTTINTTEXTUREFRAME; + info.m_nFresnelReflection = FRESNELREFLECTION; + info.m_nNoWriteZ = NOWRITEZ; + info.m_nMasked = MASKED; + info.m_nVertexColorModulate = VERTEXCOLORMODULATE; + info.m_nForceAlphaWrite = FORCEALPHAWRITE; + } + + SHADER_INIT_PARAMS() + { + Refract_DX9_Vars_t info; + SetupVars( info ); + InitParamsRefract_DX9( this, params, pMaterialName, info ); + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 82 ) + return "Refract_DX80"; + + return 0; + } + + SHADER_INIT + { + Refract_DX9_Vars_t info; + SetupVars( info ); + InitRefract_DX9( this, params, info ); + } + + SHADER_DRAW + { + Refract_DX9_Vars_t info; + SetupVars( info ); + + // If ( snapshotting ) or ( we need to draw this frame ) + bool bHasFlashlight = this->UsingFlashlight( params ); + if ( ( pShaderShadow != NULL ) || ( bHasFlashlight == false ) ) + { + DrawRefract_DX9( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + Draw( false ); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/refract_dx60.cpp b/mp/src/materialsystem/stdshaders/refract_dx60.cpp new file mode 100644 index 00000000..2ca7a83c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/refract_dx60.cpp @@ -0,0 +1,16 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// FIXME: This is a placeholder. . need to do something for real here. +DEFINE_FALLBACK_SHADER( Refract, Refract_DX60 ) +DEFINE_FALLBACK_SHADER( Refract_DX60, UnlitGeneric ) + + diff --git a/mp/src/materialsystem/stdshaders/refract_dx80.cpp b/mp/src/materialsystem/stdshaders/refract_dx80.cpp new file mode 100644 index 00000000..b6e6e5a0 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/refract_dx80.cpp @@ -0,0 +1,317 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + + +#include "BaseVSShader.h" + +#include "refract_model_vs11.inc" +#include "refract_world_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define MAXBLUR 1 + +DEFINE_FALLBACK_SHADER( Refract, Refract_DX80 ) + +BEGIN_VS_SHADER( Refract_DX80, + "Help for Refract_DX80" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( DUDVMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_dudv", "dudv bump map" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( DUDVFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $dudvmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0f", "" ) + SHADER_PARAM( BLURAMOUNT, SHADER_PARAM_TYPE_INTEGER, "1", "0, 1, or 2 for how much blur you want" ) + SHADER_PARAM( FADEOUTONSILHOUETTE, SHADER_PARAM_TYPE_BOOL, "1", "0 for no fade out on silhouette, 1 for fade out on sillhouette" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( REFRACTTINTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shield", "" ) + SHADER_PARAM( REFRACTTINTTEXTUREFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( FALLBACK, SHADER_PARAM_TYPE_STRING, "", "Name of the fallback shader" ) + SHADER_PARAM( FORCEREFRACT, SHADER_PARAM_TYPE_BOOL, "0", "Forces refraction on boards that have poor performance" ) + SHADER_PARAM( NOWRITEZ, SHADER_PARAM_TYPE_INTEGER, "0", "0 == write z, 1 = no write z" ) + SHADER_PARAM( MASKED, SHADER_PARAM_TYPE_BOOL, "0", "mask using dest alpha" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + if( !params[ENVMAPTINT]->IsDefined() ) + { + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + if( !params[ENVMAPCONTRAST]->IsDefined() ) + { + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + } + if( !params[ENVMAPSATURATION]->IsDefined() ) + { + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + } + if( !params[ENVMAPFRAME]->IsDefined() ) + { + params[ENVMAPFRAME]->SetIntValue( 0 ); + } + if( !params[FRESNELREFLECTION]->IsDefined() ) + { + params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); + } + if( !params[MASKED]->IsDefined() ) + { + params[MASKED]->SetIntValue( 0 ); + } + if( !params[BLURAMOUNT]->IsDefined() ) + { + params[BLURAMOUNT]->SetIntValue( 0 ); + } + if( !params[FADEOUTONSILHOUETTE]->IsDefined() ) + { + params[FADEOUTONSILHOUETTE]->SetIntValue( 0 ); + } + SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + SHADER_FALLBACK + { + if ( IsPC() ) + { + const char *pFallback = (params && params[FALLBACK]->IsDefined()) ? params[FALLBACK]->GetStringValue() : ""; + if (!pFallback[0]) + { + pFallback = "Refract_DX60"; + } + + if( g_pHardwareConfig->GetDXSupportLevel() < 80 || !g_pHardwareConfig->HasProjectedBumpEnv() ) + return pFallback; + + if ( g_pHardwareConfig->PreferReducedFillrate() && (params && (params[FORCEREFRACT]->GetIntValue() == 0)) ) + return pFallback; + } + + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + if (params[DUDVMAP]->IsDefined() ) + { + LoadTexture( DUDVMAP ); + } + if (params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + if( params[ENVMAP]->IsDefined() ) + { + LoadCubeMap( ENVMAP ); + } + if( params[REFRACTTINTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTINTTEXTURE ); + } + } + + inline int ComputePixelShaderIndex( bool bRefractTintTexture, bool bNormalMapAlpha ) + { + // "REFRACTTINTTEXTURE" "0..1" + // "NORMALMAPALPHA" "0..1" + int pshIndex = 0; + if( bRefractTintTexture ) pshIndex |= 0x1; + if( bNormalMapAlpha ) pshIndex |= 0x2; + return pshIndex; + } + + SHADER_DRAW + { + bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL ); + bool bHasEnvmap = params[ENVMAP]->IsTexture(); + int blurAmount = params[BLURAMOUNT]->GetIntValue(); + bool bRefractTintTexture = params[REFRACTTINTTEXTURE]->IsTexture(); + if( blurAmount < 0 ) + { + blurAmount = 0; + } + else if( blurAmount > MAXBLUR ) + { + blurAmount = MAXBLUR; + } + bool bMasked = (params[MASKED]->GetIntValue() != 0); + + SHADOW_STATE + { + if ( params[NOWRITEZ]->GetIntValue() != 0 ) + { + pShaderShadow->EnableDepthWrites( false ); + } + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // If envmap is not specified, the alpha channel is the translucency + // (If envmap *is* specified, alpha channel is the reflection amount) + bool bNormalMapAlpha = false; + if ( params[NORMALMAP]->IsTexture() && !bHasEnvmap ) + { + SetDefaultBlendingShadowState( NORMALMAP, false ); + if ( !bMasked && TextureIsTranslucent( NORMALMAP, false ) ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + bNormalMapAlpha = true; + } + } + + // dudv map + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // renderable texture for refraction + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + if( bRefractTintTexture ) + { + // refract tint texture + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + int userDataSize = 0; + if( bIsModel ) + { + userDataSize = 4; + } + else + { + fmt |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, userDataSize ); + + if( bIsModel ) + { + refract_model_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Refract_model_vs11", vshIndex.GetIndex() ); + } + else + { + refract_world_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Refract_world_vs11", vshIndex.GetIndex() ); + } + + int pshIndex; + pshIndex = ComputePixelShaderIndex( bRefractTintTexture, bNormalMapAlpha ); + pShaderShadow->SetPixelShader( "Refract_ps11", pshIndex ); + + if( bMasked ) + { + EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + } + DefaultFog(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); + + if ( params[DUDVFRAME]->GetIntValue() == 0 ) + { + BindTexture( SHADER_SAMPLER0, DUDVMAP, BUMPFRAME ); + } + else + { + BindTexture( SHADER_SAMPLER0, DUDVMAP, DUDVFRAME ); + } + + if ( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); + } + + if( bRefractTintTexture ) + { + BindTexture( SHADER_SAMPLER2, REFRACTTINTTEXTURE, REFRACTTINTTEXTUREFRAME ); + } + + if ( params[NORMALMAP]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER3, NORMALMAP, BUMPFRAME ); + } + + float fRefractionAmount = params[REFRACTAMOUNT]->GetFloatValue(); + pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fRefractionAmount, 0.0f, 0.0f, fRefractionAmount ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + // used to invert y + // xboxfixme - move this into defined constants + float c[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); + + SetPixelShaderConstant( 0, REFRACTTINT ); + if( bIsModel ) + { + refract_model_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + else + { + refract_world_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + + Draw(); + + if( bHasEnvmap ) + { + bool bNoWriteZ = (params[NOWRITEZ]->GetIntValue() != 0); + const bool bBlendSpecular = true; + if( bIsModel ) + { + DrawModelBumpedSpecularLighting( NORMALMAP, BUMPFRAME, + ENVMAP, ENVMAPFRAME, + ENVMAPTINT, ALPHA, + ENVMAPCONTRAST, ENVMAPSATURATION, + BUMPTRANSFORM, + bBlendSpecular, bNoWriteZ ); + } + else + { + DrawWorldBumpedSpecularLighting( NORMALMAP, ENVMAP, + BUMPFRAME, ENVMAPFRAME, + ENVMAPTINT, ALPHA, + ENVMAPCONTRAST, ENVMAPSATURATION, + BUMPTRANSFORM, FRESNELREFLECTION, + bBlendSpecular, bNoWriteZ ); + } + } + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/refract_dx9_helper.cpp b/mp/src/materialsystem/stdshaders/refract_dx9_helper.cpp new file mode 100644 index 00000000..f436e62a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/refract_dx9_helper.cpp @@ -0,0 +1,342 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "refract_dx9_helper.h" +#include "convar.h" +#include "Refract_vs20.inc" +#include "Refract_ps20.inc" +#include "Refract_ps20b.inc" +#include "cpp_shader_constant_register_map.h" + +#define MAXBLUR 1 + +// FIXME: doesn't support fresnel! +void InitParamsRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Refract_DX9_Vars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + if( !params[info.m_nEnvmapTint]->IsDefined() ) + { + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + if( !params[info.m_nEnvmapContrast]->IsDefined() ) + { + params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f ); + } + if( !params[info.m_nEnvmapSaturation]->IsDefined() ) + { + params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f ); + } + if( !params[info.m_nEnvmapFrame]->IsDefined() ) + { + params[info.m_nEnvmapFrame]->SetIntValue( 0 ); + } + if( !params[info.m_nFresnelReflection]->IsDefined() ) + { + params[info.m_nFresnelReflection]->SetFloatValue( 1.0f ); + } + if( !params[info.m_nMasked]->IsDefined() ) + { + params[info.m_nMasked]->SetIntValue( 0 ); + } + if( !params[info.m_nBlurAmount]->IsDefined() ) + { + params[info.m_nBlurAmount]->SetIntValue( 0 ); + } + if( !params[info.m_nFadeOutOnSilhouette]->IsDefined() ) + { + params[info.m_nFadeOutOnSilhouette]->SetIntValue( 0 ); + } + if( !params[info.m_nForceAlphaWrite]->IsDefined() ) + { + params[info.m_nForceAlphaWrite]->SetIntValue( 0 ); + } + SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); +} + +void InitRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, Refract_DX9_Vars_t &info ) +{ + if (params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + } + if (params[info.m_nNormalMap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nNormalMap ); + } + if (params[info.m_nNormalMap2]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nNormalMap2 ); + } + if( params[info.m_nEnvmap]->IsDefined() ) + { + pShader->LoadCubeMap( info.m_nEnvmap, TEXTUREFLAGS_SRGB ); + } + if( params[info.m_nRefractTintTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nRefractTintTexture, TEXTUREFLAGS_SRGB ); + } +} + +void DrawRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Refract_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL ); + bool bHasEnvmap = params[info.m_nEnvmap]->IsTexture(); + bool bRefractTintTexture = params[info.m_nRefractTintTexture]->IsTexture(); + bool bFadeOutOnSilhouette = params[info.m_nFadeOutOnSilhouette]->GetIntValue() != 0; + int blurAmount = params[info.m_nBlurAmount]->GetIntValue(); + bool bMasked = (params[info.m_nMasked]->GetIntValue() != 0); + bool bSecondaryNormal = ( ( info.m_nNormalMap2 != -1 ) && ( params[info.m_nNormalMap2]->IsTexture() ) ); + bool bColorModulate = ( ( info.m_nVertexColorModulate != -1 ) && ( params[info.m_nVertexColorModulate]->GetIntValue() ) ); + bool bWriteZ = params[info.m_nNoWriteZ]->GetIntValue() == 0; + + if( blurAmount < 0 ) + { + blurAmount = 0; + } + else if( blurAmount > MAXBLUR ) + { + blurAmount = MAXBLUR; + } + + BlendType_t nBlendType = pShader->EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + bFullyOpaque &= !bMasked; + + bool bTranslucentNormal = pShader->TextureIsTranslucent( info.m_nNormalMap, false ); + bFullyOpaque &= (! bTranslucentNormal ); + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( g_pHardwareConfig->SupportsNormalMapCompression() ) + { + ITexture *pBumpTex = params[info.m_nNormalMap]->GetTextureValue(); + if ( pBumpTex ) + { + nNormalDecodeMode = pBumpTex->GetNormalDecodeMode(); + + if ( bSecondaryNormal ) // Check encoding of secondary normal if there is one + { + ITexture *pBumpTex2 = params[info.m_nNormalMap2]->GetTextureValue(); + if ( pBumpTex2 && ( pBumpTex2->GetNormalDecodeMode() != nNormalDecodeMode ) ) + { + DevMsg("Refract: Primary and Secondary normal map compression formats don't match. This is unsupported!\n"); + Assert(0); + } + } + } + } + + SHADOW_STATE + { + pShader->SetInitialShadowState( ); + + pShaderShadow->EnableDepthWrites( bWriteZ ); + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // If envmap is not specified, the alpha channel is the translucency + // (If envmap *is* specified, alpha channel is the reflection amount) + if ( params[info.m_nNormalMap]->IsTexture() && !bHasEnvmap ) + { + pShader->SetDefaultBlendingShadowState( info.m_nNormalMap, false ); + } + + // source render target that contains the image that we are warping. + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Normal map alpha, in the compressed normal case + } + + if ( bSecondaryNormal ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Secondary normal map alpha, in the compressed normal case + } + } + + if( bHasEnvmap ) + { + // envmap + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + } + if( bRefractTintTexture ) + { + // refract tint texture + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true ); + } + + pShaderShadow->EnableSRGBWrite( true ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + int userDataSize = 0; + int nTexCoordCount = 1; + if( bIsModel ) + { + userDataSize = 4; + } + else + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + + if ( bColorModulate ) + { + flags |= VERTEX_COLOR; + } + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( refract_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel ); + SET_STATIC_VERTEX_SHADER_COMBO( COLORMODULATE, bColorModulate ); + SET_STATIC_VERTEX_SHADER( refract_vs20 ); + + // We have to do this in the shader on R500 or Leopard + bool bShaderSRGBConvert = IsOSX() && ( g_pHardwareConfig->FakeSRGBWrite() || !g_pHardwareConfig->CanDoSRGBReadFromRTs() ); + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // always send OpenGL down the ps2b path + { + DECLARE_STATIC_PIXEL_SHADER( refract_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( BLUR, blurAmount ); + SET_STATIC_PIXEL_SHADER_COMBO( FADEOUTONSILHOUETTE, bFadeOutOnSilhouette ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTTINTTEXTURE, bRefractTintTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKED, bMasked ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORMODULATE, bColorModulate ); + SET_STATIC_PIXEL_SHADER_COMBO( SECONDARY_NORMAL, bSecondaryNormal ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSRGBConvert ); + SET_STATIC_PIXEL_SHADER( refract_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( refract_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLUR, blurAmount ); + SET_STATIC_PIXEL_SHADER_COMBO( FADEOUTONSILHOUETTE, bFadeOutOnSilhouette ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTTINTTEXTURE, bRefractTintTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKED, bMasked ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORMODULATE, bColorModulate ); + SET_STATIC_PIXEL_SHADER_COMBO( SECONDARY_NORMAL, bSecondaryNormal ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( refract_ps20 ); + } + pShader->DefaultFog(); + if( bMasked ) + { + pShader->EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + } + + bool bAlphaWrites = bFullyOpaque || ( params[ info.m_nForceAlphaWrite ]->GetIntValue() != 0 ); + pShaderShadow->EnableAlphaWrites( bAlphaWrites ); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + if ( params[info.m_nBaseTexture]->IsTexture() ) + { + pShader->BindTexture( SHADER_SAMPLER2, info.m_nBaseTexture, info.m_nFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); + } + + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShader->BindTexture( SHADER_SAMPLER3, SHADER_SAMPLER6, info.m_nNormalMap, info.m_nBumpFrame ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER3, info.m_nNormalMap, info.m_nBumpFrame ); + } + + if ( bSecondaryNormal ) + { + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShader->BindTexture( SHADER_SAMPLER1, SHADER_SAMPLER7, info.m_nNormalMap2, info.m_nBumpFrame2 ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nNormalMap2, info.m_nBumpFrame2 ); + } + } + + if( bHasEnvmap ) + { + pShader->BindTexture( SHADER_SAMPLER4, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + if( bRefractTintTexture ) + { + pShader->BindTexture( SHADER_SAMPLER5, info.m_nRefractTintTexture, info.m_nRefractTintTextureFrame ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( refract_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( refract_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // always send Posix down the ps2b path + { + DECLARE_DYNAMIC_PIXEL_SHADER( refract_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteZ && bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( refract_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( refract_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( refract_ps20 ); + } + + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nBumpTransform ); // 1 & 2 + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nBumpTransform2 ); // 3 & 4 + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + pShader->SetPixelShaderConstantGammaToLinear( 0, info.m_nEnvmapTint ); + pShader->SetPixelShaderConstantGammaToLinear( 1, info.m_nRefractTint ); + pShader->SetPixelShaderConstant( 2, info.m_nEnvmapContrast ); + pShader->SetPixelShaderConstant( 3, info.m_nEnvmapSaturation ); + float c5[4] = { params[info.m_nRefractAmount]->GetFloatValue(), + params[info.m_nRefractAmount]->GetFloatValue(), 0.0f, 0.0f }; + + // Time % 1000 + c5[3] = pShaderAPI->CurrentTime(); + c5[3] -= (float)( (int)( c5[3] / 1000.0f ) ) * 1000.0f; + pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); + + float cVs3[4] = { c5[3], 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, cVs3, 1 ); + } + pShader->Draw(); +} + diff --git a/mp/src/materialsystem/stdshaders/refract_dx9_helper.h b/mp/src/materialsystem/stdshaders/refract_dx9_helper.h new file mode 100644 index 00000000..69d6116f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/refract_dx9_helper.h @@ -0,0 +1,62 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef REFRACT_DX9_HELPER_H +#define REFRACT_DX9_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct Refract_DX9_Vars_t +{ + Refract_DX9_Vars_t() { memset( this, 0xFF, sizeof( *this ) ); } + + int m_nBaseTexture; + int m_nFrame; + int m_nRefractAmount; + int m_nRefractTint; + int m_nNormalMap; + int m_nNormalMap2; + int m_nBumpFrame; + int m_nBumpFrame2; + int m_nBumpTransform; + int m_nBumpTransform2; + int m_nBlurAmount; + int m_nFadeOutOnSilhouette; + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapTint; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nRefractTintTexture; + int m_nRefractTintTextureFrame; + int m_nFresnelReflection; + int m_nNoWriteZ; + int m_nMasked; + int m_nVertexColorModulate; + int m_nForceAlphaWrite; +}; + +void InitParamsRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, + Refract_DX9_Vars_t &info ); +void InitRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, Refract_DX9_Vars_t &info ); +void DrawRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Refract_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // REFRACT_DX9_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/refract_ps2x.fxc b/mp/src/materialsystem/stdshaders/refract_ps2x.fxc new file mode 100644 index 00000000..2f974230 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/refract_ps2x.fxc @@ -0,0 +1,250 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. ======= +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "BLUR" "0..1" +// STATIC: "FADEOUTONSILHOUETTE" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "REFRACTTINTTEXTURE" "0..1" +// STATIC: "MASKED" "0..1" +// STATIC: "COLORMODULATE" "0..1" +// STATIC: "SECONDARY_NORMAL" "0..1" +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] +// STATIC: "SHADER_SRGB_READ" "0..1" [ps20b] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// SKIP: $MASKED && $BLUR + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler NormalSampler2 : register( s1 ); +sampler RefractSampler : register( s2 ); +sampler NormalSampler : register( s3 ); +#if CUBEMAP +sampler EnvmapSampler : register( s4 ); +#endif +#if REFRACTTINTTEXTURE +sampler RefractTintSampler : register( s5 ); +#endif + +#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA +sampler AlphaMapSampler : register( s6 ); // alpha +sampler AlphaMapSampler2 : register( s7 ); +#else +#define AlphaMapSampler2 NormalSampler +#define AlphaMapSampler NormalSampler2 +#endif + +const float3 g_EnvmapTint : register( c0 ); +const float3 g_RefractTint : register( c1 ); +const float3 g_EnvmapContrast : register( c2 ); +const float3 g_EnvmapSaturation : register( c3 ); +const float4 g_c5 : register( c5 ); +#define g_RefractScale g_c5.x +#define g_flTime g_c5.w + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +static const int g_BlurCount = BLUR; +static const float g_BlurFraction = 1.0f / 512.0f; +static const float g_HalfBlurFraction = 0.5 * g_BlurFraction; +static const float4 g_BlurFractionVec = float4( g_BlurFraction, g_HalfBlurFraction, + -g_BlurFraction,-g_HalfBlurFraction ); + +struct PS_INPUT +{ + float4 vBumpTexCoord : TEXCOORD0; // NormalMap1 in xy, NormalMap2 in wz + float3 vTangentVertToEyeVector : TEXCOORD1; + float3 vWorldNormal : TEXCOORD2; + float3 vWorldTangent : TEXCOORD3; + float3 vWorldBinormal : TEXCOORD4; + float3 vRefractXYW : TEXCOORD5; + float3 vWorldViewVector : TEXCOORD6; +#if COLORMODULATE + float4 ColorModulate : COLOR0; +#endif + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 result; + + float pixelFogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + +#if FADEOUTONSILHOUETTE + //float blend = -i.projNormal.z; + float blend = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) ); + blend = blend * blend * blend; +#else + float blend = 1.0f; +#endif + + // Decompress normal + float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord.xy, NORMAL_DECODE_MODE, AlphaMapSampler ); + +#if SECONDARY_NORMAL + float3 vNormal2 = DecompressNormal( NormalSampler2, i.vBumpTexCoord.wz, NORMAL_DECODE_MODE, AlphaMapSampler2 ); + vNormal.xyz = normalize( vNormal.xyz + vNormal2.xyz ); +#endif + +#if REFRACTTINTTEXTURE + float3 refractTintColor = 2.0 * g_RefractTint * tex2D( RefractTintSampler, i.vBumpTexCoord.xy ); +#else + float3 refractTintColor = g_RefractTint; +#endif + +#if COLORMODULATE + refractTintColor *= i.ColorModulate.rgb; +#endif + + // Perform division by W only once + float ooW = 1.0f / i.vRefractXYW.z; + + // Compute coordinates for sampling refraction + float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW; + float2 vRefractTexCoord = vNormal.xy; + float scale = vNormal.a * g_RefractScale; +#if COLORMODULATE + scale *= i.ColorModulate.a; +#endif + vRefractTexCoord *= scale; + vRefractTexCoord += vRefractTexCoordNoWarp; + +#if (BLUR==1) // use polyphase magic to convert 9 lookups into 4 + + // basic principle behind this transformation: + // [ A B C ] + // [ D E F ] + // [ G H I ] + // use bilinear filtering hardware to weight upper 2x2 samples evenly (0.25* [A + B + D + E]). + // scale the upper 2x2 by 4/9 (total area of kernel occupied) + // use bilinear filtering hardware to weight right 1x2 samples evenly (0.5*[C + F]) + // scale right 1x2 by 2/9 + // use bilinear filtering hardware to weight lower 2x1 samples evenly (0.5*[G + H]) + // scale bottom 2x1 by 2/9 + // fetch last sample (I) and scale by 1/9. + + float2 upper_2x2_loc = vRefractTexCoord.xy - float2(g_HalfBlurFraction, g_HalfBlurFraction); + float2 right_1x2_loc = vRefractTexCoord.xy + float2(g_BlurFraction, -g_HalfBlurFraction); + float2 lower_2x1_loc = vRefractTexCoord.xy + float2(-g_HalfBlurFraction, g_BlurFraction); + float2 singleton_loc = vRefractTexCoord.xy + float2(g_BlurFraction, g_BlurFraction); + result = tex2D(RefractSampler, upper_2x2_loc) * 0.4444444; + result += tex2D(RefractSampler, right_1x2_loc) * 0.2222222; + result += tex2D(RefractSampler, lower_2x1_loc) * 0.2222222; + result += tex2D(RefractSampler, singleton_loc) * 0.1111111; + + #if ( SHADER_SRGB_READ == 1 ) + { + // Just do this once rather than after every blur step, which is wrong, but much more efficient + result = GammaToLinear( result ); + } + #endif + + float3 unblurredColor = tex2D(RefractSampler, vRefractTexCoordNoWarp.xy); + #if ( SHADER_SRGB_READ == 1 ) + { + unblurredColor = GammaToLinear( unblurredColor ); + } + #endif + + result = lerp(unblurredColor, result * refractTintColor, blend); + +#elif (BLUR>0) // iteratively step through render target + int x, y; + + result = float3( 0.0f, 0.0f, 0.0f ); + for( x = -g_BlurCount; x <= g_BlurCount; x++ ) + { + for( y = -g_BlurCount; y <= g_BlurCount; y++ ) + { + result += tex2D( RefractSampler, vRefractTexCoord.xy + float2( g_BlurFraction * x, g_BlurFraction * y ) ); + } + } + + int width = g_BlurCount * 2 + 1; + result *= 1.0f / ( width * width ); + + #if ( SHADER_SRGB_READ == 1 ) + { + // Just do this once rather than after every blur step, which is wrong, but much more efficient + result = GammaToLinear( result ); + } + #endif + + // result is the blurred one now. . .now lerp. + float3 unblurredColor = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + unblurredColor = GammaToLinear( unblurredColor ); + } + #endif + + result = lerp( unblurredColor, result * refractTintColor, blend ); +#else +# if MASKED + float4 fMaskedResult = tex2D( RefractSampler, vRefractTexCoord.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + fMaskedResult = GammaToLinear( fMaskedResult ); + } + #endif + + return FinalOutput( fMaskedResult, pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE ); +# else + float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + colorWarp = GammaToLinear( colorWarp ); + } + #endif + float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + colorNoWarp = GammaToLinear( colorNoWarp ); + } + #endif + + colorWarp *= refractTintColor; + result = lerp( colorNoWarp, colorWarp, blend ); +# endif +#endif + +#if CUBEMAP + float specularFactor = vNormal.a; + + float3 worldSpaceNormal = Vec3TangentToWorld( vNormal.xyz, i.vWorldNormal, i.vWorldTangent, i.vWorldBinormal ); + + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vTangentVertToEyeVector ); + float3 specularLighting = texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint; + float3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); + float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); + result += specularLighting; +#endif + +#if COLORMODULATE + float resultAlpha = i.ColorModulate.a * vNormal.a; +#else + float resultAlpha = vNormal.a; +#endif + + return FinalOutput( float4( result, resultAlpha ), pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/mp/src/materialsystem/stdshaders/shadowmodel_dx8.cpp b/mp/src/materialsystem/stdshaders/shadowmodel_dx8.cpp new file mode 100644 index 00000000..e7d7228a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/shadowmodel_dx8.cpp @@ -0,0 +1,97 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "shadowmodel.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( ShadowModel, ShadowModel_DX8 ) + +BEGIN_VS_SHADER_FLAGS( ShadowModel_DX8, "Help for ShadowModel", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) + SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) + SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) + SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) + SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + if (!params[BASETEXTURESCALE]->IsDefined()) + { + Vector2D scale(1, 1); + params[BASETEXTURESCALE]->SetVecValue( scale.Base(), 2 ); + } + + if (!params[FALLOFFDISTANCE]->IsDefined()) + params[FALLOFFDISTANCE]->SetFloatValue( 100.0f ); + + if (!params[FALLOFFAMOUNT]->IsDefined()) + params[FALLOFFAMOUNT]->SetFloatValue( 0.9f ); + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + // Base texture on stage 0 + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Multiplicative blending state... + EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + shadowmodel_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "ShadowModel", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "ShadowModel" ); + + // We need to fog to *white* regardless of overbrighting... + FogToWhite(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderMatrix3x4( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, BASETEXTUREOFFSET ); + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURESCALE ); + + Vector4D shadow; + shadow[0] = params[FALLOFFOFFSET]->GetFloatValue(); + shadow[1] = params[FALLOFFDISTANCE]->GetFloatValue() + shadow[0]; + if (shadow[1] != 0.0f) + shadow[1] = 1.0f / shadow[1]; + shadow[2] = params[FALLOFFAMOUNT]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, shadow.Base(), 1 ); + + // The constant color is the shadow color... + SetModulationVertexShaderDynamicState(); + + shadowmodel_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw( ); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/shadowmodel_dx9.cpp b/mp/src/materialsystem/stdshaders/shadowmodel_dx9.cpp new file mode 100644 index 00000000..0198e86f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/shadowmodel_dx9.cpp @@ -0,0 +1,154 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +//Note: Not upgraded to vs/ps 2.0 fxc's because this shader is unused and there are no test cases to verify against. +#include "BaseVSShader.h" + +#if !defined( _X360 ) +#include "shadowmodel_ps20.inc" +#include "shadowmodel_vs20.inc" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( ShadowModel, ShadowModel_DX9 ) + + +#if !defined( _X360 ) //not used for anything at time of 360 ship, and we want to avoid storing/loading assembly shaders + +//PC version +BEGIN_VS_SHADER_FLAGS( ShadowModel_DX9, "Help for ShadowModel", SHADER_NOT_EDITABLE ) + +BEGIN_SHADER_PARAMS +SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) +SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) +SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) +SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) +SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) +END_SHADER_PARAMS + +SHADER_INIT_PARAMS() +{ + if (!params[BASETEXTURESCALE]->IsDefined()) + { + Vector2D scale(1, 1); + params[BASETEXTURESCALE]->SetVecValue( scale.Base(), 2 ); + } + + if (!params[FALLOFFDISTANCE]->IsDefined()) + params[FALLOFFDISTANCE]->SetFloatValue( 100.0f ); + + if (!params[FALLOFFAMOUNT]->IsDefined()) + params[FALLOFFAMOUNT]->SetFloatValue( 0.9f ); +} + +SHADER_FALLBACK +{ + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "ShadowModel_DX8"; + + return 0; +} + +SHADER_INIT +{ + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + } +} + +SHADER_DRAW +{ + SHADOW_STATE + { + // Base texture on stage 0 + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Multiplicative blending state... + EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( shadowmodel_vs20 ); + SET_STATIC_VERTEX_SHADER( shadowmodel_vs20 ); + + DECLARE_STATIC_PIXEL_SHADER( shadowmodel_ps20 ); + SET_STATIC_PIXEL_SHADER( shadowmodel_ps20 ); + + // We need to fog to *white* regardless of overbrighting... + FogToWhite(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderMatrix3x4( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, BASETEXTUREOFFSET ); + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURESCALE ); + + Vector4D shadow; + shadow[0] = params[FALLOFFOFFSET]->GetFloatValue(); + shadow[1] = params[FALLOFFDISTANCE]->GetFloatValue() + shadow[0]; + if (shadow[1] != 0.0f) + shadow[1] = 1.0f / shadow[1]; + shadow[2] = params[FALLOFFAMOUNT]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, shadow.Base(), 1 ); + + // The constant color is the shadow color... + SetModulationVertexShaderDynamicState(); + + DECLARE_DYNAMIC_VERTEX_SHADER( shadowmodel_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER( shadowmodel_vs20 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( shadowmodel_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( shadowmodel_ps20 ); + } + Draw( ); +} +END_SHADER + + +#else + +//360 version + +BEGIN_VS_SHADER_FLAGS( ShadowModel_DX9, "Help for ShadowModel", SHADER_NOT_EDITABLE ) + +BEGIN_SHADER_PARAMS +SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) +SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) +SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) +SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) +SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) +END_SHADER_PARAMS + +SHADER_INIT_PARAMS() +{ +} + +SHADER_FALLBACK +{ + return 0; +} + +SHADER_INIT +{ +} + +SHADER_DRAW +{ + Draw( false ); +} +END_SHADER + +#endif \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/shadowmodel_ps20.fxc b/mp/src/materialsystem/stdshaders/shadowmodel_ps20.fxc new file mode 100644 index 00000000..d0aedda9 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/shadowmodel_ps20.fxc @@ -0,0 +1,20 @@ + +struct PS_INPUT +{ + float4 T0 : TEXCOORD0; + float3 T1 : TEXCOORD1; + float3 T2 : TEXCOORD2; + float T3 : TEXCOORD3; + float3 vColor : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + // Kill pixel against various fields computed in vertex shader + clip ( i.T1 ); + clip ( i.T2 ); + clip ( i.T3 ); // Backface cull + + // i.T0.a is uninitialized by the vs, but this is how the original asm shader was written???? + return float4( lerp( float3(1,1,1), i.vColor.xyz, i.T0.a ), 1 ); +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/shadowmodel_vs20.fxc b/mp/src/materialsystem/stdshaders/shadowmodel_vs20.fxc new file mode 100644 index 00000000..9d1ff02c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/shadowmodel_vs20.fxc @@ -0,0 +1,81 @@ +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cShadowTextureMatrix[3] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cTexOrigin : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cTexScale : register( SHADER_SPECIFIC_CONST_4 ); + +// { Shadow falloff offset, 1/Shadow distance, Shadow scale, 0 } +const float3 cShadowConstants : register( SHADER_SPECIFIC_CONST_5 ); +#define flShadowFalloffOffset cShadowConstants.x +#define flOneOverShadowDist cShadowConstants.y +#define flShadowScale cShadowConstants.z + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float3 vNormal : NORMAL; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position + float3 T0 : TEXCOORD0; // PS wants this to be 4D but VS doesn't? (see original asm sources) + float3 T1 : TEXCOORD1; + float3 T2 : TEXCOORD2; + float T3 : TEXCOORD3; + float4 vColor : COLOR0; + float fog : FOG; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( g_bSkinning, v.vPos, v.vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + + // Transform into projection space + o.projPos = mul( float4( worldPos, 1 ), cViewProj ); + + // Compute fog + o.fog = CalcFog( worldPos, o.projPos, g_FogType ); + + // Transform position into texture space (from 0 to 1) + float3 vTexturePos; + vTexturePos.x = dot( worldPos.xyz, cShadowTextureMatrix[0].xyz ); + vTexturePos.y = dot( worldPos.xyz, cShadowTextureMatrix[1].xyz ); + vTexturePos.z = dot( worldPos.xyz, cShadowTextureMatrix[2].xyz ); + + // Figure out the shadow fade amount + float flShadowFade = ( vTexturePos.z - flShadowFalloffOffset ) * flOneOverShadowDist; + + // Offset it into the texture + o.T0 = vTexturePos * cTexScale + cTexOrigin; + + // We're doing clipping by using texkill + o.T1.xyz = vTexturePos.xyz; // Also clips when shadow z < 0 ! + o.T2.xyz = float3( 1.0f, 1.0f, 1.0f ) - vTexturePos.xyz; + o.T2.z = 1.0f - flShadowFade; // Clips when shadow z > shadow distance + + // We're doing backface culling by using texkill also (wow yucky) + // -------------------------------------------------------------- + // Transform z component of normal in texture space + // If it's negative, then don't draw the pixel + o.T3 = dot( worldNormal, -cShadowTextureMatrix[2] ); + + // Shadow color, falloff + o.vColor.xyz = cModulationColor.xyz; + o.vColor.w = flShadowFade * flShadowScale; + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/skin_dx9_helper.cpp b/mp/src/materialsystem/stdshaders/skin_dx9_helper.cpp new file mode 100644 index 00000000..1e2d30f3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/skin_dx9_helper.cpp @@ -0,0 +1,977 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "BaseVSShader.h" +#include "skin_dx9_helper.h" +#include "convar.h" +#include "cpp_shader_constant_register_map.h" +#include "skin_vs20.inc" +#include "skin_ps20b.inc" +#include "commandbuilder.h" + +#ifndef _X360 +#include "skin_vs30.inc" +#include "skin_ps30.inc" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); +static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT ); +static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT ); + +// Textures may be bound to the following samplers: +// SHADER_SAMPLER0 Base (Albedo) / Gloss in alpha +// SHADER_SAMPLER1 Specular warp (including iridescence) +// SHADER_SAMPLER2 Diffuse Lighting warp texture +// SHADER_SAMPLER3 Normal Map +// SHADER_SAMPLER4 Flashlight Shadow Depth Map +// SHADER_SAMPLER5 Normalization cube map +// SHADER_SAMPLER6 Flashlight Cookie +// SHADER_SAMPLER7 Specular exponent +// SHADER_SAMPLER8 Cubic environment map +// SHADER_SAMPLER9 Compressed wrinklemap +// SHADER_SAMPLER10 Stretched wrinklemap +// SHADER_SAMPLER11 Compressed wrinkle normal map +// SHADER_SAMPLER12 Stretched wrinkle normal map +// SHADER_SAMPLER13 Detail texture + + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VertexLitGeneric_DX9_Vars_t &info ) +{ + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + Assert( info.m_nFlashlightTexture >= 0 ); + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping. + if( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + // This shader can be used with hw skinning + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + // No texture means no env mask in base alpha + if ( !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + // Lots of reasons to want tangent space, since we bind a flat normal map in many cases where we don't have a bump map + bool bBump = (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined(); + bool bEnvMap = (info.m_nEnvmap != -1) && params[info.m_nEnvmap]->IsDefined(); + bool bDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined(); + bool bPhong = (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined(); + if( bBump || bEnvMap || bDiffuseWarp || bPhong ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + } + + if ( ( info.m_nSelfIllumFresnel != -1 ) && ( !params[info.m_nSelfIllumFresnel]->IsDefined() ) ) + { + params[info.m_nSelfIllumFresnel]->SetIntValue( 0 ); + } + + if ( ( info.m_nSelfIllumFresnelMinMaxExp != -1 ) && ( !params[info.m_nSelfIllumFresnelMinMaxExp]->IsDefined() ) ) + { + params[info.m_nSelfIllumFresnelMinMaxExp]->SetVecValue( 0.0f, 1.0f, 1.0f ); + } + + if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && ( !params[info.m_nBaseMapAlphaPhongMask]->IsDefined() ) ) + { + params[info.m_nBaseMapAlphaPhongMask]->SetIntValue( 0 ); + } + + if ( ( info.m_nEnvmapFresnel != -1 ) && ( !params[info.m_nEnvmapFresnel]->IsDefined() ) ) + { + params[info.m_nEnvmapFresnel]->SetFloatValue( 0 ); + } +} + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- +void InitSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, VertexLitGeneric_DX9_Vars_t &info ) +{ + Assert( info.m_nFlashlightTexture >= 0 ); + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + + bool bIsBaseTextureTranslucent = false; + if ( params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + + if ( ( info.m_nWrinkle != -1 ) && ( info.m_nStretch != -1 ) && + params[info.m_nWrinkle]->IsDefined() && params[info.m_nStretch]->IsDefined() ) + { + pShader->LoadTexture( info.m_nWrinkle, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nStretch, TEXTUREFLAGS_SRGB ); + } + } + + bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined(); + + // No alpha channel in any of the textures? No self illum or envmapmask + if ( !bIsBaseTextureTranslucent ) + { + bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + // Can still be self illum with no base alpha if using one of these alternate modes + if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsDefined() && + (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nPhongExponentTexture ); + } + + if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() && + (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); + } + + if ( (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsDefined() && + (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nPhongWarpTexture ); + } + + if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() ) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + if ( nDetailBlendMode == 0 ) // Mod2X + pShader->LoadTexture( info.m_nDetail ); + else + pShader->LoadTexture( info.m_nDetail, TEXTUREFLAGS_SRGB ); + } + + if ( g_pConfig->UseBumpmapping() ) + { + if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + + if ( ( info.m_nNormalWrinkle != -1 ) && ( info.m_nNormalStretch != -1 ) && + params[info.m_nNormalWrinkle]->IsDefined() && params[info.m_nNormalStretch]->IsDefined() ) + { + pShader->LoadTexture( info.m_nNormalWrinkle ); + pShader->LoadTexture( info.m_nNormalStretch ); + } + } + } + + if ( params[info.m_nEnvmap]->IsDefined() ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + + if ( bHasSelfIllumMask ) + { + pShader->LoadTexture( info.m_nSelfIllumMask ); + } +} + +class CSkin_DX9_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + bool m_bFastPath; + +}; + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +void DrawSkin_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bHasFlashlight, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); + bool bHasBump = (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsTexture(); + + bool bHasBaseTextureWrinkle = bHasBaseTexture && + (info.m_nWrinkle != -1) && params[info.m_nWrinkle]->IsTexture() && + (info.m_nStretch != -1) && params[info.m_nStretch]->IsTexture(); + + bool bHasBumpWrinkle = bHasBump && + (info.m_nNormalWrinkle != -1) && params[info.m_nNormalWrinkle]->IsTexture() && + (info.m_nNormalStretch != -1) && params[info.m_nNormalStretch]->IsTexture(); + + bool bHasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool bHasVertexAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bHasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) != 0; + bool bHasSelfIllumFresnel = ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + bool bHasSelfIllumMask = ( bHasSelfIllum ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsTexture(); + + // Tie these to specular + bool bHasPhong = (info.m_nPhong != -1) && ( params[info.m_nPhong]->GetIntValue() != 0 ); + bool bHasSpecularExponentTexture = (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsTexture(); + bool bHasPhongTintMap = bHasSpecularExponentTexture && (info.m_nPhongAlbedoTint != -1) && ( params[info.m_nPhongAlbedoTint]->GetIntValue() != 0 ); + bool bHasDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture(); + bool bHasPhongWarp = (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsTexture(); + bool bHasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + +#if !defined( _X360 ) + bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL ); +#endif + + // Rimlight must be set to non-zero to trigger rim light combo (also requires Phong) + bool bHasRimLight = r_rimlight.GetBool() && bHasPhong && (info.m_nRimLight != -1) && ( params[info.m_nRimLight]->GetIntValue() != 0 ); + bool bHasRimMaskMap = bHasSpecularExponentTexture && bHasRimLight && (info.m_nRimMask != -1) && ( params[info.m_nRimMask]->GetIntValue() != 0 ); + + float fBlendFactor=( info.m_nDetailTextureBlendFactor == -1 )? 1 : params[info.m_nDetailTextureBlendFactor]->GetFloatValue(); + bool hasDetailTexture = ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsTexture(); + int nDetailBlendMode = ( hasDetailTexture && info.m_nDetailTextureCombineMode != -1 ) ? params[info.m_nDetailTextureCombineMode]->GetIntValue() : 0; + + bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ) && !bHasSelfIllum; // Pixel shader can't do both BLENDTINTBYBASEALPHA and SELFILLUM, so let selfillum win + + float flTintReplacementAmount = GetFloatParam( info.m_nTintReplacesBaseColor, params ); + + BlendType_t nBlendType= pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true ); + + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && !bHasFlashlight; //dest alpha is free for special use + + CSkin_DX9_Context *pContextData = reinterpret_cast< CSkin_DX9_Context *> ( *pContextDataPtr ); + if ( ! pContextData ) + { + pContextData = new CSkin_DX9_Context; + *pContextDataPtr = pContextData; + } + + if( pShader->IsSnapshotting() ) + { + // look at color and alphamod stuff. + // Unlit generic never uses the flashlight + bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture(); + bool bHasNormal = params[info.m_nBumpmap]->IsTexture(); + bool bCanUseBaseAlphaPhongMaskFastPath = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 ); + + if ( ! ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) ) + bCanUseBaseAlphaPhongMaskFastPath = true; + + pContextData->m_bFastPath = + (! bHasBump ) && + (! bHasSpecularExponentTexture ) && + (! bHasPhongTintMap ) && + (! bHasPhongWarp ) && + (! bHasRimLight ) && + (! hasDetailTexture ) && + bCanUseBaseAlphaPhongMaskFastPath && + (! bHasSelfIllum ) && + (! bBlendTintByBaseAlpha ); + + // Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + + if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + int nShadowFilterMode = 0; + if( bHasFlashlight ) + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + + if( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + else // not flashlight pass + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); + } + + if ( bHasEnvmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Cubic environment map + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); + } + } + } + + unsigned int flags = VERTEX_POSITION; + if( bHasNormal ) + { + flags |= VERTEX_NORMAL; + } + + int userDataSize = 0; + + // Always enable...will bind white if nothing specified... + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Base (albedo) compression map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER9, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // Base (albedo) expansion map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER10, true ); + } + + if( bHasDiffuseWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Diffuse warp texture + } + + if( bHasPhongWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Specular warp texture + } + + // Specular exponent map or dummy + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Specular exponent map + + if( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); + userDataSize = 4; // tangent S + } + + // Always enable, since flat normal will be bound + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map + userDataSize = 4; // tangent S + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map + + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Normal compression map + pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); // Normal expansion map + } + + if ( hasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER13, true ); + } + + if ( bHasSelfIllum ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); + } + + if( bHasVertexColor || bHasVertexAlpha ) + { + flags |= VERTEX_COLOR; + } + + pShaderShadow->EnableSRGBWrite( true ); + + // texcoord0 : base texcoord, texcoord2 : decal hw morph delta + int pTexCoordDim[3] = { 2, 0, 3 }; + int nTexCoordCount = 1; + +#ifndef _X360 + // Special morphed decal information + if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() ) + { + nTexCoordCount = 3; + } +#endif + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( skin_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( skin_vs20 ); + + // Assume we're only going to get in here if we support 2b + DECLARE_STATIC_PIXEL_SHADER( skin_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, bHasPhongWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( RIMLIGHT, bHasRimLight ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FASTPATH_NOBUMP, pContextData->m_bFastPath ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( skin_ps20b ); + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( skin_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); + SET_STATIC_VERTEX_SHADER( skin_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( skin_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, bHasPhongWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( RIMLIGHT, bHasRimLight ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FASTPATH_NOBUMP, pContextData->m_bFastPath ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( skin_ps30 ); + } +#endif + + if( bHasFlashlight ) + { + pShader->FogToBlack(); + } + else + { + pShader->DefaultFog(); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + else // not snapshotting -- begin dynamic state + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture(); + + if( bHasBaseTexture ) + { + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + + if ( bHasBaseTextureWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER9, info.m_nWrinkle, info.m_nBaseTextureFrame ); + pShader->BindTexture( SHADER_SAMPLER10, info.m_nStretch, info.m_nBaseTextureFrame ); + } + else if ( bHasBumpWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER9, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + pShader->BindTexture( SHADER_SAMPLER10, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + + if( bHasDiffuseWarp && bHasPhong ) + { + if ( r_lightwarpidentity.GetBool() ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_IDENTITY_LIGHTWARP ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER2, info.m_nDiffuseWarpTexture ); + } + } + + if( bHasPhongWarp ) + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nPhongWarpTexture ); + } + + if( bHasSpecularExponentTexture && bHasPhong ) + { + pShader->BindTexture( SHADER_SAMPLER7, info.m_nPhongExponentTexture ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER7, TEXTURE_WHITE ); + } + + if( !g_pConfig->m_bFastNoBump ) + { + if( bHasBump ) + pShader->BindTexture( SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); + else + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + + if ( bHasBumpWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER11, info.m_nNormalWrinkle, info.m_nBumpFrame ); + pShader->BindTexture( SHADER_SAMPLER12, info.m_nNormalStretch, info.m_nBumpFrame ); + } + else if ( bHasBaseTextureWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER11, info.m_nBumpmap, info.m_nBumpFrame ); + pShader->BindTexture( SHADER_SAMPLER12, info.m_nBumpmap, info.m_nBumpFrame ); + } + } + else + { + if( bHasBump ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER11, TEXTURE_NORMALMAP_FLAT ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER12, TEXTURE_NORMALMAP_FLAT ); + } + } + + if ( hasDetailTexture ) + { + pShader->BindTexture( SHADER_SAMPLER13, info.m_nDetail, info.m_nDetailFrame ); + } + + if ( bHasSelfIllum ) + { + if ( bHasSelfIllumMask ) // Separate texture for self illum? + { + pShader->BindTexture( SHADER_SAMPLER14, info.m_nSelfIllumMask ); // Bind it + } + else // else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER14, TEXTURE_BLACK ); // Bind dummy + } + } + + LightState_t lightState = { 0, false, false }; + bool bFlashlightShadows = false; + if( bHasFlashlight ) + { + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + } + } + else // no flashlight + { + if ( bHasEnvmap ) + { + pShader->BindTexture( SHADER_SAMPLER8, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + // don't have an easy way to get this through to GLM, so just print it old school + //printf("\n-D- DrawSkin_DX9_Internal numBones is %d", numBones ); + + bool bWriteDepthToAlpha = false; + bool bWriteWaterFogToAlpha = false; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( skin_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( skin_vs20 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( skin_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( skin_ps20b ); + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( skin_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( skin_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( skin_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( skin_ps30 ); + + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } +#endif + + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + + if( bHasBump ) + { + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); + } + + if ( hasDetailTexture ) + { + if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) ) + pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, + info.m_nDetailTextureTransform, + info.m_nDetailScale ); + else + pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, + info.m_nBaseTextureTransform, + info.m_nDetailScale ); + } + + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + pShader->SetPixelShaderConstant_W( PSREG_SELFILLUMTINT, info.m_nSelfIllumTint, fBlendFactor ); + bool bInvertPhongMask = ( info.m_nInvertPhongMask != -1 ) && ( params[info.m_nInvertPhongMask]->GetIntValue() != 0 ); + float fInvertPhongMask = bInvertPhongMask ? 1 : 0; + + bool bHasBaseAlphaPhongMask = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 ); + float fHasBaseAlphaPhongMask = bHasBaseAlphaPhongMask ? 1 : 0; + // Controls for lerp-style paths through shader code + float vShaderControls[4] = { fHasBaseAlphaPhongMask, 0.0f/*unused*/, flTintReplacementAmount, fInvertPhongMask }; + pShaderAPI->SetPixelShaderConstant( PSREG_CONSTANT_27, vShaderControls, 1 ); + + if ( hasDetailTexture ) + { +#if 0 // needs constant change + if ( info.m_nDetailTint != -1 ) + pShader->SetPixelShaderConstantGammaToLinear( 10, info.m_nDetailTint ); + else + { + float boring_tint[4]={1,1,1,1}; + pShaderAPI->SetPixelShaderConstant( 10, boring_tint, 1 ); + } +#endif + } + + if ( bHasSelfIllumFresnel && !bHasFlashlight ) + { + float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; + float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f; + float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f; + float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f; + + vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias + vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale + vConstScaleBiasExp[2] = flExp; // Exp + vConstScaleBiasExp[3] = flMax; // Brightness + + pShaderAPI->SetPixelShaderConstant( PSREG_SELFILLUM_SCALE_BIAS_EXP, vConstScaleBiasExp, 1 ); + } + + pShader->SetAmbientCubeDynamicStateVertexShader(); + + if( !bHasFlashlight ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + // Setting .x to 1 means to apply Fresnel to env map. Setting w to 1 means use separate selfillummask + float vEnvMapFresnel_SelfIllumMask[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + vEnvMapFresnel_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f; + + if( bHasEnvmap ) + { + float vEnvMapTint_MaskControl[4] = {1.0f, 1.0f, 1.0f, 0.0f}; + + // If we have a tint, grab it + if ( (info.m_nEnvmapTint != -1) && params[info.m_nEnvmapTint]->IsDefined() ) + params[info.m_nEnvmapTint]->GetVecValue(vEnvMapTint_MaskControl, 3); + + // Set control for source of env map mask (normal alpha or base alpha) + vEnvMapTint_MaskControl[3] = bHasNormalMapAlphaEnvmapMask ? 1.0f : 0.0f; + + if ( (info.m_nEnvmapFresnel != -1) && params[info.m_nEnvmapFresnel]->IsDefined() ) + vEnvMapFresnel_SelfIllumMask[0] = params[info.m_nEnvmapFresnel]->GetFloatValue(); + + // Handle mat_fullbright 2 (diffuse lighting only with 50% gamma space basetexture) + if( bLightingOnly ) + { + vEnvMapTint_MaskControl[0] = vEnvMapTint_MaskControl[1] = vEnvMapTint_MaskControl[2] = 0.0f; + } + + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, vEnvMapTint_MaskControl, 1 ); + } + + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_FRESNEL__SELFILLUMMASK, vEnvMapFresnel_SelfIllumMask, 1 ); + } + + pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight ); // Force to black if not bAmbientLight + pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); + + // Pack Phong exponent in with the eye position + float vEyePos_SpecExponent[4], vFresnelRanges_SpecBoost[4] = {1, 0.5, 1, 1}, vRimBoost[4] = {1, 1, 1, 1}; + float vSpecularTint[4] = {1, 1, 1, 4}; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + + // Use the alpha channel of the normal map for the exponent by default + vEyePos_SpecExponent[3] = -1.f; + if ( (info.m_nPhongExponent != -1) && params[info.m_nPhongExponent]->IsDefined() ) + { + float fValue = params[info.m_nPhongExponent]->GetFloatValue(); + if ( fValue > 0.f ) + { + // Nonzero value in material overrides map channel + vEyePos_SpecExponent[3] = fValue; + } + } + + // Get the tint parameter + if ( (info.m_nPhongTint != -1) && params[info.m_nPhongTint]->IsDefined() ) + { + params[info.m_nPhongTint]->GetVecValue(vSpecularTint, 3); + } + + // Get the rim light power (goes in w of Phong tint) + if ( bHasRimLight && (info.m_nRimLightPower != -1) && params[info.m_nRimLightPower]->IsDefined() ) + { + vSpecularTint[3] = params[info.m_nRimLightPower]->GetFloatValue(); + vSpecularTint[3] = max(vSpecularTint[3], 1.0f); // Make sure this is at least 1 + } + + // Get the rim boost (goes in w of flashlight position) + if ( bHasRimLight && (info.m_nRimLightBoost != -1) && params[info.m_nRimLightBoost]->IsDefined() ) + { + vRimBoost[3] = params[info.m_nRimLightBoost]->GetFloatValue(); + } + + if ( !bHasFlashlight ) + { + float vRimMaskControl[4] = {0, 0, 0, 0}; // Only x is relevant in shader code + vRimMaskControl[0] = bHasRimMaskMap ? params[info.m_nRimMask]->GetFloatValue() : 0.0f; + + // Rim mask...if this is true, use alpha channel of spec exponent texture to mask the rim term + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, vRimMaskControl, 1 ); + } + + // If it's all zeros, there was no constant tint in the vmt + if ( (vSpecularTint[0] == 0.0f) && (vSpecularTint[1] == 0.0f) && (vSpecularTint[2] == 0.0f) ) + { + if ( bHasPhongTintMap ) // If we have a map to use, tell the shader + { + vSpecularTint[0] = -1; + } + else // Otherwise, just tint with white + { + vSpecularTint[0] = 1.0f; + vSpecularTint[1] = 1.0f; + vSpecularTint[2] = 1.0f; + } + } + + // handle mat_fullbright 2 (diffuse lighting only) + if( bLightingOnly ) + { + // BASETEXTURE + if( bHasSelfIllum && !bHasFlashlight ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + // DETAILTEXTURE + if ( hasDetailTexture ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER13, TEXTURE_GREY ); + } + + // turn off specularity + vSpecularTint[0] = vSpecularTint[1] = vSpecularTint[2] = 0.0f; + } + + if ( (info.m_nPhongFresnelRanges != -1) && params[info.m_nPhongFresnelRanges]->IsDefined() ) + { + params[info.m_nPhongFresnelRanges]->GetVecValue( vFresnelRanges_SpecBoost, 3 ); // Grab optional Fresnel range parameters + // Change fresnel range encoding from (min, mid, max) to ((mid-min)*2, mid, (max-mid)*2) + vFresnelRanges_SpecBoost[0] = (vFresnelRanges_SpecBoost[1] - vFresnelRanges_SpecBoost[0]) * 2; + vFresnelRanges_SpecBoost[2] = (vFresnelRanges_SpecBoost[2] - vFresnelRanges_SpecBoost[1]) * 2; + } + + if ( (info.m_nPhongBoost != -1 ) && params[info.m_nPhongBoost]->IsDefined()) // Grab optional Phong boost param + vFresnelRanges_SpecBoost[3] = params[info.m_nPhongBoost]->GetFloatValue(); + else + vFresnelRanges_SpecBoost[3] = 1.0f; + + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, vFresnelRanges_SpecBoost, 1 ); + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vRimBoost, 1 ); // Rim boost in w on non-flashlight pass + + pShaderAPI->SetPixelShaderConstant( PSREG_SPEC_RIM_PARAMS, vSpecularTint, 1 ); + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + // flashlightfixme: put this in common code. + if( bHasFlashlight ) + { + VMatrix worldToTexture; + float atten[4], pos[4], tweaks[4]; + + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // steps on rim boost + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + + if ( IsX360() ) + { + pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); + } + } + } + pShader->Draw(); +} + + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +extern ConVar r_flashlight_version2; +void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) + +{ + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + DrawSkin_DX9_Internal( pShader, params, pShaderAPI, + pShaderShadow, false, info, vertexCompression, pContextDataPtr++ ); + if ( pShaderShadow ) + { + pShader->SetInitialShadowState( ); + } + } + DrawSkin_DX9_Internal( pShader, params, pShaderAPI, + pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} diff --git a/mp/src/materialsystem/stdshaders/skin_dx9_helper.h b/mp/src/materialsystem/stdshaders/skin_dx9_helper.h new file mode 100644 index 00000000..414e8dd2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/skin_dx9_helper.h @@ -0,0 +1,35 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef SKIN_DX9_HELPER_H +#define SKIN_DX9_HELPER_H + +#include + +#include "vertexlitgeneric_dx9_helper.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +void InitParamsSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, + const char *pMaterialName, VertexLitGeneric_DX9_Vars_t &info ); +void InitSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, + VertexLitGeneric_DX9_Vars_t &info ); + +void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, + VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ); + + + +#endif // SKIN_DX9_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/skin_ps20b.fxc b/mp/src/materialsystem/stdshaders/skin_ps20b.fxc new file mode 100644 index 00000000..20c3eef9 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/skin_ps20b.fxc @@ -0,0 +1,371 @@ +//======= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====== +// STATIC: "CONVERT_TO_SRGB" "0..0" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "SELFILLUMFRESNEL" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" +// STATIC: "PHONGWARPTEXTURE" "0..1" +// STATIC: "WRINKLEMAP" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..6" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "RIMLIGHT" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "FASTPATH_NOBUMP" "0..1" +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" + +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..4" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + + +// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) + +// blend mode doesn't matter if we only have one texture +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// Only need self illum fresnel when self illum enabled +// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) + +// BlendTintByBaseAlpha and self illum and are opposing meanings for alpha channel +// SKIP: ( $BLENDTINTBYBASEALPHA ) && ( $SELFILLUM ) + +// fastpath means: +// no bumpmap +// basealphaenvmapmask (not inverted) +// no spec expmap +// no spectint +// no specwarp +// no rimlight +// no selfillum +// no detail +// no BlendTintByBaseAlpha + +// SKIP: $FASTPATH_NOBUMP && ( $RIMLIGHT || $DETAILTEXTURE || $PHONGWARPTEXTURE || $SELFILLUM || $BLENDTINTBYBASEALPHA ) + + + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +const float4 g_SelfIllumTint_and_DetailBlendFactor : register( PSREG_SELFILLUMTINT ); +#if ( SELFILLUMFRESNEL == 1 ) +const float4 g_SelfIllumScaleBiasExpBrightness : register( PSREG_SELFILLUM_SCALE_BIAS_EXP ); +#endif +const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); +const float4 g_EnvmapTint_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); // w controls spec mask +const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); +const float4 g_EnvMapFresnel : register( PSREG_ENVMAP_FRESNEL__SELFILLUMMASK ); // x is envmap fresnel ... w is selfillummask control +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_FlashlightAttenuationFactors_RimMask : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass, x has rim mask control +const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); +const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); +const float4 g_FresnelSpecParams : register( PSREG_FRESNEL_SPEC_PARAMS ); // xyz are fresnel, w is specular boost +const float4 g_SpecularRimParams : register( PSREG_SPEC_RIM_PARAMS ); // xyz are specular tint color, w is rim power +PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total (4th light spread across w's) + +// TODO: give this a better name. For now, I don't want to touch shader_constant_register_map.h since I don't want to trigger a recompile of everything... +const float4 g_ShaderControls : register( PSREG_CONSTANT_27 ); // x is basemap alpgha phong mask, y is 1 - blendtintbybasealpha, z is tint overlay amount, w controls "INVERTPHONGMASK" +#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz +#define g_fRimBoost g_FlashlightPos_RimBoost.w +#define g_FresnelRanges g_FresnelSpecParams.xyz +#define g_SpecularBoost g_FresnelSpecParams.w +#define g_SpecularTint g_SpecularRimParams.xyz +#define g_RimExponent g_SpecularRimParams.w +#define g_FlashlightAttenuationFactors g_FlashlightAttenuationFactors_RimMask +#define g_RimMaskControl g_FlashlightAttenuationFactors_RimMask.x +#define g_SelfIllumMaskControl g_EnvMapFresnel.w +#define g_fBaseMapAlphaPhongMask g_ShaderControls.x +#define g_fTintReplacementControl g_ShaderControls.z +#define g_fInvertPhongMask g_ShaderControls.w + +sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha +sampler SpecularWarpSampler : register( s1 ); // Specular warp sampler (for iridescence etc) +sampler DiffuseWarpSampler : register( s2 ); // Lighting warp sampler (1D texture for diffuse lighting modification) +sampler NormalMapSampler : register( s3 ); // Normal map, specular mask in alpha +sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler +sampler NormalizeRandRotSampler : register( s5 ); // Normalization / RandomRotation samplers +sampler FlashlightSampler : register( s6 ); // Flashlight cookie +sampler SpecExponentSampler : register( s7 ); // Specular exponent map +sampler EnvmapSampler : register( s8 ); // Cubic environment map + +#if WRINKLEMAP +sampler WrinkleSampler : register( s9 ); // Compression base +sampler StretchSampler : register( s10 ); // Expansion base +sampler NormalWrinkleSampler : register( s11 ); // Compression base +sampler NormalStretchSampler : register( s12 ); // Expansion base +#endif + +#if DETAILTEXTURE +sampler DetailSampler : register( s13 ); // detail texture +#endif + +sampler SelfIllumMaskSampler : register( s14 ); // selfillummask + + +struct PS_INPUT +{ + float4 baseTexCoordDetailTexCoord : TEXCOORD0; // xy=base zw=detail + float3 lightAtten : TEXCOORD1; // Scalar light attenuation factors for FOUR lights + float3 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3x3 tangentSpaceTranspose : TEXCOORD3; + // second row : TEXCOORD4; + // third row : TEXCOORD5; + float4 worldPos_atten3 : TEXCOORD6; + float4 projPos_fWrinkleWeight : TEXCOORD7; +}; + + + +float4 main( PS_INPUT i ) : COLOR +{ + bool bWrinkleMap = WRINKLEMAP ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + bool bDoSpecularWarp = PHONGWARPTEXTURE ? true : false; + bool bDoAmbientOcclusion = false; + bool bFlashlight = (FLASHLIGHT!=0) ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bDoRimLighting = RIMLIGHT ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + int nNumLights = NUM_LIGHTS; + + // Unpacking for convenience + float fWrinkleWeight = i.projPos_fWrinkleWeight.w; + float3 vProjPos = i.projPos_fWrinkleWeight.xyz; + float3 vWorldPos = i.worldPos_atten3.xyz; + float atten3 = i.worldPos_atten3.w; + + float4 vLightAtten = float4( i.lightAtten, atten3 ); + +#if WRINKLEMAP + float flWrinkleAmount = saturate( -fWrinkleWeight ); // One of these two is zero + float flStretchAmount = saturate( fWrinkleWeight ); // while the other is in the 0..1 range + + float flTextureAmount = 1.0f - flWrinkleAmount - flStretchAmount; // These should sum to one +#endif + + float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoordDetailTexCoord.xy ); +#if WRINKLEMAP + float4 wrinkleColor = tex2D( WrinkleSampler, i.baseTexCoordDetailTexCoord.xy ); + float4 stretchColor = tex2D( StretchSampler, i.baseTexCoordDetailTexCoord.xy ); + + // Apply wrinkle blend to only RGB. Alpha comes from the base texture + baseColor.rgb = flTextureAmount * baseColor + flWrinkleAmount * wrinkleColor + flStretchAmount * stretchColor; +#endif + +#if DETAILTEXTURE + float4 detailColor = tex2D( DetailSampler, i.baseTexCoordDetailTexCoord.zw ); + baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_SelfIllumTint_and_DetailBlendFactor.w ); +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, vWorldPos.z, vProjPos.z ); + + float3 vEyeDir = normalize(i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz); + float3 vRimAmbientCubeColor = PixelShaderAmbientLight(vEyeDir, cAmbientCube); + + float3 worldSpaceNormal, tangentSpaceNormal; + float fSpecMask = 1.0f; + float4 normalTexel = tex2D( NormalMapSampler, i.baseTexCoordDetailTexCoord.xy ); + +#if WRINKLEMAP + float4 wrinkleNormal = tex2D( NormalWrinkleSampler, i.baseTexCoordDetailTexCoord.xy ); + float4 stretchNormal = tex2D( NormalStretchSampler, i.baseTexCoordDetailTexCoord.xy ); + normalTexel = flTextureAmount * normalTexel + flWrinkleAmount * wrinkleNormal + flStretchAmount * stretchNormal; +#endif + +#if (FASTPATH_NOBUMP == 0 ) + tangentSpaceNormal = lerp( 2.0f * normalTexel.xyz - 1.0f, float3(0, 0, 1), g_fBaseMapAlphaPhongMask ); + fSpecMask = lerp( normalTexel.a, baseColor.a, g_fBaseMapAlphaPhongMask ); +#else + tangentSpaceNormal = float3(0, 0, 1); + fSpecMask = baseColor.a; +#endif + + // We need a normal if we're doing any lighting + worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) ); + + float fFresnelRanges = Fresnel( worldSpaceNormal, vEyeDir, g_FresnelRanges ); + float fRimFresnel = Fresnel4( worldSpaceNormal, vEyeDir ); + + // Break down reflect so that we can share dot(worldSpaceNormal,vEyeDir) with fresnel terms + float3 vReflect = 2 * worldSpaceNormal * dot(worldSpaceNormal, vEyeDir) - vEyeDir; + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + float3 envMapColor = float3( 0.0f, 0.0f, 0.0f ); + if( !bFlashlight ) + { + // Summation of diffuse illumination from all local lights + diffuseLighting = PixelShaderDoLighting( vWorldPos, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, true, vLightAtten, + cAmbientCube, NormalizeRandRotSampler, nNumLights, cLightInfo, true, + + // These parameters aren't passed by generic shaders: + false, 1.0f, + bDoDiffuseWarp, DiffuseWarpSampler ); + + if( bCubemap ) + { + // Mask is either normal map alpha or base map alpha +#if ( SELFILLUMFRESNEL == 1 ) // This is to match the 2.0 version of vertexlitgeneric + float fEnvMapMask = lerp( baseColor.a, g_fInvertPhongMask, g_EnvmapTint_ShadowTweaks.w ); +#else + float fEnvMapMask = lerp( baseColor.a, fSpecMask, g_EnvmapTint_ShadowTweaks.w ); +#endif + + envMapColor = (ENV_MAP_SCALE * + lerp(1, fFresnelRanges, g_EnvMapFresnel.x) * + lerp(fEnvMapMask, 1-fEnvMapMask, g_fInvertPhongMask)) * + texCUBE( EnvmapSampler, vReflect ) * + g_EnvmapTint_ShadowTweaks.xyz; + } + } + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); + float3 rimLighting = float3( 0.0f, 0.0f, 0.0f ); + + float3 vSpecularTint = 1; + float fRimMask = 0; + float fSpecExp = 1; + +#if ( FASTPATH_NOBUMP == 0 ) + float4 vSpecExpMap = tex2D( SpecExponentSampler, i.baseTexCoordDetailTexCoord.xy ); + + if ( !bFlashlight ) + { + fRimMask = lerp( 1.0f, vSpecExpMap.a, g_RimMaskControl ); // Select rim mask + } + + // If the exponent passed in as a constant is zero, use the value from the map as the exponent +#if defined( _X360 ) + [flatten] +#endif + + fSpecExp = (g_EyePos_SpecExponent.w >= 0.0) ? g_EyePos_SpecExponent.w : (1.0f + 149.0f * vSpecExpMap.r); + + // If constant tint is negative, tint with albedo, based upon scalar tint map +#if defined( _X360 ) + [flatten] +#endif + vSpecularTint = lerp( float3(1.0f, 1.0f, 1.0f), baseColor.rgb, vSpecExpMap.g ); + vSpecularTint = (g_SpecularTint.r >= 0.0) ? g_SpecularTint.rgb : vSpecularTint; + +#else + fSpecExp = max(g_EyePos_SpecExponent.w, 0); +#endif + + float3 albedo = baseColor.rgb; + + if ( !bFlashlight ) + { + // Summation of specular from all local lights besides the flashlight + PixelShaderDoSpecularLighting( vWorldPos, worldSpaceNormal, + fSpecExp, vEyeDir, vLightAtten, + nNumLights, cLightInfo, false, 1.0f, bDoSpecularWarp, + SpecularWarpSampler, fFresnelRanges, bDoRimLighting, g_RimExponent, + + // Outputs + specularLighting, rimLighting ); + } + else + { + float4 flashlightSpacePosition = mul( float4( vWorldPos, 1.0f ), g_FlashlightWorldToTexture ); + + DoSpecularFlashlight( g_FlashlightPos, vWorldPos, flashlightSpacePosition, worldSpaceNormal, + g_FlashlightAttenuationFactors.xyz, g_FlashlightAttenuationFactors.w, + FlashlightSampler, ShadowDepthSampler, NormalizeRandRotSampler, FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, vProjPos.xy / vProjPos.z, + fSpecExp, vEyeDir, bDoSpecularWarp, SpecularWarpSampler, fFresnelRanges, g_EnvmapTint_ShadowTweaks, + + // These two values are output + diffuseLighting, specularLighting ); + } + + // If we didn't already apply Fresnel to specular warp, modulate the specular + if ( !bDoSpecularWarp ) + fSpecMask *= fFresnelRanges; + + // Modulate with spec mask, boost and tint + specularLighting *= fSpecMask * g_SpecularBoost; + + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_fTintReplacementControl); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + + float3 diffuseComponent = albedo * diffuseLighting; + if ( bSelfIllum && !bFlashlight ) + { +#if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file + // This will apply a Fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look + float3 vVertexNormal = normalize( float3( i.tangentSpaceTranspose[0].z, i.tangentSpaceTranspose[1].z, i.tangentSpaceTranspose[2].z ) ); + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, vEyeDir.xyz ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo * g_SelfIllumScaleBiasExpBrightness.w, baseColor.a * saturate( flSelfIllumFresnel ) ); +#else + float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoordDetailTexCoord.xy ); + vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo, vSelfIllumMask ); +#endif + + diffuseComponent = max( 0.0f, diffuseComponent ); + } + +#if DETAILTEXTURE + diffuseComponent = TextureCombinePostLighting( diffuseComponent, detailColor, + DETAIL_BLEND_MODE, g_SelfIllumTint_and_DetailBlendFactor.w ); +#endif + + if ( bDoRimLighting && !bFlashlight ) + { + float fRimMultiply = fRimMask * fRimFresnel; // both unit range: [0, 1] + + // Add in rim light modulated with tint, mask and traditional Fresnel (not using Fresnel ranges) + rimLighting *= fRimMultiply; + + // Fold rim lighting into specular term by using the max so that we don't really add light twice... + specularLighting = max( specularLighting, rimLighting ); + + // Add in view-ray lookup from ambient cube + specularLighting += (vRimAmbientCubeColor * g_fRimBoost) * saturate(fRimMultiply * worldSpaceNormal.z); + } + + float3 result = specularLighting*vSpecularTint + envMapColor + diffuseComponent; + +#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) + float alpha = fogFactor; +#else + float alpha = g_DiffuseModulation.a; + if ( !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha = lerp( baseColor.a * alpha, alpha, g_fBaseMapAlphaPhongMask ); + } +#endif + + bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); + + //FIXME: need to take dowaterfog into consideration + return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, vProjPos.z ); +} diff --git a/mp/src/materialsystem/stdshaders/skin_vs20.fxc b/mp/src/materialsystem/stdshaders/skin_vs20.fxc new file mode 100644 index 00000000..9b04b7aa --- /dev/null +++ b/mp/src/materialsystem/stdshaders/skin_vs20.fxc @@ -0,0 +1,173 @@ +//======= Copyright (c) 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "DECAL" "0..1" [vs30] +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +//----------------------------------------------------------------------------- +// Input vertex format +//----------------------------------------------------------------------------- +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vUserData : TANGENT; + + // Position and normal/tangent deltas + float4 vPosFlex : POSITION1; + float4 vNormalFlex : NORMAL1; + +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + // Stuff that isn't seen by the pixel shader + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + // Stuff that is seen by the pixel shader + float4 baseTexCoord : TEXCOORD0; // includes detail tex coord + float3 lightAtten : TEXCOORD1; + float3 worldVertToEyeVector : TEXCOORD2; + float3x3 tangentSpaceTranspose : TEXCOORD3; + // second row : TEXCOORD4; + // third row : TEXCOORD5; + float4 worldPos_atten3 : TEXCOORD6; + float4 projPos_fWrinkleWeight : TEXCOORD7; +}; + +//----------------------------------------------------------------------------- +// Main shader entry point +//----------------------------------------------------------------------------- +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, + vPosition.xyz, vNormal, vTangent.xyz, o.projPos_fWrinkleWeight.w ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, v.vTexCoord2, + vPosition.xyz, vNormal, vTangent.xyz, o.projPos_fWrinkleWeight.w ); +#endif + + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, worldPos, + worldNormal, worldTangentS, worldTangentT ); + + // Always normalize since flex path is controlled by runtime + // constant not a shader combo and will always generate the normalization + worldNormal = normalize( worldNormal ); + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + +#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.projPos_fWrinkleWeight.xyz = vProjPos.xyz; + +#if !defined( _X360 ) + o.fog = CalcFog( worldPos, vProjPos.xyz, g_FogType ); +#endif + // Needed for water fog alpha and diffuse lighting + // FIXME: we shouldn't have to compute this all the time. + o.worldPos_atten3.xyz = worldPos; + + // Needed for specular + o.worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + + // Compute bumped lighting + // FIXME: We shouldn't have to compute this for unlit materials +#if defined ( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) + o.lightAtten.xyz = float3(0,0,0); + o.worldPos_atten3.w = 0.0f; + #if ( NUM_LIGHTS > 0 ) + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false ); + #endif + #if ( NUM_LIGHTS > 1 ) + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false ); + #endif + #if ( NUM_LIGHTS > 2 ) + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false ); + #endif + #if ( NUM_LIGHTS > 3 ) + o.worldPos_atten3.w = GetVertexAttenForLight( worldPos, 3, false ); + #endif +#else + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, true ); + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, true ); + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, true ); + o.worldPos_atten3.w = GetVertexAttenForLight( worldPos, 3, true ); +#endif + + // Base texture coordinate transform + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + o.baseTexCoord.z = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); + o.baseTexCoord.w = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); + + // Tangent space transform + o.tangentSpaceTranspose[0] = float3( worldTangentS.x, worldTangentT.x, worldNormal.x ); + o.tangentSpaceTranspose[1] = float3( worldTangentS.y, worldTangentT.y, worldNormal.y ); + o.tangentSpaceTranspose[2] = float3( worldTangentS.z, worldTangentT.z, worldNormal.z ); + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/sky_dx6.cpp b/mp/src/materialsystem/stdshaders/sky_dx6.cpp new file mode 100644 index 00000000..15bdc553 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sky_dx6.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Teeth renderer +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Sky, UnlitGeneric ) +DEFINE_FALLBACK_SHADER( Sky_dx6, UnlitGeneric ) + diff --git a/mp/src/materialsystem/stdshaders/sky_dx9.cpp b/mp/src/materialsystem/stdshaders/sky_dx9.cpp new file mode 100644 index 00000000..93eb6115 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sky_dx9.cpp @@ -0,0 +1,126 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "BaseVSShader.h" +#include "sky_vs20.inc" +#include "sky_ps20.inc" +#include "sky_ps20b.inc" + +#include "convar.h" + +BEGIN_VS_SHADER( Sky_DX9, "Help for Sky_DX9 shader" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "sky_dx6"; + } + return 0; + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NOFOG ); + SET_FLAGS( MATERIAL_VAR_IGNOREZ ); + } + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + ImageFormat fmt = params[BASETEXTURE]->GetTextureValue()->GetImageFormat(); + LoadTexture( BASETEXTURE, (fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616) ? 0 : TEXTUREFLAGS_SRGB ); + } + } + SHADER_DRAW + { + SHADOW_STATE + { + SetInitialShadowState(); + +// pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,true); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sky_vs20 ); + SET_STATIC_VERTEX_SHADER( sky_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_ps20 ); + } + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableAlphaWrites( true ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + float c1[4]={0,0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); + + float c0[4]={1,1,1,1}; + if (params[COLOR]->IsDefined()) + { + memcpy(c0,params[COLOR]->GetVecValue(),3*sizeof(float)); + } + ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( + (fmt==IMAGE_FORMAT_RGBA16161616) || + ( (fmt==IMAGE_FORMAT_RGBA16161616F) && + (g_pHardwareConfig->GetHDRType()==HDR_TYPE_INTEGER)) + ) + { + c0[0]*=16.0; + c0[1]*=16.0; + c0[2]*=16.0; + } + pShaderAPI->SetPixelShaderConstant(0,c0,1); + DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + + // Texture coord transform + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BASETEXTURETRANSFORM ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + } + } + Draw( ); + } + +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc b/mp/src/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc new file mode 100644 index 00000000..8e54d21f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc @@ -0,0 +1,29 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +#include "common_ps_fxc.h" + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +sampler ExposureTextureSampler0 : register( s0 ); +sampler ExposureTextureSampler1 : register( s1 ); +sampler ExposureTextureSampler2 : register( s2 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + HALF3 color0 = 0.25*tex2D( ExposureTextureSampler0, i.baseTexCoord ); + HALF3 color1 = 2.0*tex2D( ExposureTextureSampler1, i.baseTexCoord ); + HALF3 color2 = 16.0*tex2D( ExposureTextureSampler2, i.baseTexCoord ); + + // This is never fogged. +// return FinalOutput( float4( max(max(color0,color1),color2), 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate + return FinalOutput( float4(1,0,0,1 ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/mp/src/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc b/mp/src/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc new file mode 100644 index 00000000..4871da56 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc @@ -0,0 +1,81 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +#include "common_ps_fxc.h" + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +sampler RGBSTextureSampler : register( s0 ); +HALF4 InputScale : register( c0 ); + +float2 texWidthHeight : register( c1 ); + +float4 texOffsets : register( c2 ); + +struct PS_INPUT +{ +//#if defined( _X360 ) +// float2 baseTexCoord : TEXCOORD0; +//#else + float2 baseTexCoord00 : TEXCOORD0; + float2 baseTexCoord01 : TEXCOORD1; + float2 baseTexCoord10 : TEXCOORD2; + float2 baseTexCoord11 : TEXCOORD3; + float2 baseTexCoord_In_Pixels: TEXCOORD4; +//#endif +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 result; + +//#if defined( _X360 ) //360 has a cheaper way to handle RGBscale +// float4 Weights; +// float4 samples_0; //no arrays allowed in inline assembly +// float4 samples_1; +// float4 samples_2; +// float4 samples_3; +// float2 vTexCoord = i.baseTexCoord; +// +// asm { +// tfetch2D samples_0, vTexCoord.xy, RGBSTextureSampler, OffsetX = -0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false +// tfetch2D samples_1, vTexCoord.xy, RGBSTextureSampler, OffsetX = 0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false +// tfetch2D samples_2, vTexCoord.xy, RGBSTextureSampler, OffsetX = -0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false +// tfetch2D samples_3, vTexCoord.xy, RGBSTextureSampler, OffsetX = 0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false +// +// getWeights2D Weights, vTexCoord.xy, RGBSTextureSampler +// }; +// +// Weights = float4( (1-Weights.x)*(1-Weights.y), Weights.x*(1-Weights.y), (1-Weights.x)*Weights.y, Weights.x*Weights.y ); +// +// result.rgb = samples_0.rgb * (samples_0.a * Weights.x); +// result.rgb += samples_1.rgb * (samples_1.a * Weights.y); +// result.rgb += samples_2.rgb * (samples_2.a * Weights.z); +// result.rgb += samples_3.rgb * (samples_3.a * Weights.w); +// +//#else + float4 s00 = tex2D(RGBSTextureSampler, i.baseTexCoord00); + float4 s10 = tex2D(RGBSTextureSampler, i.baseTexCoord10); + float4 s01 = tex2D(RGBSTextureSampler, i.baseTexCoord01); + float4 s11 = tex2D(RGBSTextureSampler, i.baseTexCoord11); + + float2 fracCoord = frac(i.baseTexCoord_In_Pixels); + + s00.rgb*=s00.a; + s10.rgb*=s10.a; + + s00.xyz = lerp(s00, s10, fracCoord.x); + + s01.rgb*=s01.a; + s11.rgb*=s11.a; + s01.xyz = lerp(s01, s11, fracCoord.x); + + result = lerp(s00, s01, fracCoord.y); +//#endif + + // This is never fogged. + return FinalOutput( float4( InputScale*result, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/mp/src/materialsystem/stdshaders/sky_hdr_dx9.cpp b/mp/src/materialsystem/stdshaders/sky_hdr_dx9.cpp new file mode 100644 index 00000000..285879c0 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sky_hdr_dx9.cpp @@ -0,0 +1,297 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "BaseVSShader.h" +#include "sky_vs20.inc" +#include "sky_ps20.inc" +#include "sky_ps20b.inc" +#include "sky_hdr_compressed_ps20.inc" +#include "sky_hdr_compressed_ps20b.inc" +#include "sky_hdr_compressed_rgbs_ps20.inc" +#include "sky_hdr_compressed_rgbs_ps20b.inc" + +#include "convar.h" + +static ConVar mat_use_compressed_hdr_textures( "mat_use_compressed_hdr_textures", "1" ); + +DEFINE_FALLBACK_SHADER( Sky, Sky_HDR_DX9 ) + +BEGIN_VS_SHADER( Sky_HDR_DX9, "Help for Sky_HDR_DX9 shader" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( HDRBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture when running with HDR enabled" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture (compressed) for hdr compression method A" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE0, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture0 for hdr compression method B" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture1 for hdr compression method B" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture2 for hdr compression method B" ) + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + return "Sky_DX9"; + } + return 0; + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NOFOG ); + SET_FLAGS( MATERIAL_VAR_IGNOREZ ); + } + SHADER_INIT + { + // First figure out if sampler zero wants to be sRGB + int nSamplerZeroFlags = 0; + if ( (params[HDRCOMPRESSEDTEXTURE]->IsDefined()) && mat_use_compressed_hdr_textures.GetBool() ) + { + nSamplerZeroFlags = 0; + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + nSamplerZeroFlags = 0; + } + else + { + nSamplerZeroFlags = TEXTUREFLAGS_SRGB; + + if ( params[HDRBASETEXTURE]->IsDefined() && params[HDRBASETEXTURE]->IsTexture() ) + { + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( ( fmt == IMAGE_FORMAT_RGBA16161616F ) || ( fmt == IMAGE_FORMAT_RGBA16161616 ) ) + { + nSamplerZeroFlags = 0; + } + } + } + } + + // Next, figure out which texture will be on sampler zero + int nSampler0 = HDRCOMPRESSEDTEXTURE; + if ( params[HDRCOMPRESSEDTEXTURE]->IsDefined() && mat_use_compressed_hdr_textures.GetBool() ) + { + nSampler0 = HDRCOMPRESSEDTEXTURE; + } + else + { + if ( params[HDRCOMPRESSEDTEXTURE0]->IsDefined() ) + { + nSampler0 = HDRCOMPRESSEDTEXTURE0; + } + else + { + nSampler0 = HDRBASETEXTURE; + } + } + + // Load the appropriate textures, making sure that the texture set on sampler 0 is sRGB if necessary + if ( params[HDRCOMPRESSEDTEXTURE]->IsDefined() && (mat_use_compressed_hdr_textures.GetBool() ) ) + { + LoadTexture( HDRCOMPRESSEDTEXTURE, HDRCOMPRESSEDTEXTURE == nSampler0 ? nSamplerZeroFlags : 0 ); + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + LoadTexture( HDRCOMPRESSEDTEXTURE0, HDRCOMPRESSEDTEXTURE0 == nSampler0 ? nSamplerZeroFlags : 0 ); + if ( params[HDRCOMPRESSEDTEXTURE1]->IsDefined() ) + { + LoadTexture( HDRCOMPRESSEDTEXTURE1, HDRCOMPRESSEDTEXTURE1 == nSampler0 ? nSamplerZeroFlags : 0 ); + } + if ( params[HDRCOMPRESSEDTEXTURE2]->IsDefined()) + { + LoadTexture( HDRCOMPRESSEDTEXTURE2, HDRCOMPRESSEDTEXTURE2 == nSampler0 ? nSamplerZeroFlags : 0 ); + } + } + else + { + if ( params[HDRBASETEXTURE]->IsDefined() ) + { + LoadTexture( HDRBASETEXTURE, HDRBASETEXTURE == nSampler0 ? nSamplerZeroFlags : 0 ); + } + } + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + SetInitialShadowState(); + +// pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sky_vs20 ); + SET_STATIC_VERTEX_SHADER( sky_vs20 ); + + if ( (params[HDRCOMPRESSEDTEXTURE]->IsDefined()) && + mat_use_compressed_hdr_textures.GetBool() ) + { + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + } + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1,false); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2,false); + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + } + } + else + { + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,true); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_ps20 ); + } + } + } + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableAlphaWrites( true ); + } + + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + + // Texture coord transform + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BASETEXTURETRANSFORM ); + + float c0[4]={1,1,1,1}; + if (params[COLOR]->IsDefined()) + { + memcpy(c0,params[COLOR]->GetVecValue(),3*sizeof(float)); + } + if ( + params[HDRCOMPRESSEDTEXTURE]->IsDefined() && + mat_use_compressed_hdr_textures.GetBool() + ) + { + // set up data needs for pixel shader interpolation + ITexture *txtr=params[HDRCOMPRESSEDTEXTURE]->GetTextureValue(); + float w=txtr->GetActualWidth(); + float h=txtr->GetActualHeight(); + float FUDGE=0.01/max(w,h); // per ATI + float c1[4]={0.5/w-FUDGE, 0.5/h-FUDGE, w, h }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); + + BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE, FRAME ); + c0[0]*=8.0; + c0[1]*=8.0; + c0[2]*=8.0; + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + } + } + else + { + float c1[4]={0,0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); + + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined() ) + { + BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE0, FRAME ); + BindTexture( SHADER_SAMPLER1, HDRCOMPRESSEDTEXTURE1, FRAME ); + BindTexture( SHADER_SAMPLER2, HDRCOMPRESSEDTEXTURE2, FRAME ); + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + } + + } + else + { + BindTexture( SHADER_SAMPLER0, HDRBASETEXTURE, FRAME ); + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( + (fmt==IMAGE_FORMAT_RGBA16161616) || + ( (fmt==IMAGE_FORMAT_RGBA16161616F) && + (g_pHardwareConfig->GetHDRType()==HDR_TYPE_INTEGER)) + ) + { + c0[0]*=16.0; + c0[1]*=16.0; + c0[2]*=16.0; + } + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + } + } + } + pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); + } + Draw( ); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/sky_ps2x.fxc b/mp/src/materialsystem/stdshaders/sky_ps2x.fxc new file mode 100644 index 00000000..563fddbb --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sky_ps2x.fxc @@ -0,0 +1,27 @@ +// HDRFIXME: Make this work with nonHDR +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +#include "common_ps_fxc.h" + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +sampler BaseTextureSampler : register( s0 ); +HALF4 InputScale : register( c0 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + HALF4 color = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); + color.rgb *= InputScale.rgb; + + // This is never fogged. + return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/mp/src/materialsystem/stdshaders/sky_vs20.fxc b/mp/src/materialsystem/stdshaders/sky_vs20.fxc new file mode 100644 index 00000000..1bc2a3e6 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sky_vs20.fxc @@ -0,0 +1,64 @@ +#include "common_vs_fxc.h" + +const float4 g_vTextureSizeInfo : register( SHADER_SPECIFIC_CONST_0 ); +const float4 g_mBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); + //SHADER_SPECIFIC_CONST_2 + +#define TEXEL_XINCR (g_vTextureSizeInfo.x) +#define TEXEL_YINCR (g_vTextureSizeInfo.y) +#define U_TO_PIXEL_COORD_SCALE (g_vTextureSizeInfo.z) +#define V_TO_PIXEL_COORD_SCALE (g_vTextureSizeInfo.w) + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + +//#if defined( _X360 ) +// float2 baseTexCoord : TEXCOORD0; +//#else + float2 baseTexCoord00 : TEXCOORD0; + float2 baseTexCoord01 : TEXCOORD1; + float2 baseTexCoord10 : TEXCOORD2; + float2 baseTexCoord11 : TEXCOORD3; + float2 baseTexCoord_In_Pixels: TEXCOORD4; +//#endif +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.projPos = mul( v.vPos, cModelViewProj ); + + float4 vTexCoordInput = { v.vTexCoord0.x, v.vTexCoord0.y, 0.0f, 1.0f }; + float2 vTexCoord; + vTexCoord.x = dot( vTexCoordInput.xyzw, g_mBaseTexCoordTransform[0] ); + vTexCoord.y = dot( vTexCoordInput.xyzw, g_mBaseTexCoordTransform[1] ); + +//#if defined( _X360 ) +// o.baseTexCoord.xy = vTexCoord.xy; +//#else + // Compute quantities needed for pixel shader texture lerping + o.baseTexCoord00.x = vTexCoord.x - TEXEL_XINCR; + o.baseTexCoord00.y = vTexCoord.y - TEXEL_YINCR; + o.baseTexCoord10.x = vTexCoord.x + TEXEL_XINCR; + o.baseTexCoord10.y = vTexCoord.y - TEXEL_YINCR; + + o.baseTexCoord01.x = vTexCoord.x - TEXEL_XINCR; + o.baseTexCoord01.y = vTexCoord.y + TEXEL_YINCR; + o.baseTexCoord11.x = vTexCoord.x + TEXEL_XINCR; + o.baseTexCoord11.y = vTexCoord.y + TEXEL_YINCR; + + o.baseTexCoord_In_Pixels.xy = o.baseTexCoord00.xy; + o.baseTexCoord_In_Pixels.x *= U_TO_PIXEL_COORD_SCALE; + o.baseTexCoord_In_Pixels.y *= V_TO_PIXEL_COORD_SCALE; +//#endif + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/sprite.cpp b/mp/src/materialsystem/stdshaders/sprite.cpp new file mode 100644 index 00000000..77934f57 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sprite.cpp @@ -0,0 +1,379 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +// Implementation of the sprite shader +//=============================================================================// + +#include "BaseVSShader.h" +#include +#include "const.h" +#include "sprite_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// WARNING! Change these in engine/SpriteGn.h if you change them here! +#define SPR_VP_PARALLEL_UPRIGHT 0 +#define SPR_FACING_UPRIGHT 1 +#define SPR_VP_PARALLEL 2 +#define SPR_ORIENTED 3 +#define SPR_VP_PARALLEL_ORIENTED 4 + + +DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX8 ) + +BEGIN_VS_SHADER( Sprite_DX8, + "Help for Sprite_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) + SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) + SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) + SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "Sprite_DX6"; + return 0; + } + + SHADER_INIT_PARAMS() + { + // FIXME: This can share code with sprite.cpp + // FIXME: Not sure if this is the best solution, but it's a very] + // easy one. When graphics aren't enabled, we oftentimes need to get + // at the parameters of a shader. Therefore, we must set the default + // values in a separate phase from when we load resources. + + if (!params[ALPHA]->IsDefined()) + params[ ALPHA ]->SetFloatValue( 1.0f ); + + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); + SET_FLAGS( MATERIAL_VAR_VERTEXALPHA ); + + // translate from a string orientation to an enumeration + if (params[SPRITEORIENTATION]->IsDefined()) + { + const char *orientationString = params[SPRITEORIENTATION]->GetStringValue(); + if( stricmp( orientationString, "parallel_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + else if( stricmp( orientationString, "facing_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT ); + } + else if( stricmp( orientationString, "vp_parallel" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL ); + } + else if( stricmp( orientationString, "oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED ); + } + else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED ); + } + else + { + Warning( "error with $spriteOrientation\n" ); + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + else + { + // default case + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + +#define SHADER_USE_VERTEX_COLOR 1 +#define SHADER_USE_CONSTANT_COLOR 2 + + void SetSpriteCommonShadowState( unsigned int shaderFlags ) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + unsigned int flags = VERTEX_POSITION; + if( shaderFlags & SHADER_USE_VERTEX_COLOR ) + { + flags |= VERTEX_COLOR; + } + s_pShaderShadow->VertexShaderVertexFormat( flags, 1, 0, 0 ); + + sprite_vs11_Static_Index vshIndex; + bool vertexColor = ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false; + vshIndex.SetVERTEXCOLOR( vertexColor ); + s_pShaderShadow->SetVertexShader( "sprite_vs11", vshIndex.GetIndex() ); + + // "VERTEXCOLOR" "0..1" + // "CONSTANTCOLOR" "0..1" + int pshIndex = 0; + if ( shaderFlags & SHADER_USE_VERTEX_COLOR ) pshIndex |= 0x1; + if ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) pshIndex |= 0x2; + s_pShaderShadow->SetPixelShader( "sprite_ps11", pshIndex ); + } + + void SetSpriteCommonDynamicState( unsigned int shaderFlags ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + sprite_vs11_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( 0 ); + vshIndex.SetDOWATERFOG( fogIndex ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + s_pShaderAPI->SetPixelShaderIndex( 0 ); + if ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) + { + SetPixelShaderConstant( 0, COLOR, ALPHA ); + } + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + // identity base texture transorm + float ident[2][4] = { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f } + }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &ident[0][0], 2 ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableCulling( false ); + } + + switch( params[SPRITERENDERMODE]->GetIntValue() ) + { + case kRenderNormal: + SHADOW_STATE + { + FogToFogColor(); + SetSpriteCommonShadowState( 0 ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( 0 ); + } + Draw(); + break; + case kRenderTransColor: + case kRenderTransTexture: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderGlow: + case kRenderWorldGlow: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_ALWAYS ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlpha: + // untested cut and past from kRenderTransAlphaAdd . . same as first pass of that. + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlphaAdd: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + + SHADOW_STATE + { + SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + + case kRenderTransAdd: + { + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( flags ); + } + } + Draw(); + break; + case kRenderTransAddFrameBlend: + { + float flFrame = params[FRAME]->GetFloatValue(); + float flFade = params[ALPHA]->GetFloatValue(); + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + sprite_vs11_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( 0 ); + vshIndex.SetDOWATERFOG( fogIndex ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + s_pShaderAPI->SetPixelShaderIndex( 0 ); + + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + s_pShaderAPI->SetPixelShaderConstant( 0, color ); + + + // identity base texture transorm + float ident[2][4] = { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f } + }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &ident[0][0], 2 ); + } + Draw(); + SHADOW_STATE + { + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + int numAnimationFrames = pTexture->GetNumAnimationFrames(); + BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + sprite_vs11_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( 0 ); + vshIndex.SetDOWATERFOG( fogIndex ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + s_pShaderAPI->SetPixelShaderIndex( 0 ); + + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + s_pShaderAPI->SetPixelShaderConstant( 0, color ); + + // identity base texture transorm + float ident[2][4] = { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f } + }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &ident[0][0], 2 ); + } + Draw(); + } + break; + default: + ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); + break; + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/sprite_dx6.cpp b/mp/src/materialsystem/stdshaders/sprite_dx6.cpp new file mode 100644 index 00000000..15ba22a6 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sprite_dx6.cpp @@ -0,0 +1,289 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +// Implementation of the sprite shader +//=============================================================================// + +#include "shaderlib/cshader.h" +#include +#include "const.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// WARNING! Change these in engine/SpriteGn.h if you change them here! +#define SPR_VP_PARALLEL_UPRIGHT 0 +#define SPR_FACING_UPRIGHT 1 +#define SPR_VP_PARALLEL 2 +#define SPR_ORIENTED 3 +#define SPR_VP_PARALLEL_ORIENTED 4 + + +DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX6 ) + +BEGIN_SHADER( Sprite_DX6, + "Help for Sprite_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) + SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) + SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) + SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + // FIXME: This can share code with sprite.cpp + // FIXME: Not sure if this is the best solution, but it's a very] + // easy one. When graphics aren't enabled, we oftentimes need to get + // at the parameters of a shader. Therefore, we must set the default + // values in a separate phase from when we load resources. + + if (!params[ALPHA]->IsDefined()) + params[ ALPHA ]->SetFloatValue( 1.0f ); + + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); + SET_FLAGS( MATERIAL_VAR_VERTEXALPHA ); + + // translate from a string orientation to an enumeration + if (params[SPRITEORIENTATION]->IsDefined()) + { + const char *orientationString = params[SPRITEORIENTATION]->GetStringValue(); + if( stricmp( orientationString, "parallel_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + else if( stricmp( orientationString, "facing_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT ); + } + else if( stricmp( orientationString, "vp_parallel" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL ); + } + else if( stricmp( orientationString, "oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED ); + } + else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED ); + } + else + { + Warning( "error with $spriteOrientation\n" ); + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + else + { + // default case + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableCulling( false ); + } + + switch( params[SPRITERENDERMODE]->GetIntValue() ) + { + case kRenderNormal: + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransColor: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransTexture: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderGlow: + case kRenderWorldGlow: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableDepthTest( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToBlack(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransAlpha: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransAlphaAdd: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToBlack(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + + case kRenderTransAdd: + SHADOW_STATE + { + if( params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + } + else + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + } + pShaderShadow->EnableConstantColor( true ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + FogToBlack(); + } + DYNAMIC_STATE + { + SetColorState( COLOR, ALPHA ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransAddFrameBlend: + { + float flFrame = params[FRAME]->GetFloatValue(); + float flFade = params[ALPHA]->GetFloatValue(); + SHADOW_STATE + { + if( params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + } + else + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + } + pShaderShadow->EnableConstantColor( true ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + FogToBlack(); + } + DYNAMIC_STATE + { + float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame ); + pShaderAPI->Color3f( flFade * frameBlendAlpha, flFade * frameBlendAlpha, flFade * frameBlendAlpha ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); + } + Draw(); + SHADOW_STATE + { + FogToBlack(); + } + DYNAMIC_STATE + { + float frameBlendAlpha = ( flFrame - ( int )flFrame ); + pShaderAPI->Color3f( flFade * frameBlendAlpha, flFade * frameBlendAlpha, flFade * frameBlendAlpha ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + int numAnimationFrames = pTexture->GetNumAnimationFrames(); + BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); + } + Draw(); + } + + break; + default: + ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); + break; + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/sprite_dx9.cpp b/mp/src/materialsystem/stdshaders/sprite_dx9.cpp new file mode 100644 index 00000000..0a0bb9f4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sprite_dx9.cpp @@ -0,0 +1,490 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "BaseVSShader.h" +#include +#include "const.h" + +#include "cpp_shader_constant_register_map.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#include "sprite_vs20.inc" +#include "sprite_ps20.inc" +#include "sprite_ps20b.inc" + +// WARNING! Change these in engine/SpriteGn.h if you change them here! +#define SPR_VP_PARALLEL_UPRIGHT 0 +#define SPR_FACING_UPRIGHT 1 +#define SPR_VP_PARALLEL 2 +#define SPR_ORIENTED 3 +#define SPR_VP_PARALLEL_ORIENTED 4 + + +DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX9 ) + +BEGIN_VS_SHADER( Sprite_DX9, + "Help for Sprite_DX9" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) + SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) + SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) + SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) + SHADER_PARAM( NOSRGB, SHADER_PARAM_TYPE_BOOL, "0", "do not operate in srgb space" ) + SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if (g_pHardwareConfig->GetDXSupportLevel() < 90) + return "Sprite_DX8"; + return 0; + } + SHADER_INIT_PARAMS() + { + // FIXME: This can share code with sprite.cpp + if (!params[ALPHA]->IsDefined()) + { + params[ALPHA]->SetFloatValue( 1.0f ); + } + + if (!params[HDRCOLORSCALE]->IsDefined()) + { + params[HDRCOLORSCALE]->SetFloatValue( 1.0f ); + } + + if ( !params[NOSRGB]->IsDefined() ) + { + // Disable sRGB reads and writes by default + params[NOSRGB]->SetIntValue( 1 ); + } + + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); + SET_FLAGS( MATERIAL_VAR_VERTEXALPHA ); + + // translate from a string orientation to an enumeration + if (params[SPRITEORIENTATION]->IsDefined()) + { + const char *orientationString = params[SPRITEORIENTATION]->GetStringValue(); + if( stricmp( orientationString, "parallel_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + else if( stricmp( orientationString, "facing_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT ); + } + else if( stricmp( orientationString, "vp_parallel" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL ); + } + else if( stricmp( orientationString, "oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED ); + } + else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED ); + } + else + { + Warning( "error with $spriteOrientation\n" ); + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + else + { + // default case + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + + SHADER_INIT + { + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + LoadTexture( BASETEXTURE, bSRGB ? TEXTUREFLAGS_SRGB : 0 ); + } + +#define SHADER_USE_VERTEX_COLOR 1 +#define SHADER_USE_CONSTANT_COLOR 2 + + void SetSpriteCommonShadowState( unsigned int shaderFlags ) + { + IShaderShadow *pShaderShadow = s_pShaderShadow; + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bSRGB ); + + // Only enabling this on OSX() - it causes GL mode's light glow sprites to be much darker vs. D3D9 under Linux/Win GL. + bool bSRGBOutputAdapter = ( IsOSX() && !g_pHardwareConfig->FakeSRGBWrite() ) && !bSRGB; + + unsigned int flags = VERTEX_POSITION; + if( shaderFlags & SHADER_USE_VERTEX_COLOR ) + { + flags |= VERTEX_COLOR; + } + int numTexCoords = 1; + s_pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sprite_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_VERTEX_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_VERTEX_SHADER( sprite_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path + { + DECLARE_STATIC_PIXEL_SHADER( sprite_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( CONSTANTCOLOR, ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB_OUTPUT_ADAPTER, bSRGBOutputAdapter ); + SET_STATIC_PIXEL_SHADER( sprite_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sprite_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( CONSTANTCOLOR, ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_PIXEL_SHADER( sprite_ps20 ); + } + + // OSX always has to sRGB write (don't do this on Linux/Win GL - it causes glow sprites to be way too dark) + s_pShaderShadow->EnableSRGBWrite( bSRGB || ( IsOSX() && !g_pHardwareConfig->FakeSRGBWrite() ) ); + } + + void SetSpriteCommonDynamicState( unsigned int shaderFlags ) + { + IShaderDynamicAPI *pShaderAPI = s_pShaderAPI; + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + if( shaderFlags & SHADER_USE_CONSTANT_COLOR ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 0, COLOR, ALPHA ); + else + SetPixelShaderConstant( 0, COLOR, ALPHA ); + } + + if( IsHDREnabled() ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); + else + SetPixelShaderConstant( 1, HDRCOLORSCALE ); + } + } + + SHADER_DRAW + { + bool bSRGB = params[NOSRGB]->GetIntValue() == 0; + + SHADOW_STATE + { + pShaderShadow->EnableCulling( false ); + } + + switch( params[SPRITERENDERMODE]->GetIntValue() ) + { + case kRenderNormal: + SHADOW_STATE + { + FogToFogColor(); + + SetSpriteCommonShadowState( 0 ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( 0 ); + } + Draw(); + break; + case kRenderTransColor: + case kRenderTransTexture: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderGlow: + case kRenderWorldGlow: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableDepthTest( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlpha: + // untested cut and past from kRenderTransAlphaAdd . . same as first pass of that. + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlphaAdd: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + + SHADOW_STATE + { + SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + + case kRenderTransAdd: + { + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( flags ); + } + } + Draw(); + break; + case kRenderTransAddFrameBlend: + { + float flFrame = params[FRAME]->GetFloatValue(); + float flFade = params[ALPHA]->GetFloatValue(); + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + float color[4]; + if ( bSRGB ) + color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); + else + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + s_pShaderAPI->SetPixelShaderConstant( 0, color ); + if( IsHDREnabled() ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); + else + SetPixelShaderConstant( 1, HDRCOLORSCALE ); + } + } + Draw(); + SHADOW_STATE + { + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + int numAnimationFrames = pTexture->GetNumAnimationFrames(); + BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + float color[4]; + if ( bSRGB ) + color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); + else + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + s_pShaderAPI->SetPixelShaderConstant( 0, color ); + if( IsHDREnabled() ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); + else + SetPixelShaderConstant( 1, HDRCOLORSCALE ); + } + } + Draw(); + } + + break; + default: + ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); + break; + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/sprite_ps11.psh b/mp/src/materialsystem/stdshaders/sprite_ps11.psh new file mode 100644 index 00000000..5f5def5b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sprite_ps11.psh @@ -0,0 +1,15 @@ +; STATIC: "VERTEXCOLOR" "0..1" +; STATIC: "CONSTANTCOLOR" "0..1" + +ps.1.1 + +tex t0 +mov r0, t0 + +#if VERTEXCOLOR +mul r0, r0, v0 +#endif + +#if CONSTANTCOLOR +mul r0, r0, c0 +#endif \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/sprite_ps2x.fxc b/mp/src/materialsystem/stdshaders/sprite_ps2x.fxc new file mode 100644 index 00000000..83a7ab08 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sprite_ps2x.fxc @@ -0,0 +1,61 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "CONSTANTCOLOR" "0..1" +// STATIC: "HDRTYPE" "0..2" +// STATIC: "SRGB" "0..1" +// STATIC: "SRGB_OUTPUT_ADAPTER" "0..1" [ps20b] + +// DYNAMIC: "HDRENABLED" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +const HALF4 g_Color : register( c0 ); +const float g_HDRColorScale : register( c1 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +sampler TexSampler : register( s0 ); + +struct PS_INPUT +{ + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 result, sample = tex2D( TexSampler, i.baseTexCoord ); + +#if VERTEXCOLOR + sample *= i.color; +#endif + +#if CONSTANTCOLOR + sample *= g_Color; +#endif + +#if HDRTYPE && HDRENABLED + sample.xyz *= g_HDRColorScale; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); +#if SRGB + result = FinalOutput( sample, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +#else + result = FinalOutput( sample, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_GAMMA ); +#endif + + // On Posix, we're being forced through a linear-to-gamma curve but don't want it, so we do the opposite here first +#if SRGB_OUTPUT_ADAPTER + result = GammaToLinear( result ); +#endif + + return result; +} + diff --git a/mp/src/materialsystem/stdshaders/sprite_vs11.vsh b/mp/src/materialsystem/stdshaders/sprite_vs11.vsh new file mode 100644 index 00000000..5ffa45f1 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sprite_vs11.vsh @@ -0,0 +1,9 @@ +vs.1.1 + +# STATIC: "VERTEXCOLOR" "0..1" +# DYNAMIC: "SKINNING" "0..0" +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "UnlitGeneric_inc.vsh" + +&UnlitGeneric( 0, 0, 0, 0, $VERTEXCOLOR ); diff --git a/mp/src/materialsystem/stdshaders/sprite_vs20.fxc b/mp/src/materialsystem/stdshaders/sprite_vs20.fxc new file mode 100644 index 00000000..5e427c19 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/sprite_vs20.fxc @@ -0,0 +1,65 @@ +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "SRGB" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bVertexColor = VERTEXCOLOR ? true : false; + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vColor : COLOR0; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; +#endif + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul4x3( v.vPos, cModel[0] ); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + projPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, projPos.z ); + +#if !defined( _X360 ) + o.fog = CalcFog( worldPos, projPos, g_FogType ); +#endif + if ( g_bVertexColor ) + { + // Assume that this is unlitgeneric if you are using vertex color. +#if SRGB + o.color.rgba = GammaToLinear( v.vColor.rgba ); +#else + o.color.rgba = v.vColor.rgba; +#endif + } + + // Base texture coordinates + o.baseTexCoord.xy = v.vTexCoord0.xy; + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/spritecard.cpp b/mp/src/materialsystem/stdshaders/spritecard.cpp new file mode 100644 index 00000000..850c357a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/spritecard.cpp @@ -0,0 +1,484 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: shader for drawing sprites as cards, with animation frame lerping +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "convar.h" + +// STDSHADER_DX9_DLL_EXPORT +#include "spritecard_ps20.inc" +#include "spritecard_ps20b.inc" +#include "spritecard_vs20.inc" +#include "splinecard_vs20.inc" + +#if SUPPORT_DX8 +// STDSHADER_DX8_DLL_EXPORT +#include "spritecard_vs11.inc" +#include "spritecard_ps11.inc" +#include "splinecard_vs11.inc" +#endif + +#include "tier0/icommandline.h" //command line + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define DEFAULT_PARTICLE_FEATHERING_ENABLED 1 + +#ifdef STDSHADER_DX8_DLL_EXPORT +DEFINE_FALLBACK_SHADER( Spritecard, Spritecard_DX8 ) +#endif + +int GetDefaultDepthFeatheringValue( void ) //Allow the command-line to go against the default soft-particle value +{ + static int iRetVal = -1; + + if( iRetVal == -1 ) + { +# if( DEFAULT_PARTICLE_FEATHERING_ENABLED == 1 ) + { + if( CommandLine()->CheckParm( "-softparticlesdefaultoff" ) ) + iRetVal = 0; + else + iRetVal = 1; + } +# else + { + if( CommandLine()->CheckParm( "-softparticlesdefaulton" ) ) + iRetVal = 1; + else + iRetVal = 0; + } +# endif + } + + // On low end parts on the Mac, we reduce particles and shut off depth blending here + static ConVarRef mat_reduceparticles( "mat_reduceparticles" ); + if ( mat_reduceparticles.GetBool() ) + { + iRetVal = 0; + } + + return iRetVal; +} + + +#ifdef STDSHADER_DX9_DLL_EXPORT +BEGIN_VS_SHADER_FLAGS( Spritecard, "Help for Spritecard", SHADER_NOT_EDITABLE ) +#else +BEGIN_VS_SHADER_FLAGS( Spritecard_DX8, "Help for Spritecard_DX8", SHADER_NOT_EDITABLE ) +#endif + +BEGIN_SHADER_PARAMS +SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" ) +SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) +SHADER_PARAM( ORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "0 = always face camera, 1 = rotate around z, 2= parallel to ground" ) +SHADER_PARAM( ADDBASETEXTURE2, SHADER_PARAM_TYPE_FLOAT, "0.0", "amount to blend second texture into frame by" ) +SHADER_PARAM( OVERBRIGHTFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "overbright factor for texture. For HDR effects.") +SHADER_PARAM( DUALSEQUENCE, SHADER_PARAM_TYPE_INTEGER, "0", "blend two separate animated sequences.") +SHADER_PARAM( SEQUENCE_BLEND_MODE, SHADER_PARAM_TYPE_INTEGER, "0", "defines the blend mode between the images un dual sequence particles. 0 = avg, 1=alpha from first, rgb from 2nd, 2= first over second" ) +SHADER_PARAM( MAXLUMFRAMEBLEND1, SHADER_PARAM_TYPE_INTEGER, "0", "instead of blending between animation frames for the first sequence, select pixels based upon max luminance" ) +SHADER_PARAM( MAXLUMFRAMEBLEND2, SHADER_PARAM_TYPE_INTEGER, "0", "instead of blending between animation frames for the 2nd sequence, select pixels based upon max luminance" ) +SHADER_PARAM( RAMPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "if specified, then the red value of the image is used to index this ramp to produce the output color" ) +SHADER_PARAM( ZOOMANIMATESEQ2, SHADER_PARAM_TYPE_FLOAT, "1.0", "amount to gradually zoom between frames on the second sequence. 2.0 will double the size of a frame over its lifetime.") +SHADER_PARAM( EXTRACTGREENALPHA, SHADER_PARAM_TYPE_INTEGER, "0", "grayscale data sitting in green/alpha channels") +SHADER_PARAM( ADDOVERBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "use ONE:INVSRCALPHA blending") +SHADER_PARAM( ADDSELF, SHADER_PARAM_TYPE_FLOAT, "0.0", "amount of base texture to additively blend in" ) +SHADER_PARAM( BLENDFRAMES, SHADER_PARAM_TYPE_BOOL, "1", "whether or not to smoothly blend between animated frames" ) +SHADER_PARAM( MINSIZE, SHADER_PARAM_TYPE_FLOAT, "0.0", "minimum screen fractional size of particle") +SHADER_PARAM( STARTFADESIZE, SHADER_PARAM_TYPE_FLOAT, "10.0", "screen fractional size to start fading particle out") +SHADER_PARAM( ENDFADESIZE, SHADER_PARAM_TYPE_FLOAT, "20.0", "screen fractional size to finish fading particle out") +SHADER_PARAM( MAXSIZE, SHADER_PARAM_TYPE_FLOAT, "20.0", "maximum screen fractional size of particle") +SHADER_PARAM( USEINSTANCING, SHADER_PARAM_TYPE_BOOL, "1", "whether to use GPU vertex instancing (submit 1 vert per particle quad)") +SHADER_PARAM( SPLINETYPE, SHADER_PARAM_TYPE_INTEGER, "0", "spline type 0 = none, 1=ctamull rom") +SHADER_PARAM( MAXDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100000.0", "maximum distance to draw particles at") +SHADER_PARAM( FARFADEINTERVAL, SHADER_PARAM_TYPE_FLOAT, "400.0", "interval over which to fade out far away particles") +END_SHADER_PARAMS + +SHADER_INIT_PARAMS() +{ + INIT_FLOAT_PARM( MAXDISTANCE, 100000.0); + INIT_FLOAT_PARM( FARFADEINTERVAL, 400.0); + INIT_FLOAT_PARM( MAXSIZE, 20.0 ); + INIT_FLOAT_PARM( ENDFADESIZE, 20.0 ); + INIT_FLOAT_PARM( STARTFADESIZE, 10.0 ); + INIT_FLOAT_PARM( DEPTHBLENDSCALE, 50.0 ); + INIT_FLOAT_PARM( OVERBRIGHTFACTOR, 1.0 ); + INIT_FLOAT_PARM( ADDBASETEXTURE2, 0.0 ); + INIT_FLOAT_PARM( ADDSELF, 0.0 ); + INIT_FLOAT_PARM( ZOOMANIMATESEQ2, 0.0 ); + + if ( !params[DEPTHBLEND]->IsDefined() ) + { + params[ DEPTHBLEND ]->SetIntValue( GetDefaultDepthFeatheringValue() ); + } + if ( !g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + params[ DEPTHBLEND ]->SetIntValue( 0 ); + } + if ( !params[DUALSEQUENCE]->IsDefined() ) + { + params[DUALSEQUENCE]->SetIntValue( 0 ); + } + if ( !params[MAXLUMFRAMEBLEND1]->IsDefined() ) + { + params[MAXLUMFRAMEBLEND1]->SetIntValue( 0 ); + } + if ( !params[MAXLUMFRAMEBLEND2]->IsDefined() ) + { + params[MAXLUMFRAMEBLEND2]->SetIntValue( 0 ); + } + if ( !params[EXTRACTGREENALPHA]->IsDefined() ) + { + params[EXTRACTGREENALPHA]->SetIntValue( 0 ); + } + if ( !params[ADDOVERBLEND]->IsDefined() ) + { + params[ADDOVERBLEND]->SetIntValue( 0 ); + } + if ( !params[BLENDFRAMES]->IsDefined() ) + { + params[ BLENDFRAMES ]->SetIntValue( 1 ); + } + if ( !params[USEINSTANCING]->IsDefined() ) + { + params[ USEINSTANCING ]->SetIntValue( IsX360() ? 1 : 0 ); + } + SET_FLAGS2( MATERIAL_VAR2_IS_SPRITECARD ); +} + +SHADER_FALLBACK +{ +#ifdef STDSHADER_DX9_DLL_EXPORT + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "SpriteCard_DX8"; +#endif +#ifdef STDSHADER_DX8_DLL_EXPORT + // STDSHADER_DX8_DLL_EXPORT + if ( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "Wireframe"; +#endif + return 0; +} + +SHADER_INIT +{ +#ifdef STDSHADER_DX9_DLL_EXPORT + const bool bDX8 = false; +#endif +#ifdef STDSHADER_DX8_DLL_EXPORT + const bool bDX8 = true; +#endif + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + if ( params[BASETEXTURE]->IsDefined() ) + { + bool bExtractGreenAlpha = false; + if ( params[EXTRACTGREENALPHA]->IsDefined() ) + { + bExtractGreenAlpha = params[EXTRACTGREENALPHA]->GetIntValue() != 0; + } + + LoadTexture( BASETEXTURE, !bExtractGreenAlpha && !bDX8 ? TEXTUREFLAGS_SRGB : 0 ); + } + if ( params[RAMPTEXTURE]->IsDefined() ) + { + LoadTexture( RAMPTEXTURE, TEXTUREFLAGS_SRGB ); + } +} + +SHADER_DRAW +{ +#ifdef STDSHADER_DX9_DLL_EXPORT + const bool bDX8 = false; +#endif +#ifdef STDSHADER_DX8_DLL_EXPORT + const bool bDX8 = true; +#endif + bool bUseRampTexture = (! bDX8 ) && ( params[RAMPTEXTURE]->IsDefined() ); + bool bZoomSeq2 = (! bDX8 ) && ( ( params[ZOOMANIMATESEQ2]->GetFloatValue()) > 1.0 ); + bool bDepthBlend = (! bDX8 ) && ( params[DEPTHBLEND]->GetIntValue() != 0 ); + bool bAdditive2ndTexture = params[ADDBASETEXTURE2]->GetFloatValue() != 0.0; + int nSplineType = params[SPLINETYPE]->GetIntValue(); + + SHADOW_STATE + { + bool bSecondSequence = params[DUALSEQUENCE]->GetIntValue() != 0; + bool bAddOverBlend = params[ADDOVERBLEND]->GetIntValue() != 0; + bool bExtractGreenAlpha = (! bDX8 ) && ( params[EXTRACTGREENALPHA]->GetIntValue() != 0 ); + bool bBlendFrames = (! bDX8 ) && ( params[BLENDFRAMES]->GetIntValue() != 0 ); + if ( nSplineType ) + { + bBlendFrames = false; + } + bool bAddSelf = params[ADDSELF]->GetFloatValue() != 0.0; + bool bUseInstancing = IsX360() ? ( params[ USEINSTANCING ]->GetIntValue() != 0 ) : false; + if ( nSplineType ) + bUseInstancing = false; + + // draw back-facing because of yaw spin + pShaderShadow->EnableCulling( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + if ( bDX8 ) + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + if ( bAdditive2ndTexture && bDX8 ) + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + if ( bUseRampTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + + if ( bDepthBlend ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + + if ( bAdditive2ndTexture || bAddSelf ) + pShaderShadow->EnableAlphaTest( false ); + else + pShaderShadow->EnableAlphaTest( true ); + + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.01f ); + + if ( bAdditive2ndTexture || bAddOverBlend || bAddSelf ) + { + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + else + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + } + + unsigned int flags = VERTEX_POSITION | VERTEX_COLOR; + static int s_TexCoordSize[8]={4, // 0 = sheet bounding uvs, frame0 + 4, // 1 = sheet bounding uvs, frame 1 + 4, // 2 = frame blend, rot, radius, ??? + 2, // 3 = corner identifier ( 0/0,1/0,1/1, 1/0 ) + 4, // 4 = texture 2 bounding uvs + 4, // 5 = second sequence bounding uvs, frame0 + 4, // 6 = second sequence bounding uvs, frame1 + 4, // 7 = second sequence frame blend, ?,?,? + }; + static int s_TexCoordSizeSpline[]={4, // 0 = sheet bounding uvs, frame0 + 4, // 1 = sheet bounding uvs, frame 1 + 4, // 2 = frame blend, rot, radius, ??? + 4, // 3 = corner identifier ( 0/0,1/0,1/1, 1/0 ) + 4, // 4 = texture 2 bounding uvs + 4, // 5 = second sequence bounding uvs, frame0 + 4, // 6 = second sequence bounding uvs, frame1 + 4, // 7 = second sequence frame blend, ?,?,? + }; + + int numTexCoords = 4; + if ( true /* bAdditive2ndTexture */ ) // there is no branch for 2nd texture in the VS! -henryg + { + numTexCoords = 5; + } + if ( bSecondSequence ) + { + // the whole shebang - 2 sequences, with a possible multi-image sequence first + numTexCoords = 8; + } + pShaderShadow->VertexShaderVertexFormat( flags, + numTexCoords, + nSplineType? s_TexCoordSizeSpline : s_TexCoordSize, 0 ); + + if ( bDX8 ) + { +#if SUPPORT_DX8 + if ( nSplineType ) + { + DECLARE_STATIC_VERTEX_SHADER( splinecard_vs11 ); + SET_STATIC_VERTEX_SHADER( splinecard_vs11 ); + } + else + { + DECLARE_STATIC_VERTEX_SHADER( spritecard_vs11 ); + if ( bSecondSequence ) + bAdditive2ndTexture = false; + SET_STATIC_VERTEX_SHADER_COMBO( DUALSEQUENCE, false ); + SET_STATIC_VERTEX_SHADER_COMBO( ZOOM_ANIMATE_SEQ2, false ); + SET_STATIC_VERTEX_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha ); + SET_STATIC_VERTEX_SHADER( spritecard_vs11 ); + } + + DECLARE_STATIC_PIXEL_SHADER( spritecard_ps11 ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDSELF, bAddSelf ); + SET_STATIC_PIXEL_SHADER_COMBO( USEALPHAASRGB, bSecondSequence ); + SET_STATIC_PIXEL_SHADER( spritecard_ps11 ); +#endif + } + else + { + if ( nSplineType ) + { + DECLARE_STATIC_VERTEX_SHADER( splinecard_vs20 ); + SET_STATIC_VERTEX_SHADER( splinecard_vs20 ); + } + else + { + DECLARE_STATIC_VERTEX_SHADER( spritecard_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( DUALSEQUENCE, bSecondSequence ); + SET_STATIC_VERTEX_SHADER_COMBO( ZOOM_ANIMATE_SEQ2, bZoomSeq2 ); + SET_STATIC_VERTEX_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_INSTANCING, bUseInstancing ); + SET_STATIC_VERTEX_SHADER( spritecard_vs20 ); + } + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( spritecard_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDSELF, bAddSelf ); + SET_STATIC_PIXEL_SHADER_COMBO( ANIMBLEND, bBlendFrames ); + SET_STATIC_PIXEL_SHADER_COMBO( DUALSEQUENCE, bSecondSequence ); + SET_STATIC_PIXEL_SHADER_COMBO( SEQUENCE_BLEND_MODE, bSecondSequence ? params[SEQUENCE_BLEND_MODE]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND1, params[MAXLUMFRAMEBLEND1]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND2, bSecondSequence? params[MAXLUMFRAMEBLEND1]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORRAMP, bUseRampTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDepthBlend ); + SET_STATIC_PIXEL_SHADER( spritecard_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( spritecard_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DUALSEQUENCE, bSecondSequence ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDSELF, bAddSelf ); + SET_STATIC_PIXEL_SHADER_COMBO( ANIMBLEND, bBlendFrames ); + SET_STATIC_PIXEL_SHADER_COMBO( SEQUENCE_BLEND_MODE, bSecondSequence ? params[SEQUENCE_BLEND_MODE]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND1, params[MAXLUMFRAMEBLEND1]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND2, bSecondSequence? params[MAXLUMFRAMEBLEND1]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORRAMP, bUseRampTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha ); + SET_STATIC_PIXEL_SHADER( spritecard_ps20 ); + } + + if ( !bDX8 ) + pShaderShadow->EnableSRGBWrite( true ); + + if( !bExtractGreenAlpha && !bDX8 ) + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + if ( bDX8 ) // bind on 2nd sampelr so we can lerp + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + + if ( bDX8 && bAdditive2ndTexture ) + BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME ); + + if ( bUseRampTexture && ( !bDX8 ) ) + { + BindTexture( SHADER_SAMPLER1, RAMPTEXTURE, FRAME ); + } + + if ( bDepthBlend ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_DEPTH ); + } + + LoadViewportTransformScaledIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10 ); + + int nOrientation = params[ORIENTATION]->GetIntValue(); + nOrientation = clamp( nOrientation, 0, 2 ); + + // We need these only when screen-orienting + if ( nOrientation == 0 ) + { + LoadModelViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 ); + LoadProjectionMatrixIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 ); + } + + if ( bZoomSeq2 ) + { + float flZScale=1.0/(params[ZOOMANIMATESEQ2]->GetFloatValue()); + float C0[4]={ 0.5*(1.0+flZScale), flZScale, 0, 0 }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, C0, + ARRAYSIZE(C0)/4 ); + } + + // set fade constants in vsconsts 8 and 9 + float flMaxDistance = params[MAXDISTANCE]->GetFloatValue(); + float flStartFade = max( 1.0, flMaxDistance - params[FARFADEINTERVAL]->GetFloatValue() ); + + float VC0[8]={ params[MINSIZE]->GetFloatValue(), params[MAXSIZE]->GetFloatValue(), + params[STARTFADESIZE]->GetFloatValue(), params[ENDFADESIZE]->GetFloatValue(), + flStartFade, 1.0/(flMaxDistance-flStartFade), + 0,0 }; + + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, VC0, ARRAYSIZE(VC0)/4 ); + + pShaderAPI->SetDepthFeatheringPixelShaderConstant( 2, params[DEPTHBLENDSCALE]->GetFloatValue() ); + + float C0[4]={ params[ADDBASETEXTURE2]->GetFloatValue(), + params[OVERBRIGHTFACTOR]->GetFloatValue(), + params[ADDSELF]->GetFloatValue(), + 0.0f }; + + if ( bDX8 && ( !bAdditive2ndTexture ) ) // deal with 0..1 limit for pix shader constants + { + C0[2] *= 0.25; + C0[1] *= 0.25; + } + + pShaderAPI->SetPixelShaderConstant( 0, C0, ARRAYSIZE(C0)/4 ); + + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { +#if SUPPORT_DX8 + if ( nSplineType ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( splinecard_vs11 ); + SET_DYNAMIC_VERTEX_SHADER( splinecard_vs11 ); + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( spritecard_vs11 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( ORIENTATION, nOrientation ); + SET_DYNAMIC_VERTEX_SHADER( spritecard_vs11 ); + } +#endif + } + else + { + if ( nSplineType ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( splinecard_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( splinecard_vs20 ); + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( spritecard_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( ORIENTATION, nOrientation ); + SET_DYNAMIC_VERTEX_SHADER( spritecard_vs20 ); + } + } + } + Draw( ); +} +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/spritecard_ps11.fxc b/mp/src/materialsystem/stdshaders/spritecard_ps11.fxc new file mode 100644 index 00000000..624362cb --- /dev/null +++ b/mp/src/materialsystem/stdshaders/spritecard_ps11.fxc @@ -0,0 +1,72 @@ +// STATIC: "ADDBASETEXTURE2" "0..1" +// STATIC: "ADDSELF" "0..1" +// STATIC: "USEALPHAASRGB" "0..1" +// SKIP: $USEALPHAASRGB && $ADDSELF +// SKIP: $USEALPHAASRGB && $ADDBASETEXTURE2 + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; +#if ADDBASETEXTURE2 + float2 texCoord2 : TEXCOORD3; +#endif + float4 vScreenPos : TEXCOORD7; +}; + +sampler BaseTextureSampler : register( s0 ); + +#if ADDBASETEXTURE2 +sampler BaseTextureSampler2 : register( s3 ); +#endif + +sampler BaseTextureSampler1 : register( s1 ); +const float4 g_Parameters : register( c0 ); +const float4 g_ColorPowers : register( c1 ); + +#define fAdditiveBlendWeight g_Parameters.x +#define fOverbrightFactor g_Parameters.y +#define fAdditiveSelfBlendWeight g_Parameters.z +#define fSoftParticleBlendScale g_Parameters.w + +#pragma warning( disable : 4707 4704 ) +float4 main( PS_INPUT i ) : COLOR +{ + // Sample frames from texture 0 +#if ( ! ADDSELF ) && ( ! ADDBASETEXTURE2 ) + float4 baseTex0 = tex2D( BaseTextureSampler, i.texCoord0 ); + float4 baseTex1 = tex2D( BaseTextureSampler1, i.texCoord1 ); + float4 blended_rgb = lerp( baseTex0, baseTex1, i.blendfactor0.x ); +#else + float4 blended_rgb = tex2D( BaseTextureSampler, i.texCoord0 ); +#endif +#if USEALPHAASRGB + blended_rgb.rgb = blended_rgb.a; +#endif + +#if ADDBASETEXTURE2 + blended_rgb.a *= i.argbcolor.a; + + // In this case, we don't really want to pre-multiply by alpha + float4 color2 = tex2D( BaseTextureSampler2, i.texCoord2 ); + blended_rgb.rgb *= blended_rgb.a; + blended_rgb.rgb += fOverbrightFactor * fAdditiveBlendWeight * i.argbcolor.a * color2; + blended_rgb.rgb *= 2 * i.argbcolor.rgb; +#else +#if ADDSELF + blended_rgb.a *= i.argbcolor.a; + blended_rgb.rgb *= blended_rgb.a; + blended_rgb.rgb += fOverbrightFactor * 8 * fAdditiveSelfBlendWeight * blended_rgb; + blended_rgb.rgb *= 2 * i.argbcolor.rgb; +#else + blended_rgb *= i.argbcolor; +#endif +#endif + return blended_rgb; +} + diff --git a/mp/src/materialsystem/stdshaders/spritecard_ps2x.fxc b/mp/src/materialsystem/stdshaders/spritecard_ps2x.fxc new file mode 100644 index 00000000..1281d33a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/spritecard_ps2x.fxc @@ -0,0 +1,194 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "DUALSEQUENCE" "0..1" +// STATIC: "SEQUENCE_BLEND_MODE" "0..2" +// STATIC: "ADDBASETEXTURE2" "0..1" +// STATIC: "MAXLUMFRAMEBLEND1" "0..1" +// STATIC: "MAXLUMFRAMEBLEND2" "0..1" +// STATIC: "EXTRACTGREENALPHA" "0..1" +// STATIC: "COLORRAMP" "0..1" +// STATIC: "ANIMBLEND" "0..1" +// STATIC: "ADDSELF" "0..1" +// STATIC: "DEPTHBLEND" "0..1" [ps20b] + +#define COMBINE_MODE_AVERAGE 0 +#define COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND 1 +#define COMBINE_MODE_USE_FIRST_OVER_SECOND 2 + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +const float4 g_Parameters : register( c0 ); +const float4 g_DepthFeatheringConstants : register( c2 ); + +#define fAdditiveBlendWeight g_Parameters.x +#define fOverbrightFactor g_Parameters.y +#define fAdditiveSelfBlendWeight g_Parameters.z + +struct PS_INPUT +{ + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; +#if ADDBASETEXTURE2 + float2 texCoord2 : TEXCOORD3; +#endif +#if EXTRACTGREENALPHA + float4 blendfactor1 : TEXCOORD4; +#endif + +#if DUALSEQUENCE + float2 vSeq2TexCoord0 : TEXCOORD5; + float2 vSeq2TexCoord1 : TEXCOORD6; +#endif + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vScreenPos_ReverseZ : TEXCOORD7; +#else + float4 vScreenPos : TEXCOORD7; +#endif +}; + +sampler BaseTextureSampler : register( s0 ); +sampler ColorRampSampler : register( s1 ); +sampler DepthSampler : register( s2 ); + +float4 main( PS_INPUT i ) : COLOR +{ + bool bMaxLumFrameBlend1 = MAXLUMFRAMEBLEND1 ? true : false; + bool bMaxLumFrameBlend2 = MAXLUMFRAMEBLEND2 ? true : false; + bool bExtractGreenAlpha = EXTRACTGREENALPHA ? true : false; + bool bAddBaseTexture2 = ADDBASETEXTURE2 ? true : false; + bool bDualSequence = DUALSEQUENCE ? true : false; + bool bColorRamp = COLORRAMP ? true : false; +#ifdef DEPTHBLEND + bool bDepthBlend = DEPTHBLEND ? true : false; +#endif + int nSequenceBlendMode = SEQUENCE_BLEND_MODE; + + // Sample frames from texture 0 + float4 baseTex0 = tex2D( BaseTextureSampler, i.texCoord0 ); + + float4 baseTex1 = tex2D( BaseTextureSampler, i.texCoord1 ); + + // Blend by default (may override with bMaxLumFrameBlend1 or bExtractGreenAlpha) +#if ANIMBLEND + float4 blended_rgb = lerp( baseTex0, baseTex1, i.blendfactor0.x ); +#else + float4 blended_rgb = baseTex0; +#endif + + if ( bMaxLumFrameBlend1 ) + { + // Blend between animation frames based upon max luminance + float lum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); + float lum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); + + if ( lum0 > lum1 ) + blended_rgb = baseTex0; + else + blended_rgb = baseTex1; + } + else if( bExtractGreenAlpha ) + { +#if EXTRACTGREENALPHA + // Weight Green/Alphas from the two frames for a scalar result + blended_rgb = dot( baseTex0, i.blendfactor0 ) + dot( baseTex1, i.blendfactor1 ); +#endif + } + +#if DUALSEQUENCE + if ( bDualSequence ) + { + baseTex0 = tex2D( BaseTextureSampler, i.vSeq2TexCoord0 ); + baseTex1 = tex2D( BaseTextureSampler, i.vSeq2TexCoord1 ); + + // Blend by default (may override with bMaxLumFrameBlend2) + float4 rgb2 = lerp( baseTex0, baseTex1, i.blendfactor0.z ); + + if ( bMaxLumFrameBlend2 ) + { + // blend between animation frames based upon max luminance + float tlum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); + float tlum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); + + if ( tlum0 > tlum1 ) + rgb2 = baseTex0; + else + rgb2 = baseTex1; + } + + if ( nSequenceBlendMode == COMBINE_MODE_AVERAGE ) + { + blended_rgb = 0.5 * ( blended_rgb + rgb2 ); + } + else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND ) + { + blended_rgb.rgb = rgb2.rgb; + } + else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_OVER_SECOND ) + { + blended_rgb.rgb = lerp( blended_rgb.rgb, rgb2.rgb, rgb2.a ); + } + } // bDualSequence +#endif + + // Optional color ramp + if ( bColorRamp ) + { + blended_rgb.rgb = tex2D( ColorRampSampler, float2( blended_rgb.r, blended_rgb.g ) ); + } + + // Overbright + blended_rgb.rgb *= fOverbrightFactor; + + //Soft Particles FTW +# if (DEPTHBLEND == 1) +# if defined( _X360 ) + float fDepthBlend = DepthFeathering( DepthSampler, i.vScreenPos_ReverseZ.xy / i.vScreenPos_ReverseZ.w, i.vScreenPos_ReverseZ.z, i.vScreenPos_ReverseZ.w, g_DepthFeatheringConstants ); +# else + float fDepthBlend = DepthFeathering( DepthSampler, i.vScreenPos.xy / i.vScreenPos.w, i.vScreenPos.z, i.vScreenPos.w, g_DepthFeatheringConstants ); +# endif + i.argbcolor.a *= fDepthBlend; +# endif + + // Premultiply the alpha for a ONE:INVALPHA blend +#if ADDBASETEXTURE2 + if ( bAddBaseTexture2 ) + { + blended_rgb.a *= i.argbcolor.a; + + // In this case, we don't really want to pre-multiply by alpha + if ( !bColorRamp ) + { + blended_rgb.rgb *= blended_rgb.a; + } + + if ( bExtractGreenAlpha ) + { + blended_rgb.rgb += fAdditiveBlendWeight * i.argbcolor.a * blended_rgb.rgb; + } + else + { + blended_rgb.rgb += fOverbrightFactor * fAdditiveBlendWeight * i.argbcolor.a * tex2D( BaseTextureSampler, i.texCoord2 ); + } + + blended_rgb.rgb *= i.argbcolor.rgb; + } + else +#endif + { +#if ADDSELF + blended_rgb.a *= i.argbcolor.a; + blended_rgb.rgb *= blended_rgb.a; + blended_rgb.rgb += fOverbrightFactor * fAdditiveSelfBlendWeight * i.argbcolor.a * blended_rgb; + blended_rgb.rgb *= i.argbcolor.rgb; +#else + blended_rgb *= i.argbcolor; +#endif + } + + return FinalOutput( blended_rgb, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +} + diff --git a/mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc b/mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc new file mode 100644 index 00000000..6f670101 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc @@ -0,0 +1,347 @@ +// STATIC: "ZOOM_ANIMATE_SEQ2" "0..1" [vs20] +// STATIC: "DUALSEQUENCE" "0..1" [vs20] +// STATIC: "EXTRACTGREENALPHA" "0..1" [vs20] + +// STATIC: "ZOOM_ANIMATE_SEQ2" "0..0" [vs11] +// STATIC: "DUALSEQUENCE" "0..0" [vs11] +// STATIC: "EXTRACTGREENALPHA" "0..0" [vs11] + +// STATIC: "USE_INSTANCING" "0..1" [vs20] +// DYNAMIC: "ORIENTATION" "0..2" + + +#include "common_vs_fxc.h" + +const float4x3 cModelView : register(SHADER_SPECIFIC_CONST_0); +const float4x4 cProj : register(SHADER_SPECIFIC_CONST_3); + +#if ZOOM_ANIMATE_SEQ2 +const float4 ScaleParms : register(SHADER_SPECIFIC_CONST_7); +#define OLDFRM_SCALE_START (ScaleParms.x) +#define OLDFRM_SCALE_END (ScaleParms.y) +#endif + +const float4 SizeParms : register(SHADER_SPECIFIC_CONST_8); +const float4 SizeParms2 : register(SHADER_SPECIFIC_CONST_9); +const float4 ViewportTransformScaled : register(SHADER_SPECIFIC_CONST_10); + +#define MINIMUM_SIZE_FACTOR (SizeParms.x) +#define MAXIMUM_SIZE_FACTOR (SizeParms.y) + +#define START_FADE_SIZE_FACTOR (SizeParms.z) +#define END_FADE_SIZE_FACTOR (SizeParms.w) + +// alpha fade w/ distance +#define START_FAR_FADE ( SizeParms2.x ) +#define FAR_FADE_FACTOR ( SizeParms2.y ) // alpha = 1-min(1,max(0, (dist-start_fade)*factor)) + +// Define stuff for instancing on 360 +#if ( defined( _X360 ) && defined( SHADER_MODEL_VS_2_0 ) ) +#define CONST_PC +#define VERTEX_INDEX_PARAM_360 ,int Index:INDEX +#define DO_INSTANCING 1 +#else +#define CONST_PC const +#define VERTEX_INDEX_PARAM_360 +#endif + + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vTint : COLOR; + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vParms : TEXCOORD2; // frame blend, rot, radius, yaw + // FIXME: remove this vertex element for (USE_INSTANCING == 1), need to shuffle the following elements down + float2 vCornerID : TEXCOORD3; // 0,0 1,0 1,1 0,1 + float4 vTexCoord2 : TEXCOORD4; +#if DUALSEQUENCE + float4 vSeq2TexCoord0 : TEXCOORD5; + float4 vSeq2TexCoord1 : TEXCOORD6; + float4 vParms1 : TEXCOORD7; // second frame blend, ?,?,? +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; + float2 texCoord2 : TEXCOORD3; +#if !defined( SHADER_MODEL_VS_1_1 ) + float4 blendfactor1 : TEXCOORD4; // for extracting green/alpha +#endif +#if DUALSEQUENCE + float2 vSeq2TexCoord0 : TEXCOORD5; + float2 vSeq2TexCoord1 : TEXCOORD6; +#endif + +#if defined( _X360 ) + float4 vScreenPos_ReverseZ : TEXCOORD7; +#else + float4 vScreenPos : TEXCOORD7; +#endif +}; + +#define BLENDFACTOR v.vParms.x +#define ROTATION v.vParms.y +#define RADIUS v.vParms.z +#define YAW (v.vParms.w) + +#if ( ZOOM_ANIMATE_SEQ2 ) +float getlerpscaled( float l_in, float s0, float s1, float ts ) +{ + l_in = 2.0*(l_in-.5); + l_in *= lerp(s0,s1,ts); + return 0.5+0.5*l_in; +} + +float getlerpscale_for_old_frame( float l_in, float ts ) +{ + return getlerpscaled( l_in, OLDFRM_SCALE_START, OLDFRM_SCALE_END, ts); +} + +float getlerpscale_for_new_frame( float l_in, float ts ) +{ + return getlerpscaled( l_in, 1.0, OLDFRM_SCALE_START, ts ); +} +#endif // ZOOM_ANIMATE_SEQ2 + +#ifdef DO_INSTANCING +void InstancedVertexRead( inout VS_INPUT v, int index ) +{ + // Duplicate each VB vertex 4 times (and generate vCornerID - the only thing that varies per-corner) + float4 vTint; + float4 vPos; + float4 vTexCoord0; + float4 vTexCoord1; + float4 vParms; + float4 vTexCoord2; + float4 vSeq_TexCoord0; // NOTE: April XDK compiler barfs on var names which have a number in the middle! (i.e. vSeq2TexCoord0) + float4 vSeq_TexCoord1; + float4 vParms1; + + int spriteIndex = index / 4; + int cornerIndex = index - 4*spriteIndex; + asm + { + vfetch vTint, spriteIndex, color0; + vfetch vPos, spriteIndex, position0; + vfetch vTexCoord0, spriteIndex, texcoord0; + vfetch vTexCoord1, spriteIndex, texcoord1; + vfetch vParms, spriteIndex, texcoord2; + vfetch vTexCoord2, spriteIndex, texcoord4; +#if DUALSEQUENCE + vfetch vSeq_TexCoord0, spriteIndex, texcoord5; + vfetch vSeq_TexCoord1, spriteIndex, texcoord6; + vfetch vParms1, spriteIndex, texcoord7; +#endif + }; + + v.vTint = vTint; + v.vPos = vPos; + v.vTexCoord0 = vTexCoord0; + v.vTexCoord1 = vTexCoord1; + v.vParms = vParms; + v.vTexCoord2 = vTexCoord2; +#if DUALSEQUENCE + v.vSeq2TexCoord0 = vSeq_TexCoord0; + v.vSeq2TexCoord1 = vSeq_TexCoord1; + v.vParms1 = vParms1; +#endif + + // Compute vCornerID - order is: (0,0) (1,0) (1,1) (0,1) + // float2 IDs[4] = { {0,0}, {1,0}, {1,1}, {0,1} }; + // v.vCornerID.xy = IDs[ cornerIndex ]; + // This compiles to 2 ops on 360 (MADDs with abs/sat register read/write modifiers): + v.vCornerID.xy = float2( 1.5f, 0.0f ) + cornerIndex*float2( -1.0f, 1.0f ); + v.vCornerID.xy = saturate( float2(1.5f, -3.0f) + float2( -1.0f, 2.0f )*abs( v.vCornerID.xy ) ); +} +#endif + +VS_OUTPUT main( CONST_PC VS_INPUT v + VERTEX_INDEX_PARAM_360 ) +{ + VS_OUTPUT o; + +#ifdef DO_INSTANCING + if ( USE_INSTANCING ) + { + InstancedVertexRead( v, Index ); + } +#endif + +#if SHADER_MODEL_VS_1_1 + float4 tint = v.vTint; +#else + float4 tint = GammaToLinear( v.vTint ); +#endif + + float2 sc_yaw; + sincos( YAW, sc_yaw.y, sc_yaw.x ); + + float2 sc; + sincos( ROTATION, sc.y, sc.x ); + + float2 ix=2*v.vCornerID.xy-1; + float x1=dot(ix,sc); + float y1=sc.x*ix.y-sc.y*ix.x; + + float4 projPos; + float3 worldPos; + worldPos = mul4x3( v.vPos, cModel[0] ); + + float rad = RADIUS; + float3 v2p = ( worldPos - cEyePos ); + float l = length(v2p); + rad=max(rad, MINIMUM_SIZE_FACTOR * l); + // now, perform fade out +#ifndef SHADER_MODEL_VS_1_1 + if ( rad > START_FADE_SIZE_FACTOR * l ) + { + if ( rad > END_FADE_SIZE_FACTOR *l ) + { + tint = 0; + rad = 0; // cull so we emit 0-sized sprite + } + else + { + tint *= 1-(rad-START_FADE_SIZE_FACTOR*l)/(END_FADE_SIZE_FACTOR*l-START_FADE_SIZE_FACTOR*l); + } + } +#endif + + +#ifndef SHADER_MODEL_VS_1_1 + // perform far fade + float tscale = 1-min(1, max(0, (l-START_FAR_FADE)*FAR_FADE_FACTOR) ); + tint *= tscale; + + if ( tscale <= 0) + rad = 0; // cull so we emit 0-sized sprite +#endif + + rad=min(rad, MAXIMUM_SIZE_FACTOR * l); + +#if ORIENTATION == 0 + // Screen-aligned case + float3 viewPos; + viewPos = mul4x3( v.vPos, cModelView ); + + float3 disp=float3( -x1,y1,0); + float tmpx=disp.x*sc_yaw.x+disp.z*sc_yaw.y; + disp.z = disp.z*sc_yaw.x-disp.x*sc_yaw.y; + disp.x=tmpx; + + viewPos.xyz += disp * rad; + + projPos = mul( float4(viewPos, 1.0f), cProj ); +#endif + +#if ORIENTATION == 1 + // Z-aligned case + if (l > rad/2) + { + float3 up = float3(0,0,1); + float3 right = normalize(cross(up, v2p)); + float tmpx=right.x*sc_yaw.x+right.y*sc_yaw.y; + right.y = right.y*sc_yaw.x-right.x*sc_yaw.y; + right.x=tmpx; + + worldPos += (x1*rad)*right; + worldPos.z += (y1*rad)*up.z; + +#ifndef SHADER_MODEL_VS_1_1 + if (l < rad*2 ) + { + tint *= smoothstep(rad/2,rad,l); + } +#endif + + } + projPos = mul( float4(worldPos, 1.0f), cViewProj ); +#endif + +#if ORIENTATION == 2 + // aligned with z plane case - easy + float3 wpos=v.vPos+RADIUS*float3( y1,x1,0); + projPos = mul( float4(wpos, 1.0f), cModelViewProj ); +#endif + + o.blendfactor0 = float4( v.vParms.x, 0, 0, 0 ); + o.projPos = projPos; + o.texCoord0.x = lerp( v.vTexCoord0.z, v.vTexCoord0.x, v.vCornerID.x ); + o.texCoord0.y = lerp( v.vTexCoord0.w, v.vTexCoord0.y, v.vCornerID.y ); + o.texCoord1.x = lerp( v.vTexCoord1.z, v.vTexCoord1.x, v.vCornerID.x ); + o.texCoord1.y = lerp( v.vTexCoord1.w, v.vTexCoord1.y, v.vCornerID.y ); + o.texCoord2.x = lerp( v.vTexCoord2.z, v.vTexCoord2.x, v.vCornerID.x ); + o.texCoord2.y = lerp( v.vTexCoord2.w, v.vTexCoord2.y, v.vCornerID.y ); + +#if ( DUALSEQUENCE ) + float2 lerpold = v.vCornerID.xy; + float2 lerpnew = v.vCornerID.xy; + +#if ( ZOOM_ANIMATE_SEQ2 ) + lerpold.x = getlerpscale_for_old_frame( v.vCornerID.x, v.vParms1.x ); + lerpold.y = getlerpscale_for_old_frame( v.vCornerID.y, v.vParms1.x ); + lerpnew.x = getlerpscale_for_new_frame( v.vCornerID.x, v.vParms1.x ); + lerpnew.y = getlerpscale_for_new_frame( v.vCornerID.y, v.vParms1.x ); +#endif + + o.vSeq2TexCoord0.xy = lerp( v.vSeq2TexCoord0.zw, v.vSeq2TexCoord0.xy, lerpold.xy ); + o.vSeq2TexCoord1.xy = lerp( v.vSeq2TexCoord1.zw, v.vSeq2TexCoord1.xy, lerpnew.xy ); + + o.blendfactor0.z = v.vParms1.x; +#endif + + +#if !defined( SHADER_MODEL_VS_1_1 ) + + o.blendfactor1 = float4( 0.0f, 0.0f, 0.0f, 0.0f ); + +#if ( EXTRACTGREENALPHA ) + // Input range Output range + if ( v.vParms.x < 0.25f ) // 0.0 .. 0.25 + { + o.blendfactor0.a = v.vParms.x * 2 + 0.5f; // 0.5 .. 1.0 + o.blendfactor0.g = 1 - o.blendfactor0.a; // 0.5 .. 0.0 + } + else if ( v.vParms.x < 0.75f ) // 0.25 .. 0.75 + { + o.blendfactor1.g = v.vParms.x * 2 - 0.5f; // 0.0 .. 1.0 + o.blendfactor0.a = 1 - o.blendfactor1.g; // 1.0 .. 0.0 + } + else // 0.75 .. 1.0 + { + o.blendfactor1.a = v.vParms.x * 2 - 1.5f; // 0.0 .. 0.5 + o.blendfactor1.g = 1 - o.blendfactor1.a; // 1.0 .. 0.5 + } +#endif + +#endif + + // Map projected position to the refraction texture + float2 vScreenPos; + vScreenPos.x = projPos.x; + vScreenPos.y = -projPos.y; // invert Y + vScreenPos = (vScreenPos + projPos.w) * 0.5f; + + // Need to also account for the viewport transform, which matters when rendering with mat_viewportscale != 1.0 + vScreenPos = (vScreenPos * ViewportTransformScaled.xy) + (projPos.w * ViewportTransformScaled.zw); + +#if defined( _X360 ) + o.vScreenPos_ReverseZ = float4(vScreenPos.x, vScreenPos.y, projPos.w - projPos.z, projPos.w ); +#else + o.vScreenPos = float4(vScreenPos.x, vScreenPos.y, projPos.z, projPos.w ); +#endif + + o.argbcolor = tint; + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/teeth.cpp b/mp/src/materialsystem/stdshaders/teeth.cpp new file mode 100644 index 00000000..a3168822 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/teeth.cpp @@ -0,0 +1,578 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "BaseVSShader.h" +#include "cpp_shader_constant_register_map.h" + +#include "teeth_vs20.inc" +#include "teeth_flashlight_vs20.inc" +#include "teeth_bump_vs20.inc" +#include "teeth_ps20.inc" +#include "teeth_ps20b.inc" +#include "teeth_flashlight_ps20.inc" +#include "teeth_flashlight_ps20b.inc" +#include "teeth_bump_ps20.inc" +#include "teeth_bump_ps20b.inc" + +#ifndef _X360 +#include "teeth_vs30.inc" +#include "teeth_ps30.inc" +#include "teeth_bump_vs30.inc" +#include "teeth_bump_ps30.inc" +#include "teeth_flashlight_vs30.inc" +#include "teeth_flashlight_ps30.inc" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX9 ) + +extern ConVar r_flashlight_version2; +BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" ) + SHADER_PARAM( FORWARD, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Forward direction vector for teeth lighting" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "100", "phong exponent" ) + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is teeth in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[INTRO]->IsDefined() ) + { + params[INTRO]->SetIntValue( 0 ); + } + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pConfig->bSoftwareLighting ) + { + return "Teeth_dx8"; + } + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + + if( params[BUMPMAP]->IsDefined() ) + { + LoadTexture( BUMPMAP ); + } + } + + void DrawUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, VertexCompressionType_t vertexCompression ) + { + bool hasBump = params[BUMPMAP]->IsTexture(); + + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base map + + int flags = VERTEX_POSITION | VERTEX_NORMAL; + int nTexCoordCount = 1; + int userDataSize = 0; + + if ( hasBump ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Bump map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Normalization sampler for per-pixel lighting + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, false ); + userDataSize = 4; // tangent S + } + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + if ( hasBump ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( teeth_bump_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( teeth_bump_vs20 ); + + // ps_2_b version which does phong + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps20b ); + SET_STATIC_PIXEL_SHADER( teeth_bump_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps20 ); + SET_STATIC_PIXEL_SHADER( teeth_bump_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( teeth_bump_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( teeth_bump_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps30 ); + SET_STATIC_PIXEL_SHADER( teeth_bump_ps30 ); + } +#endif + } + else + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( teeth_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( teeth_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( teeth_ps20b ); + SET_STATIC_PIXEL_SHADER( teeth_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( teeth_ps20 ); + SET_STATIC_PIXEL_SHADER( teeth_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( teeth_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( teeth_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( teeth_ps30 ); + SET_STATIC_PIXEL_SHADER( teeth_ps30 ); + } +#endif + } + + // On DX9, do sRGB + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBWrite( true ); + + FogToFogColor(); + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + if ( hasBump ) + { + BindTexture( SHADER_SAMPLER1, BUMPMAP ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE ); + pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); + + Vector4D lighting; + params[FORWARD]->GetVecValue( lighting.Base(), 3 ); + lighting[3] = params[ILLUMFACTOR]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() ); + + LightState_t lightState; + pShaderAPI->GetDX9LightState( &lightState ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + if ( hasBump ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 ); + + // ps_2_b version which does Phong + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + Vector4D vSpecExponent; + vSpecExponent[3] = params[PHONGEXPONENT]->GetFloatValue(); + + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vSpecExponent.Base(), 1 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20 ); + } + } +#ifndef _X360 + else + { + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 ); + + Vector4D vSpecExponent; + vSpecExponent[3] = params[PHONGEXPONENT]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vSpecExponent.Base(), 1 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps30 ); + } +#endif + } + else + { + // For non-bumped case, ambient cube is computed in the vertex shader + SetAmbientCubeDynamicStateVertexShader(); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( teeth_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_ps20 ); + } + } +#ifndef _X360 + else + { + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( teeth_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_ps30 ); + } +#endif + } + + if( params[INTRO]->GetIntValue() ) + { + float curTime = params[WARPPARAM]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + Assert( params[ENTITYORIGIN]->IsDefined() ); + params[ENTITYORIGIN]->GetVecValue( timeVec, 3 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, timeVec, 1 ); + } + } + Draw(); + } + + void DrawFlashlight( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, VertexCompressionType_t vertexCompression ) + { + SHADOW_STATE + { + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Flashlight spot + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + + // Additive blend the teeth, lit by the flashlight + s_pShaderShadow->EnableAlphaTest( false ); + s_pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + s_pShaderShadow->EnableBlending( true ); + + // Set stream format (note that this shader supports compression) + int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + int nShadowFilterMode = 0; + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER2 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // shadow noise + + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_STATIC_VERTEX_SHADER( teeth_flashlight_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( teeth_flashlight_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps20 ); + SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps30 ); + } +#endif + // On DX9, do sRGB + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBWrite( true ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + // State for spotlight projection, attenuation etc + SetFlashlightVertexShaderConstants( false, -1, false, -1, true ); + + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + bool bFlashlightShadows = g_pHardwareConfig->SupportsPixelShaders_2_b() ? state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) : false; + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + BindTexture( SHADER_SAMPLER2, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_SHADOW_NOISE_2D ); + } + + Vector4D lighting; + params[FORWARD]->GetVecValue( lighting.Base(), 3 ); + lighting[3] = params[ILLUMFACTOR]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, lighting.Base() ); + + float atten[4], pos[4], tweaks[4]; + + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + BindTexture( SHADER_SAMPLER1, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // steps on rim boost + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + + float vFlashlightPos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vFlashlightPos ); + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vFlashlightPos, 1 ); + + if ( IsX360() ) + { + pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20 ); + } + } +#ifndef _X360 + else + { + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps30 ); + } +#endif + + if( params[INTRO]->GetIntValue() ) + { + float curTime = params[WARPPARAM]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + Assert( params[ENTITYORIGIN]->IsDefined() ); + params[ENTITYORIGIN]->GetVecValue( timeVec, 3 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, timeVec, 1 ); + } + } + Draw(); + } + + SHADER_DRAW + { + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + bool hasFlashlight = UsingFlashlight( params ); + if ( !hasFlashlight || ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + DrawUsingVertexShader( params, pShaderAPI, pShaderShadow, vertexCompression ); + SHADOW_STATE + { + SetInitialShadowState(); + } + } + if( hasFlashlight ) + { + DrawFlashlight( params, pShaderAPI, pShaderShadow, vertexCompression ); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/teeth_bump_ps2x.fxc b/mp/src/materialsystem/stdshaders/teeth_bump_ps2x.fxc new file mode 100644 index 00000000..72e43a10 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/teeth_bump_ps2x.fxc @@ -0,0 +1,101 @@ +//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "shader_constant_register_map.h" + +const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total + +sampler BaseTextureSampler : register( s0 ); +sampler BumpTextureSampler : register( s1 ); +sampler NormalizeSampler : register( s2 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float4 worldVertToEyeVector_Darkening : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + // second row : TEXCOORD3; + // third row : TEXCOORD4; + float4 worldPos_projPosZ : TEXCOORD5; + float2 lightAtten01 : TEXCOORD6; + float2 lightAtten23 : TEXCOORD7; +}; + + + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + +#define worldVertToEyeVector i.worldVertToEyeVector_Darkening.xyz +#define fDarkening i.worldVertToEyeVector_Darkening.w + +#endif + + + +float4 main( PS_INPUT i ) : COLOR +{ + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + int nNumLights = NUM_LIGHTS; + + float4 vLightAtten = float4( i.lightAtten01, i.lightAtten23 ); + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + + float3 worldSpaceNormal, tangentSpaceNormal = float3(0, 0, 1); + float fSpecExp = g_EyePos_SpecExponent.w; + + float4 normalTexel = tex2D( BumpTextureSampler, i.baseTexCoord ); + tangentSpaceNormal = 2.0f * normalTexel.xyz - 1.0f; + worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) ); + + // If the exponent passed in as a constant is zero, use the value from the map as the exponent + if ( fSpecExp == 0 ) + fSpecExp = 1.0f * ( 1.0f - normalTexel.w ) + 150.0f * normalTexel.w; + + // Summation of diffuse illumination from all local lights + float3 diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, + bAmbientLight, vLightAtten, + cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, true, + false, 0, false, NormalizeSampler ); + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + + float3 vDummy, specularLighting; + + // Summation of specular from all local lights + PixelShaderDoSpecularLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, fSpecExp, normalize(worldVertToEyeVector), + vLightAtten, nNumLights, cLightInfo, + false, 1.0f, false, NormalizeSampler, 1.0f, false, 1.0f, + + // Outputs + specularLighting, vDummy ); + + // Specular plus diffuse, all darkened as a function of mouth openness + float3 result = (specularLighting * baseSample.a + baseSample.rgb * diffuseLighting) * fDarkening; + +#else + float3 result = baseSample.rgb * diffuseLighting * i.worldVertToEyeVector_Darkening.w; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( float4(result, 1.0f), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/mp/src/materialsystem/stdshaders/teeth_bump_vs20.fxc b/mp/src/materialsystem/stdshaders/teeth_bump_vs20.fxc new file mode 100644 index 00000000..1dd834b5 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/teeth_bump_vs20.fxc @@ -0,0 +1,152 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== + +// STATIC: "INTRO" "0..1" +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "vortwarp_vs20_helper.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_0 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_1 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float2 vTexCoord0 : TEXCOORD0; + float4 vUserData : TANGENT; // Sign for cross product in w + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 baseTexCoord : TEXCOORD0; + float4 worldVertToEyeVector_Darkening : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + // second row : TEXCOORD3; + // third row : TEXCOORD4; + float4 worldPos_projPosZ : TEXCOORD5; + float2 lightAtten01 : TEXCOORD6; + float2 lightAtten23 : TEXCOORD7; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), + vPosition.xyz, vNormal, vTangent.xyz ); +#endif + + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, worldPos, + worldNormal, worldTangentS, worldTangentT ); + +#if INTRO + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, worldTangentS, worldTangentT ); +#endif + + // Always normalize since flex path is controlled by runtime + // constant not a shader combo and will always generate the normalization + worldNormal = normalize( worldNormal ); + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, vProjPos, g_FogType ); +#endif + // Needed for specular + o.worldVertToEyeVector_Darkening.xyz = cEyePos - worldPos; + + // Special darkening of lights for mouth open/close + o.worldVertToEyeVector_Darkening.w = cTeethLighting.w * saturate( dot( worldNormal, cTeethLighting.xyz ) );; + + // Scalar light attenuation (mouth darkening applied in pixel shader) +#if defined( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) + o.lightAtten01.xy = float2(0,0); + o.lightAtten23.xy = float2(0,0); + #if ( NUM_LIGHTS > 0 ) + o.lightAtten01.x = GetVertexAttenForLight( worldPos, 0, false ); + #endif + #if ( NUM_LIGHTS > 1 ) + o.lightAtten01.y = GetVertexAttenForLight( worldPos, 1, false ); + #endif + #if ( NUM_LIGHTS > 2 ) + o.lightAtten23.x = GetVertexAttenForLight( worldPos, 2, false ); + #endif + #if ( NUM_LIGHTS > 3 ) + o.lightAtten23.y = GetVertexAttenForLight( worldPos, 3, false ); + #endif +#else + o.lightAtten01.x = GetVertexAttenForLight( worldPos, 0, true ); + o.lightAtten01.y = GetVertexAttenForLight( worldPos, 1, true ); + o.lightAtten23.x = GetVertexAttenForLight( worldPos, 2, true ); + o.lightAtten23.y = GetVertexAttenForLight( worldPos, 3, true ); +#endif + + o.baseTexCoord = v.vTexCoord0; + + // Tangent space transform + o.tangentSpaceTranspose[0] = float3( worldTangentS.x, worldTangentT.x, worldNormal.x ); + o.tangentSpaceTranspose[1] = float3( worldTangentS.y, worldTangentT.y, worldNormal.y ); + o.tangentSpaceTranspose[2] = float3( worldTangentS.z, worldTangentT.z, worldNormal.z ); + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/teeth_dx6.cpp b/mp/src/materialsystem/stdshaders/teeth_dx6.cpp new file mode 100644 index 00000000..8c097f6a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/teeth_dx6.cpp @@ -0,0 +1,69 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "BaseVSShader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX6 ) + +BEGIN_VS_SHADER( Teeth_DX6, + "Help for Teeth_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" ) + SHADER_PARAM( FORWARD, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Forward direction vector for teeth lighting" ) + 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 ); + } + + void DrawUsingSoftwareLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + 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(); + } + + SHADER_DRAW + { + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + bool hasFlashlight = UsingFlashlight( params ); + + if( hasFlashlight ) + { + DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + } + else + { + DrawUsingSoftwareLighting( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/teeth_dx8.cpp b/mp/src/materialsystem/stdshaders/teeth_dx8.cpp new file mode 100644 index 00000000..d91626d8 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/teeth_dx8.cpp @@ -0,0 +1,116 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "BaseVSShader.h" + +#include "teeth.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX8 ) + +BEGIN_VS_SHADER( Teeth_DX8, "Help for Teeth_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" ) + SHADER_PARAM( FORWARD, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Forward direction vector for teeth lighting" ) + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is teeth in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[INTRO]->IsDefined() ) + { + params[INTRO]->SetIntValue( 0 ); + } + } + + SHADER_FALLBACK + { + if ( IsPC() && ( g_pHardwareConfig->GetDXSupportLevel() < 80 || g_pConfig->bSoftwareLighting ) ) + { + return "Teeth_dx6"; + } + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + LoadTexture( BASETEXTURE ); + } + + void DrawUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_NORMAL, 1, 0, 0 ); + teeth_Static_Index vshIndex; + vshIndex.SetHALF_LAMBERT( IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + vshIndex.SetINTRO( params[INTRO]->GetIntValue() != 0 ); + pShaderShadow->SetVertexShader( "Teeth", vshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( "VertexLitTexture_Overbright2" ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetAmbientCubeDynamicStateVertexShader(); + + Vector4D lighting; + params[FORWARD]->GetVecValue( lighting.Base(), 3 ); + lighting[3] = params[ILLUMFACTOR]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() ); + + teeth_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetLIGHT_COMBO( pShaderAPI->GetCurrentLightCombo() ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if( params[INTRO]->GetIntValue() ) + { + float curTime = params[WARPPARAM]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + Assert( params[ENTITYORIGIN]->IsDefined() ); + params[ENTITYORIGIN]->GetVecValue( timeVec, 3 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, timeVec, 1 ); + } + } + Draw(); + } + + SHADER_DRAW + { + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + bool hasFlashlight = UsingFlashlight( params ); + if( hasFlashlight ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, false, -1, -1, -1, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, false, false, 0, -1, -1, + // Optional parameters, specific to teeth: + true, FORWARD, ILLUMFACTOR ); + } + else + { + DrawUsingVertexShader( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc b/mp/src/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc new file mode 100644 index 00000000..7ef61872 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc @@ -0,0 +1,66 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); +sampler SpotSampler : register( s1 ); +sampler FlashlightDepthSampler : register( s2 ); +sampler RandomRotationSampler : register( s3 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float3 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float3 g_FlashlightPos : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); +const float4 g_FlashlightAtten : register( PSREG_FLASHLIGHT_ATTENUATION ); +const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); +const float4 g_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; // Base texture coordinates + float4 spotTexCoord : TEXCOORD1; // Spotlight texture coordinates + float3 vertAtten : TEXCOORD2; // Distance/spot attenuation + float4 projPos : TEXCOORD3; // Projective space position + float3 worldPos : TEXCOORD4; // Necessary for pixel fog +}; + +float4 main( PS_INPUT i ) : COLOR +{ +#if defined( SHADER_MODEL_PS_2_0 ) + float3 result = tex2Dproj( SpotSampler, i.spotTexCoord.xyzw ); +#else + float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; + float3 result = tex2D( SpotSampler, vProjCoords ); +#endif + + result *= cFlashlightColor.rgb; + +#if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) ) + result *= DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_ShadowTweaks, true ); +#endif + result *= 0.35f; // Without this, unshadowed teeth always seem to glow + + result *= i.vertAtten; // Distance atten, NdotL and forward vector + + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + result *= baseSample.rgb; // Multiply by base map and diffuse + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos.z, i.projPos.z ); + return FinalOutput( float4( result, baseSample.a ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} + diff --git a/mp/src/materialsystem/stdshaders/teeth_flashlight_vs20.fxc b/mp/src/materialsystem/stdshaders/teeth_flashlight_vs20.fxc new file mode 100644 index 00000000..8c5ce4c5 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/teeth_flashlight_vs20.fxc @@ -0,0 +1,149 @@ +//======= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "INTRO" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] + +#include "vortwarp_vs20_helper.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cFlashlightPosition : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cSpotlightProj1 : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cSpotlightProj2 : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cSpotlightProj3 : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cSpotlightProj4 : register( SHADER_SPECIFIC_CONST_4 ); +const float4 cFlashlighAtten : register( SHADER_SPECIFIC_CONST_5 ); // const, linear, quadratic & farZ + +const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_8 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_9 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float2 vTexCoord0 : TEXCOORD0; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 baseTexCoord : TEXCOORD0; // Base texture coordinates + float4 spotTexCoord : TEXCOORD1; // Spotlight texture coordinates + float3 vertAtten : TEXCOORD2; // Distance/spot attenuation + float4 vProjPos : TEXCOORD3; // Projective space position + float3 worldPos : TEXCOORD4; // Necessary for pixel fog +}; + + +float RemapValClamped_01( float val, float A, float B ) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + return cVal; +} + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + DecompressVertex_Normal( v.vNormal, vNormal ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); +#endif + + // Normalize the flexed normal + vNormal.xyz = normalize( vNormal.xyz ); + + // Transform the position + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, vPosition, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + +#if INTRO + float3 dummy = float3( 0.0f, 0.0f, 0.0f ); + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, dummy, dummy ); +#endif + + // Transform into projection space + o.projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.worldPos = worldPos.xyz; + o.vProjPos = o.projPos; +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, o.projPos, g_FogType ); +#endif + // Spotlight texture coordinates + o.spotTexCoord.x = dot( cSpotlightProj1, float4(worldPos, 1) ); + o.spotTexCoord.y = dot( cSpotlightProj2, float4(worldPos, 1) ); + o.spotTexCoord.z = dot( cSpotlightProj3, float4(worldPos, 1) ); + o.spotTexCoord.w = dot( cSpotlightProj4, float4(worldPos, 1) ); + + // Compute vector to light + float3 vWorldPosToLightVector = cFlashlightPosition.xyz - worldPos; + + float3 vDistAtten = float3(1, 1, 1); + vDistAtten.z = dot( vWorldPosToLightVector, vWorldPosToLightVector ); + vDistAtten.y = rsqrt( vDistAtten.z ); + + float flDist = vDistAtten.z * vDistAtten.y; // Distance to light + vDistAtten.z = 1.0f / vDistAtten.z; // 1 / distsquared + + float fFarZ = cFlashlighAtten.w; + + float NdotL = saturate( dot( worldNormal, normalize( vWorldPosToLightVector ) ) ); + + float endFalloffFactor = RemapValClamped_01( flDist, fFarZ, 0.6 * fFarZ ); + o.vertAtten.xyz = endFalloffFactor * dot( vDistAtten, cFlashlighAtten.xyz ); + + // Final attenuation from flashlight only... + float linearAtten = NdotL * dot( vDistAtten, cFlashlighAtten.xyz ) * endFalloffFactor; + + // Forward vector + float3 vForward = cTeethLighting.xyz; + float fIllumFactor = cTeethLighting.w; + + // Modulate flashlight by mouth darkening + o.vertAtten = linearAtten * fIllumFactor * saturate( dot( worldNormal, vForward ) ); + + o.baseTexCoord = v.vTexCoord0; + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/teeth_ps2x.fxc b/mp/src/materialsystem/stdshaders/teeth_ps2x.fxc new file mode 100644 index 00000000..4893f9aa --- /dev/null +++ b/mp/src/materialsystem/stdshaders/teeth_ps2x.fxc @@ -0,0 +1,48 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] + + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float3 vertAtten : TEXCOORD1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + + float4 result; + result.xyz = baseSample.xyz * i.vertAtten; + result.a = baseSample.a; + + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/mp/src/materialsystem/stdshaders/teeth_vs20.fxc b/mp/src/materialsystem/stdshaders/teeth_vs20.fxc new file mode 100644 index 00000000..9a9ab045 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/teeth_vs20.fxc @@ -0,0 +1,127 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== + +// STATIC: "INTRO" "0..1" +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "vortwarp_vs20_helper.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_0 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_1 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float2 vTexCoord0 : TEXCOORD0; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 baseTexCoord : TEXCOORD0; + float3 vertAtten : TEXCOORD1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + + float4 vPosition = v.vPos; + float3 vNormal; + DecompressVertex_Normal( v.vNormal, vNormal ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); +#endif + + // Normalize the flexed normal + vNormal.xyz = normalize( vNormal.xyz ); + + // Transform the position + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, vPosition, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + +#if INTRO + float3 dummy = float3( 0.0f, 0.0f, 0.0f ); + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, dummy, dummy ); +#endif + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, vProjPos, g_FogType ); +#endif + + // Compute lighting +#if ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) + float3 linearColor = DoLighting( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, false ); +#else + float3 linearColor = DoLightingUnrolled( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, false, NUM_LIGHTS ); +#endif + + // Forward vector + float3 vForward = cTeethLighting.xyz; + float fIllumFactor = cTeethLighting.w; + + // Darken by forward dot normal and illumination factor + linearColor *= fIllumFactor * saturate( dot( worldNormal, vForward ) ); + + o.vertAtten = linearColor; + o.baseTexCoord = v.vTexCoord0; + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh b/mp/src/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh new file mode 100644 index 00000000..8f9139df --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh @@ -0,0 +1,24 @@ +ps.1.1 +def c0,0,0,0,.1 +def c1,0,0,0,.1 +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; tc3 - detail texcoords +; +; c3 = outline color +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t3 ; detail mask + +mul r1,t0,t3 ; multiply + +mov r0.rgb, c3 ; color = outline color +;add r0.a, r1.a, c0.a +;cnd r0.rgb, r0.a, r0, r1 ; if ( alpha+c0 > 0.5 ) color = outline, else color = base +sub r0.a, r1.a, c1.a +cnd r0.rgb, r0.a, r1, r0 ; if ( alpha -c1 > 0.5) color=base diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_dx6.cpp b/mp/src/materialsystem/stdshaders/unlitgeneric_dx6.cpp new file mode 100644 index 00000000..fc8bdf47 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_dx6.cpp @@ -0,0 +1,310 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( UnlitGeneric, UnlitGeneric_DX6 ) +DEFINE_FALLBACK_SHADER( MonitorScreen, UnlitGeneric_DX6 ) +DEFINE_FALLBACK_SHADER( ParticleSphere, UnlitGeneric_DX6 ) +DEFINE_FALLBACK_SHADER( Predator, Predator_DX60 ) +DEFINE_FALLBACK_SHADER( Predator_DX60, UnlitGeneric_DX6 ) +DEFINE_FALLBACK_SHADER( WindowImposter, WindowImposter_DX60 ) +DEFINE_FALLBACK_SHADER( WindowImposter_DX60, UnlitGeneric_DX6 ) + +BEGIN_SHADER( UnlitGeneric_DX6, + "Help for UnlitGeneric_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + // No texture means no env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + // the second texture (if there is one) + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + LoadCubeMap( ENVMAP ); + else + LoadTexture( ENVMAP ); + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE); + + if (params[ENVMAPMASK]->IsDefined()) + { + LoadTexture( ENVMAPMASK ); + } + } + } + + int GetDrawFlagsPass1(IMaterialVar** params, bool doDetail) + { + int flags = SHADER_DRAW_POSITION; + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + flags |= SHADER_DRAW_COLOR; + if (params[BASETEXTURE]->IsTexture()) + flags |= SHADER_DRAW_TEXCOORD0; + if (doDetail) + flags |= SHADER_DRAW_TEXCOORD1; + return flags; + } + + void SetDetailShadowState(IShaderShadow* pShaderShadow) + { + // Specifically choose overbright2, will cause mod2x here + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 2.0f ); + } + + void SetDetailDymamicState(IShaderShadow* pShaderShadow) + { + BindTexture( SHADER_SAMPLER1, DETAIL, FRAME ); + SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, BASETEXTURETRANSFORM, DETAILSCALE ); + } + + void DrawAdditiveNonTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) + { + SHADOW_STATE + { + SetModulationShadowState(); + SetAdditiveBlendingShadowState( ); + if (doDetail) + SetDetailShadowState(pShaderShadow); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); + FogToBlack(); + } + DYNAMIC_STATE + { + SetModulationDynamicState(); + if (doDetail) + SetDetailDymamicState(pShaderShadow); + } + Draw( ); + } + + void DrawAdditiveTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + SetModulationShadowState(); + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + if (doDetail) + SetDetailShadowState(pShaderShadow); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); + FogToBlack(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + if (doDetail) + SetDetailDymamicState(pShaderShadow); + SetModulationDynamicState(); + } + Draw( ); + } + + void DrawNonTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) + { + SHADOW_STATE + { + SetModulationShadowState(); + SetNormalBlendingShadowState( ); + if (doDetail) + SetDetailShadowState(pShaderShadow); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); + FogToFogColor(); + } + DYNAMIC_STATE + { + SetModulationDynamicState(); + if (doDetail) + SetDetailDymamicState(pShaderShadow); + } + Draw( ); + } + + void DrawTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + SetModulationShadowState(); + SetNormalBlendingShadowState( BASETEXTURE, true ); + if (doDetail) + SetDetailShadowState(pShaderShadow); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + if (doDetail) + SetDetailDymamicState(pShaderShadow); + SetModulationDynamicState(); + } + Draw( ); + } + + SHADER_DRAW + { + bool isTextureDefined = params[BASETEXTURE]->IsTexture(); + bool hasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); + bool doFirstPass = isTextureDefined || hasVertexColor || (!params[ENVMAP]->IsTexture()); + + if (doFirstPass) + { + SHADOW_STATE + { + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + if( params[ALPHATESTREFERENCE]->IsDefined() && params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); + } + } + + if (IS_FLAG_SET(MATERIAL_VAR_ADDITIVE)) + { + if (!isTextureDefined) + { + bool hasDetailTexture = params[DETAIL]->IsTexture(); + DrawAdditiveNonTextured( params, pShaderAPI, pShaderShadow, hasDetailTexture ); + } + else + { + // We can't do detail in a single pass if we're also + // colormodulating and have vertex color + bool hasDetailTexture = params[DETAIL]->IsTexture(); + bool isModulating = IsColorModulating() || IsAlphaModulating(); + bool onePassDetail = hasDetailTexture && (!hasVertexColor || !isModulating); + DrawAdditiveTextured( params, pShaderAPI, pShaderShadow, onePassDetail ); + if (hasDetailTexture && !onePassDetail) + { + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + } + } + else + { + if (!isTextureDefined) + { + bool hasDetailTexture = params[DETAIL]->IsTexture(); + DrawNonTextured( params, pShaderAPI, pShaderShadow, hasDetailTexture ); + } + else + { + // We can't do detail in a single pass if we're also + // colormodulating and have vertex color + bool hasDetailTexture = params[DETAIL]->IsTexture(); + bool isModulating = IsColorModulating() || IsAlphaModulating(); + bool onePassDetail = hasDetailTexture && (!hasVertexColor || !isModulating); + DrawTextured( params, pShaderAPI, pShaderShadow, onePassDetail ); + if (hasDetailTexture && !onePassDetail) + { + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + } + } + } + + SHADOW_STATE + { + // Disable mod2x used by detail + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); + } + + // Second pass... + if (params[ENVMAP]->IsTexture() && + (!doFirstPass || IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) ) + { + if (doFirstPass || IS_FLAG_SET(MATERIAL_VAR_ADDITIVE)) + { + FixedFunctionAdditiveMaskedEnvmapPass( ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + else + { + FixedFunctionMaskedEnvmapPass( ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_dx8.cpp b/mp/src/materialsystem/stdshaders/unlitgeneric_dx8.cpp new file mode 100644 index 00000000..19d0e169 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_dx8.cpp @@ -0,0 +1,72 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( UnlitGeneric, UnlitGeneric_DX8 ) + +BEGIN_VS_SHADER( UnlitGeneric_DX8, + "Help for UnlitGeneric_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) + SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") + SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) + SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") + SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") + SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") + SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && !g_pHardwareConfig->SupportsVertexAndPixelShaders()) + { + return "UnlitGeneric_DX6"; + } + return 0; + } + + SHADER_INIT_PARAMS() + { + InitParamsUnlitGeneric_DX8( + BASETEXTURE, DETAILSCALE, ENVMAPOPTIONAL, + ENVMAP, ENVMAPTINT, ENVMAPMASKSCALE, + DETAILBLENDMODE ); + } + + SHADER_INIT + { + InitUnlitGeneric_DX8( BASETEXTURE, DETAIL, ENVMAP, ENVMAPMASK ); + } + + SHADER_DRAW + { + VertexShaderUnlitGenericPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, + DETAIL, DETAILSCALE, true, ENVMAP, ENVMAPFRAME, ENVMAPMASK, + ENVMAPMASKFRAME, ENVMAPMASKSCALE, ENVMAPTINT, ALPHATESTREFERENCE, + DETAILBLENDMODE, + OUTLINE, OUTLINECOLOR, OUTLINESTART0, OUTLINEEND1, SEPARATEDETAILUVS ); + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_dx9.cpp b/mp/src/materialsystem/stdshaders/unlitgeneric_dx9.cpp new file mode 100644 index 00000000..b57474a8 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_dx9.cpp @@ -0,0 +1,200 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx9_helper.h" + +extern ConVar r_flashlight_version2; + +BEGIN_VS_SHADER( UnlitGeneric, "Help for UnlitGeneric" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "envmap frame number" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) + SHADER_PARAM( VERTEXALPHATEST, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) + SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) + SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) + SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "2D map for warping specular" ) + SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) + SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) + SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) + SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$detail texcoord transform" ) + + SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) + + SHADER_PARAM( DISTANCEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use distance-coded alpha generated from hi-res texture by vtex.") + SHADER_PARAM( DISTANCEALPHAFROMDETAIL, SHADER_PARAM_TYPE_BOOL, "0", "Take the distance-coded alpha mask from the detail texture.") + + SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.") + SHADER_PARAM( SCALEEDGESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft edges based upon resolution. 1024x768 = nominal.") + SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha."); + SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha."); + + SHADER_PARAM( GLOW, SHADER_PARAM_TYPE_BOOL, "0", "Enable glow/shadow for distance coded textures.") + SHADER_PARAM( GLOWCOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outter glow for distance coded line art." ) + SHADER_PARAM( GLOWALPHA, SHADER_PARAM_TYPE_FLOAT, "1", "Base glow alpha amount for glows/shadows with distance alpha." ) + SHADER_PARAM( GLOWSTART, SHADER_PARAM_TYPE_FLOAT, "0.7", "start value for glow/shadow") + SHADER_PARAM( GLOWEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "end value for glow/shadow") + SHADER_PARAM( GLOWX, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset x for glow mask.") + SHADER_PARAM( GLOWY, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset y for glow mask.") + + SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") + SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) + SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline") + SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") + SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") + SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") + SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") + SHADER_PARAM( SCALEOUTLINESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft part of the outline based upon resolution. 1024x768 = nominal.") + + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) + + SHADER_PARAM( GAMMACOLORREAD, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of color texture read." ) + SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) + + SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" ) + SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) + SHADER_PARAM( RECEIVEFLASHLIGHT, SHADER_PARAM_TYPE_INTEGER, "0", "Forces this material to receive flashlights." ) + + END_SHADER_PARAMS + + void SetupVars( VertexLitGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = -1; + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTextureTransform = DETAILTEXTURETRANSFORM; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = -1; + info.m_nBumpFrame = -1; + info.m_nBumpTransform = -1; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nVertexAlphaTest = VERTEXALPHATEST; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nHDRColorScale = HDRCOLORSCALE; + info.m_nPhongExponent = -1; + info.m_nPhongExponentTexture = -1; + info.m_nDiffuseWarpTexture = -1; + info.m_nPhongWarpTexture = -1; + info.m_nPhongBoost = -1; + info.m_nPhongFresnelRanges = -1; + info.m_nPhong = -1; + info.m_nPhongTint = -1; + info.m_nPhongAlbedoTint = -1; + info.m_nSelfIllumEnvMapMask_Alpha = -1; + info.m_nAmbientOnly = -1; + info.m_nBaseMapAlphaPhongMask = -1; + info.m_nEnvmapFresnel = -1; + info.m_nSelfIllumMask = -1; + + info.m_nDistanceAlpha = DISTANCEALPHA; + info.m_nDistanceAlphaFromDetail = DISTANCEALPHAFROMDETAIL; + info.m_nSoftEdges = SOFTEDGES; + info.m_nEdgeSoftnessStart = EDGESOFTNESSSTART; + info.m_nEdgeSoftnessEnd = EDGESOFTNESSEND; + info.m_nScaleEdgeSoftnessBasedOnScreenRes = SCALEEDGESOFTNESSBASEDONSCREENRES; + + info.m_nGlow = GLOW; + info.m_nGlowColor = GLOWCOLOR; + info.m_nGlowAlpha = GLOWALPHA; + info.m_nGlowStart = GLOWSTART; + info.m_nGlowEnd = GLOWEND; + info.m_nGlowX = GLOWX; + info.m_nGlowY = GLOWY; + + info.m_nOutline = OUTLINE; + info.m_nOutlineColor = OUTLINECOLOR; + info.m_nOutlineAlpha = OUTLINEALPHA; + info.m_nOutlineStart0 = OUTLINESTART0; + info.m_nOutlineStart1 = OUTLINESTART1; + info.m_nOutlineEnd0 = OUTLINEEND0; + info.m_nOutlineEnd1 = OUTLINEEND1; + info.m_nScaleOutlineSoftnessBasedOnScreenRes = SCALEOUTLINESOFTNESSBASEDONSCREENRES; + + info.m_nSeparateDetailUVs = SEPARATEDETAILUVS; + + info.m_nLinearWrite = LINEARWRITE; + info.m_nGammaColorRead = GAMMACOLORREAD; + + info.m_nDepthBlend = DEPTHBLEND; + info.m_nDepthBlendScale = DEPTHBLENDSCALE; + info.m_nReceiveFlashlight = RECEIVEFLASHLIGHT; + } + + SHADER_INIT_PARAMS() + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitParamsVertexLitGeneric_DX9( this, params, pMaterialName, false, vars ); + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "UnlitGeneric_DX8"; + } + return 0; + } + + SHADER_INIT + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitVertexLitGeneric_DX9( this, params, false, vars ); + } + + SHADER_DRAW + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + + bool bNewFlashlightPath = IsX360() || ( r_flashlight_version2.GetInt() != 0 ); + if ( ( pShaderShadow == NULL ) && ( pShaderAPI != NULL ) && !bNewFlashlightPath && pShaderAPI->InFlashlightMode() ) // Not snapshotting && flashlight pass + { + Draw( false ); + } + else + { + DrawVertexLitGeneric_DX9( this, params, pShaderAPI, pShaderShadow, false, vars, vertexCompression, pContextDataPtr ); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_inc.vsh b/mp/src/materialsystem/stdshaders/unlitgeneric_inc.vsh new file mode 100644 index 00000000..ac2abb7e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_inc.vsh @@ -0,0 +1,142 @@ +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform +; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform +; $SHADER_SPECIFIC_CONST_4-$SHADER_SPECIFIC_CONST_5 = Detail texture transform +;------------------------------------------------------------------------------ + +sub UnlitGeneric +{ + local( $detail ) = shift; + local( $envmap ) = shift; + local( $envmapcameraspace ) = shift; + local( $envmapsphere ) = shift; + local( $vertexcolor ) = shift; + local( $separatedetailuvs ) = shift; + + local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + + ;------------------------------------------------------------------------------ + ; Vertex blending + ;------------------------------------------------------------------------------ + &AllocateRegister( \$worldPos ); + if( $envmap ) + { + &AllocateRegister( \$worldNormal ); + &SkinPositionAndNormal( $worldPos, $worldNormal ); + } + else + { + &SkinPosition( $worldPos ); + } + + ;------------------------------------------------------------------------------ + ; Transform the position from world to proj space + ;------------------------------------------------------------------------------ + + &AllocateRegister( \$projPos ); + + dp4 $projPos.x, $worldPos, $cViewProj0 + dp4 $projPos.y, $worldPos, $cViewProj1 + dp4 $projPos.z, $worldPos, $cViewProj2 + dp4 $projPos.w, $worldPos, $cViewProj3 + mov oPos, $projPos + + ;------------------------------------------------------------------------------ + ; Fog + ;------------------------------------------------------------------------------ + &CalcFog( $worldPos, $projPos ); + &FreeRegister( \$projPos ); + + if( !$envmap ) + { + &FreeRegister( \$worldPos ); + } + + ;------------------------------------------------------------------------------ + ; Texture coordinates (use world-space normal for envmap, tex transform for mask) + ;------------------------------------------------------------------------------ + dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 + dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + if ( $g_x360 ) + { + ; must write xyzw to match read in pixelshader + mov oT0.zw, $cZero + } + + if( $envmap ) + { + if( $envmapcameraspace ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + + ; transform reflection vector into view space + dp3 oT1.x, $reflectionVector, $cViewModel0 + dp3 oT1.y, $reflectionVector, $cViewModel1 + dp3 oT1.z, $reflectionVector, $cViewModel2 + if ( $g_x360 ) + { + ; must write xyzw to match read in pixelshader + mov oT1.w, $cZero + } + + &FreeRegister( \$reflectionVector ); + } + elsif( $envmapsphere ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + &ComputeSphereMapTexCoords( $reflectionVector, "oT1" ); + + &FreeRegister( \$reflectionVector ); + } + else + { + &ComputeReflectionVector( $worldPos, $worldNormal, "oT1" ); + } + + ; envmap mask + dp4 oT2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + dp4 oT2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + if ( $g_x360 ) + { + ; must write xyzw to match read in pixelshader + mov oT2.zw, $cZero + } + + &FreeRegister( \$worldPos ); + &FreeRegister( \$worldNormal ); + } + + if( $detail ) + { + if ( $separatedetailuvs ) + { + mov oT3, $vTexCoord1 + } + else + { + dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 + dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + } + + if ( $g_x360 ) + { + ; must write xyzw to match read in pixelshader + mov oT3.zw, $cZero + } + } + + if( $vertexcolor ) + { + ; Modulation color + mul oD0, $vColor, $cModulationColor + } + else + { + ; Modulation color + mov oD0, $cModulationColor + } +} diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc b/mp/src/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc new file mode 100644 index 00000000..dcbd43a2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc @@ -0,0 +1,47 @@ +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + + float4 vDiffuse : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); + + o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + + o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + o.vDiffuse = 1.0f; + + return o; +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc b/mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc new file mode 100644 index 00000000..e3970e87 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc @@ -0,0 +1,9 @@ +struct PS_INPUT +{ + float4 vColor0 : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return i.vColor0; +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc b/mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc new file mode 100644 index 00000000..e4fffb83 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc @@ -0,0 +1,14 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float4 vColor0 : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return FinalOutput( i.vColor0, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_ps11.fxc b/mp/src/materialsystem/stdshaders/unlitgeneric_ps11.fxc new file mode 100644 index 00000000..071d666c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_ps11.fxc @@ -0,0 +1,12 @@ +sampler TextureSampler : register( s0 ); + +struct PS_INPUT +{ + float4 vColor0 : COLOR0; + float2 vTexCoord0 : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return i.vColor0 * tex2D( TextureSampler, i.vTexCoord0 ); +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_ps2x.fxc b/mp/src/materialsystem/stdshaders/unlitgeneric_ps2x.fxc new file mode 100644 index 00000000..1620638f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_ps2x.fxc @@ -0,0 +1,19 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#include "common_ps_fxc.h" + +sampler TextureSampler : register( s0 ); + +struct PS_INPUT +{ + float4 vColor0 : COLOR0; + float2 vTexCoord0 : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 result = i.vColor0 * tex2D( TextureSampler, i.vTexCoord0 ); + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_vs11.vsh b/mp/src/materialsystem/stdshaders/unlitgeneric_vs11.vsh new file mode 100644 index 00000000..b165fa7a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_vs11.vsh @@ -0,0 +1,23 @@ +vs.1.1 + +# STATIC: "DETAIL" "0..1" +# STATIC: "ENVMAP" "0..1" +# STATIC: "ENVMAPCAMERASPACE" "0..0" +# STATIC: "ENVMAPSPHERE" "0..1" +# STATIC: "VERTEXCOLOR" "0..1" +# STATIC: "SEPARATEDETAILUVS" "0..1" +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +# can't have envmapshere or envmapcameraspace without envmap +# SKIP: !$ENVMAP && ( $ENVMAPSPHERE || $ENVMAPCAMERASPACE ) + +# can't have both envmapsphere and envmapcameraspace +# SKIP: $ENVMAPSPHERE && $ENVMAPCAMERASPACE + +# SKIP: !$DETAIL && $SEPARATEDETAILUVS + + +#include "UnlitGeneric_inc.vsh" + +&UnlitGeneric( $DETAIL, $ENVMAP, $ENVMAPCAMERASPACE, $ENVMAPSPHERE, $VERTEXCOLOR, $SEPARATEDETAILUVS ); diff --git a/mp/src/materialsystem/stdshaders/unlitgeneric_vs20.fxc b/mp/src/materialsystem/stdshaders/unlitgeneric_vs20.fxc new file mode 100644 index 00000000..37249305 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/unlitgeneric_vs20.fxc @@ -0,0 +1,91 @@ +// STATIC: "VERTEXCOLOR" "0..1" +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cBaseTextureTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cMaskTextureTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cDetailTextureTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); +const float4 g_vVertexColor : register( SHADER_SPECIFIC_CONST_6 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + +#if VERTEXCOLOR + float4 vColor : COLOR0; +#endif + + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + float2 vTexCoord3 : TEXCOORD3; + + float4 vColor : COLOR0; + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + float3 worldNormal; + + //------------------------------------------------------------------------------ + // Vertex blending + //------------------------------------------------------------------------------ + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); + + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos = vProjPos; + vProjPos = dot( float4( worldPos, 1 ), cViewProjZ ); + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + //------------------------------------------------------------------------------ + // Fog + //------------------------------------------------------------------------------ + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + //------------------------------------------------------------------------------ + // Texture coord transforms + //------------------------------------------------------------------------------ + o.vTexCoord0 = mul( v.vTexCoord0, (float2x4)cBaseTextureTransform ); + o.vTexCoord3 = mul( v.vTexCoord0, (float2x4)cDetailTextureTransform ); + + o.vColor = cModulationColor; + +#if VERTEXCOLOR + // 0 or 1 for g_vVertexColor.x, eliminating a bool + o.vColor = lerp( o.vColor, o.vColor * v.vColor, g_vVertexColor.x ); +#endif + + return o; +} + + + diff --git a/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc b/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc new file mode 100644 index 00000000..7768f477 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc @@ -0,0 +1,350 @@ +//======= Copyright © 1996-2008, Valve Corporation, All rights reserved. ====== + +// STATIC: "CUBEMAP" "0..1" +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "SELFILLUMFRESNEL" "0..1" +// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..6" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] [PC] + +// We don't use light combos when doing the flashlight +// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) [PC] + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// Don't do diffuse warp on flashlight +// SKIP: ( $FLASHLIGHT == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) [PC] + +// Only warp diffuse if we have it at all +// SKIP: ( $DIFFUSELIGHTING == 0 ) && ( $LIGHTWARPTEXTURE == 1 ) + +// Skip this since it blows ps20 instruction limits +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) + +// Only need self illum fresnel when self illum enabled +// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) [PC] +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) [PC] +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 ) +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 ) + +// BlendTintByBaseAlpha is incompatible with other interpretations of alpha +// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM) + +// Only _XBOX allows flashlight and cubemap in the current implementation +// SKIP: $FLASHLIGHT && $CUBEMAP [PC] + +// Meaningless combinations +// SKIP: $NORMALMAPALPHAENVMAPMASK && !$CUBEMAP + +#include "common_flashlight_fxc.h" +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); +const float4 g_DiffuseModulation : register( c1 ); +const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); +const float3 g_EnvmapSaturation : register( c3 ); +const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); +#define g_SelfIllumTint ( g_SelfIllumTint_and_BlendFactor.rgb) +#define g_DetailBlendFactor (g_SelfIllumTint_and_BlendFactor.w) + +const float3 cAmbientCube[6] : register( c5 ); + +// 11, 12 not used? +#if ( SELFILLUMFRESNEL == 1 ) + const float4 g_SelfIllumScaleBiasExpBrightness : register( c11 ); +#endif + +const float4 g_ShaderControls : register( c12 ); +#define g_fPixelFogType g_ShaderControls.x +#define g_fWriteDepthToAlpha g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z + + +// 2 registers each - 6 registers total +PixelShaderLightInfo cLightInfo[3] : register( c13 ); // through c18 + +const float3 g_EyePos : register( c20 ); +const float4 g_FogParams : register( c21 ); + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const float3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + +sampler BaseTextureSampler : register( s0 ); +sampler EnvmapSampler : register( s1 ); +sampler DetailSampler : register( s2 ); +sampler BumpmapSampler : register( s3 ); +sampler EnvmapMaskSampler : register( s4 ); +sampler NormalizeSampler : register( s5 ); +sampler RandRotSampler : register( s6 ); // RandomRotation sampler +sampler FlashlightSampler : register( s7 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler +sampler DiffuseWarpSampler : register( s9 ); // Lighting warp sampler (1D texture for diffuse lighting modification) + +struct PS_INPUT +{ + float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; + float3 lightAtten : TEXCOORD1; + float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3 vWorldNormal : TEXCOORD3; // World-space normal + float4 vWorldTangent : TEXCOORD4; +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float4 vProjPos : TEXCOORD5; +#else + float3 vWorldBinormal : TEXCOORD5; +#endif + float4 worldPos_projPosZ : TEXCOORD6; + float3 detailTexCoord_atten3 : TEXCOORD7; + float4 fogFactorW : COLOR1; + +#if defined( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; +#endif +#endif +}; + +// Calculate both types of Fog and lerp to get result +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); + return lerp( fRangeFog, fHeightFog, fPixelFogType ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + pixelFogFactor = saturate( pixelFogFactor ); + float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + return lerp( fRangeResult, fHeightResult, fPixelFogType ); +} + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + +float4 main( PS_INPUT i ) : COLOR +{ + bool bCubemap = CUBEMAP ? true : false; + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bSelfIllumFresnel = SELFILLUMFRESNEL ? true : false; + bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; + bool bHalfLambert = HALFLAMBERT ? true : false; + bool bFlashlight = (FLASHLIGHT!=0) ? true : false; + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + int nNumLights = NUM_LIGHTS; + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float3 vWorldBinormal = cross( i.vWorldNormal.xyz, i.vWorldTangent.xyz ) * i.vWorldTangent.w; +#else + float3 vWorldBinormal = i.vWorldBinormal; +#endif + + // Unpack four light attenuations + float4 vLightAtten = float4( i.lightAtten, i.detailTexCoord_atten3.z ); + + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); + +#if DETAILTEXTURE + float4 detailColor = tex2D( DetailSampler, i.detailTexCoord_atten3.xy ); + baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + + float specularFactor = 1.0f; + float4 normalTexel = tex2D( BumpmapSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); + float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; + + if ( bNormalMapAlphaEnvmapMask ) + specularFactor = normalTexel.a; + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + + float3 worldSpaceNormal = float3( 0.0f, 0.0f, 1.0f ); + if ( bDiffuseLighting || bFlashlight || bCubemap || bSelfIllumFresnel ) + { + worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal, i.vWorldNormal, i.vWorldTangent, vWorldBinormal ); +#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + worldSpaceNormal = normalize( worldSpaceNormal ); +#else + worldSpaceNormal = NormalizeWithCubemap( NormalizeSampler, worldSpaceNormal ); +#endif + } + + if ( bDiffuseLighting ) + { + diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten, + cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, + false, 1.0f, bDoDiffuseWarp, DiffuseWarpSampler ); + } + + float3 albedo = baseColor; + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + float alpha = g_DiffuseModulation.a; + if ( !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha *= baseColor.a; + } + + +#if FLASHLIGHT + if( bFlashlight ) + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; + float2 vProjPos = float2(0, 0); +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = FLASHLIGHTSHADOWS; + vProjPos = i.vProjPos.xy / i.vProjPos.w; // Screen-space position for shadow map noise +#endif + +#if defined ( _X360 ) + float4 flashlightSpacePosition = i.flashlightSpacePos; +#else + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, nShadowSampleLevel, bDoShadows, false, vProjPos, false, g_EnvmapContrast_ShadowTweaks ); + +#if defined ( _X360 ) + diffuseLighting += flashlightColor; +#else + diffuseLighting = flashlightColor; +#endif + + } +#endif + + + float3 diffuseComponent = albedo * diffuseLighting; + + +#if !FLASHLIGHT || defined ( _X360 ) + if ( bSelfIllum ) + { + #if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file + // This will apply a fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look + #if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float3 vVertexNormal = normalize( i.vWorldNormal.xyz ); + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, normalize( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + + float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); + #else + float3 vVertexNormal = i.vWorldNormal.xyz; + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, ( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + + float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); + #endif + #else + float3 selfIllumComponent = g_SelfIllumTint * albedo; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + #endif + } +#endif + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); +#if !FLASHLIGHT || defined ( _X360 ) + if( bCubemap ) + { + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ); + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; + float3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); + float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); + } +#endif + + float3 result = diffuseComponent + specularLighting; + +#if defined(SHADER_MODEL_PS_2_0) + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); +#else + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); +#endif + +#if defined( SHADER_MODEL_PS_2_0 ) + #if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; + #endif +#else // 2b or higher + alpha = lerp( alpha, fogFactor, g_fPixelFogType * g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog +#endif + +#if defined( SHADER_MODEL_PS_2_0 ) + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.worldPos_projPosZ.w ); +#else + return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.worldPos_projPosZ.w ); +#endif + +} + diff --git a/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc b/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc new file mode 100644 index 00000000..06afd956 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc @@ -0,0 +1,198 @@ +//======= Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ====== +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "USE_WITH_2B" "0..1" +// STATIC: "DECAL" "0..1" [vs30] +// STATIC: "FLASHLIGHT" "0..1" [XBOX] +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); // 0 & 1 +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); // 4 & 5 +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +//----------------------------------------------------------------------------- +// Input vertex format +//----------------------------------------------------------------------------- +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vUserData : TANGENT; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + + +//----------------------------------------------------------------------------- +// Output vertex format +//----------------------------------------------------------------------------- +struct VS_OUTPUT +{ + // Stuff that isn't seen by the pixel shader + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + // Stuff that is seen by the pixel shader + + float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; + float3 lightAtten : TEXCOORD1; + float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3 vWorldNormal : TEXCOORD3; // World-space normal + float4 vWorldTangent : TEXCOORD4; +#if USE_WITH_2B + float4 vProjPos : TEXCOORD5; +#else + float3 vWorldBinormal : TEXCOORD5; +#endif + float4 worldPos_projPosZ : TEXCOORD6; + float3 detailTexCoord_atten3 : TEXCOORD7; + float4 fogFactorW : COLOR1; + +#if defined( _X360 ) && FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; +#endif +}; + + +//----------------------------------------------------------------------------- +// Main shader entry point +//----------------------------------------------------------------------------- +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal, vTangent.xyz ); +#endif + + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, worldPos, + worldNormal, worldTangentS, worldTangentT ); + + // Always normalize since flex path is controlled by runtime + // constant not a shader combo and will always generate the normalization + worldNormal = normalize( worldNormal ); + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + +#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + o.vWorldNormal.xyz = worldNormal.xyz; + o.vWorldTangent = float4( worldTangentS.xyz, vTangent.w ); // Propagate binormal sign in world tangent.w + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + +#if USE_WITH_2B + o.vProjPos = vProjPos; +#else + o.vWorldBinormal.xyz = worldTangentT.xyz; +#endif + + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + // Needed for water fog alpha and diffuse lighting + // FIXME: we shouldn't have to compute this all the time. + o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); + + // Needed for cubemapping + parallax mapping + // FIXME: We shouldn't have to compute this all the time. + //o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); + o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = normalize( cEyePos.xyz - worldPos.xyz ); + +#if defined( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) + o.lightAtten.xyz = float3(0,0,0); + o.detailTexCoord_atten3.z = 0.0f; + #if ( NUM_LIGHTS > 0 ) + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false ); + #endif + #if ( NUM_LIGHTS > 1 ) + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false ); + #endif + #if ( NUM_LIGHTS > 2 ) + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false ); + #endif + #if ( NUM_LIGHTS > 3 ) + o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, false ); + #endif +#else + // Scalar light attenuation + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, true ); + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, true ); + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, true ); + o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, true ); +#endif + + // Base texture coordinate transform + o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + + // Detail texture coordinate transform + o.detailTexCoord_atten3.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); + o.detailTexCoord_atten3.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); + +#if defined( _X360 ) && FLASHLIGHT + o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc b/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc new file mode 100644 index 00000000..1d1a47d0 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc @@ -0,0 +1,484 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// +// +//=============================================================================// +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..9" +// STATIC: "SEAMLESS_BASE" "0..1" +// STATIC: "SEAMLESS_DETAIL" "0..1" +// STATIC: "DISTANCEALPHA" "0..1" +// STATIC: "DISTANCEALPHAFROMDETAIL" "0..1" +// STATIC: "SOFT_MASK" "0..1" +// STATIC: "OUTLINE" "0..1" +// STATIC: "OUTER_GLOW" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "DEPTHBLEND" "0..1" [ps20b] [ps30] +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" +// STATIC: "SRGB_INPUT_ADAPTER" "0..1" [ps20b] +// STATIC: "CUBEMAP_SPHERE_LEGACY" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] +// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +// detail blend mode 6 = ps20b only +// SKIP: $DETAIL_BLEND_MODE == 6 [ps20] + +// SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 ) +// SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL ) +// SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM +// SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA +// SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK) +// SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS) [PC] +// SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW) +// SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// DISTANCEALPHA-related skips +// SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA ) +// SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW ) +// SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER ) + +// SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER +// SKIP: $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA ) + +// BlendTintByBaseAlpha is incompatible with other interpretations of alpha +// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK) + +// Only _XBOX allows flashlight and cubemap in the current implementation +// SKIP: $FLASHLIGHT && $CUBEMAP [PC] + +// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) + +#include "common_flashlight_fxc.h" +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); +const float4 g_DiffuseModulation : register( c1 ); +const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); +const float4 g_EnvmapSaturation_SelfIllumMask : register( c3 ); +const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); + +const float4 g_ShaderControls : register( c12 ); +const float4 g_DepthFeatheringConstants : register( c13 ); + +const float4 g_EyePos : register( c20 ); +const float4 g_FogParams : register( c21 ); + +#define g_SelfIllumTint g_SelfIllumTint_and_BlendFactor.xyz +#define g_DetailBlendFactor g_SelfIllumTint_and_BlendFactor.w +#define g_EnvmapSaturation g_EnvmapSaturation_SelfIllumMask.xyz +#define g_SelfIllumMaskControl g_EnvmapSaturation_SelfIllumMask.w + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const HALF3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + + +sampler BaseTextureSampler : register( s0 ); +sampler EnvmapSampler : register( s1 ); +sampler DetailSampler : register( s2 ); +sampler EnvmapMaskSampler : register( s4 ); +sampler RandRotSampler : register( s6 ); // RandomRotation sampler +sampler FlashlightSampler : register( s7 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler +sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending +sampler SelfIllumMaskSampler : register( s11 ); // selfillummask + +struct PS_INPUT +{ +#if SEAMLESS_BASE + HALF3 baseTexCoord : TEXCOORD0; // Base texture coordinate +#else + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate +#endif +#if SEAMLESS_DETAIL + HALF3 detailTexCoord : TEXCOORD1; // Seamless texture coordinate +#else + HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate +#endif + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection + float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight + +#if defined ( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD5; +#endif +#endif + + float4 projPos : TEXCOORD6; + float4 worldPos_projPosZ : TEXCOORD7; + float4 fogFactorW : COLOR1; +#if SEAMLESS_BASE || SEAMLESS_DETAIL + float3 SeamlessWeights : COLOR0; // x y z projection weights +#endif +}; + +const float4 g_GlowParameters : register( c5 ); +const float4 g_GlowColor : register( c6 ); +#define GLOW_UV_OFFSET g_GlowParameters.xy +#define OUTER_GLOW_MIN_DVALUE g_GlowParameters.z +#define OUTER_GLOW_MAX_DVALUE g_GlowParameters.w +#define OUTER_GLOW_COLOR g_GlowColor + +#define g_fPixelFogType g_ShaderControls.x +#define g_fWriteDepthToAlpha g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z +#define g_fVertexAlpha g_ShaderControls.w + + +const float4 g_DistanceAlphaParams : register( c7 ); +#define SOFT_MASK_MAX g_DistanceAlphaParams.x +#define SOFT_MASK_MIN g_DistanceAlphaParams.y + +const float4 g_OutlineColor : register( c8 ); +#define OUTLINE_COLOR g_OutlineColor + +const float4 g_OutlineParams : register( c9 ); +// these are ordered this way for optimal ps20 swizzling +#define OUTLINE_MIN_VALUE0 g_OutlineParams.x +#define OUTLINE_MAX_VALUE1 g_OutlineParams.y +#define OUTLINE_MAX_VALUE0 g_OutlineParams.z +#define OUTLINE_MIN_VALUE1 g_OutlineParams.w + +#if DETAILTEXTURE +const float3 g_DetailTint : register( c10 ); +#endif + + +// Calculate unified fog +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float flDepthBelowWater = fPixelFogType*fogParams.y - flWorldPosZ; // above water = negative, below water = positive + float flDepthBelowEye = fPixelFogType*flEyePosZ - flWorldPosZ; // above eye = negative, below eye = positive + // if fPixelFogType == 0, then flDepthBelowWater == flDepthBelowEye and frac will be 1 + float frac = (flDepthBelowEye == 0) ? 1 : saturate(flDepthBelowWater/flDepthBelowEye); + return saturate( min(fogParams.z, flProjPosZ * fogParams.w * frac - fogParams.x) ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + //float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + //float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + //return lerp( fRangeResult, fHeightResult, fPixelFogType ); + pixelFogFactor = lerp( pixelFogFactor*pixelFogFactor, pixelFogFactor, fPixelFogType ); + return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor ); +} + + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + + +#if LIGHTING_PREVIEW == 2 +LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR +#else +float4 main( PS_INPUT i ) : COLOR +#endif +{ + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bHasNormal = bCubemap || bDiffuseLighting; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bVertexColor = VERTEXCOLOR ? true : false; + bool bFlashlight = FLASHLIGHT ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + + HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); +#if SEAMLESS_BASE + baseColor = + i.SeamlessWeights.x * tex2D( BaseTextureSampler, i.baseTexCoord.yz )+ + i.SeamlessWeights.y * tex2D( BaseTextureSampler, i.baseTexCoord.zx )+ + i.SeamlessWeights.z * tex2D( BaseTextureSampler, i.baseTexCoord.xy ); +#else + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); + +#if SRGB_INPUT_ADAPTER + baseColor.rgb = GammaToLinear( baseColor.rgb ); +#endif + +#endif // !SEAMLESS_BASE + + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 0) + float distAlphaMask = baseColor.a; +#endif + + +#if DETAILTEXTURE +#if SEAMLESS_DETAIL + float4 detailColor = + i.SeamlessWeights.x * tex2D( DetailSampler, i.detailTexCoord.yz )+ + i.SeamlessWeights.y * tex2D( DetailSampler, i.detailTexCoord.zx )+ + i.SeamlessWeights.z * tex2D( DetailSampler, i.detailTexCoord.xy ); +#else + float4 detailColor = tex2D( DetailSampler, i.detailTexCoord.xy ); +#endif + detailColor.rgb *= g_DetailTint; + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 1) + float distAlphaMask = detailColor.a; + detailColor.a = 1.0; // make tcombine treat as 1.0 +#endif + baseColor = + TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + +#if DISTANCEALPHA + // now, do all distance alpha effects + //if ( OUTLINE && ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) + //{ + // float oFactor=1.0; + // if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) + // { + // oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); + // } + // else + // { + // oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); + // } + // baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); + //} + if ( OUTLINE ) + { + float4 oFactors = smoothstep(g_OutlineParams.xyzw, g_OutlineParams.wzyx, distAlphaMask ); + baseColor = lerp( baseColor, g_OutlineColor, oFactors.x * oFactors.y ); + } + + float mskUsed; + if ( SOFT_MASK ) + { + mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask ); + baseColor.a *= mskUsed; + } + else + { + mskUsed = distAlphaMask >= 0.5; + if (DETAILTEXTURE ) + baseColor.a *= mskUsed; + else + baseColor.a = mskUsed; + } + + + if ( OUTER_GLOW ) + { +#if DISTANCEALPHAFROMDETAIL + float4 glowTexel = tex2D( DetailSampler, i.detailTexCoord.xy+GLOW_UV_OFFSET ); +#else + float4 glowTexel = tex2D( BaseTextureSampler, i.baseTexCoord.xy+GLOW_UV_OFFSET ); +#endif + float4 glowc = OUTER_GLOW_COLOR*smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel.a ); + baseColor = lerp( glowc, baseColor, mskUsed ); + } + +#endif // DISTANCEALPHA + + float3 specularFactor = 1.0f; + float4 envmapMaskTexel; + if( bEnvmapMask ) + { + envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord.xy ); + specularFactor *= envmapMaskTexel.xyz; + } + + if( bBaseAlphaEnvmapMask ) + { + specularFactor *= 1.0 - baseColor.a; // this blows! + } + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + if( bDiffuseLighting || bVertexColor && !( bVertexColor && bDiffuseLighting ) ) + { + diffuseLighting = i.color.rgb; + } + + float3 albedo = baseColor; + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + float alpha = g_DiffuseModulation.a; + if ( !bBaseAlphaEnvmapMask && !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha *= baseColor.a; + } + + + if( bFlashlight ) + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = true; +#endif + +#if defined ( _X360 ) + float4 flashlightSpacePosition = i.flashlightSpacePos; +#else + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + // We want the N.L to happen on the flashlight pass, but can't afford it on ps20 + bool bUseWorldNormal = true; +#if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) ) + bUseWorldNormal = false; +#endif + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + i.worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, nShadowSampleLevel, bDoShadows, false, i.projPos.xy / i.projPos.w, false, g_EnvmapContrast_ShadowTweaks, bUseWorldNormal ); + +#if defined ( _X360 ) + diffuseLighting += flashlightColor; +#else + diffuseLighting = flashlightColor; +#endif + } + + if( bVertexColor && bDiffuseLighting ) + { + albedo *= i.color.rgb; + } + + alpha = lerp( alpha, alpha * i.color.a, g_fVertexAlpha ); + + float3 diffuseComponent = albedo * diffuseLighting; + +#if DETAILTEXTURE + diffuseComponent = + TextureCombinePostLighting( diffuseComponent, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); + +#if !FLASHLIGHT || defined ( _X360 ) + #if SELFILLUM_ENVMAPMASK_ALPHA + // range of alpha: + // 0 - 0.125 = lerp(diffuse,selfillum,alpha*8) + // 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows) + HALF3 selfIllumComponent = g_SelfIllumTint * albedo; + half Adj_Alpha=8*envmapMaskTexel.a; + diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent; + #else + if ( bSelfIllum ) + { + float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoord.xy ); + vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint * albedo, vSelfIllumMask ); + } + #endif + + if( bCubemap ) + { +#if CUBEMAP_SPHERE_LEGACY + HALF3 reflectVect = normalize(CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz )); + + specularLighting = 0.5 * tex2D( EnvmapSampler, float2(reflectVect.x, reflectVect.y) ) * g_DiffuseModulation.rgb * diffuseLighting; +#else + HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz ); + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; + HALF3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); + HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); +#endif + } +#endif + + HALF3 result = diffuseComponent + specularLighting; + +#if LIGHTING_PREVIEW +# if LIGHTING_PREVIEW == 1 + float dotprod=0.7+0.25*dot(i.worldSpaceNormal,normalize(float3(1,2,-.5))); + return FinalOutput( float4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +# else + LPREVIEW_PS_OUT ret; + ret.flags=float4(1,1,1,1); + ret.color=float4( albedo.xyz, alpha ); + ret.normal=float4(i.worldSpaceNormal,alpha); + ret.position=float4(i.worldPos_projPosZ.xyz, alpha); + return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +# endif +#else + +# if (DEPTHBLEND == 1) + { + float2 vScreenPos; + vScreenPos.x = i.projPos.x; + vScreenPos.y = -i.projPos.y; + vScreenPos = (vScreenPos + i.projPos.w) * 0.5f; + alpha *= DepthFeathering( DepthSampler, vScreenPos / i.projPos.w, i.projPos.w - i.projPos.z, i.projPos.w, g_DepthFeatheringConstants ); + } +# endif + +#if defined( SHADER_MODEL_PS_2_0 ) + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); + #if (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); + #endif + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.projPos.z ); +#else // 2b or higher + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); + alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog + return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z ); +#endif + +#endif +} + diff --git a/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc b/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc new file mode 100644 index 00000000..9db6f864 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc @@ -0,0 +1,249 @@ +//======= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SEAMLESS_BASE" "0..1" +// STATIC: "SEAMLESS_DETAIL" "0..1" +// STATIC: "SEPARATE_DETAIL_UVS" "0..1" +// STATIC: "DECAL" "0..1" [vs30] +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] +// STATIC: "DONT_GAMMA_CONVERT_VERTEX_COLOR" "0..1" +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] +// SKIP: ($SEPARATE_DETAIL_UVS) && ($SEAMLESS_DETAIL) +// SKIP: ($DONT_GAMMA_CONVERT_VERTEX_COLOR && ( ! $VERTEXCOLOR ) ) +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; +static const bool g_bVertexColor = VERTEXCOLOR ? true : false; +static const bool g_bCubemap = CUBEMAP ? true : false; +static const bool g_bFlashlight = FLASHLIGHT ? true : false; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; +#if (defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL) +static const bool g_bDecalOffset = true; +#else +static const bool g_bDecalOffset = false; +#endif + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +#if SEAMLESS_DETAIL || SEAMLESS_BASE +const float cSeamlessScale : register( SHADER_SPECIFIC_CONST_2); +#define SEAMLESS_SCALE cSeamlessScale.x +#endif + +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); + +#if defined ( _X360 ) +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; +#endif + +#if SEAMLESS_BASE + HALF3 SeamlessTexCoord : TEXCOORD0; // Base texture x/y/z (indexed by swizzle) +#else + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate +#endif +#if SEAMLESS_DETAIL + HALF3 SeamlessDetailTexCoord : TEXCOORD1; // Detail texture coordinate +#else + HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate +#endif + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + +#if CUBEMAP || _X360 + float3 worldVertToEyeVector : TEXCOORD3; // Necessary for cubemaps +#endif + + float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight + +#if defined ( _X360 ) && FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD5; +#endif + + float4 vProjPos : TEXCOORD6; + float4 worldPos_ProjPosZ : TEXCOORD7; + float4 fogFactorW : COLOR1; +#if SEAMLESS_DETAIL || SEAMLESS_BASE + float3 SeamlessWeights : COLOR0; // x y z projection weights +#endif + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + bool bDoLighting = !g_bVertexColor && (bDynamicLight || bStaticLight); + + float4 vPosition = v.vPos; + float3 vNormal = 0; + if ( bDoLighting || FLASHLIGHT || SEAMLESS_BASE || SEAMLESS_DETAIL || LIGHTING_PREVIEW || g_bDecalOffset || CUBEMAP ) + { + // The vertex only contains valid normals if they are actually needed (fetching them when absent makes D3D complain) + DecompressVertex_Normal( v.vNormal, vNormal ); + } + +#if SEAMLESS_BASE || SEAMLESS_DETAIL + // compute blend weights in rgb + float3 NNormal=normalize( vNormal ); + o.SeamlessWeights.xyz = NNormal * NNormal; // sums to 1. +#endif + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal ); +#endif + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, vNormal, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + + if ( !g_bVertexColor ) + { + worldNormal = normalize( worldNormal ); + } + +#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + o.worldSpaceNormal = worldNormal; + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.vProjPos = vProjPos; + o.fogFactorW.w = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW.w; +#endif + o.worldPos_ProjPosZ.xyz = worldPos.xyz; + o.worldPos_ProjPosZ.w = vProjPos.z; + + // Needed for cubemaps +#if CUBEMAP + o.worldVertToEyeVector.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); +#endif + +#if !defined (_X360) && FLASHLIGHT + o.color = float4( 0.0f, 0.0f, 0.0f, 0.0f ); +#else + if ( g_bVertexColor ) + { + // Assume that this is unlitgeneric if you are using vertex color. + o.color.rgb = ( DONT_GAMMA_CONVERT_VERTEX_COLOR ) ? v.vColor.rgb : GammaToLinear( v.vColor.rgb ); + o.color.a = v.vColor.a; + } + else + { + #if ( ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) ) + { + o.color.xyz = DoLighting( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert ); + } + #else + { + o.color.xyz = DoLightingUnrolled( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); + } + #endif + } +#endif + + +#if SEAMLESS_BASE + o.SeamlessTexCoord.xyz = SEAMLESS_SCALE * v.vPos.xyz; +#else + // Base texture coordinates + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); +#endif + +#if SEAMLESS_DETAIL + // FIXME: detail texcoord as a 2d xform doesn't make much sense here, so I just do enough so + // that scale works. More smartness could allow 3d xform. + o.SeamlessDetailTexCoord.xyz = (SEAMLESS_SCALE*cDetailTexCoordTransform[0].x) * v.vPos.xyz; +#else + // Detail texture coordinates + // FIXME: This shouldn't have to be computed all the time. + o.detailTexCoord.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); + o.detailTexCoord.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); +#endif + +#if SEPARATE_DETAIL_UVS + o.detailTexCoord.xy = v.vTexCoord1.xy; +#endif + +#if LIGHTING_PREVIEW + float dot=0.5+0.5*worldNormal*float3(0.7071,0.7071,0); + o.color.xyz=float3(dot,dot,dot); +#endif + +#if defined ( _X360 ) && FLASHLIGHT + o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + return o; +} + + diff --git a/mp/src/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc b/mp/src/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc new file mode 100644 index 00000000..52812637 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc @@ -0,0 +1,68 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "HALFLAMBERT" "0..1" + +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_OverbrightFactor : register( c4 ); +const float3 cAmbientCube[6] : register( c6 ); + +PixelShaderLightInfo cLightInfo[3] : register(c13); + +sampler BumpmapSampler : register( s0 ); +sampler NormalizeSampler : register( s1 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. + float2 detailOrBumpTexCoord : TEXCOORD1; + // bump mapping and a separate envmap mask texture are mutually exclusive. + float2 envmapMaskTexCoord : TEXCOORD2; + float3 worldVertToEyeVector : TEXCOORD3; + float3x3 tangentSpaceTranspose : TEXCOORD4; + float4 worldPos_projPosZ : TEXCOORD5; + float2 lightAtten01 : TEXCOORD6; + float2 lightAtten23 : TEXCOORD7; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bHalfLambert = HALFLAMBERT ? true : false; + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + int nNumLights = NUM_LIGHTS; + + float4 vLightAtten = float4( i.lightAtten01, i.lightAtten23 ); + + float3 tangentSpaceNormal = float3( 0.0f, 0.0f, 1.0f ); + float4 normalTexel = 1.0f; + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + + normalTexel = tex2D( BumpmapSampler, i.detailOrBumpTexCoord ); + tangentSpaceNormal = 2.0f * normalTexel - 1.0f; + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + if( bDiffuseLighting ) + { + float3 worldSpaceNormal = mul( i.tangentSpaceTranspose, tangentSpaceNormal ); + float3 staticLightingColor = float3( 0.0f, 0.0f, 0.0f ); + diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, + vLightAtten, cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, + false, 0, false, NormalizeSampler ); + // multiply by .5 since we want a 50% (in gamma space) reflective surface) + diffuseLighting *= pow( 0.5f, 2.2f ); + } + + return FinalOutput( float4( diffuseLighting, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} + diff --git a/mp/src/materialsystem/stdshaders/vertexlit_notexture.psh b/mp/src/materialsystem/stdshaders/vertexlit_notexture.psh new file mode 100644 index 00000000..8b550bde --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlit_notexture.psh @@ -0,0 +1,13 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +mov r0, v0 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh new file mode 100644 index 00000000..5faa681d --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask (in alpha channel) + +mul r0, t0, c3 ; base times modulation +mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) +mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh new file mode 100644 index 00000000..ab653f19 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask (in alpha channel) +tex t3 ; detail texture + +mul r0, t0, c3 ; base times modulation +mul_x2 r0.rgb, r0, t3 ; detail texture +mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) +mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh new file mode 100644 index 00000000..ac030f0a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t3 ; detail texture + +mul r0, t0, c3 ; base times modulation +mul_x2 r0.rgb, r0, t3 ; detail texture +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh new file mode 100644 index 00000000..51873a08 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +mul r0, t0, c3 ; Base times modulation +mul_x2 r0.rgb, r0, t3 ; detail texture +mul r1, t1, t2 ; Envmap * mask +mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh new file mode 100644 index 00000000..44dee8d4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh @@ -0,0 +1,28 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 +tex t1 +tex t3 + +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh new file mode 100644 index 00000000..4be599ca --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh @@ -0,0 +1,29 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 ; base +tex t1 ; env map +tex t2 ; mask +tex t3 ; Detail + +mul r0.rgb, t0, c3 + ; base times modulation +mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mul r1, t2, t1 ; envmapmask * envmap +mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp new file mode 100644 index 00000000..8ecd111f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp @@ -0,0 +1,421 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( VertexLitGeneric, VertexLitGeneric_DX6 ) + +BEGIN_SHADER( VertexLitGeneric_DX6, + "Help for VertexLitGeneric_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + // No envmap uses mode 0, it's one less pass + // Also, if multipass = 0, then go to mode 0 also + if ( ( !params[ENVMAP]->IsDefined() ) || + ( !IS_FLAG_SET(MATERIAL_VAR_MULTIPASS) ) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ENVMAPMODE ); + } + + // Vertex color requires mode 1 + if ( IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPMODE ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if ( IS_FLAG_SET(MATERIAL_VAR_DECAL) ) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + SET_FLAGS2( MATERIAL_VAR2_NEEDS_SOFTWARE_LIGHTING ); + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + LoadCubeMap( ENVMAP ); + else + LoadTexture( ENVMAP ); + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + LoadTexture( ENVMAPMASK ); + } + } + + int GetDrawFlagsPass1(IMaterialVar** params) + { + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_COLOR; + if (params[BASETEXTURE]->IsTexture()) + flags |= SHADER_DRAW_TEXCOORD0; + return flags; + } + + void DrawVertexLightingOnly( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); + + SetModulationShadowState(); + SetDefaultBlendingShadowState( ); + pShaderShadow->DrawFlags( GetDrawFlagsPass1( params ) ); + DefaultFog(); + } + DYNAMIC_STATE + { + SetModulationDynamicState(); + } + Draw(); + } + + void MultiplyByVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + // FIXME: How to deal with texture alpha?? + + pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); + pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); + + // NOTE: We're not doing lightmapping here, but we want to use the + // same blend mode as we used for lightmapping + pShaderShadow->EnableBlending( true ); + SingleTextureLightmapBlendMode(); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 1 ); + + // This here will perform color = vertex light * (cc alpha) + 1 * (1 - cc alpha) + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_CONSTANTALPHA, + SHADER_TEXARG_VERTEXCOLOR, SHADER_TEXARG_CONSTANTCOLOR ); + + // Alpha isn't used, it doesn't matter what we set it to. + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_NONE, SHADER_TEXARG_NONE ); + + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR ); + FogToOOOverbright(); + } + DYNAMIC_STATE + { + // Put the alpha in the color channel to modulate the color down.... + float alpha = GetAlpha(); + pShaderAPI->Color4f( OO_OVERBRIGHT, OO_OVERBRIGHT, OO_OVERBRIGHT, alpha ); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableCustomPixelPipe( false ); + } + } + + + //----------------------------------------------------------------------------- + // Used by mode 1 + //----------------------------------------------------------------------------- + + void DrawBaseTimesVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // Base times vertex lighting, no vertex color + SHADOW_STATE + { + // alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // base + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); + + // Independenly configure alpha and color + + // Color = Color mod * Vertex Light * Tex (x2) + // Alpha = Constant Alpha * Tex Alpha (no tex alpha if self illum == 1) + // Can't have color modulation here + pShaderShadow->EnableConstantColor( IsColorModulating() ); + + // Independenly configure alpha and color + pShaderShadow->EnableAlphaPipe( true ); + pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); + pShaderShadow->EnableVertexAlpha( IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA) ); + + if (!IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && !IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, true ); + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + pShaderShadow->DrawFlags( GetDrawFlagsPass1( params ) ); + DefaultFog(); + } + DYNAMIC_STATE + { + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetModulationDynamicState(); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableAlphaPipe( false ); + } + } + + //----------------------------------------------------------------------------- + // Envmap times vertex lighting, no vertex color + //----------------------------------------------------------------------------- + + void DrawEnvmapTimesVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + int materialVarFlags = params[FLAGS]->GetIntValue(); + + // alpha test + pShaderShadow->EnableAlphaTest( false ); + + int flags = SetShadowEnvMappingState( ENVMAPMASK ) | SHADER_DRAW_COLOR; + bool hasEnvMapMask = params[ENVMAPMASK]->IsTexture(); + + pShaderShadow->OverbrightValue( hasEnvMapMask ? + SHADER_TEXTURE_STAGE1 : SHADER_TEXTURE_STAGE0, OVERBRIGHT ); + + // Independenly configure alpha and color + + // Color = Env map * Vertex Light * Envmapmask (x2) + // Alpha = Constant Alpha * Vertex light alpha * Env Map mask Alpha + pShaderShadow->EnableConstantColor( IsColorModulating() ); + + pShaderShadow->EnableAlphaPipe( true ); + pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); + pShaderShadow->EnableVertexAlpha( (materialVarFlags & MATERIAL_VAR_VERTEXALPHA) != 0 ); + if (hasEnvMapMask) + pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE1, true ); + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + } + DYNAMIC_STATE + { + SetDynamicEnvMappingState( ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableCustomPixelPipe( false ); + pShaderShadow->EnableAlphaPipe( false ); + } + } + + void DrawMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + bool texDefined = params[BASETEXTURE]->IsTexture(); + bool envDefined = params[ENVMAP]->IsTexture(); +// bool maskDefined = params[ENVMAPMASK]->IsTexture(); + + // Pass 1 : Base + env + + // FIXME: Could make it 1 pass for base + env, if it wasn't + // for the envmap tint. So this is 3 passes for now.... + + // If it's base + mask * env, gotta do that in 2 passes + // Gotta do funky stuff to fade out self-illuminated stuff + bool hasEnvMapTint = !IsWhite(ENVMAPTINT); + + // Special case, can do in one pass + if (!hasEnvMapTint && !texDefined && !IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) && + !IsColorModulating() ) + { + DrawEnvmapTimesVertexLighting( params, pShaderAPI, pShaderShadow ); + return; + } + + if (texDefined) + { + FixedFunctionBaseTimesDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + else + { + FixedFunctionMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + + // We can get here if multipass isn't set if we specify a vertex color + if ( IS_FLAG_SET(MATERIAL_VAR_MULTIPASS) ) + { + if ( texDefined && envDefined ) + { + FixedFunctionAdditiveMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + } + + // Pass 2 : * vertex lighting + MultiplyByVertexLighting( params, pShaderAPI, pShaderShadow ); + + // FIXME: We could add it to the lightmap + // Draw the selfillum pass (blows away envmap at self-illum points) + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) + { + FixedFunctionSelfIlluminationPass( + SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); + } + } + + void DrawMode0( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // Pass 1 : Base * lightmap or just lightmap + if ( params[BASETEXTURE]->IsTexture() ) + { + DrawBaseTimesVertexLighting( params, pShaderAPI, pShaderShadow ); + + // Detail map + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + + // Draw the selfillum pass + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) + { + FixedFunctionSelfIlluminationPass( + SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); + } + } + else + { + DrawVertexLightingOnly( params, pShaderAPI, pShaderShadow ); + + // Detail map + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + + // Pass 2 : Masked environment map + if ( params[ENVMAP]->IsTexture() && + (IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) ) + { + FixedFunctionAdditiveMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + } + + SHADER_DRAW + { + bool useMode1 = IS_FLAG_SET(MATERIAL_VAR_ENVMAPMODE); + if (!useMode1) + { + // Base * Vertex Lighting + env + DrawMode0( params, pShaderAPI, pShaderShadow ); + } + else + { + // ( Base + env ) * Vertex Lighting + DrawMode1( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp new file mode 100644 index 00000000..7a114a56 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp @@ -0,0 +1,413 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( VertexLitGeneric, VertexLitGeneric_DX7 ) +DEFINE_FALLBACK_SHADER( Skin_DX9, VertexLitGeneric_DX7 ) + +BEGIN_SHADER( VertexLitGeneric_DX7, + "Help for VertexLitGeneric_DX7" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + SET_FLAGS2( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS ); + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + } + + SHADER_FALLBACK + { + if (g_pHardwareConfig->GetDXSupportLevel() < 70) + return "VertexLitGeneric_DX6"; + + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + LoadCubeMap( ENVMAP ); + else + LoadTexture( ENVMAP ); + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + LoadTexture( ENVMAPMASK ); + } + } + + void DrawBaseTimesVertexColor( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + // alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + pShaderShadow->EnableCustomPixelPipe( true ); + + pShaderShadow->CustomTextureStages( 1 ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_VERTEXCOLOR ); + + // Get alpha from the texture so that alpha blend and alpha test work properly. + bool bTextureIsTranslucent = TextureIsTranslucent( BASETEXTURE, true ); + if ( bTextureIsTranslucent ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_NONE ); + } + else + { + if ( IsAlphaModulating() ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_ONE, SHADER_TEXARG_NONE ); + } + } + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_NORMAL | SHADER_DRAW_TEXCOORD0; + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + + if ( IsAlphaModulating() || IsColorModulating() ) + { + pShaderShadow->CustomTextureStages( 2 ); + + if ( IsColorModulating() ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + } + + // Get alpha from the texture so that alpha blend and alpha test work properly. + if ( IsAlphaModulating() && bTextureIsTranslucent ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + } + } + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + DYNAMIC_STATE + { + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetModulationDynamicState(); + } + Draw(); + } + + void DrawVertexColorNoBase( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + pShaderShadow->EnableCustomPixelPipe( true ); + + pShaderShadow->CustomTextureStages( 1 ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_ONE, SHADER_TEXARG_VERTEXCOLOR ); + + int flags = SHADER_DRAW_POSITION; + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + } + DYNAMIC_STATE + { +// SetModulationDynamicState(); + } + Draw(); + } + + void DrawBaseTimesBakedVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + // alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); + + // base + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + int flags = SHADER_DRAW_POSITION; + if (params[BASETEXTURE]->IsTexture()) + { + flags |= SHADER_DRAW_TEXCOORD1; + } + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 1 ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_SPECULARCOLOR, SHADER_TEXARG_TEXTURE ); + + // Get alpha from the texture so that alpha blend and alpha test work properly. + bool bTextureIsTranslucent = TextureIsTranslucent( BASETEXTURE, true ); + if ( bTextureIsTranslucent ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_NONE ); + } + else + { + if ( IsAlphaModulating() ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_ONE, SHADER_TEXARG_NONE ); + } + } + + if ( IsAlphaModulating() || IsColorModulating() ) + { + pShaderShadow->CustomTextureStages( 2 ); + + if ( IsColorModulating()) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + } + + // Get alpha from the texture so that alpha blend and alpha test work properly. + if ( IsAlphaModulating() && bTextureIsTranslucent ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + } + } + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + DYNAMIC_STATE + { + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE1, BASETEXTURETRANSFORM ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetModulationDynamicState(); + } + Draw(); + } + + void DrawBakedVertexLightingNoBase( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + int flags = SHADER_DRAW_POSITION; + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 1 ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_SPECULARCOLOR, SHADER_TEXARG_NONE ); + + // Alpha isn't used, it doesn't matter what we set it to. + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_NONE, SHADER_TEXARG_NONE ); + } + DYNAMIC_STATE + { + } + Draw(); + } + + SHADER_DRAW + { + bool bBakedLighting = IS_FLAG2_SET( MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING ); + bool hasFlashlight = UsingFlashlight( params ); + + if( hasFlashlight ) + { + DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + return; + } + // Pass 1 : Base * lightmap or just lightmap + if ( params[BASETEXTURE]->IsTexture() ) + { + // Draw base times lighting. + // Lighting is either sent down per vertex from the app, or it's in the second + // stream as color values. + if( bBakedLighting ) + { + DrawBaseTimesBakedVertexLighting( params, pShaderAPI, pShaderShadow ); + } + else + { + DrawBaseTimesVertexColor( params, pShaderAPI, pShaderShadow ); + } + + // Detail map + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + + // Draw the selfillum pass + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) + { + FixedFunctionSelfIlluminationPass( + SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); + } + } + else + { + if( bBakedLighting ) + { + DrawBakedVertexLightingNoBase( params, pShaderAPI, pShaderShadow ); + } + else + { + DrawVertexColorNoBase( params, pShaderAPI, pShaderShadow ); + } + + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + + + // Pass 2 : Masked environment map + if ( params[ENVMAP]->IsTexture() && (IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) ) + { + FixedFunctionAdditiveMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp new file mode 100644 index 00000000..31addf42 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp @@ -0,0 +1,807 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "vertexlitgeneric_vs11.inc" +#include "vertexlitgeneric_selfillumonly.inc" +#include "emissive_scroll_blended_pass_helper.h" +#include "flesh_interior_blended_pass_helper.h" +#include "cloak_blended_pass_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( VertexLitGeneric, VertexLitGeneric_DX8 ) +DEFINE_FALLBACK_SHADER( Skin_DX9, VertexLitGeneric_DX8 ) + +BEGIN_VS_SHADER( VertexLitGeneric_DX8, + "Help for VertexLitGeneric" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) + SHADER_PARAM( FORCEBUMP, SHADER_PARAM_TYPE_BOOL, "0", "0 == Do bumpmapping if the card says it can handle it. 1 == Always do bumpmapping." ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + + // Emissive Scroll Pass + SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) + SHADER_PARAM( EMISSIVEBLENDBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) + SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) + SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + // Color Replacement Pass + SHADER_PARAM( BLENDTINTBYBASEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use the base alpha to blend in the $color modulation") + SHADER_PARAM( BLENDTINTCOLOROVERBASE, SHADER_PARAM_TYPE_FLOAT, "0", "blend between tint acting as a multiplication versus a replace" ) + + END_SHADER_PARAMS + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + + // Delete these lines if not bump mapping! + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + // Emissive Scroll Pass + void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) + { + info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; + info.m_nBaseTexture = EMISSIVEBLENDBASETEXTURE; + info.m_nFlowTexture = -1; // Not used in DX8 + info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; + info.m_nEmissiveTint = EMISSIVEBLENDTINT; + info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; + info.m_nTime = TIME; + } + + // Flesh Interior Pass + void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) + { + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + + info.m_nTime = TIME; + } + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + // We don't want no stinking bump mapping on models in dx8. + // Wait a minute! We want specular bump. .need to make that work by itself. +// params[BUMPMAP]->SetUndefined(); +// if( IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ) ) +// { +// CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); +// params[ENVMAP]->SetUndefined(); +// } + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPMASKFRAME]->IsDefined() ) + params[ENVMAPMASKFRAME]->SetIntValue( 0 ); + + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + if( !params[DETAILBLENDFACTOR]->IsDefined() ) + params[DETAILBLENDFACTOR]->SetFloatValue( 1.0f ); + + if( !params[DETAILBLENDMODE]->IsDefined() ) + params[DETAILBLENDMODE]->SetFloatValue( 0 ); + + if( !params[ENVMAPCONTRAST]->IsDefined() ) + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + + if( !params[ENVMAPSATURATION]->IsDefined() ) + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPFRAME]->IsDefined() ) + params[ENVMAPFRAME]->SetIntValue( 0 ); + + if( !params[BUMPFRAME]->IsDefined() ) + params[BUMPFRAME]->SetIntValue( 0 ); + + if( !params[ALPHATESTREFERENCE]->IsDefined() ) + params[ALPHATESTREFERENCE]->SetFloatValue( 0.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If a bumpmap is defined but an envmap isn't, then ignore the bumpmap. + // It was meant to be used with diffuse + if ( !params[ENVMAP]->IsDefined() ) + { + params[BUMPMAP]->SetUndefined(); + } + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + + // Emissive Scroll Pass + if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) + { + params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); + } + else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); + } + + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } + + // Color Replacement Pass + if ( !params[BLENDTINTBYBASEALPHA]->IsDefined() ) + { + params[BLENDTINTBYBASEALPHA]->SetIntValue(0); + } + + if ( !params[BLENDTINTCOLOROVERBASE]->IsDefined() ) + { + params[BLENDTINTCOLOROVERBASE]->SetFloatValue(0); + } + } + + SHADER_FALLBACK + { + if ( IsPC() ) + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 70) + return "VertexLitGeneric_DX6"; + + if ( g_pHardwareConfig->GetDXSupportLevel() < 80) + return "VertexLitGeneric_DX7"; + + if ( g_pHardwareConfig->PreferReducedFillrate() ) + return "VertexLitGeneric_NoBump_DX8"; + } + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + if (g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined()) + { + LoadBumpMap( BUMPMAP ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + LoadCubeMap( ENVMAP ); + } + else + { + LoadTexture( ENVMAP ); + } + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + { + LoadTexture( ENVMAPMASK ); + } + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitEmissiveScrollBlendedPass( this, params, info ); + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } + } + + inline const char *GetUnbumpedPixelShaderName( IMaterialVar** params, bool bSkipEnvmap ) + { + static char const* s_pPixelShaders[] = + { + "VertexLitGeneric_EnvmapV2", + "VertexLitGeneric_SelfIlluminatedEnvmapV2", + + "VertexLitGeneric_BaseAlphaMaskedEnvmapV2", + "VertexLitGeneric_SelfIlluminatedEnvmapV2", + + // Env map mask + "VertexLitGeneric_MaskedEnvmapV2", + "VertexLitGeneric_SelfIlluminatedMaskedEnvmapV2", + + "VertexLitGeneric_MaskedEnvmapV2", + "VertexLitGeneric_SelfIlluminatedMaskedEnvmapV2", + + // Detail + "VertexLitGeneric_DetailEnvmapV2", + "VertexLitGeneric_DetailSelfIlluminatedEnvmapV2", + + "VertexLitGeneric_DetailBaseAlphaMaskedEnvmapV2", + "VertexLitGeneric_DetailSelfIlluminatedEnvmapV2", + + // Env map mask + "VertexLitGeneric_DetailMaskedEnvmapV2", + "VertexLitGeneric_DetailSelfIlluminatedMaskedEnvmapV2", + + "VertexLitGeneric_DetailMaskedEnvmapV2", + "VertexLitGeneric_DetailSelfIlluminatedMaskedEnvmapV2", + }; + + if ( !params[BASETEXTURE]->IsTexture() ) + { + if (params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + if (!params[ENVMAPMASK]->IsTexture()) + { + return "VertexLitGeneric_EnvmapNoTexture"; + } + else + { + return "VertexLitGeneric_MaskedEnvmapNoTexture"; + } + } + else + { + if ( params[DETAIL]->IsTexture() ) + { + return "VertexLitGeneric_DetailNoTexture"; + } + else + { + return "VertexLitGeneric_NoTexture"; + } + } + } + else + { + if ( params[BLENDTINTBYBASEALPHA]->GetIntValue() ) + { + return "VertexLitGeneric_BlendTint"; + } + else if ( params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + int pshIndex = 0; + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + pshIndex |= 0x1; + if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + pshIndex |= 0x2; + if (params[ENVMAPMASK]->IsTexture()) + pshIndex |= 0x4; + if (params[DETAIL]->IsTexture()) + pshIndex |= 0x8; + return s_pPixelShaders[pshIndex]; + } + else + { + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + { + if ( params[DETAIL]->IsTexture() ) + return "VertexLitGeneric_DetailSelfIlluminated"; + else + return "VertexLitGeneric_SelfIlluminated"; + } + else if ( params[DETAIL]->IsTexture() ) + { + switch( params[DETAILBLENDMODE]->GetIntValue() ) + { + case 0: + return "VertexLitGeneric_Detail"; + + case 1: // additive modes + return "VertexLitGeneric_Detail_Additive"; + + case 5: + case 6: + return "VertexLitGeneric_Detail_Additive_selfillum"; + break; + + default: + return "VertexLitGeneric_Detail_LerpBase"; + } + } + else + { + return "VertexLitGeneric"; + } + } + } + } + + void DrawUnbumpedUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bSkipEnvmap ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + if ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); + } + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + + // FIXME: We could enable this, but we'd never get it working on dx7 or lower + // FIXME: This isn't going to work until we make more vertex shaders that + // pass the vertex color and alpha values through. +#if 0 + if ( IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) || IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ) ) + fmt |= VERTEX_COLOR; +#endif + + if (params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + // envmap on stage 1 + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + // envmapmask on stage 2 + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + } + + if (params[BASETEXTURE]->IsTexture()) + { + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + else + { + SetDefaultBlendingShadowState( ENVMAPMASK, false ); + } + + if ( params[DETAIL]->IsTexture()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + // Set up the vertex shader index. + vertexlitgeneric_vs11_Static_Index vshIndex; + vshIndex.SetHALF_LAMBERT( IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + //vshIndex.SetDETAIL( params[DETAIL]->IsTexture() ); + if( params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + vshIndex.SetENVMAP( true ); + vshIndex.SetENVMAPCAMERASPACE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) ); + if( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) ) + { + vshIndex.SetENVMAPSPHERE( false ); + } + else + { + vshIndex.SetENVMAPSPHERE( IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ) ); + } + } + else + { + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + } + pShaderShadow->SetVertexShader( "vertexlitgeneric_vs11", vshIndex.GetIndex() ); + + const char *pshName = GetUnbumpedPixelShaderName( params, bSkipEnvmap ); + pShaderShadow->SetPixelShader( pshName ); + DefaultFog(); + pShaderShadow->EnableAlphaWrites( true ); + } + DYNAMIC_STATE + { + if (params[BASETEXTURE]->IsTexture()) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + +// if (params[ENVMAP]->IsTexture()) + if (params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + BindTexture( SHADER_SAMPLER1, ENVMAP, ENVMAPFRAME ); + + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + if (params[ENVMAPMASK]->IsTexture() ) + BindTexture( SHADER_SAMPLER2, ENVMAPMASK, ENVMAPMASKFRAME ); + else + BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); + + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); + } + + if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || + IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) + { + LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); + } + SetEnvMapTintPixelShaderDynamicState( 2, ENVMAPTINT, -1 ); + } + + if ( params[DETAIL]->IsTexture()) + { + BindTexture( SHADER_SAMPLER3, DETAIL, DETAILFRAME ); + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); + } + + SetAmbientCubeDynamicStateVertexShader(); + SetModulationPixelShaderDynamicState( 3 ); + EnablePixelShaderOverbright( 0, true, true ); + SetPixelShaderConstant( 1, SELFILLUMTINT ); + + if ( params[DETAIL]->IsTexture() && ( ! IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) ) ) + { + float c1[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + c1[0] = c1[1] = c1[2] = c1[3] = params[DETAILBLENDFACTOR]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 1, c1, 1 ); + } + + if ( params[BLENDTINTBYBASEALPHA]->GetIntValue() ) + { + float c1[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + c1[0] = c1[1] = c1[2] = c1[3] = params[BLENDTINTCOLOROVERBASE]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 1, c1 ); + } + + vertexlitgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetLIGHT_COMBO( pShaderAPI->GetCurrentLightCombo() ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + if( pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_WRITE_DEPTH_TO_DESTALPHA ) ) + { + pShaderAPI->SetPixelShaderIndex( 0 ); + } + else + { + // write 255 to alpha if we aren't told to write depth to dest alpha (We don't ever actually write depth to dest alpha in dx8) + pShaderAPI->SetPixelShaderIndex( 1 ); + float c4[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + pShaderAPI->SetPixelShaderConstant( 4, c4, 1 ); + } + } + Draw(); + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( false/*disabled! no effect*/ && params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + // There is some strangeness in DX8 when trying to skip the main pass, so leave this alone for now + //bDrawStandardPass = false; + } + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + // FLASHLIGHTFIXME: need to make these the same. + bool hasFlashlight = UsingFlashlight( params ); + bool bBump = g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsTexture(); + + if( hasFlashlight ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, false, false, 0, -1, -1 ); + } + else if( bBump ) + { + bool bSkipEnvmap = true; + DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bSkipEnvmap ); + + // specular pass + bool bBlendSpecular = true; + if( params[ENVMAP]->IsTexture() ) + { + DrawModelBumpedSpecularLighting( BUMPMAP, BUMPFRAME, ENVMAP, ENVMAPFRAME, + ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, BUMPTRANSFORM, bBlendSpecular ); + } + } + else + { + bool bSkipEnvmap = false; + DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bSkipEnvmap ); + } + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER + + +//----------------------------------------------------------------------------- +// Version that doesn't do bumpmapping +//----------------------------------------------------------------------------- +BEGIN_INHERITED_SHADER( VertexLitGeneric_NoBump_DX8, VertexLitGeneric_DX8, + "Help for VertexLitGeneric_NoBump_DX8" ) + + SHADER_FALLBACK + { + if (g_pConfig->bSoftwareLighting) + return "VertexLitGeneric_DX6"; + + if (!g_pHardwareConfig->SupportsVertexAndPixelShaders()) + return "VertexLitGeneric_DX7"; + + return 0; + } + + virtual bool ShouldUseBumpmapping( IMaterialVar **params ) + { + if ( !g_pConfig->UseBumpmapping() ) + return false; + + if ( !params[BUMPMAP]->IsDefined() ) + return false; + + return ( params[FORCEBUMP]->GetIntValue() != 0 ); + } + +END_INHERITED_SHADER + diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp new file mode 100644 index 00000000..47105813 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp @@ -0,0 +1,520 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=====================================================================================// + +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx9_helper.h" +#include "emissive_scroll_blended_pass_helper.h" +#include "cloak_blended_pass_helper.h" +#include "flesh_interior_blended_pass_helper.h" +#include "weapon_sheen_pass_helper.h" + + +BEGIN_VS_SHADER( VertexLitGeneric, "Help for VertexLitGeneric" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( COMPRESS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "compression wrinklemap" ) + SHADER_PARAM( STRETCH, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "expansion wrinklemap" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPCOMPRESS, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "compression bump map" ) + SHADER_PARAM( BUMPSTRETCH, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "expansion bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( SELFILLUM_ENVMAPMASK_ALPHA, SHADER_PARAM_TYPE_FLOAT,"0.0","defines that self illum value comes from env map mask alpha" ) + SHADER_PARAM( SELFILLUMFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "Self illum fresnel" ) + SHADER_PARAM( SELFILLUMFRESNELMINMAXEXP, SHADER_PARAM_TYPE_VEC4, "0", "Self illum fresnel min, max, exp" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( FLASHLIGHTNOLAMBERT, SHADER_PARAM_TYPE_BOOL, "0", "Flashlight pass sets N.L=1.0" ) + + // Debugging term for visualizing ambient data on its own + SHADER_PARAM( AMBIENTONLY, SHADER_PARAM_TYPE_INTEGER, "0", "Control drawing of non-ambient light ()" ) + + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) + SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) + SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) + SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "warp the specular term" ) + SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) + SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) + SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) + SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) + SHADER_PARAM( BASEMAPALPHAPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "indicates that there is no normal map and that the phong mask is in base alpha" ) + SHADER_PARAM( INVERTPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "invert the phong mask (0=full phong, 1=no phong)" ) + SHADER_PARAM( ENVMAPFRESNEL, SHADER_PARAM_TYPE_FLOAT, "0", "Degree to which Fresnel should be applied to env map" ) + SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) + + // detail (multi-) texturing + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + SHADER_PARAM( DETAILTEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$detail texcoord transform" ) + + // Rim lighting terms + SHADER_PARAM( RIMLIGHT, SHADER_PARAM_TYPE_BOOL, "0", "enables rim lighting" ) + SHADER_PARAM( RIMLIGHTEXPONENT, SHADER_PARAM_TYPE_FLOAT, "4.0", "Exponent for rim lights" ) + SHADER_PARAM( RIMLIGHTBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Boost for rim lights" ) + SHADER_PARAM( RIMMASK, SHADER_PARAM_TYPE_BOOL, "0", "Indicates whether or not to use alpha channel of exponent texture to mask the rim term" ) + + // Seamless mapping scale + SHADER_PARAM( SEAMLESS_BASE, SHADER_PARAM_TYPE_BOOL, "0", "whether to apply seamless mapping to the base texture. requires a smooth model." ) + SHADER_PARAM( SEAMLESS_DETAIL, SHADER_PARAM_TYPE_BOOL, "0", "where to apply seamless mapping to the detail texture." ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "the scale for the seamless mapping. # of repetions of texture per inch." ) + + // Emissive Scroll Pass + SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) + SHADER_PARAM( EMISSIVEBLENDBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) + SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) + SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( EMISSIVEBLENDFLOWTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "flow map" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + + // Weapon Sheen Pass + SHADER_PARAM( SHEENPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables weapon sheen render in a second pass" ) + SHADER_PARAM( SHEENMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "sheenmap" ) + SHADER_PARAM( SHEENMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "sheenmap mask" ) + SHADER_PARAM( SHEENMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( SHEENMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "sheenmap tint" ) + SHADER_PARAM( SHEENMAPMASKSCALEX, SHADER_PARAM_TYPE_FLOAT, "1", "X Scale the size of the map mask to the size of the target" ) + SHADER_PARAM( SHEENMAPMASKSCALEY, SHADER_PARAM_TYPE_FLOAT, "1", "Y Scale the size of the map mask to the size of the target" ) + SHADER_PARAM( SHEENMAPMASKOFFSETX, SHADER_PARAM_TYPE_FLOAT, "0", "X Offset of the mask relative to model space coords of target" ) + SHADER_PARAM( SHEENMAPMASKOFFSETY, SHADER_PARAM_TYPE_FLOAT, "0", "Y Offset of the mask relative to model space coords of target" ) + SHADER_PARAM( SHEENMAPMASKDIRECTION, SHADER_PARAM_TYPE_INTEGER, "0", "The direction the sheen should move (length direction of weapon) XYZ, 0,1,2" ) + SHADER_PARAM( SHEENINDEX, SHADER_PARAM_TYPE_INTEGER, "0", "Index of the Effect Type (Color Additive, Override etc...)" ) + + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) + SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) + SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries. Only supported without bumpmaps" ) + SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) + + SHADER_PARAM( BLENDTINTBYBASEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use the base alpha to blend in the $color modulation") + SHADER_PARAM( BLENDTINTCOLOROVERBASE, SHADER_PARAM_TYPE_FLOAT, "0", "blend between tint acting as a multiplication versus a replace" ) + END_SHADER_PARAMS + + void SetupVars( VertexLitGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nWrinkle = COMPRESS; + info.m_nStretch = STRETCH; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nNormalWrinkle = BUMPCOMPRESS; + info.m_nNormalStretch = BUMPSTRETCH; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nFlashlightNoLambert = FLASHLIGHTNOLAMBERT; + + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nSelfIllumEnvMapMask_Alpha = SELFILLUM_ENVMAPMASK_ALPHA; + info.m_nSelfIllumFresnel = SELFILLUMFRESNEL; + info.m_nSelfIllumFresnelMinMaxExp = SELFILLUMFRESNELMINMAXEXP; + + info.m_nAmbientOnly = AMBIENTONLY; + info.m_nPhongExponent = PHONGEXPONENT; + info.m_nPhongExponentTexture = PHONGEXPONENTTEXTURE; + info.m_nPhongTint = PHONGTINT; + info.m_nPhongAlbedoTint = PHONGALBEDOTINT; + info.m_nDiffuseWarpTexture = LIGHTWARPTEXTURE; + info.m_nPhongWarpTexture = PHONGWARPTEXTURE; + info.m_nPhongBoost = PHONGBOOST; + info.m_nPhongFresnelRanges = PHONGFRESNELRANGES; + info.m_nPhong = PHONG; + info.m_nBaseMapAlphaPhongMask = BASEMAPALPHAPHONGMASK; + info.m_nEnvmapFresnel = ENVMAPFRESNEL; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTextureTransform = DETAILTEXTURETRANSFORM; + + // Rim lighting parameters + info.m_nRimLight = RIMLIGHT; + info.m_nRimLightPower = RIMLIGHTEXPONENT; + info.m_nRimLightBoost = RIMLIGHTBOOST; + info.m_nRimMask = RIMMASK; + + // seamless + info.m_nSeamlessScale = SEAMLESS_SCALE; + info.m_nSeamlessDetail = SEAMLESS_DETAIL; + info.m_nSeamlessBase = SEAMLESS_BASE; + + info.m_nSeparateDetailUVs = SEPARATEDETAILUVS; + + info.m_nLinearWrite = LINEARWRITE; + info.m_nDetailTint = DETAILTINT; + info.m_nInvertPhongMask = INVERTPHONGMASK; + + info.m_nDepthBlend = DEPTHBLEND; + info.m_nDepthBlendScale = DEPTHBLENDSCALE; + + info.m_nSelfIllumMask = SELFILLUMMASK; + info.m_nBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA; + info.m_nTintReplacesBaseColor = BLENDTINTCOLOROVERBASE; + } + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + + // Delete these lines if not bump mapping! + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + } + + // Weapon Sheen Pass + void SetupVarsWeaponSheenPass( WeaponSheenPassVars_t &info ) + { + info.m_nSheenMap = SHEENMAP; + info.m_nSheenMapMask = SHEENMAPMASK; + info.m_nSheenMapMaskFrame = SHEENMAPMASKFRAME; + info.m_nSheenMapTint = SHEENMAPTINT; + info.m_nSheenMapMaskScaleX = SHEENMAPMASKSCALEX; + info.m_nSheenMapMaskScaleY = SHEENMAPMASKSCALEY; + info.m_nSheenMapMaskOffsetX = SHEENMAPMASKOFFSETX; + info.m_nSheenMapMaskOffsetY = SHEENMAPMASKOFFSETY; + info.m_nSheenMapMaskDirection = SHEENMAPMASKDIRECTION; + info.m_nSheenIndex = SHEENINDEX; + + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + if ( params[SHEENPASSENABLED]->GetIntValue() ) // If material supports weapon sheen + return true; + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + // Emissive Scroll Pass + void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) + { + info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; + info.m_nBaseTexture = EMISSIVEBLENDBASETEXTURE; + info.m_nFlowTexture = EMISSIVEBLENDFLOWTEXTURE; + info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; + info.m_nEmissiveTint = EMISSIVEBLENDTINT; + info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; + info.m_nTime = TIME; + } + + // Flesh Interior Pass + void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) + { + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + + info.m_nTime = TIME; + } + + SHADER_INIT_PARAMS() + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitParamsVertexLitGeneric_DX9( this, params, pMaterialName, true, vars ); + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + + // Sheen Pass + if ( !params[SHEENPASSENABLED]->IsDefined() ) + { + params[SHEENPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[SHEENPASSENABLED]->GetIntValue() ) + { + WeaponSheenPassVars_t info; + SetupVarsWeaponSheenPass( info ); + InitParamsWeaponSheenPass( this, params, pMaterialName, info ); + } + + // Emissive Scroll Pass + if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) + { + params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); + } + else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); + } + + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } + } + + SHADER_FALLBACK + { + if (g_pHardwareConfig->GetDXSupportLevel() < 70) + return "VertexLitGeneric_DX6"; + + if (g_pHardwareConfig->GetDXSupportLevel() < 80) + return "VertexLitGeneric_DX7"; + + if (g_pHardwareConfig->GetDXSupportLevel() < 90) + return "VertexLitGeneric_DX8"; + + return 0; + } + + SHADER_INIT + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitVertexLitGeneric_DX9( this, params, true, vars ); + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + + // TODO : Only do this if we're in range of the camera + // Weapon Sheen + if ( params[SHEENPASSENABLED]->GetIntValue() ) + { + WeaponSheenPassVars_t info; + SetupVarsWeaponSheenPass( info ); + InitWeaponSheenPass( this, params, info ); + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitEmissiveScrollBlendedPass( this, params, info ); + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + bDrawStandardPass = false; + } + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + DrawVertexLitGeneric_DX9( this, params, pShaderAPI, pShaderShadow, true, vars, vertexCompression, pContextDataPtr ); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Weapon sheen pass + // only if doing standard as well (don't do it if cloaked) + if ( params[SHEENPASSENABLED]->GetIntValue() ) + { + WeaponSheenPassVars_t info; + SetupVarsWeaponSheenPass( info ); + if ( ( pShaderShadow != NULL ) || ( bDrawStandardPass && ShouldDrawMaterialSheen( params, info ) ) ) + { + DrawWeaponSheenPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + // Skip this pass! + Draw( false ); + } + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h new file mode 100644 index 00000000..3736bfe8 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h @@ -0,0 +1,71 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VERTEXLITGENERIC_DX95_HELPER_H +#define VERTEXLITGENERIC_DX95_HELPER_H + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct VertexLitGeneric_DX95_Vars_t +{ + VertexLitGeneric_DX95_Vars_t() { memset( this, 0xFF, sizeof(VertexLitGeneric_DX95_Vars_t) ); } + + int m_nBaseTexture; + int m_nBaseTextureFrame; + int m_nBaseTexture2; + int m_nBaseTextureFrame2; + int m_nBaseTexture3; + int m_nBaseTextureFrame3; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nSelfIllumTint; + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nBumpFrame; + int m_nBumpmap2; + int m_nBumpFrame2; + int m_nBumpMask; + int m_nBumpmap3; + int m_nBumpFrame3; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nAlphaTestReference; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + int m_nSelfIllumEnvMapMask_Alpha; + +}; + +void InitParamsVertexLitGeneric_DX95( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX95_Vars_t &info ); +void InitVertexLitGeneric_DX95( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX95_Vars_t &info ); +void DrawVertexLitGeneric_DX95( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bVertexLitGeneric, VertexLitGeneric_DX95_Vars_t &info ); + + +#endif // VERTEXLITGENERIC_DX95_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp new file mode 100644 index 00000000..b1f49eab --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp @@ -0,0 +1,1434 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx9_helper.h" +#include "skin_dx9_helper.h" + +#include "VertexLit_and_unlit_Generic_vs20.inc" +#include "VertexLit_and_unlit_Generic_bump_vs20.inc" + +#include "vertexlit_and_unlit_generic_ps20.inc" +#include "vertexlit_and_unlit_generic_ps20b.inc" +#include "vertexlit_and_unlit_generic_bump_ps20.inc" +#include "vertexlit_and_unlit_generic_bump_ps20b.inc" + +#ifndef _X360 +#include "vertexlit_and_unlit_generic_vs30.inc" +#include "vertexlit_and_unlit_generic_ps30.inc" +#include "vertexlit_and_unlit_generic_bump_vs30.inc" +#include "vertexlit_and_unlit_generic_bump_ps30.inc" +#endif + +#include "commandbuilder.h" +#include "convar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); +static ConVar r_lightwarpidentity( "r_lightwarpidentity","0", FCVAR_CHEAT ); + + +static inline bool WantsSkinShader( IMaterialVar** params, const VertexLitGeneric_DX9_Vars_t &info ) +{ + if ( info.m_nPhong == -1) // Don't use skin without Phong + return false; + + if ( params[info.m_nPhong]->GetIntValue() == 0 ) // Don't use skin without Phong turned on + return false; + + if ( ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsTexture() ) // If there's Phong and diffuse warp do skin + return true; + + if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 1 ) + { + if ( info.m_nBumpmap == -1 ) // Don't use without a bump map + return false; + + if ( !params[info.m_nBumpmap]->IsTexture() ) // Don't use if the texture isn't specified + return false; + } + + return true; +} + +int g_nSnapShots; + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ) +{ + InitIntParam( info.m_nPhong, params, 0 ); + + InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); + InitIntParam( info.m_nVertexAlphaTest, params, 0 ); + + InitIntParam( info.m_nFlashlightNoLambert, params, 0 ); + + if ( info.m_nDetailTint != -1 && !params[info.m_nDetailTint]->IsDefined() ) + { + params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if ( info.m_nEnvmapTint != -1 && !params[info.m_nEnvmapTint]->IsDefined() ) + { + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + InitIntParam( info.m_nEnvmapFrame, params, 0 ); + InitIntParam( info.m_nBumpFrame, params, 0 ); + InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + InitIntParam( info.m_nReceiveFlashlight, params, 0 ); + + InitFloatParam( info.m_nDetailScale, params, 4.0f ); + + if ( (info.m_nBlendTintByBaseAlpha != -1) && (!params[info.m_nBlendTintByBaseAlpha]->IsDefined()) ) + { + params[info.m_nBlendTintByBaseAlpha]->SetIntValue( 0 ); + } + + InitFloatParam( info.m_nTintReplacesBaseColor, params, 0 ); + + if ( (info.m_nSelfIllumTint != -1) && (!params[info.m_nSelfIllumTint]->IsDefined()) ) + { + params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + + if ( WantsSkinShader( params, info ) ) + { + if ( !g_pHardwareConfig->SupportsPixelShaders_2_b() || !g_pConfig->UsePhong() ) + { + params[info.m_nPhong]->SetIntValue( 0 ); + } + else + { + InitParamsSkin_DX9( pShader, params, pMaterialName, info ); + return; + } + } + + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + if ( info.m_nFlashlightTexture != -1 ) + { + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + } + + // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping. + if ( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + // This shader can be used with hw skinning + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if ( bVertexLitGeneric ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + else + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + InitIntParam( info.m_nEnvmapMaskFrame, params, 0 ); + InitFloatParam( info.m_nEnvmapContrast, params, 0.0 ); + InitFloatParam( info.m_nEnvmapSaturation, params, 1.0f ); + InitFloatParam( info.m_nSeamlessScale, params, 0.0 ); + + // handle line art parms + InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); + InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); + InitFloatParam( info.m_nGlowAlpha, params, 1.0 ); + InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); + + // No texture means no self-illum or env mask in base alpha + if ( info.m_nBaseTexture != -1 && !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + if( ( (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() ) + // we don't need a tangent space if we have envmap without bumpmap + // || ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) + ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) // diffuse warp goes down bump path... + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else // no tangent space needed + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + } + + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + if ( hasNormalMapAlphaEnvmapMask ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) && info.m_nBumpmap != -1 && + params[info.m_nBumpmap]->IsDefined() && !hasNormalMapAlphaEnvmapMask ) + { + Warning( "material %s has a normal map and $basealphaenvmapmask. Must use $normalmapalphaenvmapmask to get specular.\n\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + + if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + if ( !hasNormalMapAlphaEnvmapMask ) + { + Warning( "material %s has a normal map and an envmapmask. Must use $normalmapalphaenvmapmask.\n\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + } + + // If mat_specular 0, then get rid of envmap + if ( !g_pConfig->UseSpecular() && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nEnvmap]->SetUndefined(); + } + + InitFloatParam( info.m_nHDRColorScale, params, 1.0f ); + + InitIntParam( info.m_nLinearWrite, params, 0 ); + InitIntParam( info.m_nGammaColorRead, params, 0 ); + + InitIntParam( info.m_nDepthBlend, params, 0 ); + InitFloatParam( info.m_nDepthBlendScale, params, 50.0f ); +} + + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- + +void InitVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ) +{ + // both detailed and bumped = needs skin shader (for now) + bool bNeedsSkinBecauseOfDetail = false; + + //bool bHasBump = ( info.m_nBumpmap != -1 ) && params[info.m_nBumpmap]->IsTexture(); + //if ( bHasBump ) + //{ + // if ( ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsDefined() ) + // bNeedsSkinBecauseOfDetail = true; + //} + + if ( bNeedsSkinBecauseOfDetail || + ( info.m_nPhong != -1 && + params[info.m_nPhong]->GetIntValue() && + g_pHardwareConfig->SupportsPixelShaders_2_b() ) ) + { + InitSkin_DX9( pShader, params, info ); + return; + } + + if ( info.m_nFlashlightTexture != -1 ) + { + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + } + + bool bIsBaseTextureTranslucent = false; + if ( info.m_nBaseTexture != -1 && params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ? 0 : TEXTUREFLAGS_SRGB ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + } + + bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined(); + + // No alpha channel in any of the textures? No self illum or envmapmask + if ( !bIsBaseTextureTranslucent ) + { + bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + // Can still be self illum with no base alpha if using one of these alternate modes + if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() ) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + if ( nDetailBlendMode == 0 ) //Mod2X + pShader->LoadTexture( info.m_nDetail ); + else + pShader->LoadTexture( info.m_nDetail, TEXTUREFLAGS_SRGB ); + } + + if ( g_pConfig->UseBumpmapping() ) + { + if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + } + else if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + } + } + + // Don't alpha test if the alpha channel is used for other purposes + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) + { + if ( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + else + { + pShader->LoadTexture( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + + if ( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + } + if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() ) + { + pShader->LoadTexture( info.m_nEnvmapMask ); + } + + if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); + } + + if ( bHasSelfIllumMask ) + { + pShader->LoadTexture( info.m_nSelfIllumMask ); + } +} + +class CVertexLitGeneric_DX9_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + +}; + + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, + bool bVertexLitGeneric, bool bHasFlashlight, + VertexLitGeneric_DX9_Vars_t &info, + VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) + +{ + CVertexLitGeneric_DX9_Context *pContextData = reinterpret_cast< CVertexLitGeneric_DX9_Context *> ( *pContextDataPtr ); + +/*^*/ // printf("\t\t>DrawVertexLitGeneric_DX9_Internal\n"); + + bool bHasBump = IsTextureSet( info.m_nBumpmap, params ); +#if !defined( _X360 ) + bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL ); +#endif + + bool hasDiffuseLighting = bVertexLitGeneric; +/*^*/ // printf("\t\t[%d] bVertexLitGeneric\n",(int)bVertexLitGeneric); + + if ( IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + bHasFlashlight = false; + } + + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bHasDiffuseWarp = (!bHasFlashlight || IsX360() ) && hasDiffuseLighting && (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture(); + + + //bool bNoCull = IS_FLAG_SET( MATERIAL_VAR_NOCULL ); + bool bFlashlightNoLambert = false; + if ( ( info.m_nFlashlightNoLambert != -1 ) && params[info.m_nFlashlightNoLambert]->GetIntValue() ) + { + bFlashlightNoLambert = true; + } + + bool bAmbientOnly = IsBoolSet( info.m_nAmbientOnly, params ); + + float fBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + bool bHasDetailTexture = IsTextureSet( info.m_nDetail, params ); + int nDetailBlendMode = bHasDetailTexture ? GetIntParam( info.m_nDetailTextureCombineMode, params ) : 0; + int nDetailTranslucencyTexture = -1; + + if ( bHasDetailTexture ) + { + if ( ( nDetailBlendMode == 6 ) && ( ! (g_pHardwareConfig->SupportsPixelShaders_2_b() ) ) ) + { + nDetailBlendMode = 5; // skip fancy threshold blending if ps2.0 + } + if ( ( nDetailBlendMode == 3 ) || ( nDetailBlendMode == 8 ) || ( nDetailBlendMode == 9 ) ) + nDetailTranslucencyTexture = info.m_nDetail; + } + + bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ); + float fTintReplaceFactor = GetFloatParam( info.m_nTintReplacesBaseColor, params, 0.0 ); + + BlendType_t nBlendType; + bool bHasBaseTexture = IsTextureSet( info.m_nBaseTexture, params ); + if ( bHasBaseTexture ) + { + // if base alpha is used for tinting, ignore the base texture for computing translucency + nBlendType = pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true, nDetailTranslucencyTexture ); + } + else + { + nBlendType = pShader->EvaluateBlendRequirements( info.m_nEnvmapMask, false ); + } + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && (!bHasFlashlight || IsX360() ); //dest alpha is free for special use + + bool bHasEnvmap = (!bHasFlashlight || IsX360() ) && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsTexture(); + + + bool bHasVertexColor = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool bHasVertexAlpha = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); +/*^*/ // printf("\t\t[%d] bHasVertexColor\n",(int)bHasVertexColor); +/*^*/ // printf("\t\t[%d] bHasVertexAlpha\n",(int)bHasVertexAlpha); + + if ( pShader->IsSnapshotting() || (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) + { +/*^*/ // printf("\t\t[1] snapshotting=%d pContextData=%08x pContextData->m_bMaterialVarsChanged=%d \n",(int)pShader->IsSnapshotting(), (int)pContextData, pContextData ? (int)pContextData->m_bMaterialVarsChanged : -1 ); + bool bSeamlessBase = IsBoolSet( info.m_nSeamlessBase, params ); + bool bSeamlessDetail = IsBoolSet( info.m_nSeamlessDetail, params ); + bool bDistanceAlpha = IsBoolSet( info.m_nDistanceAlpha, params ); + bool bHasSelfIllum = (!bHasFlashlight || IsX360() ) && IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + bool bHasEnvmapMask = (!bHasFlashlight || IsX360() ) && info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsTexture(); + bool bHasSelfIllumFresnel = ( !IsTextureSet( info.m_nDetail, params ) ) && ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + bool bHasSelfIllumMask = bHasSelfIllum && IsTextureSet( info.m_nSelfIllumMask, params ); + bool hasSelfIllumInEnvMapMask = + ( info.m_nSelfIllumEnvMapMask_Alpha != -1 ) && + ( params[info.m_nSelfIllumEnvMapMask_Alpha]->GetFloatValue() != 0.0 ) ; + + if ( pShader->IsSnapshotting() ) + { +/*^*/ // printf("\t\t[2] snapshotting...\n"); + + bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + + + if ( info.m_nVertexAlphaTest != -1 && params[info.m_nVertexAlphaTest]->GetIntValue() > 0 ) + { + bHasVertexAlpha = true; + } + + // look at color and alphamod stuff. + // Unlit generic never uses the flashlight + if ( bHasSelfIllumFresnel ) + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + hasNormalMapAlphaEnvmapMask = false; + } + + bool bHasEnvmap = (!bHasFlashlight || IsX360() ) && ( info.m_nEnvmap != -1 ) && params[info.m_nEnvmap]->IsTexture(); + bool bHasLegacyEnvSphereMap = bHasEnvmap && IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); + bool bHasNormal = bVertexLitGeneric || bHasEnvmap || bHasFlashlight || bSeamlessBase || bSeamlessDetail; + if ( IsPC() ) + { + // On PC, LIGHTING_PREVIEW requires normals (they won't use much memory - unlitgeneric isn't used on many models) + bHasNormal = true; + } + + bool bHalfLambert = IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ); + // Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + + if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + int nShadowFilterMode = 0; + if ( bHasFlashlight ) + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + + if ( !IsX360() ) + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + else + { + pShader->SetAdditiveBlendingShadowState( info.m_nEnvmapMask, false ); + } + + if ( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + } + else + { + pShader->SetBlendingShadowState( nBlendType ); + } + } + else + { + pShader->SetBlendingShadowState( nBlendType ); + } + + unsigned int flags = VERTEX_POSITION; + if ( bHasNormal ) + { + flags |= VERTEX_NORMAL; + } +/*^*/ // printf("\t\t[%1d] VERTEX_NORMAL\n",(flags&VERTEX_NORMAL)!=0); + + int userDataSize = 0; + bool bSRGBInputAdapter = false; + + // basetexture + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + if ( bHasBaseTexture ) + { + if ( ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ) + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); + else + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + // If we're on OSX GL on a crappy OS which can't do sRGB from render targets, check to see if we're reading from one... + if ( IsOSX() && !g_pHardwareConfig->CanDoSRGBReadFromRTs() ) + { + ITexture *pBaseTexture = params[info.m_nBaseTexture]->GetTextureValue(); + if ( pBaseTexture && pBaseTexture->IsRenderTarget() ) + { + bSRGBInputAdapter = true; + } + } + } + + if ( bHasEnvmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + } + if ( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Depth texture + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER8 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true ); + userDataSize = 4; // tangent S + } + + if ( bHasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + } + + if ( bHasBump || bHasDiffuseWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + userDataSize = 4; // tangent S + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + } + if ( bHasEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + + if ( bHasVertexColor || bHasVertexAlpha ) + { + flags |= VERTEX_COLOR; + } +/*^*/ // printf("\t\t[%1d] VERTEX_COLOR\n",(flags&VERTEX_COLOR)!=0); +/*^*/ // printf("\t\t[%1d] VERTEX_COLOR_STREAM_1\n",(flags&VERTEX_COLOR_STREAM_1)!=0); + + + if( bHasDiffuseWarp && (!bHasFlashlight || IsX360() ) && !bHasSelfIllumFresnel ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Diffuse warp texture + } + + if ( (info.m_nDepthBlend != -1) && (params[info.m_nDepthBlend]->GetIntValue()) ) + { + if( bHasBump ) + Warning( "DEPTHBLEND not supported by bump mapped variations of vertexlitgeneric to avoid shader bloat. Either remove the bump map or convince a graphics programmer that it's worth it.\n" ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); + } + + if( bHasSelfIllum ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // self illum mask + } + + bool bSRGBWrite = true; + if( (info.m_nLinearWrite != -1) && (params[info.m_nLinearWrite]->GetIntValue() == 1) ) + { + bSRGBWrite = false; + } + + pShaderShadow->EnableSRGBWrite( bSRGBWrite ); + + // texcoord0 : base texcoord + int pTexCoordDim[3] = { 2, 2, 3 }; + int nTexCoordCount = 1; + + if ( IsBoolSet( info.m_nSeparateDetailUVs, params ) ) + { + ++nTexCoordCount; + } + else + { + pTexCoordDim[1] = 0; + } + +#ifndef _X360 + // Special morphed decal information + if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() ) + { + nTexCoordCount = 3; + } +#endif + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; +/*^*/ // printf("\t\t[%1d] VERTEX_FORMAT_COMPRESSED\n",(flags&VERTEX_FORMAT_COMPRESSED)!=0); + +/*^*/ // printf("\t\t -> CShaderShadowDX8::VertexShaderVertexFormat( flags=%08x, texcount=%d )\n",flags,nTexCoordCount); + + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + + if ( bHasBump || bHasDiffuseWarp ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, g_pHardwareConfig->SupportsPixelShaders_2_b() ); +#ifdef _X360 + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); +#endif + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way + { + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b ); + } + else // ps_2_0 + { + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, true ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 ); + } +#endif + } + else // !(bHasBump || bHasDiffuseWarp) + { + bool bDistanceAlphaFromDetail = false; + bool bSoftMask = false; + bool bGlow = false; + bool bOutline = false; + + static ConVarRef mat_reduceparticles( "mat_reduceparticles" ); + bool bDoDepthBlend = IsBoolSet( info.m_nDepthBlend, params ) && !mat_reduceparticles.GetBool(); + + if ( bDistanceAlpha ) + { + bDistanceAlphaFromDetail = IsBoolSet( info.m_nDistanceAlphaFromDetail, params ); + bSoftMask = IsBoolSet( info.m_nSoftEdges, params ); + bGlow = IsBoolSet( info.m_nGlow, params ); + bOutline = IsBoolSet( info.m_nOutline, params ); + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER_COMBO( DONT_GAMMA_CONVERT_VERTEX_COLOR, (! bSRGBWrite ) && bHasVertexColor ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send Gl this way + { + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDoDepthBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB_INPUT_ADAPTER, bSRGBInputAdapter ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b ); + } + else // ps_2_0 + { + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); + SET_STATIC_VERTEX_SHADER_COMBO( DONT_GAMMA_CONVERT_VERTEX_COLOR, bSRGBWrite ? 0 : 1 ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDoDepthBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 ); + } +#endif + } + + if ( bHasFlashlight && !IsX360() ) + { + pShader->FogToBlack(); + } + else + { + pShader->DefaultFog(); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff and the loadout and character select screens. + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + + if ( pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) ) + { +/*^*/ // printf("\t\t[3] pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) TRUE \n"); + if ( ! pContextData ) // make sure allocated + { + ++g_nSnapShots; + pContextData = new CVertexLitGeneric_DX9_Context; + *pContextDataPtr = pContextData; + } + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_SemiStaticCmdsOut.SetPixelShaderFogParams( 21 ); + if ( bHasBaseTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + else + { + if( bHasEnvmap ) + { + // if we only have an envmap (no basetexture), then we want the albedo to be black. + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + } + if ( bHasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nDetail, info.m_nDetailFrame ); + } + if ( bHasSelfIllum ) + { + if ( bHasSelfIllumMask ) // Separate texture for self illum? + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER11, info.m_nSelfIllumMask, -1 ); // Bind it + } + else // else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER11, TEXTURE_BLACK ); // Bind dummy + } + } + + if ( (info.m_nDepthBlend != -1) && (params[info.m_nDepthBlend]->GetIntValue()) ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER10, TEXTURE_FRAME_BUFFER_FULL_DEPTH ); + } + if ( bSeamlessDetail || bSeamlessBase ) + { + float flSeamlessData[4]={ params[info.m_nSeamlessScale]->GetFloatValue(), + 0,0,0}; + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, flSeamlessData ); + } + + if ( info.m_nBaseTextureTransform != -1 ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + } + + + if ( bHasDetailTexture ) + { + if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) ) + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nDetailTextureTransform, info.m_nDetailScale ); + else + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBaseTextureTransform, info.m_nDetailScale ); + //Assert( !bHasBump ); + if ( info.m_nDetailTint != -1 ) + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstantGammaToLinear( 10, info.m_nDetailTint ); + else + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 10, 1, 1, 1, 1 ); + } + } + if ( bDistanceAlpha ) + { + float flSoftStart = GetFloatParam( info.m_nEdgeSoftnessStart, params ); + float flSoftEnd = GetFloatParam( info.m_nEdgeSoftnessEnd, params ); + // set all line art shader parms + bool bScaleEdges = IsBoolSet( info.m_nScaleEdgeSoftnessBasedOnScreenRes, params ); + bool bScaleOutline = IsBoolSet( info.m_nScaleOutlineSoftnessBasedOnScreenRes, params ); + + float flResScale = 1.0; + + float flOutlineStart0 = GetFloatParam( info.m_nOutlineStart0, params ); + float flOutlineStart1 = GetFloatParam( info.m_nOutlineStart1, params ); + float flOutlineEnd0 = GetFloatParam( info.m_nOutlineEnd0, params ); + float flOutlineEnd1 = GetFloatParam( info.m_nOutlineEnd1, params ); + + if ( bScaleEdges || bScaleOutline ) + { + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + flResScale=max( 0.5, max( 1024.0/nWidth, 768/nHeight ) ); + + if ( bScaleEdges ) + { + float flMid = 0.5 * ( flSoftStart + flSoftEnd ); + flSoftStart = clamp( flMid + flResScale * ( flSoftStart - flMid ), 0.05, 0.99 ); + flSoftEnd = clamp( flMid + flResScale * ( flSoftEnd - flMid ), 0.05, 0.99 ); + } + + + if ( bScaleOutline ) + { + // shrink the soft part of the outline, enlarging hard part + float flMidS = 0.5 * ( flOutlineStart1 + flOutlineStart0 ); + flOutlineStart1 = clamp( flMidS + flResScale * ( flOutlineStart1 - flMidS ), 0.05, 0.99 ); + float flMidE = 0.5 * ( flOutlineEnd1 + flOutlineEnd0 ); + flOutlineEnd1 = clamp( flMidE + flResScale * ( flOutlineEnd1 - flMidE ), 0.05, 0.99 ); + } + + } + + float flConsts[]={ + // c5 - glow values + GetFloatParam( info.m_nGlowX, params ), + GetFloatParam( info.m_nGlowY, params ), + GetFloatParam( info.m_nGlowStart, params ), + GetFloatParam( info.m_nGlowEnd, params ), + // c6 - glow color + 0,0,0, // will be filled in + GetFloatParam( info.m_nGlowAlpha, params ), + // c7 - mask range parms + flSoftStart, + flSoftEnd, + 0,0, + // c8 - outline color + 0,0,0, + GetFloatParam( info.m_nOutlineAlpha, params ), + // c9 - outline parms. ordered for optimal ps20 .wzyx swizzling + flOutlineStart0, + flOutlineEnd1, + flOutlineEnd0, + flOutlineStart1, + }; + + if ( info.m_nGlowColor != -1 ) + { + params[info.m_nGlowColor]->GetVecValue( flConsts+4, 3 ); + } + if ( info.m_nOutlineColor != -1 ) + { + params[info.m_nOutlineColor]->GetVecValue( flConsts+12, 3 ); + } + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 5, flConsts, 5 ); + + } + if ( !g_pConfig->m_bFastNoBump ) + { + if ( bHasBump ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); + } + else if ( bHasDiffuseWarp ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + } + else + { + if ( bHasBump ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + } + // Setting w to 1 means use separate selfillummask + float vEnvMapSaturation_SelfIllumMask[4] = {1.0f, 1.0f, 1.0f, 0.0f}; + if ( info.m_nEnvmapSaturation != -1 ) + params[info.m_nEnvmapSaturation]->GetVecValue( vEnvMapSaturation_SelfIllumMask, 3 ); + + vEnvMapSaturation_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 3, vEnvMapSaturation_SelfIllumMask, 1 ); + if ( bHasEnvmap ) + { + pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicStateGammaToLinear( 0, info.m_nEnvmapTint, fTintReplaceFactor ); + } + else + { + pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicStateGammaToLinear( 0, -1, fTintReplaceFactor); + } + + if ( bHasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); + } + + if ( bHasSelfIllumFresnel && (!bHasFlashlight || IsX360() ) ) + { + float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; + float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f; + float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f; + float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f; + + vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias + vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale + vConstScaleBiasExp[2] = flExp; // Exp + vConstScaleBiasExp[3] = flMax; // Brightness + + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 11, vConstScaleBiasExp ); + } + + if( bHasDiffuseWarp && (!bHasFlashlight || IsX360() ) && !bHasSelfIllumFresnel ) + { + if ( r_lightwarpidentity.GetBool() ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_IDENTITY_LIGHTWARP ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER9, info.m_nDiffuseWarpTexture, -1 ); + } + } + + if ( bHasFlashlight ) + { + // Tweaks associated with a given flashlight + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + float tweaks[4]; + tweaks[0] = flashlightState.m_flShadowFilterSize / flashlightState.m_flShadowMapResolution; + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( 2, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( 31, vScreenScale, 1 ); + } + + if ( ( !bHasFlashlight || IsX360() ) && ( info.m_nEnvmapContrast != -1 ) ) + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 2, info.m_nEnvmapContrast ); + + // mat_fullbright 2 handling + bool bLightingOnly = bVertexLitGeneric && mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + if( bLightingOnly ) + { + if ( bHasBaseTexture ) + { + if( ( bHasSelfIllum && !hasSelfIllumInEnvMapMask ) ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + } + if ( bHasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); + } + } + + if ( bHasBump || bHasDiffuseWarp ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + pContextData->m_SemiStaticCmdsOut.SetPixelShaderStateAmbientLightCube( 5 ); + pContextData->m_SemiStaticCmdsOut.CommitPixelShaderLighting( 13 ); + } + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant_W( 4, info.m_nSelfIllumTint, fBlendFactor ); + pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); + pContextData->m_SemiStaticCmdsOut.End(); + } + } + if ( pShaderAPI ) + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + if ( bHasEnvmap ) + { + DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER1, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + bool bFlashlightShadows = false; + if ( bHasFlashlight ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER8, pFlashlightDepthTexture, 0 ); + DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER6, TEXTURE_SHADOW_NOISE_2D ); + } + + SetFlashLightColorFromState( state, pShaderAPI, 28, bFlashlightNoLambert ); + + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER7, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); + } + + + // Set up light combo state + LightState_t lightState = {0, false, false}; + if ( bVertexLitGeneric && (!bHasFlashlight || IsX360() ) ) + { + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + if ( bHasBump || bHasDiffuseWarp ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_vs20 ); + + // Bind ps_2_b shader so we can get shadow mapping... + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way + { + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps20 ); + } + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps30 ); + + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } +#endif + } + else // !( bHasBump || bHasDiffuseWarp ) + { + if ( bAmbientOnly ) // Override selected light combo to be ambient only + { + lightState.m_bAmbientLight = true; + lightState.m_bStaticLight = false; + lightState.m_nNumLights = 0; + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( + LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_vs20 ); + + // Bind ps_2_b shader so we can get shadow mapping + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way + { + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b ); + +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( + LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( + LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps20 ); + } + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 ); +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps30 ); + + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } +#endif + } + + if ( ( info.m_nHDRColorScale != -1 ) && pShader->IsHDREnabled() ) + { + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( 1, params[info.m_nHDRColorScale]->GetFloatValue() ); + } + else + { + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + } + + float eyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + DynamicCmdsOut.SetPixelShaderConstant( 20, eyePos ); + + // Non-bump case does its own depth feathering work + if ( !bHasBump && !bHasDiffuseWarp ) + { + DynamicCmdsOut.SetDepthFeatheringPixelShaderConstant( 13, GetFloatParam( info.m_nDepthBlendScale, params, 50.0f ) ); + } + + float fPixelFogType = pShaderAPI->GetPixelFogCombo() == 1 ? 1 : 0; + float fWriteDepthToAlpha = bWriteDepthToAlpha && IsPC() ? 1 : 0; + float fWriteWaterFogToDestAlpha = (pShaderAPI->GetPixelFogCombo() == 1 && bWriteWaterFogToAlpha) ? 1 : 0; + float fVertexAlpha = bHasVertexAlpha ? 1 : 0; + + // Controls for lerp-style paths through shader code (bump and non-bump have use different register) + float vShaderControls[4] = { fPixelFogType, fWriteDepthToAlpha, fWriteWaterFogToDestAlpha, fVertexAlpha }; + DynamicCmdsOut.SetPixelShaderConstant( 12, vShaderControls, 1 ); + + // flashlightfixme: put this in common code. + if ( bHasFlashlight ) + { + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI, 28, bFlashlightNoLambert ); + + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture.Base(), 4 ); + + pShader->BindTexture( SHADER_SAMPLER7, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + float atten_pos[8]; + atten_pos[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten_pos[1] = flashlightState.m_fLinearAtten; + atten_pos[2] = flashlightState.m_fQuadraticAtten; + atten_pos[3] = flashlightState.m_FarZ; + atten_pos[4] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + atten_pos[5] = flashlightState.m_vecLightOrigin[1]; + atten_pos[6] = flashlightState.m_vecLightOrigin[2]; + atten_pos[7] = 1.0f; + DynamicCmdsOut.SetPixelShaderConstant( 22, atten_pos, 2 ); + + DynamicCmdsOut.SetPixelShaderConstant( 24, worldToTexture.Base(), 4 ); + } + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + pShader->Draw(); + +/*^*/ // printf("\t\tSupportsPixelShaders_2_b() && g_pConfig->UseBumpmapping() && g_pConfig->UsePhong() ) + { + DrawSkin_DX9( pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression, pContextDataPtr ); + return; + } + + bool bReceiveFlashlight = bVertexLitGeneric; + bool bNewFlashlight = IsX360(); + if ( bNewFlashlight ) + { + bReceiveFlashlight = bReceiveFlashlight || ( GetIntParam( info.m_nReceiveFlashlight, params ) != 0 ); + } + bool bHasFlashlight = bReceiveFlashlight && pShader->UsingFlashlight( params ); + + DrawVertexLitGeneric_DX9_Internal( pShader, params, pShaderAPI, + pShaderShadow, bVertexLitGeneric, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h new file mode 100644 index 00000000..0b5b02e4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h @@ -0,0 +1,144 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VERTEXLITGENERIC_DX9_HELPER_H +#define VERTEXLITGENERIC_DX9_HELPER_H + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct VertexLitGeneric_DX9_Vars_t +{ + VertexLitGeneric_DX9_Vars_t() { memset( this, 0xFF, sizeof(*this) ); } + + int m_nBaseTexture; + int m_nWrinkle; + int m_nStretch; + int m_nBaseTextureFrame; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nNormalWrinkle; + int m_nNormalStretch; + int m_nBumpFrame; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nAlphaTestReference; + int m_nVertexAlphaTest; + int m_nFlashlightNoLambert; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + + int m_nSelfIllumTint; + int m_nSelfIllumFresnel; + int m_nSelfIllumFresnelMinMaxExp; + + int m_nPhongExponent; + int m_nPhongTint; + int m_nPhongAlbedoTint; + int m_nPhongExponentTexture; + int m_nDiffuseWarpTexture; + int m_nPhongWarpTexture; + int m_nPhongBoost; + int m_nPhongFresnelRanges; + int m_nSelfIllumEnvMapMask_Alpha; + int m_nAmbientOnly; + int m_nHDRColorScale; + int m_nPhong; + int m_nBaseMapAlphaPhongMask; + int m_nEnvmapFresnel; + + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + + // Rim lighting parameters + int m_nRimLight; + int m_nRimLightPower; + int m_nRimLightBoost; + int m_nRimMask; + + int m_nSeamlessScale; + int m_nSeamlessBase; + int m_nSeamlessDetail; + + // distance coded line art parameters + int m_nDistanceAlpha; + int m_nDistanceAlphaFromDetail; + + int m_nSoftEdges; + int m_nEdgeSoftnessStart; + int m_nEdgeSoftnessEnd; + int m_nScaleEdgeSoftnessBasedOnScreenRes; + + int m_nGlow; + int m_nGlowColor; + int m_nGlowAlpha; + int m_nGlowStart; + int m_nGlowEnd; + int m_nGlowX; + int m_nGlowY; + int m_nOutline; + int m_nOutlineColor; + int m_nOutlineAlpha; + int m_nOutlineStart0; + int m_nOutlineStart1; + int m_nOutlineEnd0; + int m_nOutlineEnd1; + int m_nScaleOutlineSoftnessBasedOnScreenRes; + + int m_nSeparateDetailUVs; + int m_nDetailTextureTransform; + + int m_nLinearWrite; + int m_nGammaColorRead; + + int m_nDetailTint; + int m_nInvertPhongMask; + + int m_nDepthBlend; + int m_nDepthBlendScale; + + int m_nSelfIllumMask; + int m_nReceiveFlashlight; + + int m_nBlendTintByBaseAlpha; + + int m_nTintReplacesBaseColor; + +}; + +void InitParamsVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ); +void InitVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ); +void DrawVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr + ); + + +#endif // VERTEXLITGENERIC_DX9_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_envmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_envmap.psh new file mode 100644 index 00000000..e539da67 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_envmap.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map + +mul r0, t0, c3 ; base times modulation +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh new file mode 100644 index 00000000..a5810b5e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh @@ -0,0 +1,137 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" +# STATIC: "TEETH" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos ); + +alloc $worldPos +alloc $worldNormal +alloc $projPos + +if( 0 ) +{ + ; NOTE: Don't do this optimization anymore since it would mean a gazillion combos + ; Special case for static prop lighting. We can go directly from + ; world to proj space for position, with the exception of z, which + ; is needed for fogging *if* height fog is enabled. + + ; NOTE: We don't use this path if $envmap is defined since we need + ; worldpos for envmapping. + dp4 $projPos.x, $vPos, $cModelViewProj0 + dp4 $projPos.y, $vPos, $cModelViewProj1 + dp4 $projPos.z, $vPos, $cModelViewProj2 + dp4 $projPos.w, $vPos, $cModelViewProj3 + ; normal + dp3 $worldNormal.x, $vNormal, $cModel0 + dp3 $worldNormal.y, $vNormal, $cModel1 + dp3 $worldNormal.z, $vNormal, $cModel2 + + ; Need this for height fog if it's enabled and for height clipping + dp4 $worldPos.z, $vPos, $cModel2 +} +else +{ + &SkinPositionAndNormal( $worldPos, $worldNormal ); + + if( $SKINNING == 1 ) + { + &Normalize( $worldNormal ); + } + + ;------------------------------------------------------------------------------ + ; Transform the position from world to view space + ;------------------------------------------------------------------------------ + dp4 $projPos.x, $worldPos, $cViewProj0 + dp4 $projPos.y, $worldPos, $cViewProj1 + dp4 $projPos.z, $worldPos, $cViewProj2 + dp4 $projPos.w, $worldPos, $cViewProj3 +} + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +; base tex coords +dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_6 +dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_7 + +; normal map coords +;dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_8 +;dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_9 + +; spotlight texcoords +dp4 oT0.x, $worldPos, $SHADER_SPECIFIC_CONST_1 +dp4 oT0.y, $worldPos, $SHADER_SPECIFIC_CONST_2 +dp4 oT0.z, $worldPos, $SHADER_SPECIFIC_CONST_3 +dp4 oT0.w, $worldPos, $SHADER_SPECIFIC_CONST_4 + +local( $worldPosToLightVector, $distFactors ); + +alloc $worldPosToLightVector + +sub $worldPosToLightVector, $SHADER_SPECIFIC_CONST_0, $worldPos +mov oT2, $worldPosToLightVector + +local( $distatten ); +alloc $distatten +; $distatten = [ 1, 1/dist, 1/distsquared ] + +; dist squared +dp3 $distatten.z, $worldPosToLightVector, $worldPosToLightVector + +; oodist +rsq $distatten.y, $distatten.z + +mov $distatten.x, $cOne + +local( $dist ); +alloc $dist +mul $dist.x, $distatten.z, $distatten.y + +rcp $distatten.z, $distatten.z ; 1/distsquared + +local( $endFalloffFactor ); +alloc $endFalloffFactor + +; ( dist - farZ ) +sub $endFalloffFactor.x, $dist.x, $SHADER_SPECIFIC_CONST_5.w +; 1 / ( (0.6f * farZ) - farZ) +mul $endFalloffFactor, $endFalloffFactor.x, $SHADER_SPECIFIC_CONST_0.w +max $endFalloffFactor, $endFalloffFactor, $cZero +min $endFalloffFactor, $endFalloffFactor, $cOne + +local( $vertAtten ); +alloc $vertAtten +dp3 $vertAtten, $distatten, $SHADER_SPECIFIC_CONST_5 +mul $vertAtten, $vertAtten, $endFalloffFactor + +if( $TEETH ) +{ + alloc $mouthAtten + dp3 $mouthAtten, $worldNormal.xyz, $SHADER_SPECIFIC_CONST_10.xyz + max $mouthAtten, $cZero, $mouthAtten + mul $mouthAtten, $mouthAtten, $SHADER_SPECIFIC_CONST_10.w + mul $vertAtten, $vertAtten, $mouthAtten + free $mouthAtten +} + +mov oD0, $vertAtten + +mov oT3.xyz, $worldNormal.xyz + + +free $dist +free $endFalloffFactor +free $worldPos +free $worldNormal +free $projPos +free $worldPosToLightVector +free $distatten +free $vertAtten diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_inc.vsh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_inc.vsh new file mode 100644 index 00000000..da6b6bf9 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_inc.vsh @@ -0,0 +1,145 @@ +#include "macros.vsh" + +sub VertexLitGeneric +{ + local( $detail ) = shift; + local( $envmap ) = shift; + local( $envmapcameraspace ) = shift; + local( $envmapsphere ) = shift; + local( $decal ) = shift; + + local( $worldPos, $worldNormal, $projPos ); + local( $reflectionVector ); + + ;------------------------------------------------------------------------------ + ; Vertex blending + ;------------------------------------------------------------------------------ + &AllocateRegister( \$worldPos ); + &AllocateRegister( \$worldNormal ); + &AllocateRegister( \$projPos ); +; if( $g_staticLightType eq "static" && $g_ambientLightType eq "none" && +; $g_localLightType1 eq "none" && $g_localLightType2 eq "none" && !$envmap ) + if( 0 ) + { + ; NOTE: Don't do this optimization anymore since it would mean a gazillion combos + ; of the flashlight shaders + ; Special case for static prop lighting. We can go directly from + ; world to proj space for position, with the exception of z, which + ; is needed for fogging *if* height fog is enabled. + + ; NOTE: We don't use this path if $envmap is defined since we need + ; worldpos for envmapping. + dp4 $projPos.x, $vPos, $cModelViewProj0 + dp4 $projPos.y, $vPos, $cModelViewProj1 + dp4 $projPos.z, $vPos, $cModelViewProj2 + dp4 $projPos.w, $vPos, $cModelViewProj3 + ; normal + dp3 $worldNormal.x, $vNormal, $cModel0 + dp3 $worldNormal.y, $vNormal, $cModel1 + dp3 $worldNormal.z, $vNormal, $cModel2 + + ; Need this for height fog if it's enabled and for height clipping + dp4 $worldPos.z, $vPos, $cModel2 + } + else + { + &SkinPositionAndNormal( $worldPos, $worldNormal ); + + if( $SKINNING == 1 ) + { + &Normalize( $worldNormal ); + } + + ;------------------------------------------------------------------------------ + ; Transform the position from world to view space + ;------------------------------------------------------------------------------ + dp4 $projPos.x, $worldPos, $cViewProj0 + dp4 $projPos.y, $worldPos, $cViewProj1 + dp4 $projPos.z, $worldPos, $cViewProj2 + dp4 $projPos.w, $worldPos, $cViewProj3 + } + + mov oPos, $projPos + + ;------------------------------------------------------------------------------ + ; Fog + ;------------------------------------------------------------------------------ + &CalcFog( $worldPos, $projPos ); + &FreeRegister( \$projPos ); + + ;------------------------------------------------------------------------------ + ; Lighting + ;------------------------------------------------------------------------------ + &DoLighting( $worldPos, $worldNormal ); + + if( !$envmap ) + { + &FreeRegister( \$worldNormal ); + } + + ;------------------------------------------------------------------------------ + ; Texture coordinates + ;------------------------------------------------------------------------------ + + dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 + dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + if( $envmap ) + { + if( $envmapcameraspace ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + + ; transform reflection vector into view space + dp3 oT1.x, $reflectionVector, $cViewModel0 + dp3 oT1.y, $reflectionVector, $cViewModel1 + dp3 oT1.z, $reflectionVector, $cViewModel2 + + &FreeRegister( \$reflectionVector ); + } + elsif( $envmapsphere ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + &ComputeSphereMapTexCoords( $reflectionVector, "oT1" ); + + &FreeRegister( \$reflectionVector ); + } + else + { + &ComputeReflectionVector( $worldPos, $worldNormal, "oT1" ); + } + + ; envmap mask + dp4 oT2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + dp4 oT2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + + &FreeRegister( \$worldNormal ); + } + else + { + if ( $decal ) + { + &AllocateRegister( \$temp ); + mov $temp, $vTexCoord0 + sub oT1.xyz, $temp.xyz, $vTexCoord1.xyz + sub oT2.xyz, $vTexCoord2.xyz, $temp.xyz + &FreeRegister( \$temp ); + } + else + { + ; YUCK! This is to make texcoords continuous for mat_softwaretl + mov oT1, $cZero + mov oT2, $cZero + } + } + + if( $detail ) + { + dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 + dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + } + &FreeRegister( \$worldPos ); +} + diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh new file mode 100644 index 00000000..dd19efce --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh @@ -0,0 +1,5 @@ +ps.1.1 + +mov r0, v0 + + diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc b/mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc new file mode 100644 index 00000000..70ad7094 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc @@ -0,0 +1,9 @@ +struct PS_INPUT +{ + float3 vColor0 : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return float4( i.vColor0, 1.0 ); +} diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh new file mode 100644 index 00000000..c10600e3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, t2 ; Envmap * mask +mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh new file mode 100644 index 00000000..321e797b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh @@ -0,0 +1,25 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 +tex t1 + +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) + +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh new file mode 100644 index 00000000..e7c52910 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh @@ -0,0 +1,26 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 ; base +tex t1 ; env map +tex t2 ; mask + +mul r0.rgb, t0, c3 + ; base times modulation +mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha + +mul r1, t2, t1 ; envmapmask * envmap +mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting diff --git a/mp/src/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh b/mp/src/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh new file mode 100644 index 00000000..c0ab2765 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh @@ -0,0 +1,22 @@ +vs.1.1 + +# STATIC: "HALF_LAMBERT" "0..1" +# STATIC: "ENVMAP" "0..1" +# STATIC: "ENVMAPCAMERASPACE" "0..0" +# STATIC: "ENVMAPSPHERE" "0..1" +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "LIGHT_COMBO" "0..21" +# DYNAMIC: "SKINNING" "0..1" + +# can't have envmapshere or envmapcameraspace without envmap +# SKIP: !$ENVMAP && ( $ENVMAPSPHERE || $ENVMAPCAMERASPACE ) + +# can't have both envmapsphere and envmapcameraspace +# SKIP: $ENVMAPSPHERE && $ENVMAPCAMERASPACE + +# decal is by itself +# SKIP: $DECAL && ( $DETAIL || $ENVMAP || $ENVMAPCAMERASPACE || $ENVMAPSPHERE ) + +#include "VertexLitGeneric_inc.vsh" + +&VertexLitGeneric( 1, $ENVMAP, $ENVMAPCAMERASPACE, $ENVMAPSPHERE, 0 ); diff --git a/mp/src/materialsystem/stdshaders/volume_clouds.cpp b/mp/src/materialsystem/stdshaders/volume_clouds.cpp new file mode 100644 index 00000000..1421dbb4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/volume_clouds.cpp @@ -0,0 +1,59 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "volume_clouds_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( VolumeClouds, VolumeClouds_dx9 ) +BEGIN_VS_SHADER( VolumeClouds_dx9, "VolumeClouds" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Texture 1" ) + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "Texture 2" ) + SHADER_PARAM( BASETEXTURE3, SHADER_PARAM_TYPE_TEXTURE, "", "Texture 3" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) + END_SHADER_PARAMS + + void SetupVarsVolumeClouds( VolumeCloudsVars_t &info ) + { + info.m_nRefractAmount = REFRACTAMOUNT; + info.m_nTexture1 = BASETEXTURE; + info.m_nTexture2 = BASETEXTURE2; + info.m_nTexture3 = BASETEXTURE3; + info.m_nTime = TIME; + } + + SHADER_INIT_PARAMS() + { + VolumeCloudsVars_t info; + SetupVarsVolumeClouds( info ); + InitParamsVolumeClouds( this, params, pMaterialName, info ); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + // Fallback to unlit generic + return "UnlitGeneric_DX8"; + } + + return 0; + } + + SHADER_INIT + { + VolumeCloudsVars_t info; + SetupVarsVolumeClouds( info ); + InitVolumeClouds( this, params, info ); + } + + SHADER_DRAW + { + VolumeCloudsVars_t info; + SetupVarsVolumeClouds( info ); + DrawVolumeClouds( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/volume_clouds_helper.cpp b/mp/src/materialsystem/stdshaders/volume_clouds_helper.cpp new file mode 100644 index 00000000..cd2e889e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/volume_clouds_helper.cpp @@ -0,0 +1,138 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "volume_clouds_helper.h" +#include "convar.h" + +// Auto generated inc files +#include "volume_clouds_vs20.inc" +#include "volume_clouds_ps20.inc" +#include "volume_clouds_ps20b.inc" + + +void InitParamsVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VolumeCloudsVars_t &info ) +{ + // Set material flags + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nTime, 0.0f ); + + // Set material parameter default values + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nRefractAmount, kDefaultRefractAmount ); +} + +void InitVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, VolumeCloudsVars_t &info ) +{ + // Load textures + if ( (info.m_nTexture1 != -1) && params[info.m_nTexture1]->IsDefined() ) + { + pShader->LoadTexture( info.m_nTexture1, TEXTUREFLAGS_SRGB ); + } + + if ( (info.m_nTexture2 != -1) && params[info.m_nTexture2]->IsDefined() ) + { + pShader->LoadTexture( info.m_nTexture2, TEXTUREFLAGS_SRGB ); + } + + if ( (info.m_nTexture3 != -1) && params[info.m_nTexture3]->IsDefined() ) + { + pShader->LoadTexture( info.m_nTexture3, TEXTUREFLAGS_SRGB ); + } +} + +void DrawVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, VolumeCloudsVars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // Vertex Shader + DECLARE_STATIC_VERTEX_SHADER( volume_clouds_vs20 ); + SET_STATIC_VERTEX_SHADER( volume_clouds_vs20 ); + + // Pixel Shader + if( g_pHardwareConfig->SupportsPixelShaders_2_b() && !IsOpenGL() ) // Always send POSIX down the 20 path (rg - why?) + { + DECLARE_STATIC_PIXEL_SHADER( volume_clouds_ps20b ); + SET_STATIC_PIXEL_SHADER( volume_clouds_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( volume_clouds_ps20 ); + SET_STATIC_PIXEL_SHADER( volume_clouds_ps20 ); + } + + // Textures + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBWrite( true ); + + // Blending + pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableAlphaWrites( false ); + + // !!! We need to turn this back on because EnableAlphaBlending() above disables it! + //pShaderShadow->EnableDepthWrites( true ); + } + DYNAMIC_STATE + { + // Set Vertex Shader Combos + DECLARE_DYNAMIC_VERTEX_SHADER( volume_clouds_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( volume_clouds_vs20 ); + + // Set Vertex Shader Constants + + // Time + float vPackedVsConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + float flTime = IS_PARAM_DEFINED( info.m_nTime ) && params[info.m_nTime]->GetFloatValue() > 0.0f ? params[info.m_nTime]->GetFloatValue() : pShaderAPI->CurrentTime(); + float flRotateSpeed = 0.065f; + vPackedVsConst1[0] = flTime * flRotateSpeed * 1.0f; + vPackedVsConst1[1] = flTime * flRotateSpeed * 2.0f; + vPackedVsConst1[2] = flTime * flRotateSpeed * 4.0f; + vPackedVsConst1[0] -= (float)( (int)( vPackedVsConst1[0] / ( 2.0f * 3.14159f ) ) ) * 2.0f * 3.14159f; + vPackedVsConst1[1] -= (float)( (int)( vPackedVsConst1[1] / ( 2.0f * 3.14159f ) ) ) * 2.0f * 3.14159f; + vPackedVsConst1[2] -= (float)( (int)( vPackedVsConst1[2] / ( 2.0f * 3.14159f ) ) ) * 2.0f * 3.14159f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, vPackedVsConst1, 1 ); + + // Set Pixel Shader Combos + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() && !IsOpenGL() ) // Always send POSIX down the 20 path (rg - why?) + { + DECLARE_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20 ); + } + + // Bind textures + pShader->BindTexture( SHADER_SAMPLER0, info.m_nTexture1 ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nTexture2 ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nTexture3 ); + + // Set Pixel Shader Constants + float vEyePos[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + pShaderAPI->SetPixelShaderConstant( 5, vEyePos, 1 ); + + float vPackedConst6[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPackedConst6[0] = IS_PARAM_DEFINED( info.m_nRefractAmount ) ? params[info.m_nRefractAmount]->GetFloatValue() : kDefaultRefractAmount; + vPackedConst6[1] = vPackedVsConst1[0]; // Time % 1000 + pShaderAPI->SetPixelShaderConstant( 6, vPackedConst6, 1 ); + } + pShader->Draw(); +} diff --git a/mp/src/materialsystem/stdshaders/volume_clouds_helper.h b/mp/src/materialsystem/stdshaders/volume_clouds_helper.h new file mode 100644 index 00000000..abbb63b7 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/volume_clouds_helper.h @@ -0,0 +1,41 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef VOLUME_CLOUDS_HELPER_H +#define VOLUME_CLOUDS_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct VolumeCloudsVars_t +{ + VolumeCloudsVars_t() { memset( this, 0xFF, sizeof( VolumeCloudsVars_t ) ); } + + int m_nRefractAmount; + int m_nTexture1; + int m_nTexture2; + int m_nTexture3; + int m_nTime; +}; + +// Default values (Arrays should only be vec[4]) +static const float kDefaultRefractAmount = 0.1f; + +void InitParamsVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VolumeCloudsVars_t &info ); +void InitVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, VolumeCloudsVars_t &info ); +void DrawVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, VolumeCloudsVars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // VolumeClouds_HELPER_H diff --git a/mp/src/materialsystem/stdshaders/volume_clouds_ps2x.fxc b/mp/src/materialsystem/stdshaders/volume_clouds_ps2x.fxc new file mode 100644 index 00000000..7435f305 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/volume_clouds_ps2x.fxc @@ -0,0 +1,66 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +// Includes ======================================================================================= +#include "common_vertexlitgeneric_dx9.h" + +// Texture Samplers =============================================================================== +sampler g_tInnerSampler : register( s0 ); +sampler g_tMiddleSampler : register( s1 ); +sampler g_tOuterSampler : register( s2 ); + +// Shaders Constants and Globals ================================================================== +//const float4 g_vPackedConst6 : register( c6 ); +//#define g_flTime g_vPackedConst6.w + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float4 v2DTangentViewVector01 : TEXCOORD0; + float4 vUv01 : TEXCOORD1; + float4 v2DTangentViewVector2_vUv2 : TEXCOORD2; +}; + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + float4 vFinalColor = float4( 0.0f, 0.0f, 0.0f, 1.0f ); + +#if defined(SHADER_MODEL_PS_2_0) + float flNumLayers = 2.0f; +#else + float flNumLayers = 10.0f; +#endif + + //float flColorDim = 1.0f; + for ( float j=flNumLayers-1.0f; j>=0.0f; j-=1.0f ) // From hightest to lowest layer + { + float4 vInnerTexel = tex2D( g_tInnerSampler, saturate( i.vUv01.xy + i.v2DTangentViewVector01.xy * 0.005 * j ) ); + float4 vMiddleTexel = tex2D( g_tMiddleSampler, saturate( i.vUv01.wz + i.v2DTangentViewVector01.wz * 0.005 * j ) ); + float4 vOuterTexel = tex2D( g_tOuterSampler, saturate( i.v2DTangentViewVector2_vUv2.wz + i.v2DTangentViewVector2_vUv2.xy * 0.005 * j ) ); + + float4 vThisTexel; + vThisTexel.rgb = ( vInnerTexel.rgb * vInnerTexel.a ) + ( vMiddleTexel.rgb * vMiddleTexel.a ) + ( vOuterTexel.rgb * vOuterTexel.a ); + vThisTexel.a = 1.0f - ( ( 1.0f - vOuterTexel.a ) * ( 1.0f - vMiddleTexel.a ) * ( 1.0f - vInnerTexel.a ) ); + + //vThisTexel.rgb *= flColorDim; + //flColorDim *= 0.95f; + + // 5.0 and 0.8625 are magic numbers that look good with the current textures + float flBlendValue = saturate( pow( vThisTexel.a, lerp( 5.0f, 0.8625f, saturate( j/(flNumLayers-1.0f) ) ) ) ); + + vFinalColor.rgb = vThisTexel.rgb + ( vFinalColor.rgb * ( 1.0f - flBlendValue ) ); + vFinalColor.a *= 1.0f - flBlendValue; // Dest alpha scalar + } + + //===============// + // Combine terms // + //===============// + float4 result; + result.rgb = vFinalColor.rgb; + result.a = 1.0f - vFinalColor.a; + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); //go back to final output when it'll fit. +} diff --git a/mp/src/materialsystem/stdshaders/volume_clouds_vs20.fxc b/mp/src/materialsystem/stdshaders/volume_clouds_vs20.fxc new file mode 100644 index 00000000..ccab2574 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/volume_clouds_vs20.fxc @@ -0,0 +1,103 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +// Includes +#include "common_vs_fxc.h" + +// Globals +static const bool g_bSkinning = SKINNING ? true : false; + +const float3 g_vTime : register( SHADER_SPECIFIC_CONST_0 ); +#define g_flTime1x g_vTime.x +#define g_flTime2x g_vTime.y +#define g_flTime4x g_vTime.z + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); + +// Structs +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vNormal : NORMAL; // Normal + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base texture coordinates + float4 vUserData : TANGENT; +}; + +struct VS_OUTPUT +{ + float4 vProjPosition : POSITION; // Projection-space position + float4 v2DTangentViewVector01 : TEXCOORD0; + float4 vUv01 : TEXCOORD1; + float4 v2DTangentViewVector2_vUv2 : TEXCOORD2; +}; + +// Main +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + + // Decompress compressed normal and tangent + float4 vObjPosition = i.vPos.xyzw; + float3 vObjNormal; + float4 vObjTangent; + DecompressVertex_NormalTangent( i.vNormal, i.vUserData, vObjNormal, vObjTangent ); + + // Transform the position + float3 vWorldPosition = { 0.0f, 0.0f, 0.0f }; + float3 vWorldNormal = { 0.0f, 0.0f, 0.0f }; + float3 vWorldTangent = { 0.0f, 0.0f, 0.0f }; + float3 vWorldBinormal = { 0.0f, 0.0f, 0.0f }; + SkinPositionNormalAndTangentSpace( g_bSkinning, vObjPosition, vObjNormal.xyz, vObjTangent.xyzw, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal, vWorldTangent, vWorldBinormal ); + vWorldNormal.xyz = normalize( vWorldNormal.xyz ); + vWorldTangent.xyz = normalize( vWorldTangent.xyz ); + vWorldBinormal.xyz = normalize( vWorldBinormal.xyz ); + + // Transform into projection space + float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.vProjPosition = vProjPosition; + + // View vector + float3 vWorldViewVector = normalize( vWorldPosition.xyz - cEyePos.xyz ); + float3 vTangentViewVector = Vec3WorldToTangentNormalized( vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + // Texture coordinates + float4 mRotate; + float2 vBaseUv = i.vTexCoord0.xy; + + // Inner layer + mRotate.x = cos( g_flTime4x ); + mRotate.y = -sin( g_flTime4x ); + mRotate.z = -mRotate.y; + mRotate.w = mRotate.x; + o.vUv01.xy = ( vBaseUv.xy - 0.5f ) * 1.0f; + o.vUv01.xy = float2( dot( o.vUv01.xy, mRotate.xy ), dot( o.vUv01.xy, mRotate.zw ) ); + o.vUv01.xy += 0.5f; + o.v2DTangentViewVector01.xy = float2( dot( vTangentViewVector.xy, mRotate.xy ), dot( vTangentViewVector.xy, mRotate.zw ) ); + + // Middle layer + mRotate.x = cos( g_flTime2x ); + mRotate.y = -sin( g_flTime2x ); + mRotate.z = -mRotate.y; + mRotate.w = mRotate.x; + o.vUv01.wz = ( vBaseUv.xy - 0.5f ) * 1.0f; + o.vUv01.wz = float2( dot( o.vUv01.wz, mRotate.xy ), dot( o.vUv01.wz, mRotate.zw ) ); + o.vUv01.wz += 0.5f; + o.v2DTangentViewVector01.wz = float2( dot( vTangentViewVector.xy, mRotate.xy ), dot( vTangentViewVector.xy, mRotate.zw ) ); + + // Outer layer + mRotate.x = cos( g_flTime1x ); + mRotate.y = -sin( g_flTime1x ); + mRotate.z = -mRotate.y; + mRotate.w = mRotate.x; + float2 vUv2 = ( vBaseUv.xy - 0.5f ) * 1.0f; + vUv2.xy = float2( dot( vUv2.xy, mRotate.xy ), dot( vUv2.xy, mRotate.zw ) ); + vUv2.xy += 0.5f; + o.v2DTangentViewVector2_vUv2.wz = vUv2.xy; + o.v2DTangentViewVector2_vUv2.xy = float2( dot( vTangentViewVector.xy, mRotate.xy ), dot( vTangentViewVector.xy, mRotate.zw ) ); + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/vr_distort_hud.cpp b/mp/src/materialsystem/stdshaders/vr_distort_hud.cpp new file mode 100644 index 00000000..b78a3e51 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vr_distort_hud.cpp @@ -0,0 +1,224 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "BaseVSShader.h" +#include "commandbuilder.h" + +#include "vr_distort_hud_ps20.inc" +#include "vr_distort_hud_ps20b.inc" +#include "vr_distort_hud_vs20.inc" +#include "vr_distort_hud_ps30.inc" +#include "vr_distort_hud_vs30.inc" + +#include "../materialsystem_global.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +class CVRDistortTexture_DX9_Context : public CBasePerMaterialContextData +{ +public: + uint8 *m_pStaticCmds; + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; + + void ResetStaticCmds( void ) + { + if ( m_pStaticCmds ) + { + delete[] m_pStaticCmds; + m_pStaticCmds = NULL; + } + } + + CVRDistortTexture_DX9_Context( void ) + { + m_pStaticCmds = NULL; + } + + ~CVRDistortTexture_DX9_Context( void ) + { + ResetStaticCmds(); + } + +}; + + +BEGIN_VS_SHADER( vr_distort_hud, "Help for hud warp" ) + BEGIN_SHADER_PARAMS + + SHADER_PARAM( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_gui", "" ) + SHADER_PARAM( DISTORTMAP, SHADER_PARAM_TYPE_TEXTURE, "vr_distort_map_left", "" ) + SHADER_PARAM( DISTORTBOUNDS, SHADER_PARAM_TYPE_VEC4, "[ 0 0 1 1 ]", "" ) + SHADER_PARAM( HUDTRANSLUCENT, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( HUDUNDISTORT, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( DISTORTMAP, TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NODEBUGOVERRIDE | TEXTUREFLAGS_SINGLECOPY | + TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT ); + } + + SHADER_DRAW + { + CVRDistortTexture_DX9_Context *pContextData = reinterpret_cast< CVRDistortTexture_DX9_Context *> ( *pContextDataPtr ); + bool bNeedRegenStaticCmds = ( !pContextData ) || pShaderShadow; + + if ( !pContextData ) // make sure allocated + { + pContextData = new CVRDistortTexture_DX9_Context; + *pContextDataPtr = pContextData; + } + + if ( pShaderShadow || bNeedRegenStaticCmds ) + { + pContextData->ResetStaticCmds(); + CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; + + staticCmdsBuf.BindTexture( this, SHADER_SAMPLER0, BASETEXTURE, -1 ); + staticCmdsBuf.BindTexture( this, SHADER_SAMPLER1, DISTORTMAP, -1 ); + + staticCmdsBuf.End(); + + // now, copy buf + pContextData->m_pStaticCmds = new uint8[ staticCmdsBuf.Size() ]; + memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); + } + + if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) + { + // need to regenerate the semistatic cmds + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_bMaterialVarsChanged = false; + + pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); + pContextData->m_SemiStaticCmdsOut.End(); + } + + SHADOW_STATE + { + SetInitialShadowState( ); + + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableDepthTest( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->EnableSRGBWrite( true ); + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); + + if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) ) + { + pShaderShadow->EnableAlphaTest( true ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + else + { + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->EnableBlending( false ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ZERO ); + } + + DefaultFog(); + + int nFormat = 0; + nFormat |= VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( nFormat, 2, 0, 0 ); + + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_STATIC_VERTEX_SHADER( vr_distort_hud_vs20 ); + SET_STATIC_VERTEX_SHADER( vr_distort_hud_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( vr_distort_hud_ps20b ); + SET_STATIC_PIXEL_SHADER( vr_distort_hud_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( vr_distort_hud_ps20 ); + SET_STATIC_PIXEL_SHADER( vr_distort_hud_ps20 ); + } + } + else + { + DECLARE_STATIC_VERTEX_SHADER( vr_distort_hud_vs30 ); + SET_STATIC_VERTEX_SHADER( vr_distort_hud_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vr_distort_hud_ps30 ); + SET_STATIC_PIXEL_SHADER( vr_distort_hud_ps30 ); + } + } + + DYNAMIC_STATE + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + pShaderAPI->SetDefaultState(); + + SetPixelShaderConstant( 0, DISTORTBOUNDS ); + SetPixelShaderConstant( 1, HUDTRANSLUCENT ); + + int hudUndistortEnabled = ( params[ HUDUNDISTORT ]->GetIntValue() == 0 ) ? 0 : 1; + + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_HUDUNDISTORT, hudUndistortEnabled ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_HUDUNDISTORT, hudUndistortEnabled ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20 ); + } + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_HUDUNDISTORT, hudUndistortEnabled ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps30 ); + } + + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + + Draw(); + + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc b/mp/src/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc new file mode 100644 index 00000000..331c1897 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc @@ -0,0 +1,78 @@ +// DYNAMIC: "CMBO_HUDUNDISTORT" "0..1" + +#include "shader_constant_register_map.h" +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler DistortMapTextureSampler : register( s1 ); + +const float4 DistortBounds : register( c0 ); +const int bHudTranslucent : register( c1 ); + +struct PS_INPUT +{ + float2 vBaseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float2 vOriginal = i.vBaseTexCoord.xy; + + + // The full uv 0->1 range of the base texture here is shifted/scaled so that it maps + // to the region that would be minUV->maxUV of the base texture in the regular undistort + // code. This lets us overlay a higher-resolution inset rectangle directly onto the + // render target with undistort, which results in a much higher-quality HUD. + + float2 minUV = DistortBounds.xy; + float2 maxUV = DistortBounds.zw; + float2 scaleUV = 1.0 / ( maxUV - minUV ); + + + float2 vGreen; + float4 vFinal; + + #if ( CMBO_HUDUNDISTORT ) + { + float4 vRead = tex2D( DistortMapTextureSampler, vOriginal ); + + float2 vRed = vRead.xy; + float2 vBlue = vRead.zw; + + vGreen = ( vRed + vBlue ) / 2.0; + + vRed = ( vRed - minUV ) * scaleUV; + vGreen = ( vGreen - minUV ) * scaleUV; + vBlue = ( vBlue - minUV ) * scaleUV; + + vFinal.r = tex2D( BaseTextureSampler, vRed ).r; + vFinal.ga = tex2D( BaseTextureSampler, vGreen ).ga; + vFinal.b = tex2D( BaseTextureSampler, vBlue ).b; + } + #else + { + vGreen = ( vOriginal - minUV ) * scaleUV; + vFinal = tex2D( BaseTextureSampler, vGreen ); + } + #endif + + + // When the HUD isn't supposed to be rendered as translucent, some of its elements do occasionally have non-unit alpha. + // We always have blending and alphatest enabled here, so if the hud itself is not supposed to be translucent we need + // to fix up the alphas. + vFinal.a = lerp( 1, vFinal.a, bHudTranslucent ); + + + // Smooth off the edges of the quad. This also gives (0,0,0,0) in the outer areas, for alpha test and for blackout. + + const float edgeRampFrac = 0.005; + float2 uvEdgeRamp = smoothstep( float2(-edgeRampFrac,-edgeRampFrac), float2(edgeRampFrac,edgeRampFrac), vGreen ) * + ( 1 - smoothstep( float2(1-edgeRampFrac,1-edgeRampFrac), float2(1+edgeRampFrac,1+edgeRampFrac), vGreen ) ); + + float edgeRamp = uvEdgeRamp.x * uvEdgeRamp.y; + + vFinal *= edgeRamp; + + + return vFinal; +} diff --git a/mp/src/materialsystem/stdshaders/vr_distort_hud_vs20.fxc b/mp/src/materialsystem/stdshaders/vr_distort_hud_vs20.fxc new file mode 100644 index 00000000..b82bfa13 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vr_distort_hud_vs20.fxc @@ -0,0 +1,26 @@ +#include "common_vs_fxc.h" + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + o.vProjPos = v.vPos; + o.vBaseTexCoord = v.vBaseTexCoord; + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/vr_distort_texture.cpp b/mp/src/materialsystem/stdshaders/vr_distort_texture.cpp new file mode 100644 index 00000000..1e87d72a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vr_distort_texture.cpp @@ -0,0 +1,213 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "BaseVSShader.h" +#include "commandbuilder.h" + +#include "vr_distort_texture_ps20.inc" +#include "vr_distort_texture_ps20b.inc" +#include "vr_distort_texture_vs20.inc" +#include "vr_distort_texture_ps30.inc" +#include "vr_distort_texture_vs30.inc" + +#include "../materialsystem_global.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + + + + + + +class CVRDistortTexture_DX9_Context : public CBasePerMaterialContextData +{ +public: + uint8 *m_pStaticCmds; + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; + + void ResetStaticCmds( void ) + { + if ( m_pStaticCmds ) + { + delete[] m_pStaticCmds; + m_pStaticCmds = NULL; + } + } + + CVRDistortTexture_DX9_Context( void ) + { + m_pStaticCmds = NULL; + } + + ~CVRDistortTexture_DX9_Context( void ) + { + ResetStaticCmds(); + } + +}; + + +static const float kAllZeros[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + +BEGIN_VS_SHADER( vr_distort_texture, "Help for warp" ) + BEGIN_SHADER_PARAMS + + SHADER_PARAM( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( DISTORTMAP, SHADER_PARAM_TYPE_TEXTURE, "vr_distort_map", "" ) + SHADER_PARAM( USERENDERTARGET, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( DISTORTMAP, TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NODEBUGOVERRIDE | + TEXTUREFLAGS_SINGLECOPY | TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT ); + } + + SHADER_DRAW + { + CVRDistortTexture_DX9_Context *pContextData = reinterpret_cast< CVRDistortTexture_DX9_Context *> ( *pContextDataPtr ); + bool bNeedRegenStaticCmds = ( !pContextData ) || pShaderShadow; + + if ( !pContextData ) // make sure allocated + { + pContextData = new CVRDistortTexture_DX9_Context; + *pContextDataPtr = pContextData; + } + + if ( pShaderShadow || bNeedRegenStaticCmds ) + { + pContextData->ResetStaticCmds(); + CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; + + staticCmdsBuf.BindTexture( this, SHADER_SAMPLER0, BASETEXTURE, -1 ); + staticCmdsBuf.BindTexture( this, SHADER_SAMPLER1, DISTORTMAP, -1 ); + + staticCmdsBuf.End(); + + // now, copy buf + pContextData->m_pStaticCmds = new uint8[ staticCmdsBuf.Size() ]; + memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); + } + + if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) + { + // need to regenerate the semistatic cmds + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_bMaterialVarsChanged = false; + + pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); + pContextData->m_SemiStaticCmdsOut.End(); + } + + SHADOW_STATE + { + SetInitialShadowState( ); + + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableDepthTest( false ); + + pShaderShadow->EnableBlending( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->EnableSRGBWrite( true ); + pShaderShadow->EnableAlphaWrites( false ); + pShaderShadow->EnableAlphaTest( false ); + + DefaultFog(); + + int nFormat = 0; + nFormat |= VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( nFormat, 2, 0, 0 ); + + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_STATIC_VERTEX_SHADER( vr_distort_texture_vs20 ); + SET_STATIC_VERTEX_SHADER( vr_distort_texture_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( vr_distort_texture_ps20b ); + SET_STATIC_PIXEL_SHADER( vr_distort_texture_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( vr_distort_texture_ps20 ); + SET_STATIC_PIXEL_SHADER( vr_distort_texture_ps20 ); + } + } + else + { + DECLARE_STATIC_VERTEX_SHADER( vr_distort_texture_vs30 ); + SET_STATIC_VERTEX_SHADER( vr_distort_texture_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vr_distort_texture_ps30 ); + SET_STATIC_PIXEL_SHADER( vr_distort_texture_ps30 ); + } + } + + DYNAMIC_STATE + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + pShaderAPI->SetDefaultState(); + + int useRenderTarget = ( params[ USERENDERTARGET ]->GetIntValue() == 0 ) ? 0 : 1; + + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_USERENDERTARGET, useRenderTarget ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_USERENDERTARGET, useRenderTarget ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20 ); + } + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_USERENDERTARGET, useRenderTarget ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps30 ); + } + + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + Draw(); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc b/mp/src/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc new file mode 100644 index 00000000..23ff3f5f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc @@ -0,0 +1,49 @@ +// DYNAMIC: "CMBO_USERENDERTARGET" "0..1" + +#include "shader_constant_register_map.h" +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler DistortMapTextureSampler : register( s1 ); + + +struct PS_INPUT +{ + float2 vBaseTexCoord : TEXCOORD0; +}; + + +float4 main( PS_INPUT i ) : COLOR +{ + float2 vOriginal = i.vBaseTexCoord.xy; + + float4 vRead = tex2D( DistortMapTextureSampler, vOriginal ); + + float2 vGreen; + vGreen.r = ( vRead.x + vRead.z ) / 2.0; + vGreen.g = ( vRead.y + vRead.w ) / 2.0; + + float4 vFinal; + vFinal.r = tex2D( BaseTextureSampler, vRead.xy ).r; + vFinal.ga = tex2D( BaseTextureSampler, vGreen ).ga; + vFinal.b = tex2D( BaseTextureSampler, vRead.zw ).b; + + float fBoundsCheck; + #if ( CMBO_USERENDERTARGET ) + { + fBoundsCheck = saturate( dot( (vGreen.xy < float2(0.01,0.01)), float2(1,1)) + dot( (vGreen.xy > float2(0.99,0.99)), float2(1,1)) ); + } + #else + { + fBoundsCheck = saturate( dot( (vGreen.xy < float2(0.005,0.005)), float2(1,1)) + dot( (vGreen.xy > float2(0.995,0.995)), float2(1,1)) + + (vGreen.x > 0.495 && vGreen.x < 0.505 ) ); + } + #endif + + vFinal.xyz = lerp( vFinal.xyz, float3(0,0,0), fBoundsCheck ); + + return vFinal; +} + + + diff --git a/mp/src/materialsystem/stdshaders/vr_distort_texture_vs20.fxc b/mp/src/materialsystem/stdshaders/vr_distort_texture_vs20.fxc new file mode 100644 index 00000000..b82bfa13 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/vr_distort_texture_vs20.fxc @@ -0,0 +1,26 @@ +#include "common_vs_fxc.h" + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + o.vProjPos = v.vPos; + o.vBaseTexCoord = v.vBaseTexCoord; + + return o; +} diff --git a/mp/src/materialsystem/stdshaders/water.cpp b/mp/src/materialsystem/stdshaders/water.cpp new file mode 100644 index 00000000..92a26375 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/water.cpp @@ -0,0 +1,614 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "common_hlsl_cpp_consts.h" // hack hack hack! +#include "convar.h" + +#include "WaterCheap_vs20.inc" +#include "WaterCheap_ps20.inc" +#include "WaterCheap_ps20b.inc" +#include "Water_vs20.inc" +#include "Water_ps20.inc" +#include "water_ps20b.inc" + +#ifndef _X360 +static ConVar r_waterforceexpensive( "r_waterforceexpensive", "0", FCVAR_ARCHIVE ); +#endif + +DEFINE_FALLBACK_SHADER( Water, Water_DX9_HDR ) + +BEGIN_VS_SHADER( Water_DX90, + "Help for Water" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterRefraction", "" ) + SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.8", "" ) + SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "dev/water_normal", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." ) + SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( FOGSTART, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( FOGEND, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( ABOVEWATER, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( NOLOWENDLIGHTMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( SCROLL1, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( SCROLL2, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( BLURREFRACT, SHADER_PARAM_TYPE_BOOL, "0", "Cause the refraction to be blurry on ps2b hardware" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if( !params[ABOVEWATER]->IsDefined() ) + { + Warning( "***need to set $abovewater for material %s\n", pMaterialName ); + params[ABOVEWATER]->SetIntValue( 1 ); + } + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() ) + { + params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f ); + } + if( !params[CHEAPWATERENDDISTANCE]->IsDefined() ) + { + params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f ); + } + if( !params[SCALE]->IsDefined() ) + { + params[SCALE]->SetVecValue( 1.0f, 1.0f ); + } + if( !params[SCROLL1]->IsDefined() ) + { + params[SCROLL1]->SetVecValue( 0.0f, 0.0f, 0.0f ); + } + if( !params[SCROLL2]->IsDefined() ) + { + params[SCROLL2]->SetVecValue( 0.0f, 0.0f, 0.0f ); + } + if( !params[FOGCOLOR]->IsDefined() ) + { + params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f ); + Warning( "material %s needs to have a $fogcolor.\n", pMaterialName ); + } + if( !params[REFLECTENTITIES]->IsDefined() ) + { + params[REFLECTENTITIES]->SetIntValue( 0 ); + } + if( !params[REFLECTBLENDFACTOR]->IsDefined() ) + { + params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f ); + } + + // By default, we're force expensive on dx9. NO WE DON'T!!!! + if( !params[FORCEEXPENSIVE]->IsDefined() ) + { +#ifdef _X360 + params[FORCEEXPENSIVE]->SetIntValue( 0 ); +#else + params[FORCEEXPENSIVE]->SetIntValue( 1 ); +#endif + } + if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + + // Fallbacks for water need lightmaps usually + if ( !params[NOLOWENDLIGHTMAP]->GetIntValue() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[NORMALMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Water_DX81"; + } + return 0; + } + + SHADER_INIT + { + Assert( params[WATERDEPTH]->IsDefined() ); + + if( params[REFRACTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTEXTURE, TEXTUREFLAGS_SRGB ); + } + if( params[REFLECTTEXTURE]->IsDefined() ) + { + LoadTexture( REFLECTTEXTURE, TEXTUREFLAGS_SRGB ); + } + if ( params[ENVMAP]->IsDefined() ) + { + LoadCubeMap( ENVMAP, TEXTUREFLAGS_SRGB ); + } + if ( params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + if( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + } + } + + inline void GetVecParam( int constantVar, float *val ) + { + if( constantVar == -1 ) + return; + + IMaterialVar* pVar = s_ppParams[constantVar]; + Assert( pVar ); + + if (pVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pVar->GetFloatValue(); + } + + inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + if( bRefraction ) + { + // refract sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + if( bReflection ) + { + // reflect sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + if( params[BASETEXTURE]->IsTexture() ) + { + // BASETEXTURE + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + // LIGHTMAP + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); + } + } + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 1; + if( params[BASETEXTURE]->IsTexture() ) + { + numTexCoords = 3; + } + pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 ); + + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( params[NORMALMAP]->IsTexture() && g_pHardwareConfig->SupportsNormalMapCompression() ) + { + ITexture *pNormalMap = params[NORMALMAP]->GetTextureValue(); + if ( pNormalMap ) + { + // Clamp this to 0 or 1 since that's how we've authored the water shader (i.e. no separate alpha map/channel) + nNormalDecodeMode = pNormalMap->GetNormalDecodeMode() == NORMAL_DECODE_NONE ? NORMAL_DECODE_NONE : NORMAL_DECODE_ATI2N; + } + } + + DECLARE_STATIC_VERTEX_SHADER( water_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_VERTEX_SHADER( water_vs20 ); + + // "REFLECT" "0..1" + // "REFRACT" "0..1" + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( water_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_PIXEL_SHADER_COMBO( BLURRY_REFRACT, params[BLURREFRACT]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( water_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( water_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( water_ps20 ); + } + + FogToFogColor(); + + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableAlphaWrites( true ); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + if( bRefraction ) + { + // HDRFIXME: add comment about binding.. Specify the number of MRTs in the enable + BindTexture( SHADER_SAMPLER0, REFRACTTEXTURE, -1 ); + } + if( bReflection ) + { + BindTexture( SHADER_SAMPLER2, REFLECTTEXTURE, -1 ); + } + BindTexture( SHADER_SAMPLER4, NORMALMAP, BUMPFRAME ); + if( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + // Refraction tint + if( bRefraction ) + { + SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT ); + } + // Reflection tint + if( bReflection ) + { + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + // Need to multiply by 4 in linear space since we premultiplied into + // the render target by .25 to get overbright data in the reflection render target. + float gammaReflectTint[3]; + params[REFLECTTINT]->GetVecValue( gammaReflectTint, 3 ); + float linearReflectTint[4]; + linearReflectTint[0] = GammaToLinear( gammaReflectTint[0] ) * 4.0f; + linearReflectTint[1] = GammaToLinear( gammaReflectTint[1] ) * 4.0f; + linearReflectTint[2] = GammaToLinear( gammaReflectTint[2] ) * 4.0f; + linearReflectTint[3] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 4, linearReflectTint, 1 ); + } + else + { + SetPixelShaderConstantGammaToLinear( 4, REFLECTTINT ); + } + } + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + float curtime=pShaderAPI->CurrentTime(); + float vc0[4]; + float v0[4]; + params[SCROLL1]->GetVecValue(v0,4); + vc0[0]=curtime*v0[0]; + vc0[1]=curtime*v0[1]; + params[SCROLL2]->GetVecValue(v0,4); + vc0[2]=curtime*v0[0]; + vc0[3]=curtime*v0[1]; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 ); + + float c0[4] = { 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); + + float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; + pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); + + // fresnel constants + float c3[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 3, c3, 1 ); + + float c5[4] = { params[REFLECTAMOUNT]->GetFloatValue(), params[REFLECTAMOUNT]->GetFloatValue(), + params[REFRACTAMOUNT]->GetFloatValue(), params[REFRACTAMOUNT]->GetFloatValue() }; + pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); + + SetPixelShaderConstantGammaToLinear( 6, FOGCOLOR ); + + float c7[4] = + { + params[FOGSTART]->GetFloatValue(), + params[FOGEND]->GetFloatValue() - params[FOGSTART]->GetFloatValue(), + 1.0f, + 0.0f + }; + if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + // water overbright factor + c7[2] = 4.0; + } + pShaderAPI->SetPixelShaderConstant( 7, c7, 1 ); + + pShaderAPI->SetPixelShaderFogParams( 8 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( water_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( water_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( water_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( water_ps20 ); + } + } + Draw(); + } + + inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bBlend, bool bRefraction ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + + // In edit mode, use nocull + if ( UsingEditor( params ) ) + { + s_pShaderShadow->EnableCulling( false ); + } + + if( bBlend ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + // envmap + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( bRefraction && bBlend ) + { + // refraction map (used for alpha) + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( params[NORMALMAP]->IsTexture() && g_pHardwareConfig->SupportsNormalMapCompression() ) + { + ITexture *pNormalMap = params[NORMALMAP]->GetTextureValue(); + if ( pNormalMap ) + { + // Clamp this to 0 or 1 since that's how we've authored the water shader (i.e. no separate alpha map/channel) + nNormalDecodeMode = pNormalMap->GetNormalDecodeMode() == NORMAL_DECODE_NONE ? NORMAL_DECODE_NONE : NORMAL_DECODE_ATI2N; + } + } + + DECLARE_STATIC_VERTEX_SHADER( watercheap_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( BLEND, bBlend && bRefraction ); + SET_STATIC_VERTEX_SHADER( watercheap_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( watercheap_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( watercheap_ps20 ); + } + + // HDRFIXME: test cheap water! + if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + { + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + } + + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + BindTexture( SHADER_SAMPLER0, ENVMAP, ENVMAPFRAME ); + BindTexture( SHADER_SAMPLER1, NORMALMAP, BUMPFRAME ); + if( bRefraction && bBlend ) + { + BindTexture( SHADER_SAMPLER2, REFRACTTEXTURE, -1 ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + SetPixelShaderConstant( 0, FOGCOLOR ); + + float cheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue(); + float cheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); + float cheapWaterParams[4] = + { + cheapWaterStartDistance * VSHADER_VECT_SCALE, + cheapWaterEndDistance * VSHADER_VECT_SCALE, + PSHADER_VECT_SCALE / ( cheapWaterEndDistance - cheapWaterStartDistance ), + cheapWaterStartDistance / ( cheapWaterEndDistance - cheapWaterStartDistance ), + }; + pShaderAPI->SetPixelShaderConstant( 1, cheapWaterParams ); + + if( g_pConfig->bShowSpecular ) + { + SetPixelShaderConstant( 2, REFLECTTINT, REFLECTBLENDFACTOR ); + } + else + { + float zero[4] = { 0.0f, 0.0f, 0.0f, params[REFLECTBLENDFACTOR]->GetFloatValue() }; + pShaderAPI->SetPixelShaderConstant( 2, zero ); + } + + pShaderAPI->SetPixelShaderFogParams( 3 ); + + if( params[SCROLL1]->IsDefined()) + { + float curtime=pShaderAPI->CurrentTime(); + float vc0[4]; + float v0[4]; + params[SCROLL1]->GetVecValue(v0,4); + vc0[0]=curtime*v0[0]; + vc0[1]=curtime*v0[1]; + params[SCROLL2]->GetVecValue(v0,4); + vc0[2]=curtime*v0[0]; + vc0[3]=curtime*v0[1]; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( watercheap_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( watercheap_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20 ); + } + } + Draw(); + } + + SHADER_DRAW + { + // TODO: fit the cheap water stuff into the water shader so that we don't have to do + // 2 passes. +#ifdef _X360 + bool bForceExpensive = false; +#else + bool bForceExpensive = r_waterforceexpensive.GetBool(); +#endif + bool bForceCheap = (params[FORCECHEAP]->GetIntValue() != 0) || UsingEditor( params ); + if ( bForceCheap ) + { + bForceExpensive = false; + } + else + { + bForceExpensive = bForceExpensive || (params[FORCEEXPENSIVE]->GetIntValue() != 0); + } + Assert( !( bForceCheap && bForceExpensive ) ); + + bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); +#ifdef _X360 + bool bReflection = params[REFLECTTEXTURE]->IsTexture(); +#else + bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); +#endif + bool bDrewSomething = false; + if ( !bForceCheap && ( bReflection || bRefraction ) ) + { + bDrewSomething = true; + DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction ); + } + + // Use $decal to see if we are a decal or not. . if we are, then don't bother + // drawing the cheap version for now since we don't have access to env_cubemap +#ifdef _X360 + if( params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) && !bForceExpensive ) +#else + if( !bReflection && params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) +#endif + { + bDrewSomething = true; + DrawCheapWater( params, pShaderShadow, pShaderAPI, !bForceCheap, bRefraction ); + } + + if( !bDrewSomething ) + { + // We are likely here because of the tools. . . draw something so that + // we won't go into wireframe-land. + Draw(); + } + } +END_SHADER + +//----------------------------------------------------------------------------- +// This allows us to use a block labelled 'Water_DX9_HDR' in the water materials +//----------------------------------------------------------------------------- +BEGIN_INHERITED_SHADER( Water_DX9_HDR, Water_DX90, + "Help for Water_DX9_HDR" ) + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + return "WATER_DX90"; + } + return 0; + } +END_INHERITED_SHADER + diff --git a/mp/src/materialsystem/stdshaders/water_dudv.cpp b/mp/src/materialsystem/stdshaders/water_dudv.cpp new file mode 100644 index 00000000..cf29c183 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/water_dudv.cpp @@ -0,0 +1,95 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + + +#include "BaseVSShader.h" + +#include "waterdudv_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Water_DuDv, "Help for Water_DuDv" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "", "dudv bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + if ( params[BUMPMAP]->IsDefined() ) + { + LoadTexture( BUMPMAP ); + } + if( !params[REFRACTTINT]->IsDefined() ) + { + params[REFRACTTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableColorWrites( true ); + pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, true ); + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0, 0 ); + + pShaderShadow->SetVertexShader( "WaterDuDv_vs11", 0 ); + pShaderShadow->SetPixelShader( "WaterDuDv_ps11", 0 ); + DisableFog(); + } + DYNAMIC_STATE + { + waterdudv_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetDOFOG( pShaderAPI->GetSceneFogMode() != MATERIAL_FOG_NONE ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + Vector4D vec; + const float *pTint = params[REFRACTTINT]->GetVecValue(); + float flAverage = ( pTint[0] + pTint[1] + pTint[2] ) / 3.0f; + vec.Init( flAverage, flAverage, flAverage, 1.0f ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vec.Base() ); + + // Amount to refract + SetPixelShaderConstant( 0, REFRACTAMOUNT ); + + // Used to renormalize + vec.Init( 1.0f, 1.0f, 1.0f, 1.0f ); + pShaderAPI->SetPixelShaderConstant( 1, vec.Base() ); + + // Used to deal with the red channel + vec.Init( 0.0f, 1.0f, 1.0f, 1.0f ); + pShaderAPI->SetPixelShaderConstant( 2, vec.Base() ); + + vec.Init( 1.0f, 0.0f, 0.0f, 0.0f ); + pShaderAPI->SetPixelShaderConstant( 3, vec.Base() ); + + BindTexture( SHADER_TEXTURE_STAGE0, BUMPMAP, BUMPFRAME ); + } + Draw(); + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/water_dx60.cpp b/mp/src/materialsystem/stdshaders/water_dx60.cpp new file mode 100644 index 00000000..b6c952b3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/water_dx60.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// NOTE: Water DX60 is located in LightmappedGeneric_DX6 so it can inherit +DEFINE_FALLBACK_SHADER( Water, Water_DX60 ) + diff --git a/mp/src/materialsystem/stdshaders/water_dx80.cpp b/mp/src/materialsystem/stdshaders/water_dx80.cpp new file mode 100644 index 00000000..2f31bb5b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/water_dx80.cpp @@ -0,0 +1,419 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" + +#include "water_vs11.inc" +#include "watercheappervertexfresnel_vs11.inc" +#include "watercheap_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Water_DX80, + "Help for Water_DX80" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "", "dudv bump map" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." ) + SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() ) + { + params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f ); + } + if( !params[CHEAPWATERENDDISTANCE]->IsDefined() ) + { + params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f ); + } + if( !params[SCALE]->IsDefined() ) + { + params[SCALE]->SetVecValue( 1.0f, 1.0f ); + } + if( !params[FOGCOLOR]->IsDefined() ) + { + params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f ); + Warning( "material %s needs to have a $fogcolor.\n", pMaterialName ); + } + if( !params[REFLECTENTITIES]->IsDefined() ) + { + params[REFLECTENTITIES]->SetIntValue( 0 ); + } + if( !params[FORCEEXPENSIVE]->IsDefined() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + if( !params[REFLECTBLENDFACTOR]->IsDefined() ) + { + params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f ); + } + if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + } + + SHADER_FALLBACK + { + if ( IsPC() && ( g_pHardwareConfig->GetDXSupportLevel() < 80 || !g_pHardwareConfig->HasProjectedBumpEnv() ) ) + { + return "Water_DX60"; + } + return 0; + } + + SHADER_INIT + { + Assert( params[WATERDEPTH]->IsDefined() ); + if( params[REFRACTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTEXTURE ); + } + if( params[REFLECTTEXTURE]->IsDefined() ) + { + LoadTexture( REFLECTTEXTURE ); + } + if (params[BUMPMAP]->IsDefined() ) + { + LoadTexture( BUMPMAP ); + } + if (params[ENVMAP]->IsDefined() ) + { + LoadCubeMap( ENVMAP ); + } + if (params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + } + + inline void SetCheapWaterFactors( IMaterialVar **params, IShaderDynamicAPI* pShaderAPI, int nConstantReg ) + { + float flCheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue(); + float flCheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); + float flCheapWaterConstants[4] = + { + flCheapWaterStartDistance, + 1.0f / ( flCheapWaterEndDistance - flCheapWaterStartDistance ), + 0.0f, + 0.0f + }; + pShaderAPI->SetVertexShaderConstant( nConstantReg, flCheapWaterConstants ); + } + + inline void DrawReflection( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bBlendReflection ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + if( bBlendReflection ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + + water_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Water_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WaterReflect_ps11", 0 ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); + + float fReflectionAmount = params[REFLECTAMOUNT]->GetFloatValue(); + pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fReflectionAmount, 0.0f, 0.0f, fReflectionAmount ); + + BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER1, REFLECTTEXTURE, -1 ); + BindTexture( SHADER_SAMPLER2, NORMALMAP, BUMPFRAME ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); + pShaderAPI->SetVertexShaderIndex( 0 ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + // used to invert y + float c[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); + + SetPixelShaderConstant( 0, REFLECTTINT ); + + water_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + inline void DrawRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + water_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Water_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WaterRefract_ps11", 0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); + float fRefractionAmount = params[REFRACTAMOUNT]->GetFloatValue(); + pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fRefractionAmount, 0.0f, 0.0f, fRefractionAmount ); + BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER1, REFRACTTEXTURE ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + // used to invert y + float c[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); + + SetPixelShaderConstant( 0, REFRACTTINT ); + + water_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + inline void DrawRefractionForFresnel( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI ) + { + SHADOW_STATE + { + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + water_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Water_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WaterRefractFresnel_ps11", 0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); + float fRefractionAmount = params[REFRACTAMOUNT]->GetFloatValue(); + pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fRefractionAmount, 0.0f, 0.0f, fRefractionAmount ); + BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER1, REFRACTTEXTURE ); + BindTexture( SHADER_SAMPLER2, NORMALMAP, BUMPFRAME ); + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + SetCheapWaterFactors( params, pShaderAPI, VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 ); + + // used to invert y + float c[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); + + SetPixelShaderConstant( 0, REFRACTTINT ); + + water_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bBlend, bool bBlendFresnel, bool bNoPerVertexFresnel ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + + // In edit mode, use nocull + if ( UsingEditor( params ) ) + { + s_pShaderShadow->EnableCulling( false ); + } + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if( bBlend ) + { + if ( bBlendFresnel ) + { + EnableAlphaBlending( SHADER_BLEND_DST_ALPHA, SHADER_BLEND_ONE_MINUS_DST_ALPHA ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + } + + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | + VERTEX_TANGENT_T, 1, 0, 0 ); + + if( bNoPerVertexFresnel ) + { + watercheap_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WaterCheap_vs11", vshIndex.GetIndex() ); + } + else + { + watercheappervertexfresnel_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WaterCheapPerVertexFresnel_vs11", vshIndex.GetIndex() ); + } + + static const char *s_pPixelShaderName[] = + { + "WaterCheapOpaque_ps11", + "WaterCheap_ps11", + "WaterCheapNoFresnelOpaque_ps11", + "WaterCheapNoFresnel_ps11", + }; + + int nPshIndex = 0; + if ( bBlend ) nPshIndex |= 0x1; + if ( bNoPerVertexFresnel ) nPshIndex |= 0x2; + pShaderShadow->SetPixelShader( s_pPixelShaderName[nPshIndex] ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + BindTexture( SHADER_SAMPLER0, NORMALMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER3, ENVMAP, ENVMAPFRAME ); + + if( bBlend && !bBlendFresnel ) + { + SetCheapWaterFactors( params, pShaderAPI, VERTEX_SHADER_SHADER_SPECIFIC_CONST_2 ); + } + else + { + float flCheapWaterConstants[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, flCheapWaterConstants ); + } + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BUMPTRANSFORM ); + + SetPixelShaderConstant( 0, FOGCOLOR ); + SetPixelShaderConstant( 1, REFLECTTINT, REFLECTBLENDFACTOR ); + + if( bNoPerVertexFresnel ) + { + watercheap_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + else + { + watercheappervertexfresnel_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + Draw(); + } + + SHADER_DRAW + { + // NOTE: Here's what all this means. + // 1) ForceCheap means use env_cubemap only + // 2) ForceExpensive means do real reflection instead of env_cubemap. + // By default, it will do refraction and use env_cubemap for the reflection. + // If dest alpha is available, it will also use dest alpha for a fresnel term. + // otherwise there will be no fresnel term as it looks bizzare. + + bool bBlendReflection = false; + bool bForceCheap = params[FORCECHEAP]->GetIntValue() != 0 || UsingEditor( params ); + bool bForceExpensive = !bForceCheap && (params[FORCEEXPENSIVE]->GetIntValue() != 0); + bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); + bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); + bool bReflectionUseFresnel = false; + + // Can't do fresnel when forcing cheap or if there's no refraction + if( !bForceCheap ) + { + if( bRefraction ) + { + // NOTE: Expensive reflection does the fresnel correctly per-pixel + if ( g_pHardwareConfig->HasDestAlphaBuffer() && !bReflection && !params[NOFRESNEL]->GetIntValue() ) + { + DrawRefractionForFresnel( params, pShaderShadow, pShaderAPI ); + bReflectionUseFresnel = true; + } + else + { + DrawRefraction( params, pShaderShadow, pShaderAPI ); + } + bBlendReflection = true; + } + if( bReflection ) + { + DrawReflection( params, pShaderShadow, pShaderAPI, bBlendReflection ); + } + } + + // Use $decal to see if we are a decal or not. . if we are, then don't bother + // drawing the cheap version for now since we don't have access to env_cubemap + if( !bReflection && params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) + { + bool bNoPerVertexFresnel = ( params[NOFRESNEL]->GetIntValue() || bReflectionUseFresnel || bForceCheap || !bRefraction ); + DrawCheapWater( params, pShaderShadow, pShaderAPI, bBlendReflection, bReflectionUseFresnel, bNoPerVertexFresnel ); + } + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/water_dx81.cpp b/mp/src/materialsystem/stdshaders/water_dx81.cpp new file mode 100644 index 00000000..764ffe9e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/water_dx81.cpp @@ -0,0 +1,311 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" + +#include "water_ps14.inc" +#include "watercheap_vs14.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Water, Water_DX81 ) + +BEGIN_VS_SHADER( Water_DX81, + "Help for Water_DX81" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." ) + SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() ) + { + params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f ); + } + if( !params[CHEAPWATERENDDISTANCE]->IsDefined() ) + { + params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f ); + } + if( !params[SCALE]->IsDefined() ) + { + params[SCALE]->SetVecValue( 1.0f, 1.0f ); + } + if( !params[FOGCOLOR]->IsDefined() ) + { + params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f ); + Warning( "material %s needs to have a $fogcolor.\n", pMaterialName ); + } + if( !params[REFLECTENTITIES]->IsDefined() ) + { + params[REFLECTENTITIES]->SetIntValue( 0 ); + } + if( !params[FORCEEXPENSIVE]->IsDefined() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + if( !params[REFLECTBLENDFACTOR]->IsDefined() ) + { + params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f ); + } + if( !params[FORCEEXPENSIVE]->GetIntValue() && !params[ENVMAP]->IsDefined() ) + { + params[ENVMAP]->SetStringValue( "engine/defaultcubemap" ); + } + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 81 ) + { + return "Water_DX80"; + } + return 0; + } + + SHADER_INIT + { + Assert( params[WATERDEPTH]->IsDefined() ); + if( params[REFRACTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTEXTURE ); + } + if( params[REFLECTTEXTURE]->IsDefined() ) + { + LoadTexture( REFLECTTEXTURE ); + } + if (params[ENVMAP]->IsDefined() ) + { + LoadTexture( ENVMAP ); + } + if (params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + } + + inline int GetReflectionRefractionPixelShaderIndex( bool bReflection, bool bRefraction ) + { + // "REFLECT" "0..1" + // "REFRACT" "0..1" + int pshIndex = ( bReflection ? 1 : 0 ) | ( bRefraction ? 2 : 0 ); + return pshIndex; + } + + inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( bRefraction ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if( bReflection ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + water_ps14_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Water_ps14", vshIndex.GetIndex() ); + + int pshIndex = GetReflectionRefractionPixelShaderIndex( bReflection, bRefraction ); + pShaderShadow->SetPixelShader ( "Water_ps14", pshIndex ); + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_NORMALIZATION_CUBEMAP ); + if( bRefraction ) + { + BindTexture( SHADER_SAMPLER2, REFRACTTEXTURE, -1 ); + } + BindTexture( SHADER_SAMPLER3, NORMALMAP, BUMPFRAME ); + if( bReflection ) + { + BindTexture( SHADER_SAMPLER4, REFLECTTEXTURE, -1 ); + } + + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, REFLECTAMOUNT ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, REFRACTAMOUNT ); + + float c0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); + + SetPixelShaderConstant( 1, REFRACTTINT ); + SetPixelShaderConstant( 4, REFLECTTINT ); + + float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; + pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); + + // ERASE ME! + float c3[4] = { 5.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 3, c3, 1 ); + + // reflection/refraction scale + float reflectionRefractionScale[4] = { params[REFLECTAMOUNT]->GetFloatValue(), + params[REFRACTAMOUNT]->GetFloatValue(), 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 5, reflectionRefractionScale, 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, reflectionRefractionScale, 1 ); + + water_ps14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + enum DrawCheapType_t + { + DRAW_CHEAP_OPAQUE = 0, + DRAW_CHEAP_FRESNEL_OPAQUE, + DRAW_CHEAP_LOD_ONLY, + DRAW_CHEAP_FRESNEL_AND_LOD, + }; + + inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, DrawCheapType_t type ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + + // In edit mode, use nocull + if ( UsingEditor( params ) ) + { + s_pShaderShadow->EnableCulling( false ); + } + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + if ( (type != DRAW_CHEAP_OPAQUE) && (type != DRAW_CHEAP_FRESNEL_OPAQUE) ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | + VERTEX_TANGENT_T, 1, 0, 0 ); + + watercheap_vs14_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WaterCheap_vs14", vshIndex.GetIndex() ); + + static const char *s_pPixelShader[] = + { + "WaterCheapOpaque_ps14", + "WaterCheapFresnelOpaque_ps14", + "WaterCheap_ps14", + "WaterCheapFresnel_ps14", + }; + + pShaderShadow->SetPixelShader( s_pPixelShader[type] ); + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + BindTexture( SHADER_SAMPLER0, NORMALMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER3, ENVMAP, ENVMAPFRAME ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALIZATION_CUBEMAP ); + + float pCheapWaterConstants[4] = { 0, 0, 0, 0 }; + if ( (type != DRAW_CHEAP_OPAQUE) && (type != DRAW_CHEAP_FRESNEL_OPAQUE) ) + { + float flCheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue(); + float flCheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); + pCheapWaterConstants[0] = flCheapWaterStartDistance; + pCheapWaterConstants[1] = 1.0f / ( flCheapWaterEndDistance - flCheapWaterStartDistance ); + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, pCheapWaterConstants ); + + SetPixelShaderConstant( 0, FOGCOLOR ); + SetPixelShaderConstant( 1, REFLECTTINT, REFLECTBLENDFACTOR ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BUMPTRANSFORM ); + + watercheap_vs14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + SHADER_DRAW + { + // NOTE: Here's what all this means. + // 1) ForceCheap means use env_cubemap only + // 2) ForceExpensive means do real reflection instead of env_cubemap. + // By default, it will do refraction and use env_cubemap for the reflection. + + // Also, it will fade to cheap water at a particular distance, + // based on CheapWaterStartDistance and CheapWaterEndDistance + // * In the ForceCheap case, no fading is required + // * In the default case, it will fade based on these parameters in a single pass + // * In the expensive case, it will have to perform the fade in a separate pass. + + bool bForceCheap = params[FORCECHEAP]->GetIntValue() != 0 || UsingEditor( params ); + bool bForceExpensive = params[FORCEEXPENSIVE]->GetIntValue() != 0; + bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); + bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); + DrawCheapType_t type = params[NOFRESNEL]->GetIntValue() ? DRAW_CHEAP_OPAQUE : DRAW_CHEAP_FRESNEL_OPAQUE; + if( !bForceCheap && (bRefraction || bReflection) ) + { + DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction ); + if ( !bReflection ) + { + type = params[NOFRESNEL]->GetIntValue() ? DRAW_CHEAP_LOD_ONLY : DRAW_CHEAP_FRESNEL_AND_LOD; + } + else + { + type = DRAW_CHEAP_LOD_ONLY; + } + } + + // Use $decal to see if we are a decal or not. . if we are, then don't bother + // drawing the cheap version for now since we don't have access to env_cubemap + if( params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) && !bReflection ) + { + DrawCheapWater( params, pShaderShadow, pShaderAPI, type ); + } + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/water_ps2x.fxc b/mp/src/materialsystem/stdshaders/water_ps2x.fxc new file mode 100644 index 00000000..a80a8a15 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/water_ps2x.fxc @@ -0,0 +1,110 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b] [= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "BASETEXTURE" "0..1" +// STATIC: "MULTITEXTURE" "0..1" +// STATIC: "REFLECT" "0..1" +// STATIC: "REFRACT" "0..1" +// STATIC: "ABOVEWATER" "0..1" +// STATIC: "BLURRY_REFRACT" "0..1" [ps20b] + +// When we turn NORMAL_DECODE_MODE on, this shader only needs 0..1, not 0..2 +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// SKIP: $MULTITEXTURE && $BASETEXTURE + +#if defined(SHADER_MODEL_PS_2_0) +# define BLURRY_REFRACT 0 +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "water_ps2x_helper.h" + + +sampler RefractSampler : register( s0 ); +#if BASETEXTURE +sampler BaseTextureSampler : register( s1 ); +#endif +sampler ReflectSampler : register( s2 ); +#if BASETEXTURE +sampler LightmapSampler : register( s3 ); +#endif +sampler NormalSampler : register( s4 ); + +const HALF4 vRefractTint : register( c1 ); +const HALF4 vReflectTint : register( c4 ); +const float4 g_ReflectRefractScale : register( c5 ); // xy - reflect scale, zw - refract scale +const HALF4 g_WaterFogColor : register( c6 ); +const HALF4 g_WaterFogParams : register( c7 ); + +const float4 g_PixelFogParams : register( c8 ); + + +#define g_WaterFogStart g_WaterFogParams.x +#define g_WaterFogEndMinusStart g_WaterFogParams.y +#define g_Reflect_OverBright g_WaterFogParams.z + +struct PS_INPUT +{ + float2 vBumpTexCoord : TEXCOORD0; + half3 vTangentEyeVect : TEXCOORD1; + float4 vReflectXY_vRefractYX : TEXCOORD2; + float W : TEXCOORD3; + float4 vProjPos : TEXCOORD4; + float screenCoord : TEXCOORD5; +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif +#if BASETEXTURE +// CENTROID: TEXCOORD6 + HALF4 lightmapTexCoord1And2 : TEXCOORD6; +// CENTROID: TEXCOORD7 + HALF4 lightmapTexCoord3 : TEXCOORD7; +#endif + + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + DrawWater_params_t params; + + params.vBumpTexCoord = i.vBumpTexCoord; +#if MULTITEXTURE + params.vExtraBumpTexCoord = i.vExtraBumpTexCoord; +#endif + params.vReflectXY_vRefractYX = i.vReflectXY_vRefractYX; + params.w = i.W; + params.vReflectRefractScale = g_ReflectRefractScale; + params.fReflectOverbright = g_Reflect_OverBright; + params.vReflectTint = vReflectTint; + params.vRefractTint = vRefractTint; + params.vTangentEyeVect = i.vTangentEyeVect; + params.waterFogColor = g_WaterFogColor; +#if BASETEXTURE + params.lightmapTexCoord1And2 = i.lightmapTexCoord1And2; + params.lightmapTexCoord3 = i.lightmapTexCoord3; +#endif + params.vProjPos = i.vProjPos; + params.pixelFogParams = g_PixelFogParams; + params.fWaterFogStart = g_WaterFogStart; + params.fWaterFogEndMinusStart = g_WaterFogEndMinusStart; + + float4 result; + float fogFactor; + DrawWater( params, + // yay. . can't put sampler in a struct. +#if BASETEXTURE + BaseTextureSampler, + LightmapSampler, +#endif + NormalSampler, RefractSampler, ReflectSampler, + result, fogFactor ); + + return FinalOutput( float4( result.rgb, 1.0f ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.vProjPos.z ); +} + diff --git a/mp/src/materialsystem/stdshaders/water_ps2x_helper.h b/mp/src/materialsystem/stdshaders/water_ps2x_helper.h new file mode 100644 index 00000000..b15b9986 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/water_ps2x_helper.h @@ -0,0 +1,239 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#include "common_ps_fxc.h" + +struct DrawWater_params_t +{ + float2 vBumpTexCoord; +#if MULTITEXTURE + float4 vExtraBumpTexCoord; +#endif + float4 vReflectXY_vRefractYX; + float w; + float4 vReflectRefractScale; + float fReflectOverbright; + float4 vReflectTint; + float4 vRefractTint; + half3 vTangentEyeVect; + float4 waterFogColor; +#if BASETEXTURE + HALF4 lightmapTexCoord1And2; + HALF4 lightmapTexCoord3; +#endif + float4 vProjPos; + float4 pixelFogParams; + float fWaterFogStart; + float fWaterFogEndMinusStart; +}; + +void DrawWater( in DrawWater_params_t i, +#if BASETEXTURE + in sampler BaseTextureSampler, + in sampler LightmapSampler, +#endif + in sampler NormalSampler, + in sampler RefractSampler, + in sampler ReflectSampler, + out float4 result, out float fogFactor ) +{ + bool bReflect = REFLECT ? true : false; + bool bRefract = REFRACT ? true : false; + +#if MULTITEXTURE + float4 vNormal = tex2D( NormalSampler, i.vBumpTexCoord ); + float4 vNormal1 = tex2D( NormalSampler, i.vExtraBumpTexCoord.xy ); + float4 vNormal2 = tex2D( NormalSampler, i.vExtraBumpTexCoord.zw ); + vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 ); + +#if ( NORMAL_DECODE_MODE == NORM_DECODE_ATI2N ) + vNormal.xy = vNormal.xy * 2.0f - 1.0f; + vNormal.z = sqrt( 1.0f - dot(vNormal.xy, vNormal.xy) ); + vNormal.a = 1.0f; +#else + vNormal.xyz = 2.0 * vNormal.xyz - 1.0; +#endif + +#else + float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord, NORMAL_DECODE_MODE ); +#endif + + // Perform division by W only once + float ooW = 1.0f / i.w; + + float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW; + +#if ABOVEWATER + float waterFogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a; +#else + // We don't actually have valid depth values in alpha when we are underwater looking out, so + // just set to farthest value. + float waterFogDepthValue = 1.0f; +#endif + float4 reflectRefractScale = i.vReflectRefractScale; +#if !BASETEXTURE +#if ( BLURRY_REFRACT == 0 ) + reflectRefractScale *= waterFogDepthValue; +#endif +#endif + + // Compute coordinates for sampling Reflection + float2 vReflectTexCoord; + float2 vRefractTexCoord; + + // vectorize the dependent UV calculations (reflect = .xy, refract = .wz) + float4 vN; + vN.xy = vNormal.xy; + vN.w = vNormal.x; + vN.z = vNormal.y; + float4 vDependentTexCoords = vN * vNormal.a * reflectRefractScale; + + vDependentTexCoords += ( i.vReflectXY_vRefractYX * ooW ); + vReflectTexCoord = vDependentTexCoords.xy; + vRefractTexCoord = vDependentTexCoords.wz; + + HALF4 vReflectColor = tex2D( ReflectSampler, vReflectTexCoord ); +#if BLURRY_REFRACT + // Sample reflection and refraction + float2 ddx1=float2(0.005,0); + float2 ddy1=float2(0,0.005); + float4 vRefractColor=float4(0,0,0,0); + +#if 0 + float sumweights=0; + for(int ix=-2;ix<=2;ix++) + { + for(int iy=-2;iy<=2;iy++) + { + float weight=1; ///(1+abs(ix)+abs(iy)); + vRefractColor += weight*tex2D( RefractSampler, vRefractTexCoord+ix*ddx1+iy*ddy1); + sumweights+=weight; + } + } +#else + // NOTE: Generated by genwaterloop.pl in the stdshaders directory. + // Need to unroll for 360 to avoid shader compilation problems. + // Modified genwaterloop.pl and regenerate if you need different params + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 2 * ddy1 ); + float sumweights = 25; + // NOTE: end of generated code. +#endif + + vRefractColor *= (1.0/sumweights); + vReflectColor *= i.fReflectOverbright; + vReflectColor *= i.vReflectTint; + vRefractColor *= i.vRefractTint; +# if ABOVEWATER + // Don't mess with this in the underwater case since we don't really have + // depth values there. + // get the blurred depth value to be used for fog. + waterFogDepthValue = vRefractColor.a; +# endif +#else + vReflectColor *= i.vReflectTint; + HALF4 vRefractColor = tex2D( RefractSampler, vRefractTexCoord ); + // get the depth value from the refracted sample to be used for fog. +# if ABOVEWATER + // Don't mess with this in the underwater case since we don't really have + // depth values there. + waterFogDepthValue = tex2D( RefractSampler, vRefractTexCoord ).a; +# endif +#endif + + half3 vEyeVect; + vEyeVect = normalize( i.vTangentEyeVect ); + + // Fresnel term + HALF fNdotV = saturate( dot( vEyeVect, vNormal ) ); + HALF fFresnel = pow( 1.0 - fNdotV, 5 ); + +#if !BASETEXTURE + // fFresnel == 1.0f means full reflection + fFresnel *= saturate( ( waterFogDepthValue - 0.05f ) * 20.0f ); +#endif + + + // blend between refraction and fog color. +#if ABOVEWATER + vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, saturate( waterFogDepthValue - 0.05f ) ); +#else + float waterFogFactor = saturate( ( i.vProjPos.z - i.fWaterFogStart ) / i.fWaterFogEndMinusStart ); + vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, waterFogFactor ); +#endif + +#if BASETEXTURE + float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoord.xy ); + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + HALF3 lightmapColor1 = lightmapSample1.rgb; + HALF3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); + HALF3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); + + float3 dp; + dp.x = saturate( dot( vNormal, bumpBasis[0] ) ); + dp.y = saturate( dot( vNormal, bumpBasis[1] ) ); + dp.z = saturate( dot( vNormal, bumpBasis[2] ) ); + dp *= dp; + + float3 diffuseLighting = dp.x * lightmapColor1 + + dp.y * lightmapColor2 + + dp.z * lightmapColor3; + float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); + diffuseLighting *= LIGHT_MAP_SCALE / sum; + HALF3 diffuseComponent = baseSample.rgb * diffuseLighting; +#endif + + if( bReflect && bRefract ) + { + result = lerp( vRefractColor, vReflectColor, fFresnel ); + } + else if( bReflect ) + { +#if BASETEXTURE + result = float4( diffuseComponent, 1.0f ) + vReflectColor * fFresnel * baseSample.a; +#else + result = vReflectColor; +#endif + } + else if( bRefract ) + { + result = vRefractColor; + } + else + { + result = float4( 0.0f, 0.0f, 0.0f, 0.0f ); + } + +#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE) + fogFactor = CalcRangeFog( i.vProjPos.z, i.pixelFogParams.x, i.pixelFogParams.z, i.pixelFogParams.w ); +#else + fogFactor = 0; +#endif +} diff --git a/mp/src/materialsystem/stdshaders/waterreflect_ps14.psh b/mp/src/materialsystem/stdshaders/waterreflect_ps14.psh new file mode 100644 index 00000000..7104e45c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/waterreflect_ps14.psh @@ -0,0 +1,8 @@ +ps.1.4 + +texld r0, t0_dw.xyw ; sample dudv map + +phase + +texld r0, t0 + diff --git a/mp/src/materialsystem/stdshaders/waterrefract_ps14.psh b/mp/src/materialsystem/stdshaders/waterrefract_ps14.psh new file mode 100644 index 00000000..5b5d1755 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/waterrefract_ps14.psh @@ -0,0 +1,23 @@ +ps.1.4 + +; non-fresnel version +; t0: +; texture: dudv map +; texcoords: coords for normal map +; t1: +; texcoords: uvw for first dp3 +; t2: +; texture: renderable texture that we are going to perturb +; texcoords: uvw for second dp3 +;tex t0 ; sample dudv map +;texm3x2pad t1, t0 ; +;texm3x2tex t2, t0 ; sample renderabletexture + +;mul r0, t2, c1 + + +texld r0, t0 ; sample dudv map + +phase + +texld r0, t2_dw.xyw diff --git a/mp/src/materialsystem/stdshaders/worldtwotextureblend.cpp b/mp/src/materialsystem/stdshaders/worldtwotextureblend.cpp new file mode 100644 index 00000000..542013e0 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldtwotextureblend.cpp @@ -0,0 +1,500 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "convar.h" + +#include "lightmappedgeneric_vs20.inc" +#include "WorldTwoTextureBlend_ps20.inc" +#include "WorldTwoTextureBlend_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern ConVar r_flashlight_version2; + +// FIXME: Need to make a dx9 version so that "CENTROID" works. +BEGIN_VS_SHADER( WorldTwoTextureBlend, + "Help for WorldTwoTextureBlend" ) + +BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "iris texture", 0 ) + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend_detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale of the detail texture" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) +END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "WorldTwoTextureBlend_DX6"; + + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "WorldTwoTextureBlend_DX8"; + + return 0; + } + + SHADER_INIT_PARAMS() + { + + if( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->IsDefined() ) + { + params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->SetIntValue( 0 ); + } + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() && params[ALBEDO]->IsDefined() && + params[BASETEXTURE]->IsDefined() && + !( params[NODIFFUSEBUMPLIGHTING]->IsDefined() && params[NODIFFUSEBUMPLIGHTING]->GetIntValue() ) ) + { + params[BASETEXTURE]->SetStringValue( params[ALBEDO]->GetStringValue() ); + } + + if( !params[NODIFFUSEBUMPLIGHTING]->IsDefined() ) + { + params[NODIFFUSEBUMPLIGHTING]->SetIntValue( 0 ); + } + + if( !params[SELFILLUMTINT]->IsDefined() ) + { + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[DETAILSCALE]->IsDefined() ) + { + params[DETAILSCALE]->SetFloatValue( 4.0f ); + } + + if( !params[BUMPFRAME]->IsDefined() ) + { + params[BUMPFRAME]->SetIntValue( 0 ); + } + + if( !params[DETAILFRAME]->IsDefined() ) + { + params[DETAILFRAME]->SetIntValue( 0 ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() && (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0) ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + } + + SHADER_INIT + { + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) + { + LoadBumpMap( BUMPMAP ); + } + + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + // We always need this because of the flashlight. + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + + void DrawPass( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, bool hasFlashlight, VertexCompressionType_t vertexCompression ) + { + bool hasBump = params[BUMPMAP]->IsTexture(); + bool hasDiffuseBumpmap = hasBump && (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0); + bool hasBaseTexture = params[BASETEXTURE]->IsTexture(); + bool hasDetailTexture = /*!hasBump && */params[DETAIL]->IsTexture(); + bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) != 0; + bool bHasDetailAlpha = params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->GetIntValue() != 0; + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + bool bSeamlessMapping = params[SEAMLESS_SCALE]->GetFloatValue() != 0.0; + + SHADOW_STATE + { + int nShadowFilterMode = 0; + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + if( hasFlashlight ) + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + pShaderShadow->EnableDepthWrites( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + } + else + { + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + + unsigned int flags = VERTEX_POSITION; + if( hasBaseTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + // if( hasLightmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ); + } + if( hasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 ); + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL; + } + if( hasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + if( hasBump ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + if( hasVertexColor ) + { + flags |= VERTEX_COLOR; + } + + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 2; + if( hasBump ) + { + numTexCoords = 3; + } + + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + // Pre-cache pixel shaders + bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + + pShaderShadow->EnableSRGBWrite( true ); + + DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, false ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, false ); + SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, hasFlashlight ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, false ); + SET_STATIC_VERTEX_SHADER_COMBO( RELIEF_MAPPING, 0 ); //( bumpmap_variant == 2 )?1:0); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); //( bumpmap_variant == 2 )?1:0); +#ifdef _X360 + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); +#endif + SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff. + // But only do it if we're not using the alpha already for translucency + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + + + if( hasFlashlight ) + { + FogToBlack(); + } + else + { + DefaultFog(); + } + } + DYNAMIC_STATE + { + if( hasBaseTexture ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + + // if( hasLightmap ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + } + + bool bFlashlightShadows = false; + if( hasFlashlight ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + SetFlashLightColorFromState( state, pShaderAPI ); + + BindTexture( SHADER_SAMPLER2, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() ) + { + BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture ); + } + } + if( hasDetailTexture ) + { + BindTexture( SHADER_SAMPLER3, DETAIL, DETAILFRAME ); + } + if( hasBump ) + { + if( !g_pConfig->m_bFastNoBump ) + { + BindTexture( SHADER_SAMPLER4, BUMPMAP, BUMPFRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALMAP_FLAT ); + } + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + // If we don't have a texture transform, we don't have + // to set vertex shader constants or run vertex shader instructions + // for the texture transform. + bool bHasTextureTransform = + !( params[BASETEXTURETRANSFORM]->MatrixIsIdentity() && + params[BUMPTRANSFORM]->MatrixIsIdentity() ); + + bool bVertexShaderFastPath = !bHasTextureTransform; + if( params[DETAIL]->IsTexture() ) + { + bVertexShaderFastPath = false; + } + if( pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0 ) + { + bVertexShaderFastPath = false; + } + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + if( !( bVertexShaderFastPath && color[0] == 1.0f && color[1] == 1.0f && color[2] == 1.0f && color[3] == 1.0f ) ) + { + bVertexShaderFastPath = false; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + if (! bSeamlessMapping) + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + if( hasBump && !bHasDetailAlpha ) + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BUMPTRANSFORM ); + Assert( !hasDetailTexture ); + } + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( + LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z) && + (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); + } + + + // always set the transform for detail textures since I'm assuming that you'll + // always have a detailscale. + if( hasDetailTexture ) + { + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, DETAILSCALE ); + Assert( !( hasBump && !bHasDetailAlpha ) ); + } + + SetPixelShaderConstantGammaToLinear( 7, SELFILLUMTINT ); + + float eyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + pShaderAPI->SetPixelShaderConstant( 10, eyePos, 1 ); + pShaderAPI->SetPixelShaderFogParams( 11 ); + + if ( bSeamlessMapping ) + { + float map_scale[4]={ params[SEAMLESS_SCALE]->GetFloatValue(),0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale ); + } + + + if( hasFlashlight ) + { + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + + // Set the flashlight attenuation factors + float atten[4]; + atten[0] = flashlightState.m_fConstantAtten; + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( 20, atten, 1 ); + + // Set the flashlight origin + float pos[4]; + pos[0] = flashlightState.m_vecLightOrigin[0]; + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pos[3] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 15, pos, 1 ); + + pShaderAPI->SetPixelShaderConstant( 16, worldToTexture.Base(), 4 ); + } + } + Draw(); + } + + SHADER_DRAW + { + bool bHasFlashlight = UsingFlashlight( params ); + if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + DrawPass( params, pShaderAPI, pShaderShadow, false, vertexCompression ); + SHADOW_STATE + { + SetInitialShadowState( ); + } + } + DrawPass( params, pShaderAPI, pShaderShadow, bHasFlashlight, vertexCompression ); + } + +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp b/mp/src/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp new file mode 100644 index 00000000..3ae6383a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp @@ -0,0 +1,258 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +DEFINE_FALLBACK_SHADER( WorldTwoTextureBlend, WorldTwoTextureBlend_DX6 ) + + +BEGIN_SHADER( WorldTwoTextureBlend_DX6, + "Help for WorldTwoTextureBlend" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "iris texture", 0 ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend_detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale of the detail texture" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + END_SHADER_PARAMS + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + LoadTexture( BASETEXTURE ); + LoadTexture( DETAIL ); + } + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + if( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->IsDefined() ) + params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->SetIntValue( 0 ); + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + + SHADER_DRAW + { + float detailScale = params[DETAILSCALE]->GetFloatValue(); + + bool hasFlashlight = UsingFlashlight( params ); + + if( hasFlashlight ) + { + DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + return; + } + + // DX6 fallback mode. + if ( params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->GetIntValue() ) + { + DetailAlphaMaskPass1( pShaderShadow, pShaderAPI, params, detailScale ); + DetailAlphaMaskPass2( pShaderShadow, pShaderAPI, detailScale ); + } + else + { + // FIXME: add multitexture support! + NormalModePass1( pShaderShadow, pShaderAPI ); + NormalModePass2( pShaderShadow, pShaderAPI, params, detailScale ); + NormalModePass3( pShaderShadow, pShaderAPI, params, detailScale ); + } + } + + + // ------------------------------------------------------------------------------ // + // "Normal" mode - doesn't use the detail texture's alpha mask. + // ------------------------------------------------------------------------------ // + + void NormalModePass1( + IShaderShadow *pShaderShadow, + IShaderDynamicAPI *pShaderAPI ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + } + + void NormalModePass2( + IShaderShadow *pShaderShadow, + IShaderDynamicAPI *pShaderAPI, + IMaterialVar **params, + float detailScale ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + if ( detailScale != 1.0f ) + { + pShaderAPI->MatrixMode( MATERIAL_TEXTURE0 ); + pShaderAPI->LoadIdentity(); + pShaderAPI->ScaleXY( detailScale, detailScale ); + } + BindTexture( SHADER_SAMPLER0, DETAIL ); + } + Draw(); + } + + void NormalModePass3( + IShaderShadow *pShaderShadow, + IShaderDynamicAPI *pShaderAPI, + IMaterialVar **params, + float detailScale ) + { + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + SingleTextureLightmapBlendMode(); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + FogToOOOverbright(); + } + DYNAMIC_STATE + { + if ( detailScale != 1.0f ) + pShaderAPI->LoadIdentity( ); + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + Draw(); + } + + + // ------------------------------------------------------------------------------ // + // "Detail alpha mask mode". + // ------------------------------------------------------------------------------ // + + void DetailAlphaMaskPass1( + IShaderShadow *pShaderShadow, + IShaderDynamicAPI *pShaderAPI, + IMaterialVar **params, + float detailScale ) + { + // The equation is [B*Da + (1-Da)] * [D * L] + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 2 ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + // Stage 0 + // Color = B*2 + // Note the 2x here.. we do 4x total in this shader and + // the first 2x is here. The second is in SingleTextureLightmapBlendMode in the 2nd pass. + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + + // Stage 1 [where P = prev stage] + // Color = B*Da + (1-Da) + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATEINVCOLOR_ADDALPHA, + SHADER_TEXARG_INVTEXTUREALPHA, SHADER_TEXARG_PREVIOUSSTAGE ); + + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_TEXCOORD1 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, DETAIL ); + + pShaderAPI->Color4f( 1, 1, 1, 1 ); + + if ( detailScale != 1.0f ) + { + pShaderAPI->MatrixMode( MATERIAL_TEXTURE1 ); + pShaderAPI->LoadIdentity(); + pShaderAPI->ScaleXY( detailScale, detailScale ); + } + + } + Draw(); + } + + void DetailAlphaMaskPass2( IShaderShadow *pShaderShadow, IShaderDynamicAPI *pShaderAPI, float detailScale ) + { + SHADOW_STATE + { + s_pShaderShadow->EnableCustomPixelPipe( true ); + s_pShaderShadow->CustomTextureStages( 2 ); + + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true); + + // Make sure the texgen transform is applied to the texture coordinates and not to an auto-generated reflection vector or whatever. + s_pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_OBJECT_LINEAR ); + + // This turns on blending and does overbrighting if it's enabled. + SingleTextureLightmapBlendMode(); + + // Stage 0, color = D + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + + // Stage 1, color = D*L + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_TEXTURE ); + + // Use the lightmap coordinates in both stages. + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_LIGHTMAP_TEXCOORD1 ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, DETAIL); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + if ( detailScale != 1.0f ) + { + pShaderAPI->MatrixMode( MATERIAL_TEXTURE1 ); + pShaderAPI->LoadIdentity(); + + pShaderAPI->MatrixMode( MATERIAL_TEXTURE0 ); + pShaderAPI->LoadIdentity(); + pShaderAPI->ScaleXY( detailScale, detailScale ); + } + } + + Draw(); + } + +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp b/mp/src/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp new file mode 100644 index 00000000..a58d9dfb --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp @@ -0,0 +1,175 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "lightmappedgeneric_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +DEFINE_FALLBACK_SHADER( WorldTwoTextureBlend, WorldTwoTextureBlend_DX8 ) + +BEGIN_VS_SHADER( WorldTwoTextureBlend_DX8, + "Help for WorldTwoTextureBlend_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "iris texture", 0 ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend_detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale of the detail texture" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "WorldTwoTextureBlend_DX6"; + + return 0; + } + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + } + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + { + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->IsDefined() ) + { + params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->SetIntValue( 0 ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + + const char *GetPixelShaderName( IMaterialVar** params, bool bHasBaseTexture, bool bHasDetailTexture ) + { + bool bSelfIllum = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM); + if ( !bHasBaseTexture ) + { + if ( !bHasDetailTexture ) + return "LightmappedGeneric_NoTexture"; + + return "LightmappedGeneric_DetailNoTexture"; + } + + if ( !bHasDetailTexture ) + { + if ( bSelfIllum ) + return "LightmappedGeneric_SelfIlluminated"; + + return "LightmappedGeneric"; + } + + if ( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->GetIntValue() ) + { + if ( bSelfIllum ) + return "WorldTwoTextureBlend_SelfIlluminated"; + + return "WorldTwoTextureBlend"; + } + + return "WorldTwoTextureBlend_DetailAlpha"; + } + + + SHADER_DRAW + { + bool hasFlashlight = UsingFlashlight( params ); + if( hasFlashlight ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, false, -1, -1, -1, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 ); + return; + } + + bool bHasBaseTexture = params[BASETEXTURE]->IsTexture(); + bool bHasDetailTexture = params[DETAIL]->IsTexture(); + bool bHasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + + SHADOW_STATE + { + if ( bHasBaseTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if ( bHasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + pShaderShadow->EnableBlending( false ); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); + + // Let the shaders do the fun stuff. + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( bHasDetailTexture ); + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + vshIndex.SetVERTEXCOLOR( bHasVertexColor ); + pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + const char *pPixelShaderName = GetPixelShaderName( params, bHasBaseTexture, bHasDetailTexture ); + pShaderShadow->SetPixelShader( pPixelShaderName ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + if ( bHasBaseTexture ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + if ( bHasDetailTexture ) + { + BindTexture( SHADER_SAMPLER2, DETAIL ); + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); + } + + SetModulationVertexShaderDynamicState(); + + // Dynamic vertex shader index. + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + EnablePixelShaderOverbright( 0, true, true ); + SetPixelShaderConstant( 1, SELFILLUMTINT ); + } + Draw(); + } + +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc b/mp/src/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc new file mode 100644 index 00000000..b81fa7bd --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc @@ -0,0 +1,217 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "BUMPMAP" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "DETAIL_ALPHA_MASK_BASE_TEXTURE" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] + +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] + +// SKIP: $DETAILTEXTURE && ( $BUMPMAP && !$DETAIL_ALPHA_MASK_BASE_TEXTURE ) +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: $VERTEXCOLOR && $BUMPMAP +// SKIP: FLASHLIGHT && $SELFILLUM +// SKIP: FLASHLIGHT && $DETAIL_ALPHA_MASK_BASE_TEXTURE +// SKIP: FLASHLIGHT && ($BUMPMAP || $DIFFUSEBUMPMAP) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + + +#define HDRTYPE HDR_TYPE_NONE +#include "common_flashlight_fxc.h" +#include "common_ps_fxc.h" + +const HALF4 g_SelfIllumTint : register( c7 ); +static const HALF g_OverbrightFactor = 2.0f; + +const HALF3 g_EyePos : register( c10 ); +const HALF4 g_FogParams : register( c11 ); + +const HALF3 g_FlashlightPos : register( c15 ); +// flashlightfixme: Move this math into the vertex shader. +const float4x4 g_FlashlightWorldToTexture : register( c16 ); + +const float4 g_FlashlightAttenuationFactors : register( c20 ); + +sampler BaseTextureSampler : register( s0 ); +sampler LightmapSampler : register( s1 ); +sampler FlashlightSampler : register( s2 ); +sampler DetailSampler : register( s3 ); +sampler BumpmapSampler : register( s4 ); +sampler NormalizeSampler : register( s6 ); + +struct PS_INPUT +{ + HALF2 baseTexCoord : TEXCOORD0; + HALF4 detailOrBumpTexCoord : TEXCOORD1; + HALF4 lightmapTexCoord1And2 : TEXCOORD2; // CENTROID: TEXCOORD2 + HALF2 lightmapTexCoord3 : TEXCOORD3; // CENTROID: TEXCOORD3 + HALF4 worldPos_projPosZ : TEXCOORD4; + HALF3x3 tangentSpaceTranspose : TEXCOORD5; + // tangentSpaceTranspose : TEXCOORD6; + // tangentSpaceTranspose : TEXCOORD7; + HALF4 vertexColor : COLOR; +}; + + +float4 main( PS_INPUT i ) : COLOR +{ + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBumpmap = BUMPMAP ? true : false; + bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false; + bool bVertexColor = VERTEXCOLOR ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE ? true : false; + bool bFlashlight = FLASHLIGHT ? true : false; + + HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); + if( bBumpmap && bDiffuseBumpmap ) + { + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + lightmapColor1 = lightmapSample1.rgb; + lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); + lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); + } + else + { + if( !bFlashlight ) + { + HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + lightmapColor1 = lightmapSample1.rgb; + } + } + + HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); + if( bDetailTexture ) + { + detailColor = tex2D( DetailSampler, i.detailOrBumpTexCoord.xy ); + } + + HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); + if ( bDetailAlphaMaskBaseTexture ) + { + // This is what WorldTwoTextureBlend_DX6 does. + baseColor.rgb = saturate( saturate( baseColor * 2 ) * detailColor.a + (1 - detailColor.a) ); + baseColor.rgb *= detailColor; + } + else + { + baseColor.rgb = lerp( baseColor, detailColor, detailColor.a ); + } + + HALF3 normal = HALF3( 0.0f, 0.0f, 1.0f ); + if( bBumpmap ) + { + HALF3 normalTexel; + normalTexel = tex2D( BumpmapSampler, i.detailOrBumpTexCoord.xy ); + normal = 2.0 * normalTexel - 1.0; + } + + HALF3 albedo = HALF3( 1.0f, 1.0f, 1.0f ); + HALF alpha = 1.0f; + albedo *= baseColor; + if( !bSelfIllum ) + { + alpha *= baseColor.a; + } + + // The vertex color contains the modulation color + vertex color combined + albedo *= i.vertexColor; + alpha *= i.vertexColor.a; // not sure about this one + + HALF3 diffuseLighting; + if( bFlashlight ) + { + float3 worldSpaceNormal; + // Make the unbumped version not so fucking stupid and not need tangentSpaceTranspose you knob. + worldSpaceNormal = mul( normal, i.tangentSpaceTranspose ); + + int nShadowSampleLevel = 0; + bool bDoShadows = false; +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = true; +#endif + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); + + diffuseLighting = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, FlashlightSampler, NormalizeSampler, + nShadowSampleLevel, bDoShadows, false, float2(0, 0), false ); + } + else + { + if( bBumpmap && bDiffuseBumpmap ) + { + float dot1 = saturate( dot( normal, bumpBasis[0] ) ); + float dot2 = saturate( dot( normal, bumpBasis[1] ) ); + float dot3 = saturate( dot( normal, bumpBasis[2] ) ); + + float sum = dot1 + dot2 + dot3; + diffuseLighting = dot1 * lightmapColor1 + + dot2 * lightmapColor2 + + dot3 * lightmapColor3; + diffuseLighting *= 1.0f / sum; + } + else + { + diffuseLighting = lightmapColor1; + } + + // Only scale here since the flashlight will already be scaled properly + diffuseLighting *= g_OverbrightFactor; + } + + HALF3 diffuseComponent = albedo * diffuseLighting; + + if( bSelfIllum ) + { + HALF3 selfIllumComponent = g_SelfIllumTint * albedo; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + } + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); + HALF3 result = diffuseComponent + specularLighting; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + +#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; +#endif + + return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} + diff --git a/mp/src/materialsystem/stdshaders/worldvertexalpha.cpp b/mp/src/materialsystem/stdshaders/worldvertexalpha.cpp new file mode 100644 index 00000000..85bad1c1 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldvertexalpha.cpp @@ -0,0 +1,259 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "WorldVertexAlpha.inc" +#include "worldvertexalpha_ps20.inc" +#include "worldvertexalpha_ps20b.inc" + +BEGIN_VS_SHADER( WorldVertexAlpha, + "Help for WorldVertexAlpha" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + SET_FLAGS2( MATERIAL_VAR2_BLEND_WITH_LIGHTMAP_ALPHA ); + } + SHADER_INIT + { + // Load the base texture here! + LoadTexture( BASETEXTURE ); + } + + SHADER_FALLBACK + { +// if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + return "WorldVertexAlpha_DX8"; + } + return 0; + } + + SHADER_DRAW + { + if( g_pHardwareConfig->SupportsVertexAndPixelShaders() && !UsingEditor( params ) ) + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + // NOTE: This is the DX8, Non-Hammer version. + + SHADOW_STATE + { + // Base time lightmap (Need two texture stages) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + + worldvertexalpha_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WorldVertexAlpha" ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Bind the base texture (Stage0) and lightmap (Stage1) + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + EnablePixelShaderOverbright( 0, true, true ); + + worldvertexalpha_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + + Draw(); + } + else + { + // DX 9 version with HDR support + + // Pass 1 + SHADOW_STATE + { + SetInitialShadowState(); + + pShaderShadow->EnableAlphaWrites( true ); + + // Base time lightmap (Need two texture stages) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + pShaderShadow->EnableBlendingSeparateAlpha( true ); + pShaderShadow->BlendFuncSeparateAlpha( SHADER_BLEND_ZERO, SHADER_BLEND_SRC_ALPHA ); + + worldvertexalpha_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( PASS, 0 ); + SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( PASS, 0 ); + SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + } + + + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Bind the base texture (Stage0) and lightmap (Stage1) + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + worldvertexalpha_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + } + } + Draw(); + + // Pass 2 + SHADOW_STATE + { + SetInitialShadowState(); + + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableColorWrites( false ); + + // Base time lightmap (Need two texture stages) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + pShaderShadow->EnableBlendingSeparateAlpha( true ); + pShaderShadow->BlendFuncSeparateAlpha( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + + worldvertexalpha_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( PASS, 1 ); + SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( PASS, 1 ); + SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + } + + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Bind the base texture (Stage0) and lightmap (Stage1) + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + worldvertexalpha_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + } + } + Draw(); + } + } + else + { + // NOTE: This is the DX7, Hammer version. + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); +// pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + + // Use vertex color for Hammer because it puts the blending alpha in the vertices. + unsigned int colorFlag = 0; + if( UsingEditor( params ) ) + { + colorFlag |= SHADER_DRAW_COLOR; + } + + pShaderShadow->DrawFlags( colorFlag | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | + SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + + Draw(); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/worldvertexalpha_dx8.cpp b/mp/src/materialsystem/stdshaders/worldvertexalpha_dx8.cpp new file mode 100644 index 00000000..0ea139ee --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldvertexalpha_dx8.cpp @@ -0,0 +1,113 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "worldvertexalpha.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( WorldVertexAlpha, WorldVertexAlpha_DX8 ) + +BEGIN_VS_SHADER( WorldVertexAlpha_DX8, + "Help for WorldVertexAlpha_DX8" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + SHADER_INIT + { + // Load the base texture here! + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + if( g_pHardwareConfig->SupportsVertexAndPixelShaders() && !UsingEditor( params ) ) + { + // NOTE: This is the DX8, Non-Hammer version. + + SHADOW_STATE + { + // Base time lightmap (Need two texture stages) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + + worldvertexalpha_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WorldVertexAlpha" ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Bind the base texture (Stage0) and lightmap (Stage1) + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + EnablePixelShaderOverbright( 0, true, true ); + + worldvertexalpha_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + + Draw(); + } + else + { + // NOTE: This is the DX7, Hammer version. + // FIXME: Gary - you need to write a proper non-fixed function shader for this. + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); +// pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + + // Use vertex color for Hammer because it puts the blending alpha in the vertices. + unsigned int colorFlag = 0; + if( UsingEditor( params ) ) + { + colorFlag |= SHADER_DRAW_COLOR; + } + + pShaderShadow->DrawFlags( colorFlag | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | + SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + + Draw(); + } + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/worldvertextransition.cpp b/mp/src/materialsystem/stdshaders/worldvertextransition.cpp new file mode 100644 index 00000000..e7d6a9ab --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldvertextransition.cpp @@ -0,0 +1,157 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "convar.h" + +#include "worldvertextransition_dx8_helper.h" +#include "lightmappedgeneric_dx9_helper.h" + +static LightmappedGeneric_DX9_Vars_t s_info; + + +DEFINE_FALLBACK_SHADER( WorldVertexTransition, WorldVertexTransition_DX9 ) + +BEGIN_VS_SHADER( WorldVertexTransition_DX9, "Help for WorldVertexTransition" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + + // detail (multi-) texturing + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( BUMPMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( BUMPMASK, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $basetexture2" ) + SHADER_PARAM( BASETEXTURENOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( BASETEXTURE2NOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "light munging lookup texture" ) + SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) + SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) + SHADER_PARAM( MASKEDBLENDING, SHADER_PARAM_TYPE_INTEGER, "0", "blend using texture with no vertex alpha. For using texture blending on non-displacements" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + END_SHADER_PARAMS + + void SetupVars( WorldVertexTransitionEditor_DX8_Vars_t& info ) + { + info.m_nBaseTextureVar = BASETEXTURE; + info.m_nBaseTextureFrameVar = FRAME; + info.m_nBaseTextureTransformVar = BASETEXTURETRANSFORM; + info.m_nBaseTexture2Var = BASETEXTURE2; + info.m_nBaseTexture2FrameVar = FRAME2; + info.m_nBaseTexture2TransformVar = BASETEXTURETRANSFORM; // FIXME!!!! + } + + void SetupVars( LightmappedGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTint = DETAILTINT; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nFresnelReflection = FRESNELREFLECTION; + info.m_nNoDiffuseBumpLighting = NODIFFUSEBUMPLIGHTING; + info.m_nBumpmap2 = BUMPMAP2; + info.m_nBumpFrame2 = BUMPFRAME2; + info.m_nBaseTexture2 = BASETEXTURE2; + info.m_nBaseTexture2Frame = FRAME2; + info.m_nBumpTransform2 = BUMPTRANSFORM2; + info.m_nBumpMask = BUMPMASK; + info.m_nBaseTextureNoEnvmap = BASETEXTURENOENVMAP; + info.m_nBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP; + info.m_nDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nLightWarpTexture = LIGHTWARPTEXTURE; + info.m_nBlendModulateTexture = BLENDMODULATETEXTURE; + info.m_nBlendMaskTransform = BLENDMASKTRANSFORM; + info.m_nMaskedBlending = MASKEDBLENDING; + info.m_nSelfShadowedBumpFlag = SSBUMP; + info.m_nSeamlessMappingScale = SEAMLESS_SCALE; + info.m_nAlphaTestReference = -1; + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "WorldVertexTransition_DX8"; + + return 0; + } + + SHADER_INIT_PARAMS() + { + SetupVars( s_info ); + InitParamsLightmappedGeneric_DX9( this, params, pMaterialName, s_info ); + } + + SHADER_INIT + { + SetupVars( s_info ); + InitLightmappedGeneric_DX9( this, params, s_info ); + } + + SHADER_DRAW + { + if ( UsingEditor( params ) ) + { + WorldVertexTransitionEditor_DX8_Vars_t info; + SetupVars( info ); + DrawWorldVertexTransitionEditor_DX8( this, params, pShaderAPI, pShaderShadow, info ); + return; + } + + DrawLightmappedGeneric_DX9( this, params, pShaderAPI, pShaderShadow, s_info, pContextDataPtr ); + } +END_SHADER + diff --git a/mp/src/materialsystem/stdshaders/worldvertextransition_dx6.cpp b/mp/src/materialsystem/stdshaders/worldvertextransition_dx6.cpp new file mode 100644 index 00000000..163291e3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldvertextransition_dx6.cpp @@ -0,0 +1,52 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +#include "worldvertextransition_dx6_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( WorldVertexTransition, WorldVertexTransition_DX6 ) + +BEGIN_SHADER( WorldVertexTransition_DX6, + "Help for WorldVertexTransition_dx6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture2", "base texture2 help" ) + END_SHADER_PARAMS + + void SetupVars( WorldVertexTransition_DX6_Vars_t& info ) + { + info.m_nBaseTextureVar = BASETEXTURE; + info.m_nBaseTextureFrameVar = FRAME; + info.m_nBaseTexture2Var = BASETEXTURE2; + info.m_nFlashlightTextureVar = FLASHLIGHTTEXTURE; + } + + SHADER_INIT_PARAMS() + { + WorldVertexTransition_DX6_Vars_t info; + SetupVars( info ); + InitParamsWorldVertexTransition_DX6( params, info ); + } + + SHADER_INIT + { + WorldVertexTransition_DX6_Vars_t info; + SetupVars( info ); + InitWorldVertexTransition_DX6( this, params, info ); + } + + SHADER_DRAW + { + WorldVertexTransition_DX6_Vars_t info; + SetupVars( info ); + DrawWorldVertexTransition_DX6( this, params, pShaderAPI, pShaderShadow, info ); + } +END_SHADER diff --git a/mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp b/mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp new file mode 100644 index 00000000..7539ff29 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp @@ -0,0 +1,206 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "shaderlib/cshader.h" +#include "worldvertextransition_dx6_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +void InitParamsWorldVertexTransition_DX6( IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + // FLASHLIGHTFIXME + params[info.m_nFlashlightTextureVar]->SetStringValue( "effects/flashlight001" ); +} + +void InitWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ) +{ + // FLASHLIGHTFIXME + if ( params[info.m_nFlashlightTextureVar]->IsDefined() ) + { + pShader->LoadTexture( info.m_nFlashlightTextureVar ); + } + + if ( params[info.m_nBaseTextureVar]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTextureVar ); + } + + if ( params[info.m_nBaseTexture2Var]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture2Var ); + } +} + +static void DrawFlashlightPass( CBaseShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, int nPass, WorldVertexTransition_DX6_Vars_t &info ) +{ + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->SetDiffuseMaterialSource( SHADER_MATERIALSOURCE_COLOR1 ); + if( nPass == 0 ) + { + pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + else + { + pShader->EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + } + + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_COLOR | SHADER_DRAW_NORMAL; + pShaderShadow->DrawFlags( flags ); + pShader->FogToBlack(); + + pShaderShadow->EnableLighting( true ); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 2 ); + + // color stage 0 + // projected texture * vertex color (lighting) + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE, + SHADER_TEXARG_TEXTURE, + SHADER_TEXARG_VERTEXCOLOR ); + + // color stage 1 + // * base texture + 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 * vertex color + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, + SHADER_TEXOP_MODULATE, + SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_VERTEXCOLOR ); + + // 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 ); + } + DYNAMIC_STATE + { + pShader->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 ); + + pShader->BindTexture( SHADER_SAMPLER0, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + if( nPass == 0 ) + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture2Var, -1 ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTextureVar, info.m_nBaseTextureFrameVar ); + } + } + pShader->Draw(); +} + + +void DrawWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransition_DX6_Vars_t &info ) +{ + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if( bHasFlashlight ) + { + DrawFlashlightPass( pShader, params, pShaderAPI, pShaderShadow, 0, info ); + DrawFlashlightPass( pShader, params, pShaderAPI, pShaderShadow, 1, info ); + return; + } + + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); + + pShaderShadow->DrawFlags( SHADER_DRAW_COLOR | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + pShader->FogToFogColor(); + } + DYNAMIC_STATE + { + //pShaderAPI->TexMinFilter( SHADER_TEXFILTERMODE_NEAREST ); + //pShaderAPI->TexMagFilter( SHADER_TEXFILTERMODE_NEAREST ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTextureVar ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + pShader->Draw(); + + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableBlending( true ); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 2 ); + + // alpha and color stage 0 + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, + SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, + SHADER_TEXARG_TEXTURE ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, + SHADER_TEXARG_TEXTURE ); + + // alpha and color stage 1 + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, + SHADER_TEXOP_MODULATE, + SHADER_TEXARG_TEXTURE, + SHADER_TEXARG_VERTEXCOLOR ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_PREVIOUSSTAGE, + SHADER_TEXARG_TEXTURE ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + pShaderShadow->DrawFlags( SHADER_DRAW_COLOR | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + pShader->FogToFogColor(); + } + DYNAMIC_STATE + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture2Var ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + pShader->Draw(); +} diff --git a/mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.h b/mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.h new file mode 100644 index 00000000..16e0bfd5 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.h @@ -0,0 +1,39 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef WORLDVERTEXTRANSITION_DX6_HELPER_H +#define WORLDVERTEXTRANSITION_DX6_HELPER_H + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct WorldVertexTransition_DX6_Vars_t +{ + WorldVertexTransition_DX6_Vars_t() { memset( this, 0xFF, sizeof(WorldVertexTransition_DX6_Vars_t) ); } + + int m_nBaseTextureVar; + int m_nBaseTextureFrameVar; + int m_nBaseTexture2Var; + int m_nFlashlightTextureVar; +}; + +void InitParamsWorldVertexTransition_DX6( IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ); +void InitWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ); +void DrawWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransition_DX6_Vars_t &info ); + + +#endif // WORLDVERTEXTRANSITION_DX6_HELPER_H \ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp b/mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp new file mode 100644 index 00000000..6a49fd71 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp @@ -0,0 +1,81 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "worldvertextransition_dx8_helper.h" +#include "BaseVSShader.h" + +#include "WorldVertexTransition.inc" + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +void InitParamsWorldVertexTransitionEditor_DX8( IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); +} + +void InitWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ) +{ + if ( params[info.m_nBaseTextureVar]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTextureVar ); + } + + if ( params[info.m_nBaseTexture2Var]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture2Var ); + } +} + +void DrawWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransitionEditor_DX8_Vars_t &info ) +{ + SHADOW_STATE + { + // This is the dx8 worldcraft version (non-bumped always.. too bad) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + int fmt = VERTEX_POSITION | VERTEX_COLOR; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + worldvertextransition_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition", vshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( "WorldVertexTransition_Editor" ); + + pShader->FogToFogColor(); + } + DYNAMIC_STATE + { + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTextureVar, info.m_nBaseTextureFrameVar ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture2Var, info.m_nBaseTexture2FrameVar ); + + // Texture 3 = lightmap + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_LIGHTMAP ); + + pShader->EnablePixelShaderOverbright( 0, true, true ); + + // JasonM - Gnarly hack since we're calling this legacy shader from DX9 + int nTextureTransformConst = VERTEX_SHADER_SHADER_SPECIFIC_CONST_0; + int nTextureTransformConst2 = VERTEX_SHADER_SHADER_SPECIFIC_CONST_2; + if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + nTextureTransformConst -= 10; + nTextureTransformConst2 -= 10; + } + + pShader->SetVertexShaderTextureTransform( nTextureTransformConst, info.m_nBaseTextureTransformVar ); + pShader->SetVertexShaderTextureTransform( nTextureTransformConst2, info.m_nBaseTexture2TransformVar ); + + worldvertextransition_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + pShader->Draw(); +} diff --git a/mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.h b/mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.h new file mode 100644 index 00000000..d17d532e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.h @@ -0,0 +1,44 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef WORLDVERTEXTRANSITION_DX8_HELPER_H +#define WORLDVERTEXTRANSITION_DX8_HELPER_H + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct WorldVertexTransitionEditor_DX8_Vars_t +{ + WorldVertexTransitionEditor_DX8_Vars_t() { memset( this, 0xFF, sizeof(WorldVertexTransitionEditor_DX8_Vars_t) ); } + + int m_nBaseTextureVar; + int m_nBaseTextureFrameVar; + int m_nBaseTextureTransformVar; + int m_nBaseTexture2Var; + int m_nBaseTexture2FrameVar; + int m_nBaseTexture2TransformVar; +}; + +void InitParamsWorldVertexTransitionEditor_DX8( IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ); +void InitWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ); +void DrawWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransitionEditor_DX8_Vars_t &info ); + + +#endif // WORLDVERTEXTRANSITION_DX8_HELPER_H \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/BlurFilterX.cpp b/sp/src/materialsystem/stdshaders/BlurFilterX.cpp new file mode 100644 index 00000000..f462423a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/BlurFilterX.cpp @@ -0,0 +1,122 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "BlurFilter_vs20.inc" +#include "BlurFilter_ps20.inc" +#include "BlurFilter_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( BlurFilterX, "Help for BlurFilterX", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT + { + if( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "BlurFilterX_DX80"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Render targets are pegged as sRGB on POSIX, so just force these reads and writes + bool bForceSRGBReadAndWrite = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs(); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bForceSRGBReadAndWrite ); + pShaderShadow->EnableSRGBWrite( bForceSRGBReadAndWrite ); + + // Pre-cache shaders + blurfilter_vs20_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "BlurFilter_vs20", vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b ); +#ifndef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( APPROX_SRGB_ADAPTER, bForceSRGBReadAndWrite ); +#endif + SET_STATIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + } + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + + float v[4]; + + // The temp buffer is 1/4 back buffer size + ITexture *src_texture = params[BASETEXTURE]->GetTextureValue(); + int width = src_texture->GetActualWidth(); + float dX = 1.0f / width; + + // Tap offsets + v[0] = 1.3366f * dX; + v[1] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 ); + v[0] = 3.4295f * dX; + v[1] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 ); + v[0] = 5.4264f * dX; + v[1] = 0.0f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 ); + + v[0] = 7.4359f * dX; + v[1] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 0, v, 1 ); + v[0] = 9.4436f * dX; + v[1] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 1, v, 1 ); + v[0] = 11.4401f * dX; + v[1] = 0.0f; + pShaderAPI->SetPixelShaderConstant( 2, v, 1 ); + v[0] = v[1] = v[2] = v[3] = 1.0; + pShaderAPI->SetPixelShaderConstant( 3, v, 1 ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/BlurFilterX_dx80.cpp b/sp/src/materialsystem/stdshaders/BlurFilterX_dx80.cpp new file mode 100644 index 00000000..6eecfef2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/BlurFilterX_dx80.cpp @@ -0,0 +1,86 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "BaseVSShader.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( BlurFilterX, BlurFilterX_DX80 ) + +BEGIN_VS_SHADER_FLAGS( BlurFilterX_DX80, "Help for BlurFilterX_DX80", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT + { + if( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + { + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Pre-cache shaders + pShaderShadow->SetVertexShader( "BlurFilter_vs11", 0 ); + pShaderShadow->SetPixelShader( "BlurFilter_ps11", 0 ); + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER3, BASETEXTURE, -1 ); + + // The temp buffer is 1/4 back buffer size + ITexture *src_texture=params[BASETEXTURE]->GetTextureValue(); + int width = src_texture->GetActualWidth(); + float dX = 2.0f / width; + + // 4 Tap offsets, expected from pixel center + float v[4][4]; + v[0][0] = -1.5f * dX; + v[0][1] = 0; + v[1][0] = -0.5f * dX; + v[1][1] = 0; + v[2][0] = 0.5f * dX; + v[2][1] = 0; + v[3][0] = 1.5f * dX; + v[3][1] = 0; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &v[0][0], 4 ); + + v[0][0] = v[0][1] = v[0][2] = v[0][3] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 1, v[0], 1 ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + pShaderAPI->SetPixelShaderIndex( 0 ); + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/BlurFilterY.cpp b/sp/src/materialsystem/stdshaders/BlurFilterY.cpp new file mode 100644 index 00000000..57db29c0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/BlurFilterY.cpp @@ -0,0 +1,136 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "BaseVSShader.h" +#include "BlurFilter_vs20.inc" +#include "BlurFilter_ps20.inc" +#include "BlurFilter_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( BlurFilterY, "Help for BlurFilterY", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( FRAMETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if ( !( params[BLOOMAMOUNT]->IsDefined() ) ) + { + params[BLOOMAMOUNT]->SetFloatValue( 1.0 ); + } + } + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "BlurFilterY_DX80"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Render targets are pegged as sRGB on POSIX, so just force these reads and writes + bool bForceSRGBReadAndWrite = IsOSX() && g_pHardwareConfig->CanDoSRGBReadFromRTs(); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bForceSRGBReadAndWrite ); + pShaderShadow->EnableSRGBWrite( bForceSRGBReadAndWrite ); + + // Pre-cache shaders + DECLARE_STATIC_VERTEX_SHADER( blurfilter_vs20 ); + SET_STATIC_VERTEX_SHADER( blurfilter_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20b ); +#ifndef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( APPROX_SRGB_ADAPTER, bForceSRGBReadAndWrite ); +#endif + SET_STATIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_STATIC_PIXEL_SHADER( blurfilter_ps20 ); + } + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + + // The temp buffer is 1/4 back buffer size + ITexture *src_texture = params[BASETEXTURE]->GetTextureValue(); + int height = src_texture->GetActualWidth(); + float dY = 1.0f / height; +// dY *= 0.4; + float v[4]; + + // Tap offsets + v[0] = 0.0f; + v[1] = 1.3366f * dY; + v[2] = 0; + v[3] = 0; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, v, 1 ); + v[0] = 0.0f; + v[1] = 3.4295f * dY; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, v, 1 ); + v[0] = 0.0f; + v[1] = 5.4264f * dY; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, v, 1 ); + + v[0] = 0.0f; + v[1] = 7.4359f * dY; + pShaderAPI->SetPixelShaderConstant( 0, v, 1 ); + v[0] = 0.0f; + v[1] = 9.4436f * dY; + pShaderAPI->SetPixelShaderConstant( 1, v, 1 ); + v[0] = 0.0f; + v[1] = 11.4401f * dY; + pShaderAPI->SetPixelShaderConstant( 2, v, 1 ); + + v[0]=v[1]=v[2]=params[BLOOMAMOUNT]->GetFloatValue(); + + pShaderAPI->SetPixelShaderConstant( 3, v, 1 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 ); + SET_DYNAMIC_VERTEX_SHADER( blurfilter_ps20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( blurfilter_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/BlurFilterY_dx80.cpp b/sp/src/materialsystem/stdshaders/BlurFilterY_dx80.cpp new file mode 100644 index 00000000..5e01d608 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/BlurFilterY_dx80.cpp @@ -0,0 +1,91 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "BaseVSShader.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( BlurFilterY, BlurFilterY_DX80 ) + +BEGIN_VS_SHADER_FLAGS( BlurFilterY_DX80, "Help for BlurFilterY_DX80", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( BLOOMAMOUNT, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( FRAMETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_SmallHDR0", "" ) + END_SHADER_PARAMS + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + if ( !( params[BLOOMAMOUNT]->IsDefined() ) ) + params[BLOOMAMOUNT]->SetFloatValue(1.0); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + { + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + // Pre-cache shaders + pShaderShadow->SetVertexShader( "BlurFilter_vs11", 0 ); + pShaderShadow->SetPixelShader( "BlurFilter_ps11", 0 ); + + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE, -1 ); + BindTexture( SHADER_SAMPLER3, BASETEXTURE, -1 ); + + int width, height; + pShaderAPI->GetBackBufferDimensions( width, height ); + + // The temp buffer is 1/4 back buffer size + float dY = 2.0f / height; + + // 4 Tap offsets, expected from pixel center + float v[4][4]; + v[0][0] = 0; + v[0][1] = -1.5f * dY; + v[1][0] = 0; + v[1][1] = -0.5f * dY; + v[2][0] = 0; + v[2][1] = 0.5f * dY; + v[3][0] = 0; + v[3][1] = 1.5f * dY; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &v[0][0], 4 ); + + v[0][0] = v[0][1] = v[0][2] = params[BLOOMAMOUNT]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 1, v[0], 1 ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + pShaderAPI->SetPixelShaderIndex( 0 ); + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/BlurFilter_ps11.psh b/sp/src/materialsystem/stdshaders/BlurFilter_ps11.psh new file mode 100644 index 00000000..6bc9bc57 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/BlurFilter_ps11.psh @@ -0,0 +1,18 @@ +ps.1.1 + +// 1221 filter constants +def c0, 0.1667f, 0.1667f, 0.1667f, 0.3333f + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0.rgb, t0, c0 +mad r0.rgb, t1, c0.a, r0 +mad r0.rgb, t2, c0.a, r0 +mad r0.rgb, t3, c0, r0 + +mul r0.rgb, r0, c1 + +mov r0.a, t0.a + diff --git a/sp/src/materialsystem/stdshaders/BlurFilter_ps2x.fxc b/sp/src/materialsystem/stdshaders/BlurFilter_ps2x.fxc new file mode 100644 index 00000000..bfd082b3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/BlurFilter_ps2x.fxc @@ -0,0 +1,91 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "APPROX_SRGB_ADAPTER" "0..1" [ps20b] [PC] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler TexSampler : register( s0 ); + +struct PS_INPUT +{ + float2 coordTap0 : TEXCOORD0; + float2 coordTap1 : TEXCOORD1; + float2 coordTap2 : TEXCOORD2; + float2 coordTap3 : TEXCOORD3; + float2 coordTap1Neg : TEXCOORD4; + float2 coordTap2Neg : TEXCOORD5; + float2 coordTap3Neg : TEXCOORD6; +}; + +float2 psTapOffs[3] : register( c0 ); +float3 scale_factor : register( c3 ); + +float4 SampleTexture( sampler texSampler, float2 uv ) +{ + float4 cSample = tex2D( texSampler, uv ); + + #if ( APPROX_SRGB_ADAPTER ) + { + cSample.rgb = max( cSample.rgb, float3( 0.00001f, 0.00001f, 0.00001f ) ); // rsqrt doesn't like inputs of zero + + float3 ooSQRT; // + ooSQRT.r = rsqrt( cSample.r ); // + ooSQRT.g = rsqrt( cSample.g ); // Approximate linear-to-sRGB conversion + ooSQRT.b = rsqrt( cSample.b ); // + cSample.rgb *= ooSQRT.rgb; // + } + #endif + + return cSample; +} + +float4 main( PS_INPUT i ) : COLOR +{ + float4 s0, s1, s2, s3, s4, s5, s6, color; + + // Sample taps with coordinates from VS + s0 = SampleTexture( TexSampler, i.coordTap0 ); + s1 = SampleTexture( TexSampler, i.coordTap1 ); + s2 = SampleTexture( TexSampler, i.coordTap2 ); + s3 = SampleTexture( TexSampler, i.coordTap3 ); + s4 = SampleTexture( TexSampler, i.coordTap1Neg ); + s5 = SampleTexture( TexSampler, i.coordTap2Neg ); + s6 = SampleTexture( TexSampler, i.coordTap3Neg ); + + color = s0 * 0.2013f; + color += ( s1 + s4 ) * 0.2185f; + color += ( s2 + s5 ) * 0.0821f; + color += ( s3 + s6 ) * 0.0461f; + + // Compute tex coords for other taps + float2 coordTap4 = i.coordTap0 + psTapOffs[0]; + float2 coordTap5 = i.coordTap0 + psTapOffs[1]; + float2 coordTap6 = i.coordTap0 + psTapOffs[2]; + float2 coordTap4Neg = i.coordTap0 - psTapOffs[0]; + float2 coordTap5Neg = i.coordTap0 - psTapOffs[1]; + float2 coordTap6Neg = i.coordTap0 - psTapOffs[2]; + + // Sample the taps + s1 = SampleTexture( TexSampler, coordTap4 ); + s2 = SampleTexture( TexSampler, coordTap5 ); + s3 = SampleTexture( TexSampler, coordTap6 ); + s4 = SampleTexture( TexSampler, coordTap4Neg ); + s5 = SampleTexture( TexSampler, coordTap5Neg ); + s6 = SampleTexture( TexSampler, coordTap6Neg ); + + color += ( s1 + s4 ) * 0.0262f; + color += ( s2 + s5 ) * 0.0162f; + color += ( s3 + s6 ) * 0.0102f; + color.xyz*=scale_factor.xyz; + + #if ( APPROX_SRGB_ADAPTER ) + { + color.xyz *= color.xyz; // Approximate sRGB-to-linear conversion + } + #endif + + return color; + //return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} + diff --git a/sp/src/materialsystem/stdshaders/BlurFilter_vs11.fxc b/sp/src/materialsystem/stdshaders/BlurFilter_vs11.fxc new file mode 100644 index 00000000..0a213522 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/BlurFilter_vs11.fxc @@ -0,0 +1,34 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 coordTap0 : TEXCOORD0; + float2 coordTap1 : TEXCOORD1; + float2 coordTap2 : TEXCOORD2; + float2 coordTap3 : TEXCOORD3; +}; + +float2 vsTapOffs[4] : register ( SHADER_SPECIFIC_CONST_0 ); + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.projPos = float4( v.vPos, 1.0f ); + + o.coordTap0 = v.vBaseTexCoord + vsTapOffs[0]; + o.coordTap1 = v.vBaseTexCoord + vsTapOffs[1]; + o.coordTap2 = v.vBaseTexCoord + vsTapOffs[2]; + o.coordTap3 = v.vBaseTexCoord + vsTapOffs[3]; + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/BlurFilter_vs20.fxc b/sp/src/materialsystem/stdshaders/BlurFilter_vs20.fxc new file mode 100644 index 00000000..3c37fa74 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/BlurFilter_vs20.fxc @@ -0,0 +1,39 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 coordTap0 : TEXCOORD0; + float2 coordTap1 : TEXCOORD1; + float2 coordTap2 : TEXCOORD2; + float2 coordTap3 : TEXCOORD3; + float2 coordTap1Neg : TEXCOORD4; + float2 coordTap2Neg : TEXCOORD5; + float2 coordTap3Neg : TEXCOORD6; +}; + +float2 vsTapOffs[3] : register ( SHADER_SPECIFIC_CONST_0 ); + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.projPos = float4( v.vPos, 1.0f ); + o.coordTap0 = v.vBaseTexCoord; + o.coordTap1 = v.vBaseTexCoord + vsTapOffs[0]; + o.coordTap2 = v.vBaseTexCoord + vsTapOffs[1]; + o.coordTap3 = v.vBaseTexCoord + vsTapOffs[2]; + o.coordTap1Neg = v.vBaseTexCoord - vsTapOffs[0]; + o.coordTap2Neg = v.vBaseTexCoord - vsTapOffs[1]; + o.coordTap3Neg = v.vBaseTexCoord - vsTapOffs[2]; + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/Cable.psh b/sp/src/materialsystem/stdshaders/Cable.psh new file mode 100644 index 00000000..a73b1130 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Cable.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; See the vertex shader for info +; +; This shader takes: +; t0 = normal map +; t1 = base texture +; v0 = directional light color +; t2 = directional light direction (biased into 0-1) +; c0 = percent of dirlight to add as ambient +; +; Output: +; (t0 dot t1) * v0 +;------------------------------------------------------------------------------ + +tex t0 ; Get the 3-vector from the normal map +tex t1 ; Interpret tcoord t1 as color data. +texcoord t2 + +dp3 r1, t0_bx2, t2_bx2 ; r1 = normalMap dot dirLightDir +add r0, r1, c0 ; + 0.5 + +mul r1, v0, r0 ; scale the dot product by the dirlight's actual color +mul r0.rgb, r1, t1 + ; scale by the texture color + +mul r0.a, t1.a, v0.a diff --git a/sp/src/materialsystem/stdshaders/Cable.vsh b/sp/src/materialsystem/stdshaders/Cable.vsh new file mode 100644 index 00000000..857a2e3b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Cable.vsh @@ -0,0 +1,117 @@ +vs.1.1 + +#include "macros.vsh" + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; The cable equation is: +; [L dot N] * C * T +; +; where: +; C = directional light color +; T = baseTexture +; N = particle normal (stored in the normal map) +; L = directional light direction +; +; $SHADER_SPECIFIC_CONST_0 = Directional light direction +;------------------------------------------------------------------------------ + + +;------------------------------------------------------------------------------ +; Transform position from object to projection space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Setup the tangent space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$tmp1 ); +&AllocateRegister( \$tmp2 ); +&AllocateRegister( \$tmp3 ); +&AllocateRegister( \$r ); + +; Get S crossed with T (call it R) +mov $tmp1, $vTangentS +mov $tmp2, $vTangentT + +mul $tmp3, $vTangentS.yzxw, $tmp2.zxyw +mad $r, -$vTangentS.zxyw, $tmp2.yzxw, $tmp3 + +&FreeRegister( \$tmp2 ); +&FreeRegister( \$tmp3 ); + +&AllocateRegister( \$s ); + +; Normalize S (into $s) +dp3 $s.w, $vTangentS, $vTangentS +rsq $s.w, $s.w +mul $s.xyz, $vTangentS, $s.w + +; Normalize R (into $r) +dp3 $r.w, $r, $r +rsq $r.w, $r.w +mul $r.xyz, $r, $r.w + +&AllocateRegister( \$t ); + +; Regenerate T (into $t) +mul $t, $r.yzxw, $tmp1.zxyw +mad $t, -$r.zxyw, $tmp1.yzxw, $t + +&FreeRegister( \$tmp1 ); + +;------------------------------------------------------------------------------ +; Transform the light direction (into oD1) +;------------------------------------------------------------------------------ + +&AllocateRegister( \$lightDirection ); + +dp3 $lightDirection.x, $s, $SHADER_SPECIFIC_CONST_0 +dp3 $lightDirection.y, $t, $SHADER_SPECIFIC_CONST_0 +dp3 $lightDirection.z, $r, $SHADER_SPECIFIC_CONST_0 + +&FreeRegister( \$r ); +&FreeRegister( \$s ); +&FreeRegister( \$t ); + +; Scale into 0-1 range (we're assuming light direction was normalized prior to here) +add oT2, $lightDirection, $cHalf ; + 0.5 +&FreeRegister( \$lightDirection ); + +;------------------------------------------------------------------------------ +; Copy texcoords for the normal map and base texture +;------------------------------------------------------------------------------ + +mov oT0, $vTexCoord0 +mov oT1, $vTexCoord1 + +; Pass the dirlight color through +mov oD0.xyzw, $vColor + + diff --git a/sp/src/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc b/sp/src/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc new file mode 100644 index 00000000..c90ef086 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc @@ -0,0 +1,23 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float4 projPos : POSITION; + float3 zValue : TEXCOORD0; +}; + +const float3 g_ZFilter : register( c1 ); +const float3 g_ModulationColor : register( c2 ); + +float4 main( PS_INPUT i ) : COLOR +{ + float z = dot( i.zValue, g_ZFilter ); + z = saturate( z ); + float4 color = float4( z, z, z, 1.0f ); + color.rgb *= g_ModulationColor; + return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} diff --git a/sp/src/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc b/sp/src/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc new file mode 100644 index 00000000..647acde0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc @@ -0,0 +1,38 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float2 cDepthFactor : register( SHADER_SPECIFIC_CONST_0 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 zValue : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + o.zValue.x = (o.projPos.z - cDepthFactor.y) / cDepthFactor.x; + o.zValue.y = (o.projPos.w - cDepthFactor.y) / cDepthFactor.x; + return o; +} + + + + diff --git a/sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp b/sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp new file mode 100644 index 00000000..9f3c34bf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp @@ -0,0 +1,94 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "BaseVSShader.h" +#include "debugdrawenvmapmask_vs20.inc" +#include "debugdrawenvmapmask_ps20.inc" +#include "debugdrawenvmapmask_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( DebugDrawEnvmapMask, "Help for DebugDrawEnvmapMask", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SHOWALPHA, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_INIT + { + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { +// Assert( 0 ); + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); + SET_STATIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); + SET_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); + SET_STATIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); + } + } + DYNAMIC_STATE + { + int numBones = s_pShaderAPI->GetCurrentNumBones(); + + DECLARE_DYNAMIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( debugdrawenvmapmask_vs20 ); + + bool bShowAlpha = params[SHOWALPHA]->GetIntValue() ? true : false; + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( SHOWALPHA, bShowAlpha ); + SET_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( SHOWALPHA, bShowAlpha ); + SET_DYNAMIC_PIXEL_SHADER( debugdrawenvmapmask_ps20 ); + } + + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc b/sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc new file mode 100644 index 00000000..f97589af --- /dev/null +++ b/sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc @@ -0,0 +1,26 @@ +// DYNAMIC: "SHOWALPHA" "0..1" + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); + +struct PS_INPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); +#if SHOWALPHA + float4 result = float4( baseColor.a, baseColor.a, baseColor.a, 1.0f ); +#else + float4 result = float4( baseColor.rgb, 1.0f ); +#endif + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} diff --git a/sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc b/sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc new file mode 100644 index 00000000..33aa5dac --- /dev/null +++ b/sp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc @@ -0,0 +1,39 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + return o; +} + + + + diff --git a/sp/src/materialsystem/stdshaders/DebugTextureView.cpp b/sp/src/materialsystem/stdshaders/DebugTextureView.cpp new file mode 100644 index 00000000..70d73d34 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/DebugTextureView.cpp @@ -0,0 +1,104 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "shaderlib/cshader.h" + +#include "debugtextureview_vs20.inc" +#include "debugtextureview_ps20.inc" +#include "debugtextureview_ps20b.inc" + +DEFINE_FALLBACK_SHADER( DebugTextureView, DebugTextureView_dx9 ) +BEGIN_VS_SHADER( DebugTextureView_dx9, "Help for DebugTextureView" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( SHOWALPHA, SHADER_PARAM_TYPE_BOOL, "0", "" ) + END_SHADER_PARAMS + + SHADER_INIT + { + if ( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "UnlitGeneric"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaTest( true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( debugtextureview_vs20 ); + SET_STATIC_VERTEX_SHADER( debugtextureview_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( debugtextureview_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( SHOWALPHA, params[SHOWALPHA]->GetIntValue() != 0 ); + SET_STATIC_PIXEL_SHADER( debugtextureview_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( debugtextureview_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( SHOWALPHA, params[SHOWALPHA]->GetIntValue() != 0 ); + SET_STATIC_PIXEL_SHADER( debugtextureview_ps20 ); + } + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + //pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + + float cPsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + if ( ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA16161616F ) || + ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA16161616 ) || + ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGB323232F ) || + ( pTexture->GetImageFormat() == IMAGE_FORMAT_RGBA32323232F ) ) + { + if ( pTexture->IsCubeMap() ) + cPsConst0[0] = 1.0f; + else + cPsConst0[1] = 1.0f; + } + pShaderAPI->SetPixelShaderConstant( 0, cPsConst0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( debugtextureview_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( debugtextureview_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ISCUBEMAP, pTexture->IsCubeMap() ); + SET_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ISCUBEMAP, pTexture->IsCubeMap() ); + SET_DYNAMIC_PIXEL_SHADER( debugtextureview_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/DebugTextureView_ps2x.fxc b/sp/src/materialsystem/stdshaders/DebugTextureView_ps2x.fxc new file mode 100644 index 00000000..4b22d55b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/DebugTextureView_ps2x.fxc @@ -0,0 +1,81 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "SHOWALPHA" "0..1" +// DYNAMIC: "ISCUBEMAP" "0..1" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler g_tSampler : register( s0 ); + +struct PS_INPUT +{ + float2 texCoord : TEXCOORD0; +}; + +const float3 g_vConst0 : register( c0 ); +#define g_flIsHdrCube g_vConst0.x +#define g_flIsHdr2D g_vConst0.y + +float4 main( PS_INPUT i ) : COLOR +{ + float4 sample = tex2D( g_tSampler, i.texCoord ); + float4 result = { 0.0f, 0.0f, 0.0f, 1.0f }; + + result.rgb = sample.rgb; + #if SHOWALPHA + result.rgb = sample.a; + #endif + + if ( g_flIsHdr2D ) + result.rgb *= MAX_HDR_OVERBRIGHT; + + #if ISCUBEMAP + bool bNoDataForThisPixel = false; + float3 vec = float3( 0, 0, 0 ); + float x = i.texCoord.x; + float y = i.texCoord.y; + float x2 = frac( ( i.texCoord.x ) * 3.0f ) * 2.0f - 1.0f; + float y2 = frac( ( i.texCoord.y ) * 4.0f ) * 2.0f - 1.0f; + if ( ( x >= 0.3333f ) && ( x <= 0.6666f ) ) //Center row + { + if ( y >= 0.75f ) + vec = float3( x2, 1.0, y2 ); + else if ( y >= 0.5f ) + vec = float3( x2, y2, -1.0 ); + else if ( y >= 0.25f ) + vec = float3( x2, -1.0, -y2 ); + else if ( y >= 0.0f ) + vec = float3( x2, -y2, 1.0 ); + } + else if ( ( y >= 0.25f ) && ( y <= 0.5f ) ) + { + if ( x <= 0.3333f ) + vec = float3( -1.0f, -x2, -y2 ); + else if (x >= 0.6666f) + vec = float3( 1.0f, x2, -y2 ); + else + bNoDataForThisPixel = true; + } + else + { + bNoDataForThisPixel = true; + } + + float4 cBase = texCUBE( g_tSampler, vec ); + #if SHOWALPHA + cBase.rgb = cBase.a; + #endif + + if ( g_flIsHdrCube ) + cBase.rgb *= ENV_MAP_SCALE; + + if ( bNoDataForThisPixel == true ) + cBase.rgb = float3( 0.9f, 0.4f, 0.15f ); + + result.rgb = cBase.rgb; + result.a = 1.0f; // - bNoDataForThisPixel; + #endif + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} diff --git a/sp/src/materialsystem/stdshaders/DebugTextureView_vs20.fxc b/sp/src/materialsystem/stdshaders/DebugTextureView_vs20.fxc new file mode 100644 index 00000000..48c3b7e4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/DebugTextureView_vs20.fxc @@ -0,0 +1,23 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" + +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vUv0 : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + o.vProjPos.xyzw = mul( i.vPos.xyzw, cModelViewProj ); + o.vUv0.xy = i.vTexCoord0.xy; + return o; +} diff --git a/sp/src/materialsystem/stdshaders/Eyes.psh b/sp/src/materialsystem/stdshaders/Eyes.psh new file mode 100644 index 00000000..6e5e5646 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Eyes.psh @@ -0,0 +1,16 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw the eyes +; t0 - texture +; t1 - iris +; t2 - glint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +lrp r0, t1.a, t1, t0 ; Blend in the iris with the background +mad r0.rgb, r0, v0, t2 + ; Modulate by the illumination, add in the glint +mov r0.a, t0.a diff --git a/sp/src/materialsystem/stdshaders/Eyes_Overbright2.psh b/sp/src/materialsystem/stdshaders/Eyes_Overbright2.psh new file mode 100644 index 00000000..11119233 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Eyes_Overbright2.psh @@ -0,0 +1,18 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw the eyes +; t0 - texture +; t1 - iris +; t2 - glint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +lrp r0, t1.a, t1, t0 ; Blend in the iris with the background +mul_x2 r0, v0, r0 ; Modulate by the illumination with overbright + +add r0.rgb, r0, t2 + ; Add in the glint +mov r0.a, t0.a diff --git a/sp/src/materialsystem/stdshaders/Eyes_vs20.fxc b/sp/src/materialsystem/stdshaders/Eyes_vs20.fxc new file mode 100644 index 00000000..b055eed7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Eyes_vs20.fxc @@ -0,0 +1,145 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== +// $SHADER_SPECIFIC_CONST_0 = eyeball origin +// $SHADER_SPECIFIC_CONST_1 = eyeball up * 0.5 +// $SHADER_SPECIFIC_CONST_2 = iris projection U +// $SHADER_SPECIFIC_CONST_3 = iris projection V +// $SHADER_SPECIFIC_CONST_4 = glint projection U +// $SHADER_SPECIFIC_CONST_5 = glint projection V +//============================================================================= + +// STATIC: "INTRO" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "vortwarp_vs20_helper.h" + +static const int g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; + +const float3 cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 ); +const float3 cHalfEyeballUp : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cGlintProjectionU : register( SHADER_SPECIFIC_CONST_4 ); +const float4 cGlintProjectionV : register( SHADER_SPECIFIC_CONST_5 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_6 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_7 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_8 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates + + float3 vPosFlex : POSITION1; // Delta positions for flexing +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; // Fixed-function fog factor +#endif + float2 baseTC : TEXCOORD0; // Base texture coordinate + float2 irisTC : TEXCOORD1; // Iris texture coordinates + float2 glintTC : TEXCOORD2; // Glint texture coordinates + float3 vColor : TEXCOORD3; // Vertex-lit color + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + + float4 vPosition = v.vPos; + float3 dummy = v.vPos.xyz; // dummy values that can't be optimized out + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, vPosition.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, dummy, vPosition.xyz ); +#endif + + // Transform the position and dummy normal (not doing the dummy normal causes invariance issues with the flashlight!) + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, dummy, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + +#if INTRO + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, dummy, dummy, dummy ); +#endif + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, vProjPos, g_FogType ); +#endif + + // Normal = (Pos - Eye origin) - just step on dummy normal created above + worldNormal = worldPos - cEyeOrigin; + + // Normal -= 0.5f * (Normal dot Eye Up) * Eye Up + float normalDotUp = -dot( worldNormal, cHalfEyeballUp) * 0.5f; + worldNormal = normalize(normalDotUp * cHalfEyeballUp + worldNormal); + + // Vertex lighting +#if ( USE_STATIC_CONTROL_FLOW || defined ( SHADER_MODEL_VS_3_0 ) ) + o.vColor = DoLighting( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert ); +#else + o.vColor = DoLightingUnrolled( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); +#endif + + // Texture 0 is the base texture + // Texture 1 is a planar projection used for the iris + // Texture 2 is a planar projection used for the glint + o.baseTC = v.vTexCoord0; + o.irisTC.x = dot( cIrisProjectionU, float4(worldPos, 1) ); + o.irisTC.y = dot( cIrisProjectionV, float4(worldPos, 1) ); + o.glintTC.x = dot( cGlintProjectionU, float4(worldPos, 1) ); + o.glintTC.y = dot( cGlintProjectionV, float4(worldPos, 1) ); + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric.psh new file mode 100644 index 00000000..a6794e7e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh new file mode 100644 index 00000000..7b042e7a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t2 ; cube map +tex t3 ; envmap mask + +mul r0.rgb, t2, 1-t3.a +mul r0.rgb, c2, r0 ; apply the envmaptint ++ mul r0.a, c2.a, v0.a diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh new file mode 100644 index 00000000..ccc2c7b1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t2 ; cube map +tex t3 ; envmap mask + +mul r0.rgb, t2, t3 +mul r0.rgb, c2, r0 ++ mul r0.a, c2.a, v0.a diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh new file mode 100644 index 00000000..fd4fd7a5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t2 ; cube map + +mul r0.rgb, t2, c2 ++ mul r0.a, v0.a, c2.a diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh new file mode 100644 index 00000000..236db8e3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul r1, t2, 1-t3.a ; envmap * envmapmask (alpha) +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh new file mode 100644 index 00000000..75aab35b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh @@ -0,0 +1,14 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 +mul r0, t0, c0 + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh new file mode 100644 index 00000000..6cef1e5d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh @@ -0,0 +1,38 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh new file mode 100644 index 00000000..8eea421f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh @@ -0,0 +1,43 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + +dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + +mov oT2, $vTexCoord1 + +; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. +mov oD0, $vColor diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh new file mode 100644 index 00000000..ba349187 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh @@ -0,0 +1,66 @@ +; STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +ps.1.1 + +;------------------------------------------------------------------------------ +; Environment mapping on a bumped surface +; t0 - Normalmap +; t3 - Cube environment map (*must* be a cube map!) +; +; c0 - color to multiply the results by +; c1 - envmap contrast +; c2 - envmap saturation +; c3 - grey weights +; c4 - fresnel amount +; Input texture coords required here are a little wonky. +; tc0.uv <- U,V into the normal map +; tc1.uvw, tc2.uvw, tc3.uvw <- 3x3 matrix transform +; from tangent space->env map space +; tc1.q, tc2.q, tc3.q <- eye vector in env map space +;------------------------------------------------------------------------------ + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +; FIXME FIXME - Need to do specialized versions of this with and without: +; - constant color +; - fresnel amount of exactly 0 or 1 or in between +; - envmap contrast of 0, 1, or in between +; - envmap saturation of 0, 1, or in between + +; r0 = constant color * result of bump into envmap +mul r0.rgb, t3, c0 + +; dot eye-vector with per-pixel normal from t0 +dp3_sat r1, v0_bx2, t0_bx2 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +mul r1.rgb, r0, r0 ; color squared ++mul r0.a, 1-r1.a, 1-r1.a ; squared + +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color ++mul r0.a, r0.a, r0.a ; quartic + +dp3 r1.rgb, r0, c3 ; color greyscaled ++mul r0.a, r0.a, 1-r1.a ; quintic + +; FIXME - these should be able to pair (I think), but don't on nvidia for some reason. +; (I think) cannot pair due to use of >2 constants in single stage +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale +mad r0.a, r0.a, c6.a, c4.a ; Take Fresnel R(0) into consideration + +mul r0.rgb, r0, r0.a ; multiply output color by result of fresnel calc + +#if NORMALMAPALPHAENVMAPMASK ++mul r0.a, c0.a, t0.a ; Fade amount * alpha from the texture +#else ++mov r0.a, c0.a ; Just use the fade amount +#endif + + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh new file mode 100644 index 00000000..73769dce --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh @@ -0,0 +1,96 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Shader specific constant: +; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; Move it into the w component of the texture coords, as the wacky +; pixel shader wants it there. +mov oT1.w, $worldEyeVect.x +mov oT2.w, $worldEyeVect.y +mov oT3.w, $worldEyeVect.z + +alloc $tangentEyeVect + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal + +&FreeRegister( \$worldEyeVect ); + +&Normalize( $tangentEyeVect ); + +; stick the tangent space eye vector into oD0 +mad oD0.xyz, $tangentEyeVect, $cHalf, $cHalf + +&FreeRegister( \$tangentEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh new file mode 100644 index 00000000..2a4efc7d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh @@ -0,0 +1,72 @@ +; STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +ps.1.4 +;------------------------------------------------------------------------------ +; Phase 1 +;------------------------------------------------------------------------------ +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! +;mov r0.rgba, r4 + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +#if NORMALMAPALPHAENVMAPMASK +; Alpha gets lost after phase marker, so store it here +mov r5, r0.a +#endif + +;------------------------------------------------------------------------------ +; Phase 2 +;------------------------------------------------------------------------------ +; What's left over from the last phase: +; r0 - normal +; r1 - free +; r2 - vector to sample in envmap +; r3 - free +; r4 - normal +; r5 - normal map alpha (rgba) + +phase + +; Sample environment map +texld r3, r2 + +; dot eye-vector with per-pixel normal from r0 +dp3_sat r1, v0_bx2, r0_bx2 + +; Result goes in output color (multiply by constant color c0) +mul r0.rgb, r3, c0 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +mul r1.rgb, r0, r0 ++mul r0.a, 1-r1.a, 1-r1.a ; squared + +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color ++mul r0.a, r0.a, r0.a ; quartic + +dp3 r1.rgb, r0, c3 ++mul r0.a, r0.a, 1-r1.a ; quintic + +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale +mad r0.a, r0.a, c6.a, c4.a ; Take Fresnel R(0) into consideration + +mul r0.rgb, r0, r0.a ; multiply output color by result of fresnel calc + +#if NORMALMAPALPHAENVMAPMASK ++mul r0.a, c0.a, r5.r ; Fade amount * alpha from the texture +#else ++mov r0.a, c0.a ; Just use the fade amount +#endif diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh new file mode 100644 index 00000000..ea0f143a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh @@ -0,0 +1,92 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Shader specific constant: +; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; eye vector +mov oT4.xyz, $worldEyeVect + +alloc $tangentEyeVect + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal + +&FreeRegister( \$worldEyeVect ); + +&Normalize( $tangentEyeVect ); + +; stick the tangent space eye vector into oD0 +mad oD0.xyz, $tangentEyeVect, $cHalf, $cHalf + +&FreeRegister( \$tangentEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh new file mode 100644 index 00000000..9e55248e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh @@ -0,0 +1,79 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - Normalmap +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +; c0, c1, c2 - Axes of the lightmap coordinate system in tangent space +;------------------------------------------------------------------------------ + +; Get the 3-vector from the normal map +tex t0 + +; Sample the lightmaps +tex t1 +tex t2 +tex t3 + +; output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) + + +; r0 = ( N dot basis[0] ) +; don't "_sat" here so that everything adds up to one even if the normal is outside of the basis!!!!! +dp3 r0, t0_bx2, c0 + +; r1 = ( N dot basis[1] ) +dp3 r1, t0_bx2, c1 + +;---- +; r0 = ( N dot basis[0] ) +; r1 = ( N dot basis[1] ) +;---- + +; r0.rgb = ( N dot basis[0] )^2 +mul r0.rgb, r0, r0 + +; r1.a = ( N dot basis[1] )^2 ++mul r1.a, r1, r1 + +;---- +; r0.rgb = ( N dot basis[0] )^2 +; r1.a = ( N dot basis[1] )^2 +;---- + +mul t1, r0, t1 + +;---- +; r1.a = ( N dot basis[1] )^2 +; t1 = lightmapColor[0] * ( N dot basis[0] )^2 +;---- + +dp3 r0, t0_bx2, c2 + +;---- +; r1.a = ( N dot basis[1] )^2 +; t1 = lightmapColor[0] * ( N dot basis[0] )^2 +; r0 = ( N dot basis[2] ) +;---- + +mad t1.rgb, r1.a, t2, t1 ++mul r0.a, r0, r0 + +;---- +; t1.rgb = lightmapColor[0] * ( N dot basis[0] )^2 + lightmapColor[1] * ( N dot basis[1] )^2 +; r0.a = ( N dot basis[2] )^2 +;---- + +mad r0.rgba, r0.a, t3, t1 + +;---- +; r0.rgb = lightmapColor[0] * ( N dot basis[0] )^2 + +; lightmapColor[1] * ( N dot basis[1] )^2 + +; lightmapColor[2] * ( N dot basis[2] )^2 +;---- diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh new file mode 100644 index 00000000..229a839a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh @@ -0,0 +1,54 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +; Compute the texture coordinates given the offset between +; each bumped lightmap +&AllocateRegister( \$offset ); +mov $offset.xy, $vTexCoord2 +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +add oT1.xy, $offset, $vTexCoord1 +mad oT2.xy, $offset, $cTwo, $vTexCoord1 +; make a 3 +alloc $three +add $three, $cOne, $cTwo +mad oT3.xy, $offset, $three, $vTexCoord1 +free $three + +&FreeRegister( \$offset ); diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh new file mode 100644 index 00000000..39a25964 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - Normalmap +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; t4 - Base +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +; c0, c1, c2 - Axes of the lightmap coordinate system in tangent space +;------------------------------------------------------------------------------ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 + +; Sample the lightmaps +texld r1, t1 +texld r2, t2 +texld r3, t3 + +; Sample the base texture +texld r4, t4 + +; output = (lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) ) * base + +dp3 r5.r, r0_bx2, c0 +dp3 r5.g, r0_bx2, c1 +dp3 r5.b, r0_bx2, c2 +mul r5.rgb, r5, r5 +mul r1, r1, r5.r +mad r1, r2, r5.g, r1 +mad r1, r3, r5.g, r1 + +; assume overbright_2 !!! +mul_x2 r0, r1, r4 diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh new file mode 100644 index 00000000..a78d0851 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh @@ -0,0 +1,55 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +; Compute the texture coordinates given the offset between +; each bumped lightmap +&AllocateRegister( \$offset ); +mov $offset.xy, $vTexCoord2 +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +add oT1.xy, $offset, $vTexCoord1 +mad oT2.xy, $offset, $cTwo, $vTexCoord1 +alloc $three +add $three, $cOne, $cTwo +mad oT3.xy, $offset, $three, $vTexCoord1 +free $three +dp4 oT4.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT4.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + +&FreeRegister( \$offset ); diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh new file mode 100644 index 00000000..f17f14cf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh @@ -0,0 +1,47 @@ +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - Normalmap +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; t4 - Base1 +; t5 - Base2 +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +; c0, c1, c2 - Axes of the lightmap coordinate system in tangent space +;------------------------------------------------------------------------------ +ps.1.4 + +; output = (lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) ) * lerp(base1, base2, lightmapColor[0].a) + +; Get the 3-vector from the normal map +texld r0, t0 + +dp3 r5.r, r0_bx2, c0 +dp3 r5.g, r0_bx2, c1 +dp3 r5.b, r0_bx2, c2 +mul r5.rgb, r5, r5 + +phase + +; Sample the lightmaps +texld r1, t1 +texld r2, t2 +texld r3, t3 + +; Sample the base textures +texld r4, t4 +texld r5, t5 + +mul r1, r1, r5.r +mad r1, r2, r5.g, r1 +mad r1, r3, r5.g, r1 + +; blend base textures +lrp r4, r4, r5, r1.a + +; assume overbright_2 !!! +mul_x2 r0, r1, r4 diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh new file mode 100644 index 00000000..7773d335 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh @@ -0,0 +1,57 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +; Compute the texture coordinates given the offset between +; each bumped lightmap +&AllocateRegister( \$offset ); +mov $offset.xy, $vTexCoord2 +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +add oT1.xy, $offset, $vTexCoord1 +mad oT2.xy, $offset, $cTwo, $vTexCoord1 +alloc $three +add $three, $cOne, $cTwo +mad oT3.xy, $offset, $three, $vTexCoord1 +free $three +dp4 oT4.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT4.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 +dp4 oT5.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT5.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + +&FreeRegister( \$offset ); diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.psh new file mode 100644 index 00000000..86e627e5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.psh @@ -0,0 +1,47 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - decal texture +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +; c0, c1, c2 - ( ( N dot basis[0] )^2 ), ( ( N dot basis[1] )^2 ), ( ( N dot basis[2] )^2 ) +;------------------------------------------------------------------------------ + +; Get the decal color +tex t0 + +; Sample the lightmaps +tex t1 +tex t2 +tex t3 + +; output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) + + +; r0 = lightmapColor[0] * ( ( N dot basis[0] )^2 ) +mul r0, t1, c0 + +; r0 = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + lightmapColor[1] * ( ( N dot basis[1] )^2 ) +mad r0, t2, c1, r0 + +; r0 = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + +; lightmapColor[1] * ( ( N dot basis[1] )^2 ) + +; lightmapColor[2] * ( ( N dot basis[2] )^2 ) +mad r0, t3, c2, r0 + +; Modulate by decal texture +mul r0.rgb, r0, t0 ++ mov r0.a, t0.a + +; Modulate by constant color +mul r0, r0, c3 + +; Modulate by per-vertex factor +mul r0, r0, v0 + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh new file mode 100644 index 00000000..a9db9faa --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh @@ -0,0 +1,56 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +; Compute the texture coordinates given the offset between +; each bumped lightmap +&AllocateRegister( \$offset ); +mov $offset.x, $vTexCoord2.x +mov $offset.y, $cZero +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +add oT1.xy, $offset, $vTexCoord1 +mad oT2.xy, $offset, $cTwo, $vTexCoord1 +; make a 3 +alloc $three +add $three, $cOne, $cTwo +mad oT3.xy, $offset, $three, $vTexCoord1 +free $three +mov oD0, $vColor + +&FreeRegister( \$offset ); diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_Detail.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_Detail.psh new file mode 100644 index 00000000..89b6c322 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_Detail.psh @@ -0,0 +1,18 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r1.rgb, r0, t2 ; detail texture +lrp r0.rgb, c2, r1, r0 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh new file mode 100644 index 00000000..a9129757 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh @@ -0,0 +1,16 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t1 +tex t2 +mul r0.rgb, t1, v0 + ; base times vertex color (with alpha) +mov r0.a, v0.a +mul_x2 r0.rgb, r0, t2 ; detail texture +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh new file mode 100644 index 00000000..a9e05150 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh @@ -0,0 +1,23 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r1.rgb, r0, t2 ; detail texture +lrp r0.rgb, c2, r1, r0 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, c1, t0 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lightmap diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh new file mode 100644 index 00000000..919da94c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t1 +tex t2 + +mov r0.rgb, v0 + ; vertex color +mul r0.a, v0.a, t2.a ; vertex alpha * envmap alpha + +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh new file mode 100644 index 00000000..f0205e86 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh new file mode 100644 index 00000000..5f740f86 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh @@ -0,0 +1,45 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform +; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform +; $SHADER_SPECIFIC_CONST_4 = Modulation color +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +alloc $worldPos +if( $DOWATERFOG == 1 ) +{ + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 +} +&CalcFog( $worldPos, $projPos ); +free $worldPos + +&FreeRegister( \$projPos ); + +; YUCK! This is to make texcoords continuous for mat_softwaretl +mov oT0, $cZero +; Texture coordinates +mov oT1, $vTexCoord1 + +mov oD0, $cOne + + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh new file mode 100644 index 00000000..30bd9f76 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh @@ -0,0 +1,6 @@ +ps.1.1 + +tex t1 + +mov r0.rgba, t1 + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh new file mode 100644 index 00000000..ee59d663 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh @@ -0,0 +1,24 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t1 +tex t2 +tex t3 + +mov r0.rgb, v0 ; vertex color +mul r1, t2, t3 ; envmap * envmapmask + +mad r0.rgb, r1, c2, r0 + ; + envmap * envmapmask * envmaptint (color only) +mul r0.a, v0.a, r1.a ; alpha = vertex alpha * envmap alpha * envmapmask alpha + +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh new file mode 100644 index 00000000..398ed46a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul r1, t2, t3 ; envmap * envmapmask +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh new file mode 100644 index 00000000..7944e730 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c2, 1.0f, 1.0f, 1.0f, 1.0f + +tex t0 +tex t1 + +; Blend between grey and lightmap color based on total alpha + +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mul_sat r1.a, t0, v0 ; base times vertex alpha +lrp r0, r1.a, r1, c2 ; interpolate between white + color diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh new file mode 100644 index 00000000..e0fb27b7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c2, 1.0f, 1.0f, 1.0f, 1.0f + +tex t0 +tex t1 + +; Blend between grey and lightmap color based on total alpha + +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mov_sat r1.a, v0 ; vertex alpha +lrp r0, r1.a, r1, c2 ; interpolate between white + color diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh new file mode 100644 index 00000000..1282ecac --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh @@ -0,0 +1,23 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c2, 1.0f, 1.0f, 1.0f, 1.0f + +tex t0 +tex t1 + +; Blend between white and lightmap color based on total alpha +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mov_sat r1.a, v0 ; opacity == vertex opacity (no alpha in texture) + +lrp r0.rgb, t0.a, c1, r1 ; Blend between self-illum + lightmap ++ mov r0.a, c2.a + +lrp r0.rgb, r1.a, r0, c2 ; interpolate between white + color diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh new file mode 100644 index 00000000..f02de34b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh @@ -0,0 +1,14 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t1 +mul r0.rgb, t1, v0 + ; base times vertex color (with alpha) +mov r0.a, v0.a +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh new file mode 100644 index 00000000..bdcb7783 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh @@ -0,0 +1,34 @@ +ps.1.1 +def c0, 1,0,0,0 +def c1, 0,1,0,0 +def c2, 0,0,1,0 + +;------------------------------------------------------------------------------ +; Computes the diffuse component of lighting using lightmap + bumpmap +; t0 - Normalmap +; t1 - Lightmap1 +; t2 - Lightmap2 +; t3 - Lightmap3 +; +; The texture coordinates need to be defined as follows: +; tc0 - Normalmap and lightmap texture coordinates +;------------------------------------------------------------------------------ + +; Get the 3-vector from the normal map +tex t0 + +; Sample the lightmaps +tex t1 +tex t2 +tex t3 + +; output = lightmapColor[0] * n.r + lightmapColor[1] * n.g + lightmapColor[2] * n.b + + +mov r0, t0 +dp3 r1, t0, c0 +mul r0.rgb, r1, t1 +dp3 r1, t0, c1 +mad r0.rgb, r1, t2, r0 +dp3 r1, t0, c2 +mad r0.rgb, r1, t3, r0 diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh new file mode 100644 index 00000000..cf800a2e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 + +mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, c1, t0 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lightmap diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh new file mode 100644 index 00000000..9fd0a1c5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r1, t0.a, t0 ; Self illum +mad r1, c1, r1, t1 ; Self illum * tint + lightmap + +mul r0.rgb, r1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh new file mode 100644 index 00000000..1e62a416 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh @@ -0,0 +1,28 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0.rgb, t0, v0 + ; base times vertex color (with alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r1, c1, t0.a ; Self illum alpha * tint +mad r1, t0, r1, t1 ; Self illum * tint + lightmap +mul r0.rgb, r1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t2, t3 ; envmap * envmapmask +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) + diff --git a/sp/src/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh b/sp/src/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh new file mode 100644 index 00000000..a434a941 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh @@ -0,0 +1,15 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "LightmappedGeneric_inc.vsh" + +$detail = 0; +$envmap = 0; +$envmapcameraspace = 0; +$envmapsphere = 0; +$vertexcolor = 1; + +&LightmappedGeneric( $detail, $envmap, $envmapcameraspace, $envmapsphere, + $vertexcolor ); + diff --git a/sp/src/materialsystem/stdshaders/Refract_model_vs11.vsh b/sp/src/materialsystem/stdshaders/Refract_model_vs11.vsh new file mode 100644 index 00000000..a6eea2b7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Refract_model_vs11.vsh @@ -0,0 +1,105 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; c0 = (0, 1, 2, 0.5) +; c1 = (1/2.2, 0, 0, 0) +; c2 = camera position *in world space* +; c4-c7 = modelViewProj matrix (transpose) +; c8-c11 = ViewProj matrix (transpose) +; c12-c15 = model->view matrix (transpose) +; c16 = [fogStart, fogEnd, fogRange, undefined] +; +; Vertex components (as specified in the vertex DECL) +; $vPos = Position +; $vTexCoord0.xy = TexCoord0 +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +; Vertex components +; $vPos = Position +; $vNormal = normal +; $vTexCoord0.xy = TexCoord0 +; $vTangentS = S axis of Texture space +; $vTangentT = T axis of Texture space + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +alloc $worldPos +alloc $worldNormal +alloc $worldTangentS +alloc $worldTangentT + +&SkinPositionNormalAndTangentSpace( $worldPos, $worldNormal, + $worldTangentS, $worldTangentT ); + +alloc $projPos + +; Transform position from world to projection space +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 + +&CalcFog( $worldPos, $projPos ); + +alloc $worldEyeVect + +; Get the eye vector in world space +add $worldEyeVect.xyz, -$worldPos, $cEyePos + +alloc $tangentEyeVect +; transform the eye vector to tangent space +dp3 oT3.x, $worldEyeVect, $worldTangentS +dp3 oT3.y, $worldEyeVect, $worldTangentT +dp3 oT3.z, $worldEyeVect, $worldNormal + +alloc $bumpTexCoord + +dp4 $bumpTexCoord.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 $bumpTexCoord.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + +; dudv map +mov oT0.xy, $bumpTexCoord + +; refract tint + alpha channel +mov oT2.xy, $bumpTexCoord +mov oT3.xy, $bumpTexCoord + +free $bumpTexCoord + +mov oPos, $projPos + +; special case perspective correct texture projection so that the texture fits exactly on the screen + +; flip Y by multiplying by -1 +mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_4.w + +; transform from [-w,w] to [0,2*w] +; The reason this is w is because we are in perspective space/homogenous clip space. +add $projPos.xy, $projPos.xy, $projPos.w + +; transform from [0,2*w] to [0,w] +; We'll end up dividing by w in the pixel shader to get to [0,1] +mul $projPos.xy, $projPos.xy, $cHalf + +mov oT1.xy, $projPos.xy + +; emit w to both z and w in case the driver screws up and divides by z +mov oT1.z, $projPos.w +mov oT1.w, $projPos.w + +free $projPos +free $worldPos +free $worldEyeVect +free $tangentEyeVect +free $w +free $worldNormal +free $worldTangentS +free $worldTangentT diff --git a/sp/src/materialsystem/stdshaders/Refract_ps11.psh b/sp/src/materialsystem/stdshaders/Refract_ps11.psh new file mode 100644 index 00000000..f3fe34d2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Refract_ps11.psh @@ -0,0 +1,36 @@ +; STATIC: "REFRACTTINTTEXTURE" "0..1" +; STATIC: "NORMALMAPALPHA" "0..1" + +ps.1.1 + +; t0: +; texture: dudv map +; texcoords: dudvmap texcoords +; t1: +; texture: refraction render target +; texcoords: + +tex t0 ; sample dudv map +texbem t1, t0 ; refraction + +#if REFRACTTINTTEXTURE +tex t2 +#endif + +#if NORMALMAPALPHA +tex t3 +#endif + +; refracttint +#if REFRACTTINTTEXTURE +mul_x2 r0, t1, t2 +#else +mov r0, t1 +#endif + +#if NORMALMAPALPHA +mul r0.rgb, r0, c0 + +mov r0.a, t3.a +#else +mul r0.rgb, r0, c0 +#endif diff --git a/sp/src/materialsystem/stdshaders/Refract_vs20.fxc b/sp/src/materialsystem/stdshaders/Refract_vs20.fxc new file mode 100644 index 00000000..698dd192 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Refract_vs20.fxc @@ -0,0 +1,140 @@ +//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "MODEL" "0..1" +// STATIC: "COLORMODULATE" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const bool g_bModel = MODEL ? true : false; + +const float4 cBumpTexCoordTransform[4] : register( SHADER_SPECIFIC_CONST_1 ); + +const float g_flTime : register( SHADER_SPECIFIC_CONST_5 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vBaseTexCoord : TEXCOORD0; +#if !MODEL + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL0; +#else + float4 vUserData : TANGENT; +#endif +#if COLORMODULATE + float4 vColor : COLOR0; +#endif +}; + +struct VS_OUTPUT +{ + float4 vProjPos_POSITION : POSITION; +#if !defined( _X360 ) + float vFog : FOG; +#endif + float4 vBumpTexCoord : TEXCOORD0; + float3 vTangentEyeVect : TEXCOORD1; + float3 vWorldNormal : TEXCOORD2; + float3 vWorldTangent : TEXCOORD3; + float3 vWorldBinormal : TEXCOORD4; + float3 vRefractXYW : TEXCOORD5; + float3 vWorldViewVector : TEXCOORD6; +#if COLORMODULATE + float4 vColor : COLOR0; +#endif + float4 fogFactorW : COLOR1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + +#if COLORMODULATE + o.vColor = v.vColor; +#endif + + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + + float3 vObjNormal; +#if MODEL + float4 vObjTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vObjNormal, vObjTangent ); + + SkinPositionNormalAndTangentSpace( + g_bSkinning, + v.vPos, vObjNormal, vObjTangent, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal, worldTangentS, worldTangentT ); +#else + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + worldPos = mul( v.vPos, cModel[0] ); + worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); +#endif + + // World normal + o.vWorldNormal.xyz = normalize( worldNormal.xyz ); + + // Projected position + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos_POSITION = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + //o.projNormal.xyz = mul( worldNormal, cViewProj ); + + // Map projected position to the refraction texture + float2 vRefractPos; + vRefractPos.x = vProjPos.x; + vRefractPos.y = -vProjPos.y; // invert Y + vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; + + // Refraction transform + o.vRefractXYW = float3(vRefractPos.x, vRefractPos.y, vProjPos.w); + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + o.fogFactorW = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE ); +#if !defined( _X360 ) + o.vFog = o.fogFactorW; +#endif + + // Eye vector + float3 vWorldEyeVect = normalize( cEyePos - vWorldPos ); + o.vWorldViewVector.xyz = -vWorldEyeVect.xyz; + + // Transform to the tangent space + o.vTangentEyeVect.x = dot( vWorldEyeVect, worldTangentS ); + o.vTangentEyeVect.y = dot( vWorldEyeVect, worldTangentT ); + o.vTangentEyeVect.z = dot( vWorldEyeVect, worldNormal ); + + // Tranform bump coordinates + o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); + o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); + + // Tranform bump coordinates (note wz, not zw) + o.vBumpTexCoord.w = dot( v.vBaseTexCoord, cBumpTexCoordTransform[2] ); + o.vBumpTexCoord.z = dot( v.vBaseTexCoord, cBumpTexCoordTransform[3] ); + + + // Tangent space transform + o.vWorldNormal.xyz = normalize( worldNormal.xyz ); + o.vWorldTangent.xyz = worldTangentS.xyz; + o.vWorldBinormal.xyz = worldTangentT.xyz; + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/Refract_world_vs11.vsh b/sp/src/materialsystem/stdshaders/Refract_world_vs11.vsh new file mode 100644 index 00000000..90f0debe --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Refract_world_vs11.vsh @@ -0,0 +1,168 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; c0 = (0, 1, 2, 0.5) +; c1 = (1/2.2, 0, 0, 0) +; c2 = camera position *in world space* +; c4-c7 = modelViewProj matrix (transpose) +; c8-c11 = ViewProj matrix (transpose) +; c12-c15 = model->view matrix (transpose) +; c16 = [fogStart, fogEnd, fogRange, undefined] +; +; Vertex components (as specified in the vertex DECL) +; $vPos = Position +; $vTexCoord0.xy = TexCoord0 +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +; Vertex components +; $vPos = Position +; $vNormal = normal +; $vTexCoord0.xy = TexCoord0 +; $vTangentS = S axis of Texture space +; $vTangentT = T axis of Texture space + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +alloc $worldPos +alloc $worldNormal +alloc $worldTangentS +alloc $worldTangentT +alloc $projPos + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +dp3 $worldPos.x, $vPos, $cModel0 +dp3 $worldPos.y, $vPos, $cModel1 +dp3 $worldPos.z, $vPos, $cModel2 + +dp3 $worldNormal.x, $vNormal, $cModel0 +dp3 $worldNormal.y, $vNormal, $cModel1 +dp3 $worldNormal.z, $vNormal, $cModel2 + +dp3 $worldTangentS.x, $vTangentS, $cModel0 +dp3 $worldTangentS.y, $vTangentS, $cModel1 +dp3 $worldTangentS.z, $vTangentS, $cModel2 + +dp3 $worldTangentT.x, $vTangentT, $cModel0 +dp3 $worldTangentT.y, $vTangentT, $cModel1 +dp3 $worldTangentT.z, $vTangentT, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +alloc $worldEyeVect + +; Get the eye vector in world space +add $worldEyeVect.xyz, -$worldPos, $cEyePos + +alloc $tangentEyeVect +alloc $bumpTexCoord + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $worldTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $worldTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $worldNormal + +&Normalize( $tangentEyeVect ); + +; stick the tangent space eye vector into oD0 +mad oD0.xyz, $tangentEyeVect, $cHalf, $cHalf + +dp4 $bumpTexCoord.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 $bumpTexCoord.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + +; dudv map +mov oT0.xy, $bumpTexCoord + +; refract tint +mov oT3.xy, $bumpTexCoord + +free $bumpTexCoord + +alloc $newProjPos +alloc $w + +mov oPos, $projPos + +; special case perspective correct texture projection so that the texture fits exactly on the screen +mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_4.w +add $projPos.xy, $projPos.xy, $projPos.w +mul $projPos.xy, $projPos.xy, $cHalf + +; Do the perspective divide here. .yuck . . we aren't going to be perspective correct +rcp $w.w, $projPos.w +mul $projPos, $projPos, $w.w + +#max $projPos.x, $projPos.x, -$cOne +#min $projPos.x, $projPos.x, $cOne +#max $projPos.z, $projPos.z, $cZero +#min $projPos.z, $projPos.z, $cOne + +;------------------------------------------------------------------------------ +; Transform the tangentS from world to view space +;------------------------------------------------------------------------------ + +alloc $projTangentS + +; we only care about x and y +dp3 $projTangentS.x, $worldTangentS, $cViewProj0 +dp3 $projTangentS.y, $worldTangentS, $cViewProj1 + +; project tangentS +mul $projTangentS.xy, $projTangentS.xy, $w.w + +;max $projTangentS.xy, $projTangentS.xy, $cOne +;min $projTangentS.xy, $projTangentS.xy, -$cOne + +;------------------------------------------------------------------------------ +; Transform the tangentT from world to view space +;------------------------------------------------------------------------------ + +alloc $projTangentT +alloc $texCoord + +; we only care about x and y +dp3 $projTangentT.x, $worldTangentT, $cViewProj0 +dp3 $projTangentT.y, $worldTangentT, $cViewProj1 + +; project tangentT +mul $projTangentT.xy, $projTangentT.xy, $w.w + +;max $projTangentT.xy, $projTangentT.xy, $cOne +;min $projTangentT.xy, $projTangentT.xy, -$cOne + +;max $projPos.xy, $projPos.xy, $cOne +;min $projPos.xy, $projPos.xy, -$cOne + +mul oT1.x, $projTangentS.x, $SHADER_SPECIFIC_CONST_3.x +mul oT1.y, $projTangentT.x, $SHADER_SPECIFIC_CONST_3.x +mov oT1.z, $projPos.x ; huh? + +mul $texCoord.x, $projTangentS.y, -$SHADER_SPECIFIC_CONST_3.x +mul $texCoord.y, $projTangentT.y, -$SHADER_SPECIFIC_CONST_3.x +mov $texCoord.z, $projPos.y +mov oT2.xyz, $texCoord +mov oT3.xyz, $texCoord + +free $texCoord +free $projPos +free $worldPos +free $worldEyeVect +free $tangentEyeVect +free $w +free $projTangentS +free $projTangentT +free $newProjPos +free $worldNormal +free $worldTangentS +free $worldTangentT diff --git a/sp/src/materialsystem/stdshaders/ShadowModel.psh b/sp/src/materialsystem/stdshaders/ShadowModel.psh new file mode 100644 index 00000000..a7514020 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShadowModel.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c0,1.0f, 1.0f, 1.0f, 1.0f + +tex t0 ; shadow color +texkill t1 ; Clip +texkill t2 +texkill t3 ; backface cull + +; Darkening equation, compute a color = (shadow color * shadow alpha + 1- shadow alpha) +;sub r1, t0, v0.a ; r1 = shadow alpha +lrp r0.rgb, t0.a, v0, c0 + ; r0.rgb = (shadow color * shadow alpha + 1 - shadow alpha) +mov r0.a, c0.a ; r0.a = 1 + diff --git a/sp/src/materialsystem/stdshaders/ShadowModel.vsh b/sp/src/materialsystem/stdshaders/ShadowModel.vsh new file mode 100644 index 00000000..3e4b9eba --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShadowModel.vsh @@ -0,0 +1,85 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_2 = Shadow texture matrix +; $SHADER_SPECIFIC_CONST_3 = Tex origin +; $SHADER_SPECIFIC_CONST_4 = Tex Scale +; $SHADER_SPECIFIC_CONST_5 = [Shadow falloff offset, 1/Shadow distance, Shadow scale, 0 ] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending (whacks r1-r7, positions in r7, normals in r8) +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&SkinPositionAndNormal( $worldPos, $worldNormal ); + +; Transform the position from world to view space +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Transform position into texture space (from 0 to 1) +;------------------------------------------------------------------------------ +&AllocateRegister( \$texturePos ); +dp4 $texturePos.x, $worldPos, $SHADER_SPECIFIC_CONST_0 +dp4 $texturePos.y, $worldPos, $SHADER_SPECIFIC_CONST_1 +dp4 $texturePos.z, $worldPos, $SHADER_SPECIFIC_CONST_2 +&FreeRegister( \$worldPos ); + +;------------------------------------------------------------------------------ +; Figure out the shadow fade amount +;------------------------------------------------------------------------------ +&AllocateRegister( \$shadowFade ); +sub $shadowFade, $texturePos.z, $SHADER_SPECIFIC_CONST_5.x +mul $shadowFade, $shadowFade, $SHADER_SPECIFIC_CONST_5.y + +;------------------------------------------------------------------------------ +; Offset it into the texture +;------------------------------------------------------------------------------ +&AllocateRegister( \$actualTextureCoord ); +mul $actualTextureCoord.xyz, $SHADER_SPECIFIC_CONST_4, $texturePos +add oT0.xyz, $actualTextureCoord, $SHADER_SPECIFIC_CONST_3 +;mov oT0.xyz, $texturePos +&FreeRegister( \$actualTextureCoord ); + +;------------------------------------------------------------------------------ +; We're doing clipping by using texkill +;------------------------------------------------------------------------------ +mov oT1.xyz, $texturePos ; also clips when shadow z < 0 ! +sub oT2.xyz, $cOne, $texturePos +sub oT2.z, $cOne, $shadowFade.z ; clips when shadow z > shadow distance +&FreeRegister( \$texturePos ); + +;------------------------------------------------------------------------------ +; We're doing backface culling by using texkill also (wow yucky) +;------------------------------------------------------------------------------ +; Transform z component of normal in texture space +; If it's negative, then don't draw the pixel +dp3 oT3, $worldNormal, -$SHADER_SPECIFIC_CONST_2 +&FreeRegister( \$worldNormal ); + +;------------------------------------------------------------------------------ +; Shadow color, falloff +;------------------------------------------------------------------------------ +mov oD0, $cModulationColor +mul oD0.w, $shadowFade.x, $SHADER_SPECIFIC_CONST_5.z +&FreeRegister( \$shadowFade ); + diff --git a/sp/src/materialsystem/stdshaders/Teeth.vsh b/sp/src/materialsystem/stdshaders/Teeth.vsh new file mode 100644 index 00000000..065f0703 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Teeth.vsh @@ -0,0 +1,97 @@ +vs.1.1 + +# STATIC: "INTRO" "0..1" +# STATIC: "HALF_LAMBERT" "0..1" +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "LIGHT_COMBO" "0..21" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0 = xyz = mouth forward direction vector, w = illum factor +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +$WARPPARAM = $SHADER_SPECIFIC_CONST_2; +$ENTITY_ORIGIN = $SHADER_SPECIFIC_CONST_3; + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +alloc $worldPos +alloc $worldNormal +&SkinPositionAndNormal( $worldPos, $worldNormal ); + +;------------------------------------------------------------------------------ +; Optional intro warping +;------------------------------------------------------------------------------ +if ( $INTRO == 1 ) +{ + alloc $tmp + sub $tmp.xyz, $worldPos, $ENTITY_ORIGIN + mul $tmp.xy, $tmp, $WARPPARAM + add $worldPos.xyz, $tmp, $ENTITY_ORIGIN + free $tmp +} + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +alloc $projPos + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +&CalcFog( $worldPos, $projPos ); + +free $projPos + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ +alloc $linearColor +&DoDynamicLightingToLinear( $worldPos, $worldNormal, $linearColor ); + +;------------------------------------------------------------------------------ +; Factor in teeth darkening factors +;------------------------------------------------------------------------------ + +alloc $tmp + +mul $linearColor.xyz, $SHADER_SPECIFIC_CONST_0.w, $linearColor ; FIXME Color darkened by illumination factor +dp3 $tmp, $worldNormal, $SHADER_SPECIFIC_CONST_0 ; Figure out mouth forward dot normal +max $tmp, $cZero, $tmp ; clamp from 0 to 1 +mul $linearColor.xyz, $tmp, $linearColor ; Darken by forward dot normal too + +;------------------------------------------------------------------------------ +; Output color (gamma correction) +;------------------------------------------------------------------------------ + +alloc $gammaColor +&LinearToGamma( $linearColor, $gammaColor ); +free $linearColor +mul oD0.xyz, $gammaColor.xyz, $cOverbrightFactor +mov oD0.w, $cOne ; make sure all components are defined + + +free $gammaColor +free $worldPos +free $worldNormal +free $tmp + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +mov oT0, $vTexCoord0 + + + diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric.psh new file mode 100644 index 00000000..53fab24d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric.psh @@ -0,0 +1,13 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color + +mul r0, t0, v0 \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh new file mode 100644 index 00000000..1ed9314e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0.rgb, t1, 1-t2.a ; can't use mad cause can't use 3 texture registers +mul r0.rgb, c2, r0 ; apply the envmaptint +mad r0.rgb, t0, v0, r0 ++ mul r0.a, t0, v0 diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_Detail.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_Detail.psh new file mode 100644 index 00000000..5fcb3f31 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_Detail.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t3 ; detail texture + +mul r0, t0, v0 +mul_x2 r0.rgb, r0, t3 \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh new file mode 100644 index 00000000..69693331 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh @@ -0,0 +1,29 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +;mul r0.rgb, t1, 1-t2.a ; can't use mad cause can't use 3 texture registers +;mul r0.rgb, c2, r0 ; apply the envmaptint +;mad r0.rgb, t0, v0, r0 +;+ mul r0.a, t0, v0 +;mul_x2 r0.rgb, r0, t3 ; mod2x detail texture + +; version 2: applies the mod2x *before* environment map +mul r0, t0, v0 ; Base times modulation color +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture +mul r1, t1, 1-t2.a ; Have to invert the alpha for basealpha (feh!) +mul r1, c2, r1 ; apply the envmaptint +add r0.rgb, r0, r1 ; add in the envmap diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh new file mode 100644 index 00000000..dab6efbb --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh @@ -0,0 +1,25 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +;mul r1, c2, t1 +;mad r0.rgb, t0, v0, r1 +;+ mul r0.a, t0, v0 +;mul_x2 r0.rgb, r0, t3 ; mod2x detail texture + +; version 2: applies the mod2x *before* environment map +mul r0, t0, v0 ; Base times modulation color +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture +mad r0.rgb, c2, t1, r0 ; add in tinted envmap diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh new file mode 100644 index 00000000..29411c9b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh @@ -0,0 +1,29 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +;mul r0.rgb, t1, t2 ; can't use mad cause can't use 3 texture registers +;mul r0.rgb, c2, r0 ; apply the envmaptint +;mad r0.rgb, t0, v0, r0 +;+ mul r0.a, t0, v0 +;mul_x2 r0.rgb, r0, t3 ; mod2x detail texture + +; version 2: applies the mod2x *before* environment map +mul r0, t0, v0 ; Base times modulation color +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture +mul r1, t1, t2 ; Envmap * envmapmask +mul r1, c2, r1 ; apply the envmaptint +add r0.rgb, r0, r1 ; add in the envmap diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh new file mode 100644 index 00000000..e8c6f3cb --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +; version 2 doesn't make sense here! +mul r0, t1, t2 +mul r0.rgb, c2, r0 +mul r0, r0, v0 +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh new file mode 100644 index 00000000..829849b9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t1 ; cube map +tex t3 ; detail texture + +; version 1: applies the mod2x *after* environment map +; version 2 doesn't make sense here! +mul r0, v0, t1 +mul r0.rgb, r0, c2 +mul_x2 r0.rgb, r0, t3 ; mod2x detail texture \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh new file mode 100644 index 00000000..c79dc2ce --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh @@ -0,0 +1,10 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Just use the vertex color +;------------------------------------------------------------------------------ + +tex t3 + +mul_x2 r0.rgb, v0, t3 ++ mov r0.a, v0.a \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh new file mode 100644 index 00000000..9116997f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map + +mul r1, c2, t1 +mad r0.rgb, t0, v0, r1 ++ mul r0.a, t0, v0 diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh new file mode 100644 index 00000000..f8de572c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0.rgb, t1, t2 ; can't use mad cause can't use 3 texture registers +mul r0.rgb, c2, r0 ; apply the envmaptint +mad r0.rgb, t0, v0, r0 ++ mul r0.a, t0, v0 diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh new file mode 100644 index 00000000..a9bd7e46 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0, t1, t2 +mul r0.rgb, c2, r0 +mul r0, r0, v0 diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh new file mode 100644 index 00000000..966255fd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c2 - envmaptint +;------------------------------------------------------------------------------ + +tex t1 ; cube map + +mul r0, v0, t1 +mul r0.rgb, r0, c2 diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh b/sp/src/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh new file mode 100644 index 00000000..6361c811 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh @@ -0,0 +1,21 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +&AllocateRegister( \$worldPos ); +&SkinPosition( $worldPos ); + +; Transform the position from world to view space +dp4 oPos.x, $worldPos, $cViewProj0 +dp4 oPos.y, $worldPos, $cViewProj1 +dp4 oPos.z, $worldPos, $cViewProj2 +dp4 oPos.w, $worldPos, $cViewProj3 + +&FreeRegister( \$worldPos ); + +mov oD0, $cOne + + diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc b/sp/src/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc new file mode 100644 index 00000000..f46a7617 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc @@ -0,0 +1,20 @@ +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD3; +}; + +sampler BaseTextureSampler : register( s0 ); +sampler DetailTextureSampler : register( s3 ); + +float4 main( PS_INPUT i ) : COLOR +{ + // Sample frames from texture 0 + float4 base= tex2D( BaseTextureSampler, i.texCoord0 ); + float4 detail=tex2D( DetailTextureSampler, i.texCoord1 ); + + return float4(base.rgb, base.a * detail.a); +} diff --git a/sp/src/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh b/sp/src/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh new file mode 100644 index 00000000..feb29ba6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh @@ -0,0 +1,7 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Just use the vertex color +;------------------------------------------------------------------------------ + +mov r0, v0 diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric.psh new file mode 100644 index 00000000..9824a915 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric.psh @@ -0,0 +1,13 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 + +mul r0, t0, c3 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh new file mode 100644 index 00000000..1844c402 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh @@ -0,0 +1,17 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif + diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh new file mode 100644 index 00000000..f719821b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh @@ -0,0 +1,17 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 + +mul r0, c3, t0 +lrp r0.rgb, c1, c3, r0 +lrp r0.rgb, t0.a, r0, t0 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#else ++mov r0.a, c3 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail.psh new file mode 100644 index 00000000..f42d54ac --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail.psh @@ -0,0 +1,16 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +mul r0, t0, c3 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r1.rgb, r0, t3 ; detail texture +lrp r0.rgb, c1, r1, r0 + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh new file mode 100644 index 00000000..09bf59ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh @@ -0,0 +1,18 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r0.rgb, r0, t3 ; detail texture +mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh new file mode 100644 index 00000000..12b2295c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh @@ -0,0 +1,16 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t3 ; detail texture + +mul r0, t0, c3 ; base times modulation +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r0.rgb, r0, t3 ; detail texture +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh new file mode 100644 index 00000000..ec35a8ba --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh @@ -0,0 +1,18 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, t2 ; Envmap * mask +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r0.rgb, r0, t3 ; detail texture +mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh new file mode 100644 index 00000000..d75a2790 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh @@ -0,0 +1,12 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t3 + +mul r0, v0, c3 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mul_x2 r0.rgb, r0, t3 ; detail texture + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh new file mode 100644 index 00000000..4b80e91b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh @@ -0,0 +1,22 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +; interpolate between illuminated + non-selfilluminated +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +#if WRITEONETODESTALPHA +mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh new file mode 100644 index 00000000..e625791a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh @@ -0,0 +1,24 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t1 +tex t3 + +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh new file mode 100644 index 00000000..119633a9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh @@ -0,0 +1,26 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 ; base +tex t1 ; env map +tex t2 ; mask +tex t3 ; detail + +mul r0.rgb, t0, c3 + ; base times modulation +mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +mul r1, t2, t1 ; envmapmask * envmap +mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh new file mode 100644 index 00000000..7a9ce740 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh @@ -0,0 +1,15 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +lrp r0, c1, t3, t0 ; Lerp between textures +mul r0, r0, c3 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh new file mode 100644 index 00000000..64501f74 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh @@ -0,0 +1,15 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +mul r1, c1, t3 +mad r0, t0, c3, r1 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh new file mode 100644 index 00000000..07f9d387 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh @@ -0,0 +1,15 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t3 + +mul r0, c3, t0 +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, c1, t3, r0 + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh new file mode 100644 index 00000000..4ce3caca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh @@ -0,0 +1,14 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t1 ; cube map + +mul r0.rgb, t1, c2 + ; envmap * envmaptint (color only) + +mov r0.a, c3.a ; Use alpha from modulation... (?) + +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh new file mode 100644 index 00000000..80ef4330 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh @@ -0,0 +1,14 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map + +mul r0, t0, c3 ; base times modulation +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh new file mode 100644 index 00000000..e6b0c6e4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh @@ -0,0 +1,36 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Environment mapping on a bumped surface +; t0 - Normalmap +; t3 - Cube environment map (*must* be a cube map!) +; +; c0 - color to multiply the results by +; Input texture coords required here are a little wonky. +; tc0.uv <- U,V into the normal map +; tc1.uvw, tc2.uvw, tc3.uvw <- 3x3 matrix transform +; from tangent space->env map space +; tc1.q, tc2.q, tc3.q <- eye vector in env map space +;------------------------------------------------------------------------------ +; This version doesn't multiply by lighting. + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +; result goes in output color +mul r0.rgb, t3, c0 ; constant color ++mov r0.a, c0.a + +mul r1.rgb, r0, r0 +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color +dp3 r1.rgb, r0, c3 +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale + + diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh new file mode 100644 index 00000000..9fa7db3e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh @@ -0,0 +1,42 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Environment mapping on a bumped surface +; t0 - Normalmap +; t3 - Cube environment map (*must* be a cube map!) +; +; c0 - color to multiply the results by +; Input texture coords required here are a little wonky. +; tc0.uv <- U,V into the normal map +; tc1.uvw, tc2.uvw, tc3.uvw <- 3x3 matrix transform +; from tangent space->env map space +; tc1.q, tc2.q, tc3.q <- eye vector in env map space +;------------------------------------------------------------------------------ +; This version doesn't multiply by lighting. + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +; result goes in output color +mul r0.rgb, t3, c0 ; constant color ++mov r0.a, c0.a + +mul r1.rgb, r0, r0 +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color +dp3 r1.rgb, r0, c3 +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale + +; Multiply the output color by the alpha channel of the normal map. +mul r0.rgb, t0.a, r0 + + + + + diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh new file mode 100644 index 00000000..eac900c9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh @@ -0,0 +1,42 @@ +ps.1.4 +;------------------------------------------------------------------------------ +; Phase 1 +;------------------------------------------------------------------------------ +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! +;mov r0.rgba, r4 + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) +; Alpha gets lost after phase marker, so store it here +mov r5, r0.a +;------------------------------------------------------------------------------ +; Phase 2 +;------------------------------------------------------------------------------ +phase +; Sample environment map +texld r3, r2 +; Result goes in output color (multiply by constant color c0) +mul r0.rgb, r3, c0 ++mov r0.a, c0.a + +mul r1.rgb, r0, r0 +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color +dp3 r1.rgb, r0, c3 +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale + +; mult by alpha +mul r0.rgb, r0, r5 diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh new file mode 100644 index 00000000..7c88013f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh @@ -0,0 +1,39 @@ +ps.1.4 +;------------------------------------------------------------------------------ +; Phase 1 +;------------------------------------------------------------------------------ +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) +; Alpha gets lost after phase marker, so store it here +mov r5, r0.a +;------------------------------------------------------------------------------ +; Phase 2 +;------------------------------------------------------------------------------ +phase +; Sample environment map +texld r3, r2 +; Result goes in output color (multiply by constant color c0) +mul r0.rgb, r3, c0 ++mov r0.a, c0.a + +mul r1.rgb, r0, r0 +lrp r0.rgb, c1, r1, r0 ; blend between color and color * color +dp3 r1.rgb, r0, c3 +lrp r0.rgb, c2, r0, r1 ; blend between color and greyscale + diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh new file mode 100644 index 00000000..576e31cf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh @@ -0,0 +1,93 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; Shader specific constant: +; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$worldTangentS ); +&AllocateRegister( \$worldTangentT ); + +&SkinPositionNormalAndTangentSpace( $worldPos, $worldNormal, + $worldTangentS, $worldTangentT ); + +;------------------------------------------------------------------------------ +; Transform the position from world to proj space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +; svect +mov oT1.x, $worldTangentS.x +mov oT2.x, $worldTangentS.y +mov oT3.x, $worldTangentS.z +&FreeRegister( \$worldTangentS ); + +; tvect +mov oT1.y, $worldTangentT.x +mov oT2.y, $worldTangentT.y +mov oT3.y, $worldTangentT.z +&FreeRegister( \$worldTangentT ); + +; normal +mov oT1.z, $worldNormal.x +mov oT2.z, $worldNormal.y +mov oT3.z, $worldNormal.z + +&FreeRegister( \$worldNormal ); + +; Compute the vector from vertex to camera +&AllocateRegister( \$eyeVector ); +sub $eyeVector.xyz, $cEyePos, $worldPos + +&FreeRegister( \$worldPos ); + +; Move it into the w component of the texture coords, as the wacky +; pixel shader wants it there. +mov oT1.w, $eyeVector.x +mov oT2.w, $eyeVector.y +mov oT3.w, $eyeVector.z + +&FreeRegister( \$eyeVector ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + + diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh new file mode 100644 index 00000000..2ac66164 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh @@ -0,0 +1,90 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +;------------------------------------------------------------------------------ +; Shader specific constant: +; $SHADER_SPECIFIC_CONST_5 = [sOffset, tOffset, 0, 0] +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$worldTangentS ); +&AllocateRegister( \$worldTangentT ); + +&SkinPositionNormalAndTangentSpace( $worldPos, $worldNormal, + $worldTangentS, $worldTangentT ); + +;------------------------------------------------------------------------------ +; Transform the position from world to proj space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +; svect +mov oT1.x, $worldTangentS.x +mov oT2.x, $worldTangentS.y +mov oT3.x, $worldTangentS.z +&FreeRegister( \$worldTangentS ); + +; tvect +mov oT1.y, $worldTangentT.x +mov oT2.y, $worldTangentT.y +mov oT3.y, $worldTangentT.z +&FreeRegister( \$worldTangentT ); + +; normal +mov oT1.z, $worldNormal.x +mov oT2.z, $worldNormal.y +mov oT3.z, $worldNormal.z + +&FreeRegister( \$worldNormal ); + +; Compute the vector from vertex to camera +&AllocateRegister( \$eyeVector ); +sub $eyeVector.xyz, $cEyePos, $worldPos + +&FreeRegister( \$worldPos ); + +; eye vector +mov oT4.xyz, $eyeVector + +&FreeRegister( \$eyeVector ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + + diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh new file mode 100644 index 00000000..4c65d906 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh @@ -0,0 +1,15 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t1 ; cube map +tex t2 ; envmap mask + +mul r1, t1, t2 ; Envmap * mask +mul r0.rgb, r1, c2 ; envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 + ; * 2 * (overbrightFactor/2) +mul r0.a, c3.a, t2.a ; alpha = modulation * mask alpha + +#if WRITEONETODESTALPHA +mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh new file mode 100644 index 00000000..ffa3f1e0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh @@ -0,0 +1,16 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, t2 ; Envmap * mask +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) +mad r0.rgb, r1, c2, r0 ; + envmap * mask * tint + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh new file mode 100644 index 00000000..b98b9396 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh @@ -0,0 +1,9 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +mul r0, v0, c3 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh new file mode 100644 index 00000000..86710123 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh @@ -0,0 +1,5 @@ +ps.1.1 + +tex t0 + +mul r0.rgba, c0, t0 diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh new file mode 100644 index 00000000..40eb8d28 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh @@ -0,0 +1,41 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&SkinPosition( $worldPos ); + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +&CalcFog( $worldPos, $projPos ); +&FreeRegister( \$projPos ); +&FreeRegister( \$worldPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh new file mode 100644 index 00000000..c837e9af --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh @@ -0,0 +1,19 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 + +; interpolate between illuminated + non-selfilluminated +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh new file mode 100644 index 00000000..2d280f5c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh @@ -0,0 +1,21 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 +tex t1 + +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh new file mode 100644 index 00000000..da6b77c3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh @@ -0,0 +1,23 @@ +; DYNAMIC: "WRITEONETODESTALPHA" "0..1" +ps.1.1 + +; Get the color from the texture +tex t0 ; base +tex t1 ; env map +tex t2 ; mask + +mul r0.rgb, t0, c3 + ; base times modulation +mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + +mul r1, t2, t1 ; envmapmask * envmap +mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) + +#if WRITEONETODESTALPHA ++mov r0.a, c4 ; make alpha 255 +#endif diff --git a/sp/src/materialsystem/stdshaders/VertexLitTexture.psh b/sp/src/materialsystem/stdshaders/VertexLitTexture.psh new file mode 100644 index 00000000..7a692c92 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitTexture.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 + +mul r0, t0, v0 + diff --git a/sp/src/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh b/sp/src/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh new file mode 100644 index 00000000..a69250bf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh @@ -0,0 +1,16 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 + +mul_x2 r0.rgb, t0, v0 ++ mul r0.a, t0, v0 + diff --git a/sp/src/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh b/sp/src/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh new file mode 100644 index 00000000..08438dcb --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh @@ -0,0 +1,40 @@ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +phase + +; Sample environment map +texld r3, r2 +texld r4, t5 ; Normalize the tangent-space eye vector + +; dot eye-vector with per-pixel normal from r0 +dp3_sat r1, r4_bx2, r0_bx2 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +mul r0.a, 1-r1.a, 1-r1.a ; squared +mul r0.a, r0.a, r0.a ; quartic +mul_sat r1.a, r0.a, 1-r1.a ; quintic + +; multiply color by reflecttint +mul r0, r3, c1 + +; blend between reflected color and fog color based on fresnel +lrp r0.rgb, r1.a, r0, c0 \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh b/sp/src/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh new file mode 100644 index 00000000..5ebb39f4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh @@ -0,0 +1,39 @@ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +phase + +; Sample environment map +texld r3, r2 +texld r4, t5 ; Normalize the tangent-space eye vector + +; dot eye-vector with per-pixel normal from r0 +dp3_sat r1, r4_bx2, r0_bx2 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +mul r0.a, 1-r1.a, 1-r1.a ; squared +mul r0.a, r0.a, r0.a ; quartic +mul_sat r1.a, r0.a, 1-r1.a ; quintic + +; multiply color by reflecttint +mul r0.rgb, r3, c1 ++mov_sat r0.a, v0.a +add_sat r0.a, r1.a, r0.a diff --git a/sp/src/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh b/sp/src/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh new file mode 100644 index 00000000..60502016 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh @@ -0,0 +1,19 @@ +ps.1.1 + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +mul r0, t3, c1 ; multiply color by reflecttint +lrp r0.rgb, c1.a, r0, c0 ; blend between reflected color and fog color based on constant factor + + + + + diff --git a/sp/src/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh b/sp/src/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh new file mode 100644 index 00000000..fe76d772 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh @@ -0,0 +1,18 @@ +ps.1.1 + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +mul r0.rgb, t3, c1 ; multiply color by reflecttint ++mov_sat r0.a, v0.a ; NOTE: This is necessary since v0.a can be outside 0 - 1! +add_sat r0.a, c1.a, r0.a ; cheap water blend factor + constant blend factor + + + diff --git a/sp/src/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh b/sp/src/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh new file mode 100644 index 00000000..50d7f803 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh @@ -0,0 +1,26 @@ +ps.1.1 + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +mul r0, t3, c1 ; envmap color * envmaptint + +dp3_sat t2, v0_bx2, t0_bx2 ; dot eye-vector with per-pixel normal from t0 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +; NOTE: This is not perspective-correct and results in strange artifacts +mul r1.a, 1-t2.a, 1-t2.a ; squared +mul r1.a, r1.a, r1.a ; quartic +mul_sat r1.a, r1.a, 1-t2.a ; quintic + +; t1.a is now the fresnel factor +lrp r0.rgb, r1.a, r0, c0 ; blend between reflected color and fog color based on fresnel + + diff --git a/sp/src/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh b/sp/src/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh new file mode 100644 index 00000000..bd491d58 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh @@ -0,0 +1,31 @@ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +phase + +; Sample environment map +texld r3, r2 + +; multiply color by reflecttint +mul r0, r3, c1 + +; blend between reflected color and fog color based on constant factor +lrp r0.rgb, c1.a, r0, c0 diff --git a/sp/src/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh b/sp/src/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh new file mode 100644 index 00000000..6ca504cf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh @@ -0,0 +1,100 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; Move it into the w component of the texture coords, as the wacky +; pixel shader wants it there. +mov oT1.w, $worldEyeVect.x +mov oT2.w, $worldEyeVect.y +mov oT3.w, $worldEyeVect.z + +&AllocateRegister( \$tangentEyeVect ); + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal + +&Normalize( $tangentEyeVect ); +mov oD0.xyz, $tangentEyeVect + +&FreeRegister( \$tangentEyeVect ); + +; Get the magnitude of worldEyeVect +dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect +rsq $worldEyeVect.w, $worldEyeVect.w +rcp $worldEyeVect.w, $worldEyeVect.w + +; calculate the cheap water blend factor and stick it into oD0.a +; NOTE: This won't be perspective correct!!!!! +; OPTIMIZE: This could turn into a mad. +add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_2.x +mul oD0.w, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_2.y + +&FreeRegister( \$worldEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/sp/src/materialsystem/stdshaders/WaterCheap_ps11.psh b/sp/src/materialsystem/stdshaders/WaterCheap_ps11.psh new file mode 100644 index 00000000..34178d28 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheap_ps11.psh @@ -0,0 +1,26 @@ +ps.1.1 + +; Get the 3-vector from the normal map +tex t0 + +; Perform matrix multiply to get a local normal bump. Then +; reflect the eye vector through the normal and sample from +; a cubic environment map. +texm3x3pad t1, t0_bx2 +texm3x3pad t2, t0_bx2 +texm3x3vspec t3, t0_bx2 + +mul r0.rgb, t3, c1 ; envmap color * envmaptint ++mov_sat r0.a, v0.a ; Put the cheap water blend factor here + +dp3_sat t2, v0_bx2, t0_bx2 ; dot eye-vector with per-pixel normal from t0 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 in alpha channel +; NOTE: This is not perspective-correct and results in strange artifacts +mul r1.a, 1-t2.a, 1-t2.a ; squared +mul r1.a, r1.a, r1.a ; quartic +mul_sat r1.a, r1.a, 1-t2.a ; quintic + +; t1.a is now the fresnel factor +add_sat r0.a, r1.a, r0.a ; Now we have the final blend factor between cheap water + refraction + diff --git a/sp/src/materialsystem/stdshaders/WaterCheap_ps14.psh b/sp/src/materialsystem/stdshaders/WaterCheap_ps14.psh new file mode 100644 index 00000000..2c452539 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheap_ps14.psh @@ -0,0 +1,30 @@ +ps.1.4 + +; Get the 3-vector from the normal map +texld r0, t0 +; Get environment matrix +texcrd r1.rgb, t1 +texcrd r2.rgb, t2 +texcrd r3.rgb, t3 +; Normalize eye-ray vector through normalizer cube map +texld r4, t4 ; <---- CUBE MAP here!!! + +; Transform normal +dp3 r5.r, r1, r0_bx2 +dp3 r5.g, r2, r0_bx2 +dp3 r5.b, r3, r0_bx2 +; Reflection calculatiom +dp3_x2 r3.rgb, r5, r4_bx2 ; 2(N.Eye) +mul r3.rgb, r5, r3 ; 2N(N.Eye) +dp3 r2.rgb, r5, r5 ; N.N +mad r2.rgb, -r4_bx2, r2, r3 ; 2N(N.Eye) - Eye(N.N) + +phase + +; Sample environment map +texld r3, r2 + +; multiply color by reflecttint +mul r0.rgb, r3, c1 ++mov_sat r0.a, v0.a ; Necessary since v0.a may be negative +add_sat r0.a, c1.a, r0.a diff --git a/sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc b/sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc new file mode 100644 index 00000000..4ca66570 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc @@ -0,0 +1,152 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "MULTITEXTURE" "0..1" +// STATIC: "FRESNEL" "0..1" +// STATIC: "BLEND" "0..1" +// STATIC: "REFRACTALPHA" "0..1" +// STATIC: "HDRTYPE" "0..2" +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] + +// DYNAMIC: "HDRENABLED" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" + +const HALF3 g_WaterFogColor : register( c0 ); +const HALF4 g_CheapWaterParams : register( c1 ); +const HALF4 g_ReflectTint : register( c2 ); +const float4 g_PixelFogParams : register( c3 ); + +#define g_CheapWaterStart g_CheapWaterParams.x +#define g_CheapWaterEnd g_CheapWaterParams.y +#define g_CheapWaterDeltaRecip g_CheapWaterParams.z +#define g_CheapWaterStartDivDelta g_CheapWaterParams.w + +sampler EnvmapSampler : register( s0 ); +sampler NormalMapSampler : register( s1 ); +#if REFRACTALPHA +sampler RefractSampler : register( s2 ); +#endif +sampler NormalizeSampler : register( s6 ); + +struct PS_INPUT +{ + float2 normalMapTexCoord : TEXCOORD0; + HALF3 worldSpaceEyeVect : TEXCOORD1; + HALF3x3 tangentSpaceTranspose : TEXCOORD2; + float4 vRefract_W_ProjZ : TEXCOORD5; + +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bBlend = BLEND ? true : false; + +#if MULTITEXTURE + float3 vNormal = tex2D( NormalMapSampler, i.normalMapTexCoord ); + float3 vNormal1 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.xy ); + float3 vNormal2 = tex2D( NormalMapSampler, i.vExtraBumpTexCoord.zw ); + vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 ); + +#if ( NORMAL_DECODE_MODE == NORM_DECODE_ATI2N ) + vNormal.xy = vNormal.xy * 2.0f - 1.0f; + vNormal.z = sqrt( 1.0f - dot(vNormal.xy, vNormal.xy) ); +#else + vNormal = 2.0 * vNormal - 1.0; +#endif + +#else + float3 vNormal = DecompressNormal( NormalMapSampler, i.normalMapTexCoord, NORMAL_DECODE_MODE ); +#endif + + HALF3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); + HALF3 worldSpaceEye; + + HALF flWorldSpaceDist = 1.0f; + +#ifdef NV3X + // for some reason, fxc doesn't convert length( half3 v ) into all _pp opcodes. + if (bBlend) + { + worldSpaceEye = i.worldSpaceEyeVect; + HALF worldSpaceDistSqr = dot( worldSpaceEye, worldSpaceEye ); + HALF rcpWorldSpaceDist = rsqrt( worldSpaceDistSqr ); + worldSpaceEye *= rcpWorldSpaceDist; + flWorldSpaceDist = worldSpaceDistSqr * rcpWorldSpaceDist; + } + else + { + worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); + } +#else // !NV3X + if (bBlend) + { + worldSpaceEye = i.worldSpaceEyeVect; + flWorldSpaceDist = length( worldSpaceEye ); + worldSpaceEye /= flWorldSpaceDist; + } + else + { + worldSpaceEye = NormalizeWithCubemap( NormalizeSampler, i.worldSpaceEyeVect ); + } +#endif + + HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldSpaceEye ); + HALF3 specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= g_ReflectTint; + +#if FRESNEL + // FIXME: It's unclear that we want to do this for cheap water + // but the code did this previously and I didn't want to change it + HALF flDotResult = dot( worldSpaceEye, worldSpaceNormal ); + flDotResult = 1.0f - max( 0.0f, flDotResult ); + + HALF flFresnelFactor = flDotResult * flDotResult; + flFresnelFactor *= flFresnelFactor; + flFresnelFactor *= flDotResult; +#else + HALF flFresnelFactor = g_ReflectTint.a; +#endif + + HALF flAlpha; + if (bBlend) + { + HALF flReflectAmount = saturate( flWorldSpaceDist * g_CheapWaterDeltaRecip - g_CheapWaterStartDivDelta ); + flAlpha = saturate( flFresnelFactor + flReflectAmount ); + +#if REFRACTALPHA + // Perform division by W only once + float ooW = 1.0f / i.vRefract_W_ProjZ.z; + float2 unwarpedRefractTexCoord = i.vRefract_W_ProjZ * ooW; + float fogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a; + // Fade on the border between the water and land. + flAlpha *= saturate( ( fogDepthValue - .05f ) * 20.0f ); +#endif + } + else + { + flAlpha = 1.0f; +#if HDRTYPE == 0 || HDRENABLED == 0 + specularLighting = lerp( g_WaterFogColor, specularLighting, flFresnelFactor ); +#else + specularLighting = lerp( GammaToLinear( g_WaterFogColor ), specularLighting, flFresnelFactor ); +#endif + } + + // multiply the color by alpha.since we are using alpha blending to blend against dest alpha for borders. + + + +#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE) + float fogFactor = CalcRangeFog( i.vRefract_W_ProjZ.w, g_PixelFogParams.x, g_PixelFogParams.z, g_PixelFogParams.w ); +#else + float fogFactor = 0; +#endif + + return FinalOutput( float4( specularLighting, flAlpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} diff --git a/sp/src/materialsystem/stdshaders/WaterCheap_vs11.vsh b/sp/src/materialsystem/stdshaders/WaterCheap_vs11.vsh new file mode 100644 index 00000000..b1cdd61f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheap_vs11.vsh @@ -0,0 +1,88 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; Move it into the w component of the texture coords, as the wacky +; pixel shader wants it there. +mov oT1.w, $worldEyeVect.x +mov oT2.w, $worldEyeVect.y +mov oT3.w, $worldEyeVect.z + +; Get the magnitude of worldEyeVect +dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect +rsq $worldEyeVect.w, $worldEyeVect.w +rcp $worldEyeVect.w, $worldEyeVect.w + +; calculate the cheap water blend factor and stick it into oD0.a +; NOTE: This won't be perspective correct!!!!! +; OPTIMIZE: This could turn into a mad. +add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_2.x +mul oD0, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_2.y + +&FreeRegister( \$worldEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/sp/src/materialsystem/stdshaders/WaterCheap_vs14.vsh b/sp/src/materialsystem/stdshaders/WaterCheap_vs14.vsh new file mode 100644 index 00000000..0e5a1074 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheap_vs14.vsh @@ -0,0 +1,96 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ + +&AllocateRegister( \$worldPos ); + +; Transform position from object to world +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&AllocateRegister( \$projPos ); + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ + +; Transform tangent space basis vectors to env map space (world space) +; This will produce a set of vectors mapping from tangent space to env space +; We'll use this to transform normals from the normal map from tangent space +; to environment map space. +; NOTE: use dp3 here since the basis vectors are vectors, not points + +dp3 oT1.x, $vTangentS, $cModel0 +dp3 oT2.x, $vTangentS, $cModel1 +dp3 oT3.x, $vTangentS, $cModel2 + +dp3 oT1.y, $vTangentT, $cModel0 +dp3 oT2.y, $vTangentT, $cModel1 +dp3 oT3.y, $vTangentT, $cModel2 + +dp3 oT1.z, $vNormal, $cModel0 +dp3 oT2.z, $vNormal, $cModel1 +dp3 oT3.z, $vNormal, $cModel2 + +; Compute the vector from vertex to camera +&AllocateRegister( \$worldEyeVect ); +sub $worldEyeVect.xyz, $cEyePos, $worldPos +&FreeRegister( \$worldPos ); + +; eye vector +mov oT4.xyz, $worldEyeVect + +alloc $tangentEyeVect + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal + +; Get the magnitude of worldEyeVect +dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect +rsq $worldEyeVect.w, $worldEyeVect.w +rcp $worldEyeVect.w, $worldEyeVect.w + +; calculate the cheap water blend factor and stick it into oD0.a +; NOTE: This won't be perspective correct!!!!! +; OPTIMIZE: This could turn into a mad. +add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_2.x +mul oD0, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_2.y + +; stick the tangent space eye vector into oT5.xyz +mov oT5.xyz, $tangentEyeVect + +&FreeRegister( \$worldEyeVect ); +&FreeRegister( \$tangentEyeVect ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + + diff --git a/sp/src/materialsystem/stdshaders/WaterCheap_vs20.fxc b/sp/src/materialsystem/stdshaders/WaterCheap_vs20.fxc new file mode 100644 index 00000000..bae02380 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterCheap_vs20.fxc @@ -0,0 +1,84 @@ +// STATIC: "BLEND" "0..1" +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vNormal : NORMAL; + float2 vNormalMapCoord : TEXCOORD0; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 normalMapTexCoord : TEXCOORD0; + float3 worldVertToEyeVector : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + float4 vRefract_W_ProjZ : TEXCOORD5; + float4 vExtraBumpTexCoord : TEXCOORD6; + float4 fogFactorW : COLOR1; +}; + +const float4 cNormalMapTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 ); + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float4 projPos; + float3 worldPos; + + projPos = mul( v.vPos, cModelViewProj ); + o.projPos = projPos; + +#if BLEND + // Map projected position to the reflection texture + o.vRefract_W_ProjZ.x = projPos.x; + o.vRefract_W_ProjZ.y = -projPos.y; // invert Y + o.vRefract_W_ProjZ.xy = (o.vRefract_W_ProjZ + projPos.w) * 0.5f; + o.vRefract_W_ProjZ.z = projPos.w; +#endif + + o.vRefract_W_ProjZ.w = projPos.z; + + worldPos = mul( v.vPos, cModel[0] ); + + float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + o.tangentSpaceTranspose[0] = worldTangentS; + o.tangentSpaceTranspose[1] = worldTangentT; + o.tangentSpaceTranspose[2] = worldNormal; + + float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + o.worldVertToEyeVector = worldVertToEyeVector; + + // FIXME: need to add a normalMapTransform to all of the water shaders. + //o.normalMapTexCoord.x = dot( v.vNormalMapCoord, cNormalMapTransform[0] ) + cNormalMapTransform[0].w; + //o.normalMapTexCoord.y = dot( v.vNormalMapCoord, cNormalMapTransform[1] ) + cNormalMapTransform[1].w; + o.normalMapTexCoord = v.vNormalMapCoord; + + float f45x=v.vNormalMapCoord.x+v.vNormalMapCoord.y; + float f45y=v.vNormalMapCoord.y-v.vNormalMapCoord.x; + o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x; + o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y; + o.vExtraBumpTexCoord.z=v.vNormalMapCoord.y*0.45+TexOffsets.z; + o.vExtraBumpTexCoord.w=v.vNormalMapCoord.x*0.45+TexOffsets.w; + + o.fogFactorW = CalcFog( worldPos, projPos, FOGTYPE_RANGE ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/WaterReflect_ps11.psh b/sp/src/materialsystem/stdshaders/WaterReflect_ps11.psh new file mode 100644 index 00000000..d31ab49c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterReflect_ps11.psh @@ -0,0 +1,27 @@ +ps.1.1 + +; t0: +; texture: dudv map +; texcoords: dudvmap texcoords +; t1: +; texture: reflection render target +; texcoords: +; t2: +; texture: normal map (usef for fresnel calculation) +; texcoords: +; t4: texture: normalization cube map +; texcoords: eye vect + +tex t0 ; sample dudv map +texbem t1, t0 ; reflection +tex t2 ; normal map +tex t3 ; eye vector (through normalization cubemap) + +; dot eye-vector with per-pixel normal from t2 +dp3_sat r1.rgba, t3_bx2, t2_bx2 + +; run Fresnel approx. on it: R0 + (1-R0) (1-cos(q))^5 +mul r0.a, 1-r1.a, 1-r1.a // squared +mul r0.a, r0.a, r0.a // quartic +mul r0.rgb, t1, c0 // shove color from reflection render target into r0 ++mul_sat r0.a, r0.a, 1-r1.a // quintic \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh b/sp/src/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh new file mode 100644 index 00000000..88d1f8dc --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh @@ -0,0 +1,24 @@ +ps.1.1 + +; t0: +; texture: dudv map +; texcoords: dudvmap texcoords +; t1: +; texture: refraction render target +; texcoords: + +tex t0 ; sample dudv map +texbem t1, t0 ; refraction +tex t2 ; The normal map +tex t3 ; Normalize the tangent-space vector to the eye + +; dot eye-vector with per-pixel normal from t2 +dp3_sat r1.rgba, t2_bx2, t3_bx2 + +mul r0.a, 1-r1.a, 1-r1.a ; squared +mul r0.a, r0.a, r0.a ; quartic + +mul r0.rgb, t1, c0 ++mul_sat r0.a, r0.a, 1-r1.a ; quintic + +add_sat r0.a, r0.a, v0.a ; cheap water distance diff --git a/sp/src/materialsystem/stdshaders/WaterRefract_ps11.psh b/sp/src/materialsystem/stdshaders/WaterRefract_ps11.psh new file mode 100644 index 00000000..7e3ee733 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WaterRefract_ps11.psh @@ -0,0 +1,13 @@ +ps.1.1 + +; t0: +; texture: dudv map +; texcoords: dudvmap texcoords +; t1: +; texture: refraction render target +; texcoords: + +tex t0 ; sample dudv map +texbem t1, t0 ; refraction + +mul r0, t1, c0 diff --git a/sp/src/materialsystem/stdshaders/Water_ps14.psh b/sp/src/materialsystem/stdshaders/Water_ps14.psh new file mode 100644 index 00000000..e9daecd1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Water_ps14.psh @@ -0,0 +1,96 @@ +; STATIC: "REFLECT" "0..1" +; STATIC: "REFRACT" "0..1" +ps.1.4 +; T2 - refraction +; T3 - normal map +; T4 - reflection +; TC0 - normal map coords +; TC1 - proj tex coords (reflection) +; TC2 - proj tex coords (refraction) +; TC3 - tangent space view vec +; TC4 - displacement scale + +; sample normal map +texld r3, t0 + +#if REFLECT +; reflection coords +texcrd r4.xy, t1_dw.xyw +#endif +#if REFRACT +; refraction coords +texcrd r2.xy, t2_dw.xyw +#endif +; tangent space eye vector +texld r1, t5 ; <---- Normalizing CUBE MAP here!!! +; reflection/refraction scale (x,y) +texcrd r0.xyz, t4.xyz + +; perturb coords by constant displacement +; and by normal map alpha (which has 1/(2**miplevel in it) +mul r0.rg, r0, r3.a +#if REFLECT +mad r4.rg, r3_bx2, r0.x, r4 +#endif + +#if REFRACT +mad r2.rg, r3_bx2, r0.y, r2 +#endif + +; stuff something into z so that texld will deal +#if REFLECT +mov r4.b, c5 +#endif +#if REFRACT +mov r2.b, c5 +#endif + +phase + +#if REFLECT +; reflection +texld r4, r4 +#endif +#if REFRACT +; refraction +texld r2, r2 +#endif + +#if REFLECT +; N.V +dp3_sat r1.a, r3_bx2, r1_bx2 +#endif + +#if REFRACT +; tint refraction +mul r2.rgb, r2, c1 +#endif + +#if REFLECT +; tint reflction +mul r4.rgb, r4, c4 + +; (1-N.V) ^ 5 ++mul r0.a, 1-r1.a, 1-r1.a +mul r0.a, r0.a, r0.a +mul_sat r0.a, r0.a, 1-r1.a +#endif + +#if !REFLECT && !REFRACT +; This is wrong!!!! +mov r0.rgba, c0 +#endif + +#if !REFLECT && REFRACT +mov r0.rgba, r2 +#endif + +#if REFLECT && !REFRACT +mov r0.rgba, r4 +#endif + +#if REFLECT && REFRACT +; reflection * fresnel + refraction * ( 1 - fresnel ) +lrp r0.rgba, r0.a, r4, r2 +#endif + diff --git a/sp/src/materialsystem/stdshaders/Water_ps14.vsh b/sp/src/materialsystem/stdshaders/Water_ps14.vsh new file mode 100644 index 00000000..0ec30aa7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Water_ps14.vsh @@ -0,0 +1,95 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; c0 = (0, 1, 2, 0.5) +; c1 = (1/2.2, 0, 0, 0) +; c2 = camera position *in world space* +; c4-c7 = modelViewProj matrix (transpose) +; c8-c11 = ViewProj matrix (transpose) +; c12-c15 = model->view matrix (transpose) +; c16 = [fogStart, fogEnd, fogRange, undefined] +; +; $SHADER_SPECIFIC_CONST_0..$SHADER_SPECIFIC_CONST_3 - special proj matrix +; +; Vertex components (as specified in the vertex DECL) +; $vPos = Position +; $vTexCoord0.xy = TexCoord0 +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +; Vertex components +; $vPos = Position +; $vNormal = normal +; $vTexCoord0.xy = TexCoord0 +; $vTangentS = S axis of Texture space +; $vTangentT = T axis of Texture space + + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + + +alloc $projPos + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +alloc $worldPos + +; Transform position from object to world space +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +alloc $worldEyeVect + +; Get the eye vector in world space +add $worldEyeVect.xyz, -$worldPos, $cEyePos + +alloc $tangentEyeVect + +; transform the eye vector to tangent space +dp3 $tangentEyeVect.x, $worldEyeVect, $vTangentS +dp3 $tangentEyeVect.y, $worldEyeVect, $vTangentT +dp3 $tangentEyeVect.z, $worldEyeVect, $vNormal +mov $tangentEyeVect.w, $cZero + +mov oT5, $tangentEyeVect + +; base coordinates +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + +; reflection +alloc $projPosReflect + +mov $projPosReflect, $projPos +add $projPosReflect.xy, $projPosReflect, $projPosReflect.w +mul $projPosReflect.xy, $projPosReflect, $cHalf +mov oT1, $projPosReflect + +; refraction +mov $projPos.y, -$projPos.y +add $projPos.xy, $projPos, $projPos.w +mul $projPos.xy, $projPos, $cHalf +mov oT2, $projPos + +; reflectionscale, refractionscale +mov oT4, $SHADER_SPECIFIC_CONST_4 + +free $worldEyeVect +free $tangentEyeVect +free $projPosReflect +free $worldPos +free $projPos \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/Water_vs11.vsh b/sp/src/materialsystem/stdshaders/Water_vs11.vsh new file mode 100644 index 00000000..3b0131b8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Water_vs11.vsh @@ -0,0 +1,102 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +;------------------------------------------------------------------------------ +; Constants specified by the app +; c0 = (0, 1, 2, 0.5) +; c1 = (1/2.2, 0, 0, 0) +; c2 = camera position *in world space* +; c4-c7 = modelViewProj matrix (transpose) +; c8-c11 = ViewProj matrix (transpose) +; c12-c15 = model->view matrix (transpose) +; c16 = [fogStart, fogEnd, fogRange, undefined] +; +; Vertex components (as specified in the vertex DECL) +; $vPos = Position +; $vTexCoord0.xy = TexCoord0 +;------------------------------------------------------------------------------ + +#include "macros.vsh" + +; Vertex components +; $vPos = Position +; $vNormal = normal +; $vTexCoord0.xy = TexCoord0 +; $vTangentS = S axis of Texture space +; $vTangentT = T axis of Texture space + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +alloc $projPos + +; Transform position from object to projection space +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 + +alloc $worldPos + +; Transform position from object to world space +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +alloc $worldEyeVect + +; Get the eye vector in world space +add $worldEyeVect.xyz, -$worldPos, $cEyePos + +; transform the eye vector to tangent space +dp3 oT3.x, $worldEyeVect, $vTangentS +dp3 oT3.y, $worldEyeVect, $vTangentT +dp3 oT3.z, $worldEyeVect, $vNormal + +; Get the magnitude of worldEyeVect +dp3 $worldEyeVect.w, $worldEyeVect, $worldEyeVect +rsq $worldEyeVect.w, $worldEyeVect.w +rcp $worldEyeVect.w, $worldEyeVect.w + +; calculate the cheap water blend factor and stick it into oD0.a +; NOTE: This won't be perspective correct!!!!! +; OPTIMIZE: This could turn into a mad. +add $worldEyeVect.w, $worldEyeVect.w, -$SHADER_SPECIFIC_CONST_3.x +mul oD0, $worldEyeVect.w, $SHADER_SPECIFIC_CONST_3.y + +; dudv map +alloc $bumpTexCoord + +dp4 $bumpTexCoord.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 $bumpTexCoord.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + +mov oT0.xy, $bumpTexCoord + +; normal map +mov oT2.xy, $bumpTexCoord + +free $bumpTexCoord + +alloc $newProjPos + +mov oPos, $projPos + +; special case perspective correct texture projection so that the texture fits exactly on the screen +mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_4.w +add $projPos.xy, $projPos.xy, $projPos.w +mul $projPos.xy, $projPos.xy, $cHalf + +mov oT1.xy, $projPos.xy +mov oT1.z, $cZero +mov oT1.w, $projPos.w + +free $projPos +free $worldPos +free $worldEyeVect +free $projTangentS +free $projTangentT +free $newProjPos diff --git a/sp/src/materialsystem/stdshaders/Water_vs20.fxc b/sp/src/materialsystem/stdshaders/Water_vs20.fxc new file mode 100644 index 00000000..8f3a7a81 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/Water_vs20.fxc @@ -0,0 +1,117 @@ +// STATIC: "BASETEXTURE" "0..1" +// STATIC: "MULTITEXTURE" "0..1" + +// SKIP: $MULTITEXTURE && $BASETEXTURE + +#include "common_vs_fxc.h" + +const float4 cBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); +const float4 TexOffsets : register( SHADER_SPECIFIC_CONST_3 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vNormal : NORMAL; + float4 vBaseTexCoord : TEXCOORD0; + float2 vLightmapTexCoord : TEXCOORD1; + float2 vLightmapTexCoordOffset : TEXCOORD2; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos_POSITION : POSITION; +#if !defined( _X360 ) + float vFog : FOG; +#endif + float2 vBumpTexCoord : TEXCOORD0; + float3 vTangentEyeVect : TEXCOORD1; + float4 vReflectXY_vRefractYX : TEXCOORD2; + float W : TEXCOORD3; + float4 vProjPos : TEXCOORD4; + float screenCoord : TEXCOORD5; +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif +#if BASETEXTURE + HALF4 lightmapTexCoord1And2 : TEXCOORD6; + HALF4 lightmapTexCoord3 : TEXCOORD7; +#endif + float4 fogFactorW : COLOR1; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + // Projected position + float4 vProjPos = mul( v.vPos, cModelViewProj ); + o.vProjPos = o.vProjPos_POSITION = vProjPos; + + // Project tangent basis + float2 vProjTangentS = mul( v.vTangentS, cViewProj ); + float2 vProjTangentT = mul( v.vTangentT, cViewProj ); + + // Map projected position to the reflection texture + float2 vReflectPos; + vReflectPos = (vProjPos.xy + vProjPos.w) * 0.5f; + + // Map projected position to the refraction texture + float2 vRefractPos; + vRefractPos.x = vProjPos.x; + vRefractPos.y = -vProjPos.y; // invert Y + vRefractPos = (vRefractPos + vProjPos.w) * 0.5f; + + // Reflection transform + o.vReflectXY_vRefractYX = float4( vReflectPos.x, vReflectPos.y, vRefractPos.y, vRefractPos.x ); + o.W = vProjPos.w; + + o.screenCoord = vProjPos.x; + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + o.fogFactorW = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE ); +#if !defined( _X360 ) + o.vFog = o.fogFactorW; +#endif + + // Eye vector + float3 vWorldEyeVect = cEyePos - vWorldPos; + // Transform to the tangent space + o.vTangentEyeVect.x = dot( vWorldEyeVect, v.vTangentS ); + o.vTangentEyeVect.y = dot( vWorldEyeVect, v.vTangentT ); + o.vTangentEyeVect.z = dot( vWorldEyeVect, vObjNormal ); + + // Tranform bump coordinates + o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] ); + o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] ); + float f45x=v.vBaseTexCoord.x+v.vBaseTexCoord.y; + float f45y=v.vBaseTexCoord.y-v.vBaseTexCoord.x; +#if MULTITEXTURE + o.vExtraBumpTexCoord.x=f45x*0.1+TexOffsets.x; + o.vExtraBumpTexCoord.y=f45y*0.1+TexOffsets.y; + o.vExtraBumpTexCoord.z=v.vBaseTexCoord.y*0.45+TexOffsets.z; + o.vExtraBumpTexCoord.w=v.vBaseTexCoord.x*0.45+TexOffsets.w; +#endif + +#if BASETEXTURE + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; + + float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; + float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; + + // reversed component order + o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; + o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; + + o.lightmapTexCoord3.xy = lightmapTexCoord3; +#endif + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/WorldTexture.psh b/sp/src/materialsystem/stdshaders/WorldTexture.psh new file mode 100644 index 00000000..6144fdf2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldTexture.psh @@ -0,0 +1,14 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 +mov r0, t0 + diff --git a/sp/src/materialsystem/stdshaders/WorldTwoTextureBlend.psh b/sp/src/materialsystem/stdshaders/WorldTwoTextureBlend.psh new file mode 100644 index 00000000..b9494b02 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldTwoTextureBlend.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mov r0.rgb, t0 + +mul r0.a, t0.a, v0.a ; Grab alpha from vertex color + +lrp r0.rgb, t2.a, t2, r0 ; Base = base * (1 - detail alpha) + detail * detail alpha +mul r0.rgb, r0, v0 ; modulate by vertex color +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh b/sp/src/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh new file mode 100644 index 00000000..033730bb --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh @@ -0,0 +1,25 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +def c1, 1.0f, 1.0f, 1.0f, 1.0f + +tex t0 +tex t1 +tex t2 + +mov_x2_sat r0.rgb, t0 + ; r0 = sat( t0 * 2 ) +mul r0.a, t0.a, v0.a ; Grab alpha from vertex color + +lrp_sat r0.rgb, t2.a, r0, c1 ; r0 = B*Da + (1-Da) + +mul r0.rgb, r0, t2 ; modulate by detail color +mul r0.rgb, r0, v0 ; modulate by vertex color +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh b/sp/src/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh new file mode 100644 index 00000000..2f5a8ca5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mov r0.rgb, t0 + +mov r0.a, v0.a ; Grab alpha from vertex color + +lrp r0.rgb, t2.a, t2, r0 ; Base = base * (1 - detail alpha) + detail * detail alpha +mul r0.rgb, r0, v0 ; modulate by vertex color +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1.rgb, c1, t0 ; Self illum * tint ++ mul r1.a, t0.a, 1-t2.a ; Reduce self-illum amount based on 1 - detailalpha + +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lightmap + diff --git a/sp/src/materialsystem/stdshaders/WorldVertexAlpha.psh b/sp/src/materialsystem/stdshaders/WorldVertexAlpha.psh new file mode 100644 index 00000000..e610452e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexAlpha.psh @@ -0,0 +1,10 @@ +ps.1.1 + +tex t0 ; basetexture +tex t1 ; lightmap + +mov r0.a, 1-t1.a +;mov r0.rgb, t0 ; * 2 * (overbrightFactor/2) +;mov_x2 r0.rgb, t0 ; * 2 * (overbrightFactor/2) +mul r0.rgb, t0, t1; +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/WorldVertexAlpha.vsh b/sp/src/materialsystem/stdshaders/WorldVertexAlpha.vsh new file mode 100644 index 00000000..ae2566a6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexAlpha.vsh @@ -0,0 +1,37 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +&AllocateRegister( \$worldPos ); + +; garymcthack +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$worldPos ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +; base texcoords +mov oT0, $vTexCoord0 + +; lightmap texcoords +mov oT1, $vTexCoord1 + +&FreeRegister( \$worldPos ); # garymcthack + diff --git a/sp/src/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc b/sp/src/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc new file mode 100644 index 00000000..7ccc584a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc @@ -0,0 +1,43 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "PASS" "0..1" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +// CENTROID: TEXCOORD1 + +sampler BaseSampler : register( s0 ); +sampler LightmapSampler: register( s1 ); +sampler LightmapAlphaSampler: register( s2 ); + +struct PS_INPUT +{ + float2 baseCoord : TEXCOORD0; + float2 lightmapCoord : TEXCOORD1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bAlphaPass = PASS ? true : false; + + float4 base = tex2D( BaseSampler, i.baseCoord ); + float4 lightmap = tex2D( LightmapSampler, i.lightmapCoord ); + float4 alpha = tex2D( LightmapAlphaSampler, i.lightmapCoord ); + + float4 color; + + base.a = dot( base, HALF3( HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f) ) ); + color = 2.0f * base * lightmap; // The 2x is for an assumed overbright 2 (it's always 2 on dx9) + + if( bAlphaPass ) + { + // Don't care about color, just return pre-multiplied alpha + return FinalOutput( float4( 0.0f, 0.0f, 1.0f, (1.0f - alpha.a) * color.a ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); + } + else + { + return FinalOutput( float4( color.rgb, (1.0f - alpha.a) ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); + } +} + diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition.psh b/sp/src/materialsystem/stdshaders/WorldVertexTransition.psh new file mode 100644 index 00000000..4fd2882b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition.psh @@ -0,0 +1,18 @@ +; STATIC: "DETAIL" "0..1" +ps.1.1 + +tex t0 ; basetexture +tex t1 ; basetexture2 +tex t2 ; lightmap +#if DETAIL +tex t3 ; detail +#endif + +mov_sat r1.a, v0.a +lrp r0, r1.a, t1, t0 + +mul r0, r0, t2 +#if DETAIL +mul_x2 r0.rgb, r0, t3 +#endif +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition.vsh b/sp/src/materialsystem/stdshaders/WorldVertexTransition.vsh new file mode 100644 index 00000000..81e56dbe --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition.vsh @@ -0,0 +1,48 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +&AllocateRegister( \$worldPos ); + +; garymcthack +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$worldPos ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +; base texcoords +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + +dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + +; lightmap texcoords +mov oT2, $vTexCoord1 + +; detail +dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + +; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. +mov oD0, $vColor + +&FreeRegister( \$worldPos ); # garymcthack + diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh b/sp/src/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh new file mode 100644 index 00000000..d4a5c623 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh @@ -0,0 +1,16 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +mul r0.rgb, t1, t0 ; fold in lightmap (color) ++mov r0.a, v0.a ; fold in lightmap (alpha) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition_Editor.psh b/sp/src/materialsystem/stdshaders/WorldVertexTransition_Editor.psh new file mode 100644 index 00000000..936edc9e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition_Editor.psh @@ -0,0 +1,10 @@ +ps.1.1 + +tex t0 ; basetexture +tex t1 ; basetexture2 +tex t2 ; lightmap + +; The editor uses vertex alpha as the blend factor +lrp r0, 1-v0.a, t1, t0 +mul r0, r0, t2 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh b/sp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh new file mode 100644 index 00000000..8d4edad0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh @@ -0,0 +1,23 @@ +ps.1.1 + +def c0, 1.0f, 0.0f, 0.0f, 0.0f +def c1, 0.0f, 1.0f, 0.0f, 0.0f +def c2, 0.0f, 0.0f, 1.0f, 0.0f + +tex t0 ; basetexture zy +tex t1 ; basetexture xz +tex t2 ; basetexture xy +tex t3 ; lightmap + +dp3_sat r1, v0, c0 +mul r0, t0, r1 + +dp3_sat r1, v0, c1 +mad r0, t1, r1, r0 + +dp3_sat r1, v0, c2 +mad r0, t2, r1, r0 + +; multiply by lightmap +mul_x2 r0.rgb, r0, t3 ++mov r0.a, v0 ; $vColor diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh b/sp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh new file mode 100644 index 00000000..dd0cc99c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh @@ -0,0 +1,54 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + +alloc $projPos + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +alloc $worldPos +alloc $worldNormal + +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 + +dp3 $worldNormal.x, $vNormal, $cModel0 +dp3 $worldNormal.y, $vNormal, $cModel1 +dp3 $worldNormal.z, $vNormal, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +free $projPos + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +; base texcoords +alloc $texcoord +mul $texcoord.xyz, $worldPos, $SHADER_SPECIFIC_CONST_0 + +mov oT0.xy, $texcoord.zy; +mov oT1.xy, $texcoord.xz; +mov oT2.xy, $texcoord.xy; + +free $texcoord + +; lightmap texcoords +mov oT3, $vTexCoord1 + +mul oD0.rgb, $worldNormal, $worldNormal + +; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. +mov oD0.a, $vColor + +free $worldPos +free $worldNormal diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp b/sp/src/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp new file mode 100644 index 00000000..331f8f17 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp @@ -0,0 +1,537 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "convar.h" + +#include "worldvertextransition.inc" +#include "worldvertextransition_vs14.inc" +#include "worldvertextransition_seamless.inc" +#include "lightmappedgeneric_vs11.inc" +#include "writevertexalphatodestalpha_vs11.inc" +#include "worldvertextransition_dx8_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( WorldVertexTransition, WorldVertexTransition_DX8 ) + +ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); + +BEGIN_VS_SHADER( WorldVertexTransition_DX8, + "Help for WorldVertexTransition_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture2", "base texture2 help" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $baseTexture" ) + SHADER_PARAM( BASETEXTURETRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$baseTexture texcoord transform" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map for BASETEXTURE" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( BUMPBASETEXTURE2WITHBUMPMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "0.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) + SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "WorldVertexTransition_DX6"; + return 0; + } + + void SetupVars( WorldVertexTransitionEditor_DX8_Vars_t& info ) + { + info.m_nBaseTextureVar = BASETEXTURE; + info.m_nBaseTextureFrameVar = FRAME; + info.m_nBaseTextureTransformVar = BASETEXTURETRANSFORM; + info.m_nBaseTexture2Var = BASETEXTURE2; + info.m_nBaseTexture2FrameVar = FRAME2; + info.m_nBaseTexture2TransformVar = BASETEXTURETRANSFORM2; + } + + SHADER_INIT_PARAMS() + { + // Initializes FLASHLIGHTTEXTURE + MATERIAL_VAR2_LIGHTING_LIGHTMAP + WorldVertexTransitionEditor_DX8_Vars_t info; + SetupVars( info ); + InitParamsWorldVertexTransitionEditor_DX8( params, info ); + + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + if( IsUsingGraphics() && params[ENVMAP]->IsDefined() && !CanUseEditorMaterials() ) + { + if( stricmp( params[ENVMAP]->GetStringValue(), "env_cubemap" ) == 0 ) + { + Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); + params[ENVMAP]->SetUndefined(); + } + } + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + { + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + } + + if( !params[ENVMAPTINT]->IsDefined() ) + { + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[SELFILLUMTINT]->IsDefined() ) + { + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[DETAILSCALE]->IsDefined() ) + { + params[DETAILSCALE]->SetFloatValue( 4.0f ); + } + + if( !params[FRESNELREFLECTION]->IsDefined() ) + { + params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); + } + + if( !params[ENVMAPMASKFRAME]->IsDefined() ) + { + params[ENVMAPMASKFRAME]->SetIntValue( 0 ); + } + + if( !params[ENVMAPFRAME]->IsDefined() ) + { + params[ENVMAPFRAME]->SetIntValue( 0 ); + } + + if( !params[BUMPFRAME]->IsDefined() ) + { + params[BUMPFRAME]->SetIntValue( 0 ); + } + + if( !params[ENVMAPCONTRAST]->IsDefined() ) + { + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + } + + if( !params[ENVMAPSATURATION]->IsDefined() ) + { + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + + if( !params[BUMPBASETEXTURE2WITHBUMPMAP]->IsDefined() ) + { + params[BUMPBASETEXTURE2WITHBUMPMAP]->SetIntValue( 0 ); + } + + if( !params[DETAILSCALE]->IsDefined() ) + { + params[DETAILSCALE]->SetFloatValue( 4.0f ); + } + + if( !params[DETAILFRAME]->IsDefined() ) + { + params[DETAILFRAME]->SetIntValue( 0 ); + } + + if( params[SEAMLESS_SCALE]->IsDefined() && params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) + { + // seamless scale is going to be used, so kill some other features. . might implement with these features later. + params[DETAIL]->SetUndefined(); + params[BUMPMAP]->SetUndefined(); + params[ENVMAP]->SetUndefined(); + } + + if ( !params[SEAMLESS_SCALE]->IsDefined() ) + { + // zero means don't do seamless mapping. + params[SEAMLESS_SCALE]->SetFloatValue( 0.0f ); + } + + if( params[SSBUMP]->IsDefined() && params[SSBUMP]->GetIntValue() != 0 ) + { + // turn of normal mapping since we have ssbump defined, which + // means that we didn't make a dx8 fallback for this material. + params[BUMPMAP]->SetUndefined(); + } + } + SHADER_INIT + { + // Loads BASETEXTURE, BASETEXTURE2 + WorldVertexTransitionEditor_DX8_Vars_t info; + SetupVars( info ); + InitWorldVertexTransitionEditor_DX8( this, params, info ); + + // FLASHLIGHTFIXME + if ( params[FLASHLIGHTTEXTURE]->IsDefined() ) + { + LoadTexture( FLASHLIGHTTEXTURE ); + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + if ( g_pHardwareConfig->SupportsPixelShaders_1_4() && params[BLENDMODULATETEXTURE]->IsDefined() ) + { + LoadTexture( BLENDMODULATETEXTURE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( params[ENVMAP]->IsDefined() && !params[BUMPMAP]->IsDefined() ) + { + Warning( "must have $bumpmap if you have $envmap for worldvertextransition\n" ); + params[ENVMAP]->SetUndefined(); + params[BUMPMAP]->SetUndefined(); + } + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + LoadBumpMap( BUMPMAP ); + } + if( params[ENVMAP]->IsDefined() ) + { + if( !IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ) ) + { + LoadCubeMap( ENVMAP ); + } + else + { + Warning( "$envmapsphere not supported by worldvertextransition\n" ); + params[ENVMAP]->SetUndefined(); + } + } + } + + void WriteVertexAlphaToDestAlpha( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + if( pShaderShadow ) + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableColorWrites( false ); + + writevertexalphatodestalpha_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "writevertexalphatodestalpha_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "writevertexalphatodestalpha_ps11" ); + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_COLOR, 2, 0, 0 ); + } + else + { + writevertexalphatodestalpha_vs11_Dynamic_Index vshIndex; + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + void DrawFlashlightPass( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, int passID ) + { + bool bBump = ( passID == 0 ) && ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture(); + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, true, passID, BASETEXTURE2, FRAME2 ); + } + + bool ShouldUseBumpmapping( IMaterialVar **params ) + { + return g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined(); + } + + void DrawFlashlight( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + WriteVertexAlphaToDestAlpha( params, pShaderAPI, pShaderShadow ); + DrawFlashlightPass( params, pShaderAPI, pShaderShadow, 0 ); + DrawFlashlightPass( params, pShaderAPI, pShaderShadow, 1 ); + } + + SHADER_DRAW + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + bool bSupports14 = g_pHardwareConfig->SupportsPixelShaders_1_4(); + + // FLASHLIGHTFIXME: need to make these the same. + bool hasFlashlight = UsingFlashlight( params ); + if( hasFlashlight ) + { + DrawFlashlight( params, pShaderAPI, pShaderShadow ); + } + else if ( params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) + { + // This is the seamless_scale version, which doesn't use $detail or $bumpmap + SHADOW_STATE + { + // three copies of the base texture for seamless blending + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // lightmap + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + worldvertextransition_seamless_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition_Seamless", vshIndex.GetIndex() ); + + int pshIndex = 0; + pShaderShadow->SetPixelShader( "WorldVertexTransition_Seamless", pshIndex ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + // Texture 0..2 + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); + } + + // Texture 3 = lightmap + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); + + EnablePixelShaderOverbright( 0, true, true ); + + float fSeamlessScale = params[SEAMLESS_SCALE]->GetFloatValue(); + float map_scale[4]= { fSeamlessScale, fSeamlessScale, fSeamlessScale, fSeamlessScale }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale ); + + worldvertextransition_seamless_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + SHADOW_STATE + { + // inherit state from previous pass + + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + DYNAMIC_STATE + { + if( !bLightingOnly ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE2, FRAME2 ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE2, FRAME2 ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE2, FRAME2 ); + } + } + Draw(); + } + else if( !params[BUMPMAP]->IsTexture() || !g_pConfig->UseBumpmapping() ) + { + bool bDetail = params[DETAIL]->IsTexture(); + bool bBlendModulate = params[BLENDMODULATETEXTURE]->IsTexture(); + SHADOW_STATE + { + // This is the dx8, non-worldcraft version, non-bumped version + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if( bDetail ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + if ( bSupports14 && bBlendModulate ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + + int fmt = VERTEX_POSITION | VERTEX_COLOR; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + if ( !bSupports14 ) + { + worldvertextransition_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition", vshIndex.GetIndex() ); + + int pshIndex = bDetail ? 1 : 0; + pShaderShadow->SetPixelShader( "WorldVertexTransition", pshIndex ); + } + else + { + worldvertextransition_vs14_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition_vs14", vshIndex.GetIndex() ); + + int pshIndex = bDetail ? 1 : 0; + pshIndex += bBlendModulate ? 2 : 0; + pShaderShadow->SetPixelShader( "WorldVertexTransition_ps14", pshIndex ); + } + + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Texture 1 + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE2, FRAME2 ); + } + if( bDetail ) + { + BindTexture( SHADER_SAMPLER3, DETAIL, DETAILFRAME ); + } + if ( bSupports14 && bBlendModulate ) + { + BindTexture( SHADER_SAMPLER4, BLENDMODULATETEXTURE ); + } + + // always set the transform for detail textures since I'm assuming that you'll + // always have a detailscale. + // go ahead and set this even if we don't have a detail texture so the vertex shader doesn't + // barf chunks with unitialized data. + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); + + if ( bSupports14 ) + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BLENDMASKTRANSFORM ); + } + + // Texture 3 = lightmap + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_LIGHTMAP ); + + EnablePixelShaderOverbright( 0, true, true ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM2 ); + if ( !bSupports14 ) + { + worldvertextransition_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + else + { + worldvertextransition_vs14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + Draw(); + } + else + { + if( params[BUMPBASETEXTURE2WITHBUMPMAP]->GetIntValue() ) + { + DrawWorldBumpedUsingVertexShader( BASETEXTURE, BASETEXTURETRANSFORM, + BUMPMAP, BUMPFRAME, BUMPTRANSFORM, ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP, + ENVMAPFRAME, ENVMAPTINT, COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, + FRESNELREFLECTION, true, BASETEXTURE2, BASETEXTURETRANSFORM2, FRAME2, false ); + } + else + { + // draw the base texture with everything else you normally would for + // bumped world materials + DrawWorldBumpedUsingVertexShader( + BASETEXTURE, BASETEXTURETRANSFORM, + BUMPMAP, BUMPFRAME, BUMPTRANSFORM, + ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP, ENVMAPFRAME, ENVMAPTINT, + COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, + FRESNELREFLECTION, + false, -1, -1, -1, false ); + + // blend basetexture 2 on top of everything using lightmap alpha. + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_COLOR, 2, 0, 0 ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( false ); + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + vshIndex.SetVERTEXCOLOR( true ); + pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WorldVertexTransition_BlendBase2" ); + FogToFogColor(); + } + DYNAMIC_STATE + { + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE2, FRAME2 ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + float half[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; + pShaderAPI->SetPixelShaderConstant( 4, half ); + EnablePixelShaderOverbright( 0, true, true ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM2 ); + + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + } + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition_ps14.psh b/sp/src/materialsystem/stdshaders/WorldVertexTransition_ps14.psh new file mode 100644 index 00000000..763a5d11 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition_ps14.psh @@ -0,0 +1,32 @@ +; STATIC: "DETAIL" "0..1" +; STATIC: "BLENDMODULATETEXTURE" "0..1" +ps.1.4 + +def c1, 3.0, -2.0, 0.5, 0.5 + +texld r0, t0 +texld r1, t1 +texld r2, t2 +#if DETAIL +texld r3, t3 ; detail +#endif +#if BLENDMODULATETEXTURE +texld r4, t4 ; detail +#endif + +#if BLEND_MODULATETEXTURE +sub r5.a, v0.a, r4.g +add_sat r5.a, r5.a, c1.a +mad r6.a, c1.g, r5.a, c1.r +mul r6.a, r6.a, r5.a +mul r5.a, r6.a, r5.a +#else +mov_sat r5.a, v0.a +#endif +lrp r0, r5.a, r1, r0 + +mul r0, r0, r2 +#if DETAIL +mul_x2 r0.rgb, r0, r3 +#endif +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc b/sp/src/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc new file mode 100644 index 00000000..f27e870d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc @@ -0,0 +1,47 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "MACROS" "0..1" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + + +sampler BaseSampler : register( s0 ); +// NOTE: LightmapSampler is at the same place as the lightmap sampler in lightmappedgeneric so that we have +// generally the same texture state here. +// CENTROID: TEXCOORD1 +sampler LightmapSampler: register( s1 ); +sampler BaseSampler2: register( s2 ); +sampler LightmapAlphaSampler: register( s3 ); +sampler MacrosSampler: register( s4 ); + +struct PS_INPUT +{ + float2 baseCoord : TEXCOORD0; + float2 baseCoord2 : TEXCOORD1; + float2 lightmapCoord : TEXCOORD2; + float2 macrosCoord : TEXCOORD3; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bMacros = MACROS ? true : false; + + float4 base = tex2D( BaseSampler, i.baseCoord ); + float4 base2 = tex2D( BaseSampler2, i.baseCoord2 ); + + float4 lightmap = tex2D( LightmapSampler, i.lightmapCoord ); + float blendFactor = lightmap.a; + + float4 color = 2.0f * lightmap * lerp( base2, base, blendFactor ); + if( bMacros ) + { + float4 macros = tex2D( MacrosSampler, i.macrosCoord ); + + // Not sure what to do with macro alpha + color.rgb *= 2.0f * lerp( macros.a, macros.b, blendFactor ); + } + + return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} + diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh b/sp/src/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh new file mode 100644 index 00000000..eecc1c89 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh @@ -0,0 +1,52 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +&AllocateRegister( \$worldPos ); + +; garymcthack +dp4 $worldPos.z, $vPos, $cModel2 + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$worldPos ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +; base texcoords +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + +dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 +dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + +; lightmap texcoords +mov oT2, $vTexCoord1 + +; detail +dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 +dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + +; mask +dp4 oT4.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_6 +dp4 oT4.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_7 + +; Now the basetexture/basetexture2 blend uses vertex color, so send it into the psh. +mov oD0, $vColor + +&FreeRegister( \$worldPos ); # garymcthack + diff --git a/sp/src/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc b/sp/src/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc new file mode 100644 index 00000000..5f18ca81 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc @@ -0,0 +1,64 @@ +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cBaseTexCoordTransform2[2] : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cMacrosTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vColor : COLOR0; + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 baseCoord : TEXCOORD0; + float2 baseCoord2 : TEXCOORD1; + float2 lightmapCoord : TEXCOORD2; + float2 macrosCoord : TEXCOORD3; + float4 color : COLOR0; + float4 fogFactorW : COLOR1; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldNormal, worldPos; + float2 texCoord; + worldPos = mul( v.vPos, cModel[0] ); + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + o.color = v.vColor; + + o.baseCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + + o.baseCoord2.x = dot( v.vTexCoord0, cBaseTexCoordTransform2[0] ); + o.baseCoord2.y = dot( v.vTexCoord0, cBaseTexCoordTransform2[1] ); + + o.lightmapCoord = v.vTexCoord1; + + o.macrosCoord.x = dot( v.vTexCoord0, cMacrosTexCoordTransform[0] ); + o.macrosCoord.y = dot( v.vTexCoord0, cMacrosTexCoordTransform[1] ); + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/cable_dx6.cpp b/sp/src/materialsystem/stdshaders/cable_dx6.cpp new file mode 100644 index 00000000..9b11551f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cable_dx6.cpp @@ -0,0 +1,62 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Cable, Cable_DX6 ) + +BEGIN_SHADER( Cable_DX6, + "Help for Cable_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.25", "Minimum amount of light (0-1 value)" ) + SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.25", "Maximum amount of light" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + int GetDrawFlagsPass1(IMaterialVar** params ) + { + int flags = SHADER_DRAW_POSITION; + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + flags |= SHADER_DRAW_COLOR; + flags |= SHADER_DRAW_TEXCOORD0; + return flags; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableConstantColor( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + SetNormalBlendingShadowState( BASETEXTURE, true ); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params) ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + Vector min, max; + params[MINLIGHT]->GetVecValue( &min.x, 3 ); + params[MAXLIGHT]->GetVecValue( &max.x, 3 ); + Vector avg = ( min + max ) * 0.5f; + pShaderAPI->Color3fv( &avg.x ); + } + Draw( ); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/cable_dx8.cpp b/sp/src/materialsystem/stdshaders/cable_dx8.cpp new file mode 100644 index 00000000..9e3c98dd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cable_dx8.cpp @@ -0,0 +1,132 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: A wet version of base * lightmap +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "cable.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Cable, Cable_DX8 ) + +BEGIN_VS_SHADER( Cable_DX8, + "Help for Cable shader" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "cable/cablenormalmap", "bumpmap texture" ) + SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.1", "Minimum amount of light (0-1 value)" ) + SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.3", "Maximum amount of light" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && !g_pHardwareConfig->SupportsVertexAndPixelShaders()) + { + return "UnlitGeneric_DX6"; + } + return 0; + } + + SHADER_INIT + { + LoadBumpMap( BUMPMAP ); + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + // Enable blending? + if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) ) + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + + int tCoordDimensions[] = {2,2}; + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_COLOR | VERTEX_TANGENT_S | VERTEX_TANGENT_T, + 2, tCoordDimensions, 0 ); + + cable_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Cable", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "Cable" ); + + // we are writing linear values from this shader. + // This is kinda wrong. We are writing linear or gamma depending on "IsHDREnabled" below. + // The COLOR really decides if we are gamma or linear. + if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + pShaderShadow->EnableSRGBWrite( true ); + } + + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BUMPMAP ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE ); + + + // The dot product with the light is remapped from the range + // [-1,1] to [MinLight, MaxLight]. + + // Given: + // -A + B = MinLight + // A + B = MaxLight + // then A = (MaxLight - MinLight) / 2 + // and B = (MaxLight + MinLight) / 2 + + // So here, we multiply the light direction by A to scale the dot product. + // Then in the pixel shader we add by B. + float flMinLight = params[MINLIGHT]->GetFloatValue(); + float flMaxLight = params[MAXLIGHT]->GetFloatValue(); + + float A = (flMaxLight - flMinLight) * 0.5f; + float B = (flMaxLight + flMinLight) * 0.5f; + + float b4[4] = {B,B,B,B}; + if( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + SetPixelShaderConstantGammaToLinear( 0, b4 ); + } + else + { + pShaderAPI->SetPixelShaderConstant( 0, b4 ); + } + + // This is the light direction [0,1,0,0] * A * 0.5 + float lightDir[4] = {0, A*0.5, 0, 0}; + if( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + SetVertexShaderConstantGammaToLinear( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lightDir ); + } + else + { + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lightDir ); + } + + cable_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/cable_dx9.cpp b/sp/src/materialsystem/stdshaders/cable_dx9.cpp new file mode 100644 index 00000000..5b25ed61 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cable_dx9.cpp @@ -0,0 +1,141 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: A wet version of base * lightmap +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "cable_vs20.inc" +#include "cable_ps20.inc" +#include "cable_ps20b.inc" +#include "cpp_shader_constant_register_map.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern ConVar mat_fullbright; + +DEFINE_FALLBACK_SHADER( Cable, Cable_DX9 ) + +BEGIN_VS_SHADER( Cable_DX9, + "Help for Cable shader" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "cable/cablenormalmap", "bumpmap texture" ) + SHADER_PARAM( MINLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.1", "Minimum amount of light (0-1 value)" ) + SHADER_PARAM( MAXLIGHT, SHADER_PARAM_TYPE_FLOAT, "0.3", "Maximum amount of light" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( !(g_pHardwareConfig->SupportsPixelShaders_2_0() && g_pHardwareConfig->SupportsVertexShaders_2_0()) || + (g_pHardwareConfig->GetDXSupportLevel() < 90) ) + { + return "Cable_DX8"; + } + return 0; + } + + SHADER_INIT + { + LoadBumpMap( BUMPMAP ); + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + } + + SHADER_DRAW + { + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + // Enable blending? + if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) ) + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + + int tCoordDimensions[] = {2,2}; + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_COLOR | VERTEX_TANGENT_S | VERTEX_TANGENT_T, + 2, tCoordDimensions, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( cable_vs20 ); + SET_STATIC_VERTEX_SHADER( cable_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( cable_ps20b ); + SET_STATIC_PIXEL_SHADER( cable_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( cable_ps20 ); + SET_STATIC_PIXEL_SHADER( cable_ps20 ); + } + + // we are writing linear values from this shader. + // This is kinda wrong. We are writing linear or gamma depending on "IsHDREnabled" below. + // The COLOR really decides if we are gamma or linear. + pShaderShadow->EnableSRGBWrite( true ); + + FogToFogColor(); + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + + BindTexture( SHADER_SAMPLER0, BUMPMAP ); + if ( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + + } + else + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( cable_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER( cable_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( cable_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( cable_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( cable_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( cable_ps20 ); + } + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/cable_ps2x.fxc b/sp/src/materialsystem/stdshaders/cable_ps2x.fxc new file mode 100644 index 00000000..a3c7ff13 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cable_ps2x.fxc @@ -0,0 +1,54 @@ +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler NormalSampler : register( s0 ); +sampler BaseTextureSampler : register( s1 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +struct PS_INPUT +{ + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + + float4 directionalLightColor : COLOR0; + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 vNormalMapDir = tex2D( NormalSampler, i.vTexCoord0 ); // Get the 3-vector from the normal map + float4 textureColor = tex2D( BaseTextureSampler, i.vTexCoord1 ); // Interpret tcoord t1 as color data. + + //Expand compacted vectors + //TODO: find if there's a better way to expand a color normal to a full vector ( _bx2 was used in the assembly code ) + vNormalMapDir = (vNormalMapDir - 0.5) * 2.0; + float3 vLightDir = float3( 0.0f, 0.0f, 1.0f ); + + float lightDirDotNormalMap = dot( vNormalMapDir, vLightDir ); //normalMap dot dirLightDir + + // do half-lambert on the dot + lightDirDotNormalMap = lightDirDotNormalMap * 0.5 + 0.5; + lightDirDotNormalMap = lightDirDotNormalMap * lightDirDotNormalMap; + + float4 resultColor; + resultColor.xyz = lightDirDotNormalMap * ( textureColor.rgb * i.directionalLightColor.rgb ); + resultColor.a = textureColor.a * i.directionalLightColor.a; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/sp/src/materialsystem/stdshaders/cable_vs20.fxc b/sp/src/materialsystem/stdshaders/cable_vs20.fxc new file mode 100644 index 00000000..adb3559e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cable_vs20.fxc @@ -0,0 +1,80 @@ +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 directionalLightColor : COLOR0; + + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + + float4 directionalLightColor : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul( v.vPos, cModel[0] ); + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + //------------------------------------------------------------------------------ + // Setup the tangent space + //------------------------------------------------------------------------------ + + // Get S crossed with T (call it R) + float3 r = cross( v.vTangentS, v.vTangentT ); + + // Normalize S (into s) + float3 s = normalize( v.vTangentS ); + + // Normalize R (into r) + r = normalize( r ); + + // Regenerate T (into t) + float3 t = cross( r, v.vTangentS ); + + //------------------------------------------------------------------------------ + // Copy texcoords for the normal map and base texture + //------------------------------------------------------------------------------ + o.vTexCoord0 = v.vTexCoord0; + o.vTexCoord1 = v.vTexCoord1; + + // Pass the dirlight color through + o.directionalLightColor = v.directionalLightColor; + + return o; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/cloud.cpp b/sp/src/materialsystem/stdshaders/cloud.cpp new file mode 100644 index 00000000..810e6c4d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cloud.cpp @@ -0,0 +1,76 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_SHADER( Cloud, + "Help for Cloud" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 ) + SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" ) + SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" ) + SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" ) + END_SHADER_PARAMS + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + LoadTexture( CLOUDALPHATEXTURE ); + if( !params[CLOUDSCALE]->IsDefined() ) + { + params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f ); + } + if( !params[MASKSCALE]->IsDefined() ) + { + params[MASKSCALE]->SetVecValue( 1.0f, 1.0f ); + } + } + + SHADER_DRAW + { + if( g_pHardwareConfig->GetSamplerCount() >= 2 ) + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + { + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + else + { + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | + SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_TEXCOORD1 ); + DefaultFog(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); + + // handle scrolling of base texture + SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE0, + BASETEXTURETRANSFORM, CLOUDSCALE ); + SetFixedFunctionTextureScale( MATERIAL_TEXTURE1, MASKSCALE ); + } + Draw(); + } + else + { + ShaderWarning("Cloud not supported for single-texturing boards!\n"); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/cloud_dx8.cpp b/sp/src/materialsystem/stdshaders/cloud_dx8.cpp new file mode 100644 index 00000000..d3bc2530 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cloud_dx8.cpp @@ -0,0 +1,77 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "cloud_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Cloud_dx8, "Help for Cloud" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 ) + SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" ) + SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" ) + SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" ) + END_SHADER_PARAMS + + SHADER_INIT + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( CLOUDALPHATEXTURE, TEXTUREFLAGS_SRGB ); + if ( !params[CLOUDSCALE]->IsDefined() ) + { + params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f ); + } + if ( !params[MASKSCALE]->IsDefined() ) + { + params[MASKSCALE]->SetVecValue( 1.0f, 1.0f ); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + { + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + else + { + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); + + cloud_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "cloud_vs11", vshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( "cloud_ps11" ); + + DefaultFog(); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); + + // handle scrolling of base texture + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM, CLOUDSCALE ); + SetVertexShaderTextureScale( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, MASKSCALE ); + + pShaderAPI->SetVertexShaderIndex( 0 ); + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/cloud_dx9.cpp b/sp/src/materialsystem/stdshaders/cloud_dx9.cpp new file mode 100644 index 00000000..4b04b8b4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cloud_dx9.cpp @@ -0,0 +1,94 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// DirectX 9 Cloud shader +// +//=============================================================================== + +#include "BaseVSShader.h" +#include "cloud_vs20.inc" +#include "cloud_ps20.inc" + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Cloud, Cloud_dx9 ) + +BEGIN_VS_SHADER( Cloud_dx9, "Help for Cloud" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloud", "cloud texture", 0 ) + SHADER_PARAM( CLOUDALPHATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/cloudalpha", "cloud alpha texture" ) + SHADER_PARAM( CLOUDSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "cloudscale" ) + SHADER_PARAM( MASKSCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "maskscale" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "Cloud_dx8"; + + return 0; + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( CLOUDALPHATEXTURE, TEXTUREFLAGS_SRGB ); + if ( !params[CLOUDSCALE]->IsDefined() ) + { + params[CLOUDSCALE]->SetVecValue( 1.0f, 1.0f ); + } + if ( !params[MASKSCALE]->IsDefined() ) + { + params[MASKSCALE]->SetVecValue( 1.0f, 1.0f ); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + if ( IS_FLAG_SET( MATERIAL_VAR_ADDITIVE ) ) + { + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + } + else + { + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( cloud_vs20 ); + SET_STATIC_VERTEX_SHADER( cloud_vs20 ); + + DECLARE_STATIC_PIXEL_SHADER( cloud_ps20 ); + SET_STATIC_PIXEL_SHADER( cloud_ps20 ); + + DefaultFog(); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, CLOUDALPHATEXTURE ); + + // Handle scrolling of base texture + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM, CLOUDSCALE ); + SetVertexShaderTextureScale( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, MASKSCALE ); + + DECLARE_DYNAMIC_VERTEX_SHADER( cloud_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( cloud_vs20 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( cloud_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( cloud_ps20 ); + } + + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/cloud_ps11.psh b/sp/src/materialsystem/stdshaders/cloud_ps11.psh new file mode 100644 index 00000000..8e5627cb --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cloud_ps11.psh @@ -0,0 +1,6 @@ +ps.1.1 + +tex t0 +tex t1 + +mul r0, t0, t1 diff --git a/sp/src/materialsystem/stdshaders/cloud_ps20.fxc b/sp/src/materialsystem/stdshaders/cloud_ps20.fxc new file mode 100644 index 00000000..31f8bbd2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cloud_ps20.fxc @@ -0,0 +1,26 @@ +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler CloudAlphaSampler : register( s1 ); + +struct PS_INPUT +{ + float2 baseCoords : TEXCOORD0; + float2 cloudAlphaCoords : TEXCOORD1; + float fogFactor : TEXCOORD2; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 vBase = tex2D( BaseTextureSampler, i.baseCoords ); + float4 vCloudAlpha = tex2D( CloudAlphaSampler, i.cloudAlphaCoords ); + + float fogFactor = 2.0f * smoothstep( 0.3f, 0.6f, i.fogFactor ); + + float4 result = vBase * vCloudAlpha; + result.a *= fogFactor; + + // No actual fog. Use the "fog factor" to modulate alpha (after some smoothstep mojo) + return FinalOutput( result, 1.0f, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +} diff --git a/sp/src/materialsystem/stdshaders/cloud_vs11.vsh b/sp/src/materialsystem/stdshaders/cloud_vs11.vsh new file mode 100644 index 00000000..6348937e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cloud_vs11.vsh @@ -0,0 +1,26 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..0" + +#include "macros.vsh" + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + +&AllocateRegister( \$worldPos ); +; $worldPos unused, for above water, range fog calcs +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); +&FreeRegister( \$worldPos ); + +dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 +dp4 oT1.x, $vTexCoord1, $SHADER_SPECIFIC_CONST_2 +dp4 oT1.y, $vTexCoord1, $SHADER_SPECIFIC_CONST_3 + diff --git a/sp/src/materialsystem/stdshaders/cloud_vs20.fxc b/sp/src/materialsystem/stdshaders/cloud_vs20.fxc new file mode 100644 index 00000000..3655e9fa --- /dev/null +++ b/sp/src/materialsystem/stdshaders/cloud_vs20.fxc @@ -0,0 +1,37 @@ +#include "common_vs_fxc.h" + +const float4 g_matBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 g_matCloudTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseCoords : TEXCOORD0; + float2 cloudAlphaCoords : TEXCOORD1; + float fogFactor : TEXCOORD2; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + o.projPos = mul( v.vPos, cModelViewProj ); + + // Compute fog based on the position + float3 vWorldPos = mul( v.vPos, cModel[0] ); + o.fogFactor = CalcFog( vWorldPos, o.projPos, FOGTYPE_RANGE ); + + // Texture coordinate transforms + o.baseCoords.x = dot( v.vTexCoord0.xyzw, g_matBaseTexCoordTransform[0] ); + o.baseCoords.y = dot( v.vTexCoord0.xyzw, g_matBaseTexCoordTransform[1] ); + o.cloudAlphaCoords.x = dot( v.vTexCoord1.xyzw, g_matCloudTexCoordTransform[0] ); + o.cloudAlphaCoords.y = dot( v.vTexCoord1.xyzw, g_matCloudTexCoordTransform[1] ); + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/debugdepth.cpp b/sp/src/materialsystem/stdshaders/debugdepth.cpp new file mode 100644 index 00000000..65e55e0c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugdepth.cpp @@ -0,0 +1,113 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "shaderlib/cshader.h" +#include "convar.h" +#include "debugdrawdepth_vs20.inc" +#include "debugdrawdepth_ps20.inc" +#include "debugdrawdepth_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_debugdepthmode( "mat_debugdepthmode", "0" ); +static ConVar mat_debugdepthval( "mat_debugdepthval", "128.0f" ); +static ConVar mat_debugdepthvalmax( "mat_debugdepthvalmax", "256.0f" ); + +BEGIN_SHADER_FLAGS( DebugDepth, "Help for DebugDepth", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_INIT + { + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { +// Assert( 0 ); + return "WireFrame"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( debugdrawdepth_vs20 ); + SET_STATIC_VERTEX_SHADER( debugdrawdepth_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( debugdrawdepth_ps20b ); + SET_STATIC_PIXEL_SHADER( debugdrawdepth_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( debugdrawdepth_ps20 ); + SET_STATIC_PIXEL_SHADER( debugdrawdepth_ps20 ); + } + } + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( debugdrawdepth_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, s_pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( debugdrawdepth_vs20 ); + + Vector4D vecZFilter( 0, 0, 0, 1 ); + int nDepthMode = mat_debugdepthmode.GetInt(); + if ( nDepthMode > 1 ) + { + nDepthMode = 0; + } + + vecZFilter[nDepthMode] = 1; + s_pShaderAPI->SetPixelShaderConstant( 1, vecZFilter.Base() ); + + Vector4D vecModulationColor( 0, 0, 0, 1 ); + if ( IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) + { + vecModulationColor[0] = 0; + vecModulationColor[1] = 1; + vecModulationColor[2] = 1; + } + else + { + vecModulationColor[0] = 1; + vecModulationColor[1] = 1; + vecModulationColor[2] = 1; + } + s_pShaderAPI->SetPixelShaderConstant( 2, vecModulationColor.Base() ); + + float flDepthFactor = mat_debugdepthval.GetFloat(); + float flDepthFactorMax = mat_debugdepthvalmax.GetFloat(); + if ( flDepthFactor == 0 ) + { + flDepthFactor = 1.0f; + } + Vector4D vecZFactor( (flDepthFactorMax - flDepthFactor), flDepthFactor, 1, 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, vecZFactor.Base() ); + } + Draw(); + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/debugluxel.cpp b/sp/src/materialsystem/stdshaders/debugluxel.cpp new file mode 100644 index 00000000..b3135fcb --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugluxel.cpp @@ -0,0 +1,140 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "shaderlib/cshader.h" + +#define USE_NEW_SHADER //Updating assembly shaders to fxc, this is for A/B testing. + +#ifdef USE_NEW_SHADER + +#include "unlitgeneric_vs20.inc" +#include "unlitgeneric_ps20.inc" +#include "unlitgeneric_ps20b.inc" + +#endif + + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_SHADER_FLAGS( DebugLuxels, "Help for DebugLuxels", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( NOSCALE, SHADER_PARAM_TYPE_BOOL, "0", "fixme" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } +#endif +} + +SHADER_INIT +{ + LoadTexture( BASETEXTURE ); +} + +SHADER_DRAW +{ + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + if (IS_FLAG_SET(MATERIAL_VAR_TRANSLUCENT)) + { + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + else + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + bool bVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); + + DECLARE_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bVertexColor ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); + } + } +#endif + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + int texCoordScaleX = 1, texCoordScaleY = 1; + if (!params[NOSCALE]->GetIntValue()) + { + pShaderAPI->GetLightmapDimensions( &texCoordScaleX, &texCoordScaleY ); + } + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + float vVertexColor[4] = { IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) ? 1.0f : 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, vVertexColor, 1 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); + } + + //texture scale transform + Vector4D transformation[2]; + transformation[0].Init( (float)texCoordScaleX, 0.0f, 0.0f, 0.0f ); + transformation[1].Init( 0.0f, (float)texCoordScaleY, 0.0f, 0.0f ); + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, transformation[0].Base(), 2 ); + } + else +#endif + { + if (!params[NOSCALE]->GetIntValue()) + { + pShaderAPI->MatrixMode( MATERIAL_TEXTURE0 ); + pShaderAPI->LoadIdentity( ); + pShaderAPI->ScaleXY( texCoordScaleX, texCoordScaleY ); + } + } + } + Draw(); +} +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/debugmodifyvertex.cpp b/sp/src/materialsystem/stdshaders/debugmodifyvertex.cpp new file mode 100644 index 00000000..c497ca95 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugmodifyvertex.cpp @@ -0,0 +1,93 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: This is an example of a material that modifies vertex data +// in the shader. NOTE: Every pass is given a clean set of vertex data. +// Modifications made in the first pass are *not* carried over to the next pass +// Modifications must take place during the DYNAMIC_STATE block. +// Use the function MeshBuilder() to build the mesh +// +// Also note: Using thie feature is *really expensive*! It makes a copy of +// the vertex data *per pass!* If you wish to modify vertex data to be used +// with all passes, your best bet is to construct a dynamic mesh instead. +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_SHADER_FLAGS( DebugModifyVertex, "Help for DebugModifyVertex", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( WAVE, SHADER_PARAM_TYPE_FLOAT, "1.0", "wave amplitude" ) + END_SHADER_PARAMS + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + if( g_pHardwareConfig->GetSamplerCount() >= 2 ) + { + // lightmap + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableVertexDataPreprocess( true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + float amp = params[WAVE]->GetFloatValue(); + float currTime = pShaderAPI->CurrentTime(); + for (int i = 0; i < MeshBuilder()->NumVertices(); ++i) + { + float const* pPos = MeshBuilder()->Position(); + MeshBuilder()->Position3f( pPos[0] + amp * sin( currTime + pPos[2] / 4 ), + pPos[1] + amp * sin( currTime + pPos[2] / 4 + 2 * 3.14 / 3 ), + pPos[2] + amp * sin( currTime + pPos[2] / 4 + 4 * 3.14 / 3 ) ); + MeshBuilder()->AdvanceVertex(); + } + } + Draw(); + + // base * vertex color + SHADOW_STATE + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR | + SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + // Notice here that since we didn't modify the position, and this is a second + // pass, the position has been reset to it's initial, unmodified position + float currTime = pShaderAPI->CurrentTime(); + for (int i = 0; i < MeshBuilder()->NumVertices(); ++i) + { + float const* pPos = MeshBuilder()->Position(); + MeshBuilder()->Color3f( ( sin( currTime + pPos[0] ) + 1.0F) * 0.5, + ( sin( currTime + pPos[1] ) + 1.0F) * 0.5, + ( sin( currTime + pPos[2] ) + 1.0F) * 0.5 ); + MeshBuilder()->AdvanceVertex(); + } + } + Draw(); + } + else + { + ShaderWarning( "DebugModifyVertex: not " + "implemented for single-texturing hardware\n" ); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp b/sp/src/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp new file mode 100644 index 00000000..2f5c6a8e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp @@ -0,0 +1,64 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "debugmorphaccumulator_ps30.inc" +#include "debugmorphaccumulator_vs30.inc" + +BEGIN_VS_SHADER_FLAGS( DebugMorphAccumulator, "Help for Debug Morph Accumulator", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableDepthTest( false ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableCulling( false ); + pShaderShadow->FogMode( SHADER_FOGMODE_DISABLED ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBWrite( false ); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); + SET_STATIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); + SET_STATIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + + DECLARE_DYNAMIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( debugmorphaccumulator_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); + SET_DYNAMIC_PIXEL_SHADER( debugmorphaccumulator_ps30 ); + } + Draw( ); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc b/sp/src/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc new file mode 100644 index 00000000..b479085c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc @@ -0,0 +1,16 @@ +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float2 vTexCoord : TEXCOORD0; +}; + +sampler MorphAccumulator : register( s0 ); + +HALF4 main( PS_INPUT i ) : COLOR +{ + float4 vDeltas = tex2D( MorphAccumulator, i.vTexCoord ); + return float4( abs( vDeltas.x ), abs( vDeltas.z ), abs( vDeltas.y ) + abs( vDeltas.w ), 1.0f ); +} + diff --git a/sp/src/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc b/sp/src/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc new file mode 100644 index 00000000..4ff8a742 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc @@ -0,0 +1,23 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.vProjPos = mul( v.vPos, cModelViewProj ); + o.vTexCoord = v.vTexCoord; + + return o; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/debugmrttexture.cpp b/sp/src/materialsystem/stdshaders/debugmrttexture.cpp new file mode 100644 index 00000000..04a1128e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugmrttexture.cpp @@ -0,0 +1,86 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "debugmrttexture_ps20.inc" +#include "debugmrttexture_ps20b.inc" +#include "debugmrttexture_vs20.inc" + +BEGIN_VS_SHADER_FLAGS( DebugMRTTexture, "Help for DebugMRTTexture", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( MRTINDEX, SHADER_PARAM_TYPE_INTEGER, "", "" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { +// if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) +// { +// return "UnlitGeneric_DX8"; +// } + return 0; + } + + SHADER_INIT_PARAMS() + { + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + DECLARE_STATIC_VERTEX_SHADER( debugmrttexture_vs20 ); + SET_STATIC_VERTEX_SHADER( debugmrttexture_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( debugmrttexture_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( MRTINDEX, params[MRTINDEX]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER( debugmrttexture_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( debugmrttexture_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( MRTINDEX, params[MRTINDEX]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER( debugmrttexture_ps20 ); + } + + int numTexCoords = 2; + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, numTexCoords, 0, 0 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + DECLARE_DYNAMIC_VERTEX_SHADER( debugmrttexture_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( debugmrttexture_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( debugmrttexture_ps20 ); + } + } + Draw(); + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/debugmrttexture_ps2x.fxc b/sp/src/materialsystem/stdshaders/debugmrttexture_ps2x.fxc new file mode 100644 index 00000000..7764e529 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugmrttexture_ps2x.fxc @@ -0,0 +1,26 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "MRTINDEX" "0..1" + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; +}; + +sampler BaseTextureSampler1 : register( s0 ); +sampler BaseTextureSampler2 : register( s1 ); + +float4 main( PS_INPUT i ) : COLOR +{ +#if MRTINDEX == 0 + float4 result = tex2D( BaseTextureSampler1, i.baseTexCoord ); +#else + float4 result = tex2D( BaseTextureSampler2, i.baseTexCoord ); +#endif + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} + diff --git a/sp/src/materialsystem/stdshaders/debugmrttexture_vs20.fxc b/sp/src/materialsystem/stdshaders/debugmrttexture_vs20.fxc new file mode 100644 index 00000000..db5c4863 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugmrttexture_vs20.fxc @@ -0,0 +1,29 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 baseTexCoord : TEXCOORD0; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 projPos; + float3 worldPos; + + projPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + o.projPos = projPos; + + o.baseTexCoord = v.vBaseTexCoord; + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/debugnormalmap.cpp b/sp/src/materialsystem/stdshaders/debugnormalmap.cpp new file mode 100644 index 00000000..0be5246a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugnormalmap.cpp @@ -0,0 +1,148 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#define USE_NEW_SHADER //Updating assembly shaders to fxc, this is for A/B testing. + + + +#ifdef USE_NEW_SHADER + +#include "unlitgeneric_vs20.inc" +#include "unlitgeneric_ps20.inc" +#include "unlitgeneric_ps20b.inc" + +#endif + +#include "unlitgeneric_vs11.inc" + + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER_FLAGS( DebugNormalMap, "Help for DebugNormalMap", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldDiffuseBumpMap_bump", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_INIT + { + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + { +// Assert( 0 ); + return "Wireframe"; + } + return 0; + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + DECLARE_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, 0 ); + SET_STATIC_VERTEX_SHADER( unlitgeneric_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_ps20 ); + } + } + else +#endif + { + unlitgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( false ); + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + vshIndex.SetVERTEXCOLOR( false ); + vshIndex.SetSEPARATEDETAILUVS( false ); + pShaderShadow->SetVertexShader( "unlitgeneric_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "unlitgeneric" ); + } + } + DYNAMIC_STATE + { + if ( params[BUMPMAP]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT ); + } + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BUMPTRANSFORM ); +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + float vVertexColor[4] = { 0, 0, 0, 0 }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, vVertexColor, 1 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( unlitgeneric_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_ps20 ); + } + } + else +#endif + { + unlitgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + Draw(); + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/debugsoftwarevertexshader.cpp b/sp/src/materialsystem/stdshaders/debugsoftwarevertexshader.cpp new file mode 100644 index 00000000..be7cedf3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugsoftwarevertexshader.cpp @@ -0,0 +1,56 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ) +{ + float t = pShaderAPI->CurrentTime(); + for( int i = 0; i < meshBuilder.NumVertices(); i++ ) + { + const float *pPos = meshBuilder.Position(); + meshBuilder.Position3f( pPos[0], pPos[1], pPos[2] + 10.0f * sin( t + pPos[0] ) ); + meshBuilder.AdvanceVertex(); + } +} + +FORWARD_DECLARE_SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ); + +BEGIN_SHADER_FLAGS( DebugSoftwareVertexShader, "blah", SHADER_NOT_EDITABLE ) + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/basetexture", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( FRAME, SHADER_PARAM_TYPE_INTEGER, "0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( BASETEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_INIT + { + if( g_pHardwareConfig->SupportsVertexAndPixelShaders() ) + { + USE_SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ); + } + else + { + USE_SOFTWARE_VERTEX_SHADER( myHappyLittleSoftwareVertexShader ); + } + } + SHADER_DRAW + { + SHADOW_STATE + { + } + DYNAMIC_STATE + { + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/debugtangentspace.cpp b/sp/src/materialsystem/stdshaders/debugtangentspace.cpp new file mode 100644 index 00000000..30279012 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugtangentspace.cpp @@ -0,0 +1,133 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +#define USE_NEW_SHADER //Updating assembly shaders to fxc, this is for A/B testing. + +#ifdef USE_NEW_SHADER +#include "debugtangentspace_vs11.inc" +#include "debugtangentspace_vs20.inc" +#include "unlitgeneric_notexture_ps11.inc" +#include "unlitgeneric_notexture_ps20.inc" +#include "unlitgeneric_notexture_ps20b.inc" + +#else +#include "debugtangentspace.inc" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_SHADER( DebugTangentSpace, "Help for DebugTangentSpace" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/basetexture", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( FRAME, SHADER_PARAM_TYPE_INTEGER, "0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( BASETEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + if (g_pHardwareConfig->SupportsVertexAndPixelShaders()) + { + SHADOW_STATE + { + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 0; + int userDataSize = 4; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + DECLARE_STATIC_VERTEX_SHADER( debugtangentspace_vs20 ); + SET_STATIC_VERTEX_SHADER( debugtangentspace_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); + } + } + else + { + DECLARE_STATIC_VERTEX_SHADER( debugtangentspace_vs11 ); + SET_STATIC_VERTEX_SHADER( debugtangentspace_vs11 ); + + DECLARE_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); + SET_STATIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); + } +#else + debugtangentspace_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "DebugTangentSpace", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "UnlitGeneric_NoTexture" ); +#endif + } + DYNAMIC_STATE + { + +#ifdef USE_NEW_SHADER + if( g_pHardwareConfig->GetDXSupportLevel() >= 90 ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps20 ); + } + } + else // legacy hardware + { + DECLARE_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs11 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER( debugtangentspace_vs11 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); + SET_DYNAMIC_PIXEL_SHADER( unlitgeneric_notexture_ps11 ); + } +#else + debugtangentspace_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); +#endif + } + Draw(); + } + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/debugtangentspace.vsh b/sp/src/materialsystem/stdshaders/debugtangentspace.vsh new file mode 100644 index 00000000..cb38a23b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugtangentspace.vsh @@ -0,0 +1,34 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&SkinPositionAndNormal( $worldPos, $worldNormal ); + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +&FreeRegister( \$worldPos ); + +; stick the normal in the color channel +mov oD0.xyz, $worldNormal.xyz +mov oD0.w, $cOne ; make sure all components are defined + +&FreeRegister( \$projPos ); +&FreeRegister( \$worldNormal ); diff --git a/sp/src/materialsystem/stdshaders/debugtangentspace_vs11.fxc b/sp/src/materialsystem/stdshaders/debugtangentspace_vs11.fxc new file mode 100644 index 00000000..1584ef26 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugtangentspace_vs11.fxc @@ -0,0 +1,51 @@ +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float3 vNormal : NORMAL; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + + float4 vDiffuse : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, v.vPos, v.vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + + o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + + o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + // stick the normal in the color channel + o.vDiffuse.rgb = worldNormal; + o.vDiffuse.a = 1.0f; + + return o; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/debugtangentspace_vs20.fxc b/sp/src/materialsystem/stdshaders/debugtangentspace_vs20.fxc new file mode 100644 index 00000000..f829bde9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/debugtangentspace_vs20.fxc @@ -0,0 +1,55 @@ +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + + float4 vDiffuse : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, v.vPos, vObjNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + + o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + + o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + // stick the normal in the color channel + o.vDiffuse.rgb = worldNormal; + o.vDiffuse.a = 1.0f; + + return o; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc b/sp/src/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc new file mode 100644 index 00000000..61daa238 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc @@ -0,0 +1,11 @@ +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float projPosZ : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return FinalOutput( float4( 0, 0, 0, 1.0f ), 0.0f, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE, true, i.projPosZ ); +} diff --git a/sp/src/materialsystem/stdshaders/depthtodestalpha_vs20.fxc b/sp/src/materialsystem/stdshaders/depthtodestalpha_vs20.fxc new file mode 100644 index 00000000..9891502e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/depthtodestalpha_vs20.fxc @@ -0,0 +1,23 @@ +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float4 vPos : POSITION; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float projPosZ : TEXCOORD0; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.vProjPos = mul( v.vPos, cModelViewProj ); + o.projPosZ = o.vProjPos.z; + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/depthwrite.cpp b/sp/src/materialsystem/stdshaders/depthwrite.cpp new file mode 100644 index 00000000..06d7690f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/depthwrite.cpp @@ -0,0 +1,207 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "depthwrite_ps20.inc" +#include "depthwrite_ps20b.inc" +#include "depthwrite_vs20.inc" + +#if !defined( _X360 ) +#include "depthwrite_ps30.inc" +#include "depthwrite_vs30.inc" +#endif + +BEGIN_VS_SHADER_FLAGS( DepthWrite, "Help for Depth Write", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "", "Alpha reference value" ) + SHADER_PARAM( COLOR_DEPTH, SHADER_PARAM_TYPE_BOOL, "0", "Write depth as color") + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Wireframe"; + } + return 0; + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + bool bAlphaClip = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ); + int nColorDepth = GetIntParam( COLOR_DEPTH, params, 0 ); + + SHADOW_STATE + { + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + if ( nColorDepth == 0 ) + { + // Bias primitives when rendering into shadow map so we get slope-scaled depth bias + // rather than having to apply a constant bias in the filtering shader later + pShaderShadow->EnablePolyOffset( SHADER_POLYOFFSET_SHADOW_BIAS ); + } + + // Turn off writes to color buffer since we always sample shadows from the DEPTH texture later + // This gives us double-speed fill when rendering INTO the shadow map + pShaderShadow->EnableColorWrites( ( nColorDepth == 1 ) ); + pShaderShadow->EnableAlphaWrites( false ); + + // Don't backface cull unless alpha clipping, since this can cause artifacts when the + // geometry is clipped by the flashlight near plane + // If a material was already marked nocull, don't cull it + pShaderShadow->EnableCulling( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) && !IS_FLAG_SET(MATERIAL_VAR_NOCULL) ); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_STATIC_VERTEX_SHADER( depthwrite_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( ONLY_PROJECT_POSITION, !bAlphaClip && IsX360() && !nColorDepth ); //360 needs to know if it *shouldn't* output texture coordinates to avoid shader patches + SET_STATIC_VERTEX_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_VERTEX_SHADER( depthwrite_vs20 ); + + if ( bAlphaClip || g_pHardwareConfig->PlatformRequiresNonNullPixelShaders() || nColorDepth ) + { + if( bAlphaClip ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( depthwrite_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_PIXEL_SHADER( depthwrite_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( depthwrite_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_PIXEL_SHADER( depthwrite_ps20 ); + } + } + } +#ifndef _X360 + else + { + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( depthwrite_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( ONLY_PROJECT_POSITION, 0 ); //360 only combo, and this is a PC path + SET_STATIC_VERTEX_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_VERTEX_SHADER( depthwrite_vs30 ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + DECLARE_STATIC_PIXEL_SHADER( depthwrite_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLOR_DEPTH, nColorDepth ); + SET_STATIC_PIXEL_SHADER( depthwrite_ps30 ); + } +#endif + } + DYNAMIC_STATE + { + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + depthwrite_vs20_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetCOMPRESSED_VERTS( (int)vertexCompression ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if ( bAlphaClip ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + float vAlphaThreshold[4] = {0.7f, 0.7f, 0.7f, 0.7f}; + if ( ALPHATESTREFERENCE != -1 && ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) ) + { + vAlphaThreshold[0] = vAlphaThreshold[1] = vAlphaThreshold[2] = vAlphaThreshold[3] = params[ALPHATESTREFERENCE]->GetFloatValue(); + } + + pShaderAPI->SetPixelShaderConstant( 0, vAlphaThreshold, 1 ); + } + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( depthwrite_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); + SET_DYNAMIC_PIXEL_SHADER( depthwrite_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( depthwrite_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); + SET_DYNAMIC_PIXEL_SHADER( depthwrite_ps20 ); + } + } +#ifndef _X360 + else // 3.0 shader case (PC only) + { + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + depthwrite_vs30_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetMORPHING( pShaderAPI->IsHWMorphingEnabled() ); + vshIndex.SetCOMPRESSED_VERTS( (int)vertexCompression ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if ( bAlphaClip ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + float vAlphaThreshold[4] = {0.7f, 0.7f, 0.7f, 0.7f}; + if ( ALPHATESTREFERENCE != -1 && ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) ) + { + vAlphaThreshold[0] = vAlphaThreshold[1] = vAlphaThreshold[2] = vAlphaThreshold[3] = params[ALPHATESTREFERENCE]->GetFloatValue(); + } + + pShaderAPI->SetPixelShaderConstant( 0, vAlphaThreshold, 1 ); + } + + DECLARE_DYNAMIC_PIXEL_SHADER( depthwrite_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( ALPHACLIP, bAlphaClip ); + SET_DYNAMIC_PIXEL_SHADER( depthwrite_ps30 ); + } +#endif + + Vector4D vParms; + + // set up arbitrary far planes, as the real ones are too far ( 30,000 ) +// pShaderAPI->SetPSNearAndFarZ( 1 ); + vParms.x = 7.0f; // arbitrary near + vParms.y = 4000.0f; // arbitrary far + vParms.z = 0.0f; + vParms.w = 0.0f; + pShaderAPI->SetPixelShaderConstant( 1, vParms.Base(), 2 ); + + } // DYNAMIC_STATE + + Draw( ); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/depthwrite_ps2x.fxc b/sp/src/materialsystem/stdshaders/depthwrite_ps2x.fxc new file mode 100644 index 00000000..1baabcf3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/depthwrite_ps2x.fxc @@ -0,0 +1,44 @@ +// STATIC: "COLOR_DEPTH" "0..1" + +// DYNAMIC: "ALPHACLIP" "0..1" + +const float g_AlphaThreshold : register( c0 ); + +const float2 g_vNearFarPlanes : register( c1 ); + #define g_flNearPlane g_vNearFarPlanes.x + #define g_flFarPlane g_vNearFarPlanes.y + +struct PS_INPUT +{ +#if ALPHACLIP + float2 texCoord0 : TEXCOORD0; +#endif + +#if COLOR_DEPTH + float4 vWorldPos_projPosZ : TEXCOORD1; +#endif +}; + +sampler BaseTextureSampler : register( s0 ); + +float4 main( PS_INPUT i ) : COLOR +{ + float4 color = float4( 1, 0, 0, 1 ); // opaque alpha....the color doesn't matter for this shader + +#if ALPHACLIP + color = tex2D( BaseTextureSampler, i.texCoord0 ); + + clip( color.a - g_AlphaThreshold ); + +#endif + +#if ( COLOR_DEPTH == 1 ) + + return float4( i.vWorldPos_projPosZ.w / g_flFarPlane, 0.0, 0.0, 1.0 ); + +#else + + return color; + +#endif +} diff --git a/sp/src/materialsystem/stdshaders/depthwrite_vs20.fxc b/sp/src/materialsystem/stdshaders/depthwrite_vs20.fxc new file mode 100644 index 00000000..f98e40e2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/depthwrite_vs20.fxc @@ -0,0 +1,83 @@ +// STATIC: "ONLY_PROJECT_POSITION" "0..1" [XBOX] +// STATIC: "ONLY_PROJECT_POSITION" "0..0" [PC] +// STATIC: "COLOR_DEPTH" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord : TEXCOORD0; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + + // Position delta stream + float3 vPosFlex : POSITION1; + +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + +#if (ONLY_PROJECT_POSITION == 0) //360 sometimes runs without the pixel shader component, but has to patch this output if it does. + float2 texCoord : TEXCOORD0; +#endif + +#if COLOR_DEPTH + float4 vWorldPos_projPosZ : TEXCOORD1; +#endif + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + float3 vWorldPos; + float4 vPosition = v.vPos; + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, vPosition.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, float3(0, 0, 0), vPosition.xyz ); +#endif + + SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, vWorldPos ); + + float4 vProjPos = mul( float4( vWorldPos, 1.0f ), cViewProj ); + + o.vProjPos = vProjPos; + +#if (ONLY_PROJECT_POSITION == 0) + o.texCoord = v.vTexCoord; +#endif + +#if ( COLOR_DEPTH && !ONLY_PROJECT_POSITION ) + o.vWorldPos_projPosZ.z = vProjPos.z; + o.vWorldPos_projPosZ.w = vProjPos.w; +#endif + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/detail.cpp b/sp/src/materialsystem/stdshaders/detail.cpp new file mode 100644 index 00000000..956bf518 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/detail.cpp @@ -0,0 +1,37 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Detail, "Help for Detail" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + } + + SHADER_FALLBACK + { + return "UnlitGeneric"; + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + } + +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/detail_ps11.psh b/sp/src/materialsystem/stdshaders/detail_ps11.psh new file mode 100644 index 00000000..fb5916ab --- /dev/null +++ b/sp/src/materialsystem/stdshaders/detail_ps11.psh @@ -0,0 +1,12 @@ +ps.1.1 + +tex t0 +tex t1 + +mul r0.rgb, t0, v0 + + +; handle distance fade +sub r0.a, t0.a, 1-v0.a + +sub r0.a, r0.a, t1_bias.a +cnd r0.a, r0.a, c0.a, c1.a diff --git a/sp/src/materialsystem/stdshaders/detail_vs11.vsh b/sp/src/materialsystem/stdshaders/detail_vs11.vsh new file mode 100644 index 00000000..28dee2fd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/detail_vs11.vsh @@ -0,0 +1,56 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +dp4 $worldPos.x, $vPos, $cModel0 +dp4 $worldPos.y, $vPos, $cModel1 +dp4 $worldPos.z, $vPos, $cModel2 +mov $worldPos.w, $cOne + + +;------------------------------------------------------------------------------ +; Transform the position from world to proj space +;------------------------------------------------------------------------------ +&AllocateRegister( \$projPos ); +dp4 $projPos.x, $vPos, $cModelViewProj0 +dp4 $projPos.y, $vPos, $cModelViewProj1 +dp4 $projPos.z, $vPos, $cModelViewProj2 +dp4 $projPos.w, $vPos, $cModelViewProj3 +mov oPos, $projPos + + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); +&FreeRegister( \$worldPos ); + + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ +mov oT0.xy, $vTexCoord0.xy + +; special case perspective correct texture projection so that the texture fits exactly on the screen +mul $projPos.y, $projPos.y, $SHADER_SPECIFIC_CONST_0.w +add $projPos.xy, $projPos.xy, $projPos.w +mul $projPos.xy, $projPos.xy, $cHalf +mul $projPos.xy, $projPos.xy, $SHADER_SPECIFIC_CONST_0.xy +mad $projPos.xy, $projPos.w, $SHADER_SPECIFIC_CONST_1.xy, $projPos.xy + +mov oT1.xy, $projPos.xy +mov oT1.z, $projPos.w +mov oT1.w, $projPos.w + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Modulation color +;------------------------------------------------------------------------------ +mov oD0, $vColor diff --git a/sp/src/materialsystem/stdshaders/eye_refract.cpp b/sp/src/materialsystem/stdshaders/eye_refract.cpp new file mode 100644 index 00000000..87528028 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eye_refract.cpp @@ -0,0 +1,253 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "eye_refract_helper.h" +#include "cloak_blended_pass_helper.h" +#include "emissive_scroll_blended_pass_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( EyeRefract, EyeRefract_dx9 ) +BEGIN_VS_SHADER( EyeRefract_dx9, "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( CORNEATEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "cornea texture" ) + SHADER_PARAM( AMBIENTOCCLTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "reflection texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + + SHADER_PARAM( EYEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "origin 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( DILATION, SHADER_PARAM_TYPE_FLOAT, "0", "Pupil dilation (0 is none, 1 is maximal)" ) + SHADER_PARAM( GLOSSINESS, SHADER_PARAM_TYPE_FLOAT, "1", "Glossiness of eye (1 is default, 0 is not glossy at all)" ) + SHADER_PARAM( SPHERETEXKILLCOMBO, SHADER_PARAM_TYPE_BOOL, "1", "texkill pixels not on sphere" ) + SHADER_PARAM( RAYTRACESPHERE, SHADER_PARAM_TYPE_BOOL, "1", "Raytrace sphere" ) + SHADER_PARAM( PARALLAXSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1", "Parallax strength" ) + SHADER_PARAM( CORNEABUMPSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1", "Cornea strength" ) + + SHADER_PARAM( AMBIENTOCCLCOLOR, SHADER_PARAM_TYPE_VEC3, "[1 1 1]", "Ambient occlusion color" ) + SHADER_PARAM( EYEBALLRADIUS, SHADER_PARAM_TYPE_FLOAT, "0", "Eyeball radius for ray casting" ) + + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is eyes in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + + // Emissive Scroll Pass + SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) + SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) + SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) + SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( EMISSIVEBLENDFLOWTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "flow map" ) + END_SHADER_PARAMS + + void SetupVarsEyeRefract( Eye_Refract_Vars_t &info ) + { + info.m_nFrame = FRAME; + info.m_nIris = IRIS; + info.m_nIrisFrame = IRISFRAME; + info.m_nEyeOrigin = EYEORIGIN; + info.m_nIrisU = IRISU; + info.m_nIrisV = IRISV; + info.m_nDilation = DILATION; + info.m_nGlossiness = GLOSSINESS; + info.m_nIntro = INTRO; + info.m_nEntityOrigin = ENTITYORIGIN; + info.m_nWarpParam = WARPPARAM; + info.m_nCorneaTexture = CORNEATEXTURE; + info.m_nAmbientOcclTexture = AMBIENTOCCLTEXTURE; + info.m_nEnvmap = ENVMAP; + info.m_nSphereTexKillCombo = SPHERETEXKILLCOMBO; + info.m_nRaytraceSphere = RAYTRACESPHERE; + info.m_nParallaxStrength = PARALLAXSTRENGTH; + info.m_nCorneaBumpStrength = CORNEABUMPSTRENGTH; + info.m_nAmbientOcclColor = AMBIENTOCCLCOLOR; + info.m_nEyeballRadius = EYEBALLRADIUS; + info.m_nDiffuseWarpTexture = LIGHTWARPTEXTURE; + } + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + // Emissive Scroll Pass + void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) + { + info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; + info.m_nBaseTexture = IRIS; + info.m_nFlowTexture = EMISSIVEBLENDFLOWTEXTURE; + info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; + info.m_nEmissiveTint = EMISSIVEBLENDTINT; + info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; + } + + SHADER_INIT_PARAMS() + { + Eye_Refract_Vars_t info; + SetupVarsEyeRefract( info ); + InitParams_Eyes_Refract( this, params, pMaterialName, info ); + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + + // Emissive Scroll Pass + if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) + { + params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); + } + else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); + } + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Eyes_dx8"; + } + + return 0; + } + + SHADER_INIT + { + Eye_Refract_Vars_t info; + SetupVarsEyeRefract( info ); + Init_Eyes_Refract( this, params, info ); + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitEmissiveScrollBlendedPass( this, params, info ); + } + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardEye = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + bDrawStandardEye = false; + } + } + + // Standard rendering pass + if ( bDrawStandardEye ) + { + Eye_Refract_Vars_t info; + SetupVarsEyeRefract( info ); + Draw_Eyes_Refract( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/eye_refract_helper.cpp b/sp/src/materialsystem/stdshaders/eye_refract_helper.cpp new file mode 100644 index 00000000..af4d2c08 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eye_refract_helper.cpp @@ -0,0 +1,461 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "eye_refract_helper.h" + +#include "cpp_shader_constant_register_map.h" + +#include "eyes_flashlight_vs11.inc" +#include "eyes_flashlight_ps11.inc" + +#include "eye_refract_vs20.inc" +#include "eye_refract_ps20.inc" +#include "eye_refract_ps20b.inc" + +#ifndef _X360 +#include "eye_refract_vs30.inc" +#include "eye_refract_ps30.inc" +#endif + +#include "convar.h" + +static ConVar r_lightwarpidentity( "r_lightwarpidentity","0", FCVAR_CHEAT ); + +void InitParams_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Eye_Refract_Vars_t &info ) +{ + // FLASHLIGHTFIXME + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + + // Set material flags + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + // Set material parameter default values + if ( ( info.m_nIntro >= 0 ) && ( !params[info.m_nIntro]->IsDefined() ) ) + { + params[info.m_nIntro]->SetIntValue( kDefaultIntro ); + } + + if ( ( info.m_nDilation >= 0 ) && ( !params[info.m_nDilation]->IsDefined() ) ) + { + params[info.m_nDilation]->SetFloatValue( kDefaultDilation ); + } + + if ( ( info.m_nGlossiness >= 0 ) && ( !params[info.m_nGlossiness]->IsDefined() ) ) + { + params[info.m_nGlossiness]->SetFloatValue( kDefaultGlossiness ); + } + + if ( ( info.m_nSphereTexKillCombo >= 0 ) && ( !params[info.m_nSphereTexKillCombo]->IsDefined() ) ) + { + params[info.m_nSphereTexKillCombo]->SetIntValue( kDefaultSphereTexKillCombo ); + } + + if ( ( info.m_nRaytraceSphere >= 0 ) && ( !params[info.m_nRaytraceSphere]->IsDefined() ) ) + { + params[info.m_nRaytraceSphere]->SetIntValue( kDefaultRaytraceSphere ); + } + + if ( ( info.m_nAmbientOcclColor >= 0 ) && ( !params[info.m_nAmbientOcclColor]->IsDefined() ) ) + { + params[info.m_nAmbientOcclColor]->SetVecValue( kDefaultAmbientOcclColor, 4 ); + } + + if ( ( info.m_nEyeballRadius >= 0 ) && ( !params[info.m_nEyeballRadius]->IsDefined() ) ) + { + params[info.m_nEyeballRadius]->SetFloatValue( kDefaultEyeballRadius ); + } + + if ( ( info.m_nParallaxStrength >= 0 ) && ( !params[info.m_nParallaxStrength]->IsDefined() ) ) + { + params[info.m_nParallaxStrength]->SetFloatValue( kDefaultParallaxStrength ); + } + + if ( ( info.m_nCorneaBumpStrength >= 0 ) && ( !params[info.m_nCorneaBumpStrength]->IsDefined() ) ) + { + params[info.m_nCorneaBumpStrength]->SetFloatValue( kDefaultCorneaBumpStrength ); + } +} + +void Init_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, Eye_Refract_Vars_t &info ) +{ + pShader->LoadTexture( info.m_nCorneaTexture ); // SHADER_SAMPLER0 (this is a normal, hence not sRGB) + pShader->LoadTexture( info.m_nIris, TEXTUREFLAGS_SRGB ); // SHADER_SAMPLER1 + pShader->LoadCubeMap( info.m_nEnvmap, TEXTUREFLAGS_SRGB ); // SHADER_SAMPLER2 + pShader->LoadTexture( info.m_nAmbientOcclTexture, TEXTUREFLAGS_SRGB ); // SHADER_SAMPLER3 + + if ( IS_PARAM_DEFINED( info.m_nDiffuseWarpTexture ) ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); // SHADER_SAMPLER4 + } + + pShader->LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); // SHADER_SAMPLER5 +} + +void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, bool bDrawFlashlightAdditivePass, Eye_Refract_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + bool bDiffuseWarp = IS_PARAM_DEFINED( info.m_nDiffuseWarpTexture ); + bool bIntro = IS_PARAM_DEFINED( info.m_nIntro ) ? ( params[info.m_nIntro]->GetIntValue() ? true : false ) : false; + + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Cornea normal + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Iris + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Cube reflection + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Ambient occlusion + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + if ( bDiffuseWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Light warp + } + + int nShadowFilterMode = 0; + if ( bDrawFlashlightAdditivePass == true ) + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + + pShaderShadow->EnableDepthWrites( false ); + pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Write over the eyes that were already there + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Flashlight cookie + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_STATIC_VERTEX_SHADER( eye_refract_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, bIntro ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( eye_refract_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + bool bSphereTexKillCombo = IS_PARAM_DEFINED( info.m_nSphereTexKillCombo ) ? ( params[info.m_nSphereTexKillCombo]->GetIntValue() ? true : false ) : ( kDefaultSphereTexKillCombo ? true : false ); + bool bRayTraceSphere = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? ( params[info.m_nRaytraceSphere]->GetIntValue() ? true : false ) : ( kDefaultRaytraceSphere ? true : false ); + + DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( SPHERETEXKILLCOMBO, bSphereTexKillCombo ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( RAYTRACESPHERE, bRayTraceSphere ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( eye_refract_ps20b ); + + if ( bDrawFlashlightAdditivePass == true ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER6 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Noise map + } + } + else + { + DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER( eye_refract_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( eye_refract_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, bIntro ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( eye_refract_vs30 ); + + bool bSphereTexKillCombo = IS_PARAM_DEFINED( info.m_nSphereTexKillCombo ) ? ( params[info.m_nSphereTexKillCombo]->GetIntValue() ? true : false ) : ( kDefaultSphereTexKillCombo ? true : false ); + bool bRayTraceSphere = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? ( params[info.m_nRaytraceSphere]->GetIntValue() ? true : false ) : ( kDefaultRaytraceSphere ? true : false ); + + DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( SPHERETEXKILLCOMBO, bSphereTexKillCombo ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( RAYTRACESPHERE, bRayTraceSphere ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( eye_refract_ps30 ); + + if ( bDrawFlashlightAdditivePass == true ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Shadow depth map + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Noise map + } + } +#endif + + // On DX9, get the gamma read and write correct + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // Iris + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); // Cube map reflection + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); // Ambient occlusion + pShaderShadow->EnableSRGBWrite( true ); + + if ( bDrawFlashlightAdditivePass == true ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true ); // Flashlight cookie + } + + // Fog + if ( bDrawFlashlightAdditivePass == true ) + { + pShader->FogToBlack(); + } + else + { + pShader->FogToFogColor(); + } + } + DYNAMIC_STATE + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture = NULL; + FlashlightState_t flashlightState; + bool bFlashlightShadows = false; + if ( bDrawFlashlightAdditivePass == true ) + { + flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + } + + pShader->BindTexture( SHADER_SAMPLER0, info.m_nCorneaTexture ); // Cornea normal + pShader->BindTexture( SHADER_SAMPLER1, info.m_nIris, info.m_nIrisFrame ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nEnvmap ); + pShader->BindTexture( SHADER_SAMPLER3, info.m_nAmbientOcclTexture ); + + if ( bDiffuseWarp ) + { + if ( r_lightwarpidentity.GetBool() ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_IDENTITY_LIGHTWARP ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER4, info.m_nDiffuseWarpTexture ); + } + } + + if ( bDrawFlashlightAdditivePass == true ) + pShader->BindTexture( SHADER_SAMPLER5, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + pShader->SetAmbientCubeDynamicStateVertexShader(); + + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nEyeOrigin ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nIrisU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nIrisV ); + + if ( bDrawFlashlightAdditivePass == true ) + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, flashlightState.m_vecLightOrigin.Base(), 1 ); + + LightState_t lightState = { 0, false, false }; + if ( bDrawFlashlightAdditivePass == false ) + { + pShaderAPI->GetDX9LightState( &lightState ); + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_DYNAMIC_VERTEX_SHADER( eye_refract_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eye_refract_vs20 ); + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( eye_refract_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eye_refract_vs30 ); + } +#endif + + // Get luminance of ambient cube and saturate it + float fAverageAmbient = max(0.0f, min( pShaderAPI->GetAmbientLightCubeLuminance(), 1.0f ) ); + + // Special constant for DX9 eyes: { Dilation, Glossiness, x, x }; + float vPSConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPSConst[0] = IS_PARAM_DEFINED( info.m_nDilation ) ? params[info.m_nDilation]->GetFloatValue() : kDefaultDilation; + vPSConst[1] = IS_PARAM_DEFINED( info.m_nGlossiness ) ? params[info.m_nGlossiness]->GetFloatValue() : kDefaultGlossiness; + vPSConst[2] = fAverageAmbient; + vPSConst[3] = IS_PARAM_DEFINED( info.m_nCorneaBumpStrength ) ? params[info.m_nCorneaBumpStrength]->GetFloatValue() : kDefaultCorneaBumpStrength; + pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); + + pShaderAPI->SetPixelShaderConstant( 1, IS_PARAM_DEFINED( info.m_nEyeOrigin ) ? params[info.m_nEyeOrigin]->GetVecValue() : kDefaultEyeOrigin, 1 ); + pShaderAPI->SetPixelShaderConstant( 2, IS_PARAM_DEFINED( info.m_nIrisU ) ? params[info.m_nIrisU]->GetVecValue() : kDefaultIrisU, 1 ); + pShaderAPI->SetPixelShaderConstant( 3, IS_PARAM_DEFINED( info.m_nIrisV ) ? params[info.m_nIrisV]->GetVecValue() : kDefaultIrisV, 1 ); + + float vEyePos[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + pShaderAPI->SetPixelShaderConstant( 4, vEyePos, 1 ); + pShaderAPI->SetPixelShaderConstant( 5, IS_PARAM_DEFINED( info.m_nAmbientOcclColor ) ? params[info.m_nAmbientOcclColor]->GetVecValue() : kDefaultAmbientOcclColor, 1 ); + + float vPackedConst6[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + //vPackedConst6[0] Unused + vPackedConst6[1] = IS_PARAM_DEFINED( info.m_nEyeballRadius ) ? params[info.m_nEyeballRadius]->GetFloatValue() : kDefaultEyeballRadius; + //vPackedConst6[2] = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? params[info.m_nRaytraceSphere]->GetFloatValue() : kDefaultRaytraceSphere; + vPackedConst6[3] = IS_PARAM_DEFINED( info.m_nParallaxStrength ) ? params[info.m_nParallaxStrength]->GetFloatValue() : kDefaultParallaxStrength; + pShaderAPI->SetPixelShaderConstant( 6, vPackedConst6, 1 ); + + float fPixelFogType = pShaderAPI->GetPixelFogCombo() == 1 ? 1 : 0; + + // Controls for lerp-style paths through shader code + float vShaderControls[4] = { fPixelFogType, 0, 0, 0 }; + pShaderAPI->SetPixelShaderConstant( 10, vShaderControls, 1 ); + + if ( bDrawFlashlightAdditivePass == true ) + { + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + if ( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER6, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER7, TEXTURE_SHADOW_NOISE_2D ); + } + } + + // Flashlight tax +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps20b ); + } + else // ps.2.0 + { + DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps20 ); + } + } +#ifndef _X360 + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps30 ); + } +#endif + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + if ( bDrawFlashlightAdditivePass == true ) + { + float atten[4], pos[4], tweaks[4]; + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( 7, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( 8, pos, 1 ); + + //pShaderAPI->SetPixelShaderConstant( 9, worldToTexture.Base(), 4 ); + //10 + //11 + //12 + + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture[0], 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, worldToTexture[1], 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, worldToTexture[2], 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, worldToTexture[3], 1 ); + + // Tweaks associated with a given flashlight + tweaks[0] = flashlightState.m_flShadowFilterSize / flashlightState.m_flShadowMapResolution; + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( 9, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + } + else // Lighting constants when not drawing flashlight + { + pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); + } + + // Intro tax + if ( bIntro ) + { + float curTime = params[info.m_nWarpParam]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + if ( IS_PARAM_DEFINED( info.m_nEntityOrigin ) ) + { + params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, timeVec, 1 ); + } + } + pShader->Draw(); +} + + +extern ConVar r_flashlight_version2; +void Draw_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eye_Refract_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + Draw_Eyes_Refract_Internal( pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression ); + if ( pShaderShadow ) + { + pShader->SetInitialShadowState( ); + } + } + Draw_Eyes_Refract_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression ); +} diff --git a/sp/src/materialsystem/stdshaders/eye_refract_helper.h b/sp/src/materialsystem/stdshaders/eye_refract_helper.h new file mode 100644 index 00000000..ce62a33b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eye_refract_helper.h @@ -0,0 +1,69 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef EYE_REFRACT_HELPER_H +#define EYE_REFRACT_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct Eye_Refract_Vars_t +{ + Eye_Refract_Vars_t() { memset( this, 0xFF, sizeof(Eye_Refract_Vars_t) ); } + + int m_nFrame; + int m_nIris; + int m_nIrisFrame; + int m_nEyeOrigin; + int m_nIrisU; + int m_nIrisV; + int m_nDilation; + int m_nGlossiness; + int m_nIntro; + int m_nEntityOrigin; // Needed for intro + int m_nWarpParam; + int m_nCorneaTexture; + int m_nAmbientOcclTexture; + int m_nEnvmap; + int m_nSphereTexKillCombo; + int m_nRaytraceSphere; + int m_nParallaxStrength; + int m_nCorneaBumpStrength; + int m_nAmbientOcclColor; + int m_nEyeballRadius; + int m_nDiffuseWarpTexture; +}; + +// Default values (Arrays should only be vec[4]) +static const int kDefaultIntro = 0; +static const float kDefaultEyeOrigin[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; +static const float kDefaultIrisU[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; +static const float kDefaultIrisV[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; +static const float kDefaultDilation = 0.5f; +static const float kDefaultGlossiness = 1.0f; +static const float kDefaultWarpParam = 0.0f; +static const int kDefaultSphereTexKillCombo = 0; +static const int kDefaultRaytraceSphere = 0; +static const float kDefaultParallaxStrength = 0.25f; +static const float kDefaultCorneaBumpStrength = 1.0f; +static const float kDefaultAmbientOcclColor[4] = { 0.33f, 0.33f, 0.33f, 0.0f }; +static const float kDefaultEyeballRadius = 0.5f; + +void InitParams_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Eye_Refract_Vars_t &info ); +void Init_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, Eye_Refract_Vars_t &info ); +void Draw_Eyes_Refract( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eye_Refract_Vars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // EYES_DX8_DX9_HELPER_H diff --git a/sp/src/materialsystem/stdshaders/eye_refract_ps2x.fxc b/sp/src/materialsystem/stdshaders/eye_refract_ps2x.fxc new file mode 100644 index 00000000..da053d22 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eye_refract_ps2x.fxc @@ -0,0 +1,494 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =========================== + +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" + +// STATIC: "SPHERETEXKILLCOMBO" "0..1" [ps20b] +// STATIC: "SPHERETEXKILLCOMBO" "0..1" [ps30] + +// STATIC: "RAYTRACESPHERE" "0..1" [ps20b] +// STATIC: "RAYTRACESPHERE" "0..1" [ps30] + +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] + +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] + +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +// We don't use other lights when doing the flashlight +// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// SKIP: ( $RAYTRACESPHERE == 0 ) && ( $SPHERETEXKILLCOMBO == 1 ) [ps30] +// SKIP: ( $RAYTRACESPHERE == 0 ) && ( $SPHERETEXKILLCOMBO == 1 ) [ps20b] + +// Debug 2.0 shader locally +//#ifdef SHADER_MODEL_PS_2_B +//#undef SHADER_MODEL_PS_2_B +//#define SHADER_MODEL_PS_2_0 +//#endif + + +// Includes ======================================================================================= +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +// Texture Samplers =============================================================================== +sampler g_tCorneaSampler : register( s0 ); +sampler g_tIrisSampler : register( s1 ); +sampler g_tEyeReflectionCubemapSampler : register( s2 ); +sampler g_tEyeAmbientOcclSampler : register( s3 ); +sampler g_tLightwarpSampler : register( s4 ); // 1D texture for TF NPR lighting + +sampler g_tFlashlightCookieSampler : register( s5 ); +sampler g_tFlashlightDepthSampler : register( s6 ); +sampler g_tRandomRotationSampler : register( s7 ); + +// Shaders Constants and Globals ================================================================== +const float4 g_vPackedConst0 : register( c0 ); +#define g_flDilationFactor g_vPackedConst0.x +#define g_flGlossiness g_vPackedConst0.y +#define g_flAverageAmbient g_vPackedConst0.z +#define g_flCorneaBumpStrength g_vPackedConst0.w + +const float3 g_vEyeOrigin : register( c1 ); +const float4 g_vIrisProjectionU : register( c2 ); +const float4 g_vIrisProjectionV : register( c3 ); +const float4 g_vCameraPosition : register( c4 ); +const float3 g_cAmbientOcclColor : register( c5 ); + +const float4 g_vPackedConst6 : register( c6 ); +#define g_flEyeballRadius g_vPackedConst6.y //0.51f +//#define g_bRaytraceSphere g_vPackedConst6.z //1.0f +#define g_flParallaxStrength g_vPackedConst6.w //0.25f + +// Flashlight constants +const float4 g_vFlashlightAttenuationFactors : register( c7 ); // FarZ in w +const float3 g_vFlashlightPos : register( c8 ); +const float4 g_vShadowTweaks : register( c9 ); +const float4 g_ShaderControls : register( c10 ); +#define g_fPixelFogType g_ShaderControls.x + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); + +PixelShaderLightInfo g_sLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float4 vAmbientOcclUv_fallbackCorneaUv : TEXCOORD0; + float4 cVertexLight : TEXCOORD1; // w is used for the flashlight pass + float4 vTangentViewVector : TEXCOORD2; // Tangent view vector (Note: w is used for flashlight pass) + float4 vWorldPosition_ProjPosZ : TEXCOORD3; + float3 vWorldNormal : TEXCOORD4; // World-space normal + float3 vWorldTangent : TEXCOORD5; // World-space tangent + float4 vLightFalloffCosine01 : TEXCOORD6; // Light falloff and cosine terms for first two local lights + float4 vLightFalloffCosine23 : TEXCOORD7; // Light falloff and cosine terms for next two local lights + + float3 vWorldBinormal : COLOR0; // World-space normal +}; + +// Ray sphere intersect returns distance along ray to intersection ================================ +float IntersectRaySphere ( float3 cameraPos, float3 ray, float3 sphereCenter, float sphereRadius) +{ + float3 dst = cameraPos.xyz - sphereCenter.xyz; + float B = dot(dst, ray); + float C = dot(dst, dst) - (sphereRadius * sphereRadius); + float D = B*B - C; + return (D > 0) ? (-B - sqrt(D)) : 0; +} + +// Calculate both types of Fog and lerp to get result +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); + return lerp( fRangeFog, fHeightFog, fPixelFogType ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + pixelFogFactor = saturate( pixelFogFactor ); + float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + return lerp( fRangeResult, fHeightResult, fPixelFogType ); +} + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + // Set bools to compile out code + bool bFlashlight = ( FLASHLIGHT != 0 ) ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + int nNumLights = FLASHLIGHT ? 1 : NUM_LIGHTS; // Flashlight is considered one light, otherwise, use numlights combo + +#if !defined( SHADER_MODEL_PS_2_0 ) + bool bRayCast = RAYTRACESPHERE ? true : false; + bool bRayCastTexKill = SPHERETEXKILLCOMBO ? true : false; +#endif + + float flFlashlightNDotL = i.vTangentViewVector.w; + float4 vFlashlightTexCoord = { 0.0f, 0.0f, 0.0f, 0.0f }; + if ( bFlashlight ) + { + vFlashlightTexCoord.xyzw = i.cVertexLight.xyzw; // This was hidden in this interpolator + i.cVertexLight.rgba = float4( 0.0f, 0.0f, 0.0f, 0.0f ); + } + + // Interpolated vectors + float3 vWorldNormal = i.vWorldNormal.xyz; + float3 vWorldTangent = i.vWorldTangent.xyz; + float3 vWorldBinormal = ( i.vWorldBinormal.xyz * 2.0f ) - 1.0f; // normalize( cross( vWorldNormal.xyz, vWorldTangent.xyz ) ); + + float3 vTangentViewVector = i.vTangentViewVector.xyz; + + // World position + float3 vWorldPosition = i.vWorldPosition_ProjPosZ.xyz; + + // World view vector to pixel + float3 vWorldViewVector = normalize( vWorldPosition.xyz - g_vCameraPosition.xyz ); + + //=================// + // TF NPR lighting // + //=================// + if ( bDoDiffuseWarp ) + { + // Replace the interpolated vertex light + if ( bFlashlight == true ) + { + // Deal with this below in the flashlight section + } + else + { + if ( nNumLights > 0 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine01.z ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ) * cWarpedLight.rgb; + } + + if ( nNumLights > 1 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine01.w ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ) * cWarpedLight.rgb; + } + + if ( nNumLights > 2 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine23.z ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ) * cWarpedLight.rgb; + } + + if ( nNumLights > 3 ) + { + float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, i.vLightFalloffCosine23.w ).rgb; + i.cVertexLight.rgb += i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ) * cWarpedLight.rgb; + } + } + } + + //==========================================================================================================// + // Ray cast against sphere representing eyeball to reduce artifacts from non-spherical morphed eye geometry // + //==========================================================================================================// +#if !defined( SHADER_MODEL_PS_2_0 ) + if ( bRayCast ) + { + float fSphereRayCastDistance = IntersectRaySphere( g_vCameraPosition.xyz, vWorldViewVector.xyz, g_vEyeOrigin.xyz, g_flEyeballRadius ); + vWorldPosition.xyz = g_vCameraPosition.xyz + ( vWorldViewVector.xyz * fSphereRayCastDistance ); + if (fSphereRayCastDistance == 0) + { + if ( bRayCastTexKill ) + clip(-1); // texkill to get a better silhouette + vWorldPosition.xyz = g_vEyeOrigin.xyz + ( vWorldNormal.xyz * g_flEyeballRadius ); + } + } +#endif + + //=================================// + // Generate sphere and cornea uv's // + //=================================// +#if !defined( SHADER_MODEL_PS_2_0 ) + float2 vCorneaUv; // Note: Cornea texture is a cropped version of the iris texture + vCorneaUv.x = dot( g_vIrisProjectionU, float4( vWorldPosition, 1.0f ) ); + vCorneaUv.y = dot( g_vIrisProjectionV, float4( vWorldPosition, 1.0f ) ); + float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; +#else // ps_20 + float2 vCorneaUv = i.vAmbientOcclUv_fallbackCorneaUv.wz; // Note: Cornea texture is a cropped version of the iris texture + float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; +#endif + + //=================================// + // Hacked parallax mapping on iris // + //=================================// + float fIrisOffset = tex2D( g_tCorneaSampler, vCorneaUv.xy ).b; + +#if !defined( SHADER_MODEL_PS_2_0 ) + float2 vParallaxVector = ( ( vTangentViewVector.xy * fIrisOffset * g_flParallaxStrength ) / ( 1.0f - vTangentViewVector.z ) ); // Note: 0.25 is a magic number + vParallaxVector.x = -vParallaxVector.x; //Need to flip x...not sure why. + //vParallaxVector.x *= -1.0; //Need to flip x...not sure why. + //vParallaxVector = 0.0f; //Disable parallax for debugging +#else // Disable parallax effect in 2.0 version + float2 vParallaxVector = { 0.0f, 0.0f }; +#endif + + float2 vIrisUv = vSphereUv.xy - vParallaxVector.xy; + + // Note: We fetch from this texture twice right now with different uv's for the color and alpha + float2 vCorneaNoiseUv = vSphereUv.xy + ( vParallaxVector.xy * 0.5 ); + float fCorneaNoise = tex2D( g_tIrisSampler, vCorneaNoiseUv.xy ).a; + + //===============// + // Cornea normal // + //===============// + // Sample 2D normal from texture + float3 vCorneaTangentNormal = { 0.0, 0.0, 1.0 }; + float4 vCorneaSample = tex2D( g_tCorneaSampler, vCorneaUv.xy ); + vCorneaTangentNormal.xy = vCorneaSample.rg - 0.5f; // Note: This scales the bump to 50% strength + + // Scale strength of normal + vCorneaTangentNormal.xy *= g_flCorneaBumpStrength; + + // Add in surface noise and imperfections (NOTE: This should be baked into the normal map!) + vCorneaTangentNormal.xy += fCorneaNoise * 0.1f; + + // Normalize tangent vector +#if !defined( SHADER_MODEL_PS_2_0 ) + // Since this isn't used later in 2.0, skip the normalize to save shader instructions + vCorneaTangentNormal.xyz = normalize( vCorneaTangentNormal.xyz ); +#endif + + // Transform into world space + float3 vCorneaWorldNormal = Vec3TangentToWorldNormalized( vCorneaTangentNormal.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + //============// + // Flashlight // + //============// + float3 vFlashlightVector = { 0.0f, 0.0f, 0.0f }; + float3 cFlashlightColorFalloff = { 0.0f, 0.0f, 0.0f }; + if ( bFlashlight == true ) + { + // Flashlight vector + vFlashlightVector.xyz = normalize( g_vFlashlightPos.xyz - i.vWorldPosition_ProjPosZ.xyz ); + + // Distance attenuation for flashlight and to fade out shadow over distance + float3 vDelta = g_vFlashlightPos.xyz - i.vWorldPosition_ProjPosZ.xyz; + float flDistSquared = dot( vDelta, vDelta ); + float flDist = sqrt( flDistSquared ); + float flFlashlightAttenuation = dot( g_vFlashlightAttenuationFactors.xyz, float3( 1.0f, 1.0f/flDist, 1.0f/flDistSquared ) ); + + // Flashlight cookie +#if !defined( SHADER_MODEL_PS_2_0 ) + float3 vProjCoords = vFlashlightTexCoord.xyz / vFlashlightTexCoord.w; + float3 cFlashlightCookieColor = tex2D( g_tFlashlightCookieSampler, vProjCoords ); +#else + float3 cFlashlightCookieColor = tex2Dproj( g_tFlashlightCookieSampler, vFlashlightTexCoord.xyzw ); +#endif + + // Shadow depth map +#if FLASHLIGHTSHADOWS && !defined( SHADER_MODEL_PS_2_0 ) + int nShadowLevel = FLASHLIGHTDEPTHFILTERMODE; + float flShadow = DoFlashlightShadow( g_tFlashlightDepthSampler, g_tRandomRotationSampler, vProjCoords, float2(0,0), nShadowLevel, g_vShadowTweaks, false ); + float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = lerp( flAttenuated, flShadow, flFlashlightAttenuation ); // Blend between shadow and above, according to light attenuation + cFlashlightCookieColor *= flShadow; // Apply shadow term to cookie color +#endif + + // Flashlight color intensity (needs to be multiplied by global flashlight color later) + cFlashlightColorFalloff.rgb = flFlashlightAttenuation * cFlashlightCookieColor.rgb; + + // Add this into the interpolated lighting + if ( bDoDiffuseWarp ) + { + //float3 cWarpedLight = 2.0f * tex1D( g_tLightwarpSampler, flFlashlightNDotL ).rgb; + //i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * cWarpedLight.rgb; + i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * flFlashlightNDotL; // No light warp for now + } + else + { + i.cVertexLight.rgb += cFlashlightColorFalloff.rgb * cFlashlightColor.rgb * flFlashlightNDotL; + } + } + + //==============// + // Dilate pupil // + //==============// +#if !defined( SHADER_MODEL_PS_2_0 ) + vIrisUv.xy -= 0.5f; // Center around (0,0) + float fPupilCenterToBorder = saturate( length( vIrisUv.xy ) / 0.2f ); //Note: 0.2 is the uv radius of the iris + float fPupilDilateFactor = g_flDilationFactor; // This value should be between 0-1 + vIrisUv.xy *= lerp (1.0f, fPupilCenterToBorder, saturate( fPupilDilateFactor ) * 2.5f - 1.25f ); + vIrisUv.xy += 0.5f; +#endif + + //============// + // Iris color // + //============// + float4 cIrisColor = tex2D( g_tIrisSampler, vIrisUv.xy ); + + //==========================// + // Iris lighting highlights // + //==========================// + float3 cIrisLighting = float3( 0.0f, 0.0f, 0.0f ); + +#if !defined( SHADER_MODEL_PS_2_0 ) + // Mask off everything but the iris pixels + float fIrisHighlightMask = tex2D( g_tCorneaSampler, vCorneaUv.xy ).a; + + // Generate the normal + float3 vIrisTangentNormal = vCorneaTangentNormal.xyz; + vIrisTangentNormal.xy *= -2.5f; // I'm not normalizing on purpose + + for ( int j=0; j < nNumLights; j++ ) + { + // World light vector + float3 vWorldLightVector; + if ( ( j == 0 ) && ( bFlashlight == true ) ) + vWorldLightVector = vFlashlightVector.xyz; + else + vWorldLightVector = PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, j ); + + // Tangent light vector + float3 vTangentLightVector = Vec3WorldToTangent( vWorldLightVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + // Adjust the tangent light vector to generate the iris lighting + float3 tmpv = -vTangentLightVector.xyz; + tmpv.xy *= -0.5f; //Flatten tangent view + tmpv.z = max( tmpv.z, 0.5f ); //Clamp z of tangent view to help maintain highlight + tmpv.xyz = normalize( tmpv.xyz ); + + // Core iris lighting math + float fIrisFacing = pow( abs( dot( vIrisTangentNormal.xyz, tmpv.xyz ) ), 6.0f ) * 0.5f; // Yes, 6.0 and 0.5 are magic numbers + + // Cone of darkness to darken iris highlights when light falls behind eyeball past a certain point + float flConeOfDarkness = pow( 1.0f - saturate( ( -vTangentLightVector.z - 0.25f ) / 0.75f ), 4.0f ); + //float flConeOfDarkness = pow( 1.0f - saturate( ( -dot( vIrisTangentNormal.xyz, vTangentLightVector.xyz ) - 0.15f ) / 0.85f ), 8.0f ); + + // Tint by iris color and cone of darkness + float3 cIrisLightingTmp = fIrisFacing * fIrisHighlightMask * flConeOfDarkness; + + // Attenuate by light color and light falloff + if ( ( j == 0 ) && ( bFlashlight == true ) ) + cIrisLightingTmp.rgb *= cFlashlightColorFalloff.rgb * cFlashlightColor.rgb; + else if ( j == 0 ) + cIrisLightingTmp.rgb *= i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ); + else if ( j == 1 ) + cIrisLightingTmp.rgb *= i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ); + else if ( j == 2 ) + cIrisLightingTmp.rgb *= i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ); + else + cIrisLightingTmp.rgb *= i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ); + + // Sum into final variable + cIrisLighting.rgb += cIrisLightingTmp.rgb; + } + + // Add slight view dependent iris lighting based on ambient light intensity to enhance situations with no local lights (0.5f is to help keep it subtle) + cIrisLighting.rgb += saturate( dot( vIrisTangentNormal.xyz, -vTangentViewVector.xyz ) ) * g_flAverageAmbient * fIrisHighlightMask * 0.5f; +#else + // Else, intensify light over cornea to simulate the brightening that happens above + cIrisLighting.rgb += i.cVertexLight.rgb * vCorneaSample.a; +#endif + + //===================// + // Ambient occlusion // + //===================// + float3 cAmbientOcclFromTexture = tex2D( g_tEyeAmbientOcclSampler, i.vAmbientOcclUv_fallbackCorneaUv.xy ).rgb; + float3 cAmbientOcclColor = lerp( g_cAmbientOcclColor, 1.0f, cAmbientOcclFromTexture.rgb ); // Color the ambient occlusion + i.cVertexLight.rgb *= cAmbientOcclColor.rgb; + + //==========================// + // Reflection from cube map // + //==========================// + float3 vCorneaReflectionVector = reflect ( vWorldViewVector.xyz, vCorneaWorldNormal.xyz ); + + //float3 cReflection = ENV_MAP_SCALE * texCUBE( g_tEyeReflectionCubemapSampler, vCorneaReflectionVector.xyz ).rgb; + float3 cReflection = g_flGlossiness * texCUBE( g_tEyeReflectionCubemapSampler, vCorneaReflectionVector.xyz ).rgb; + + // Hack: Only add in half of the env map for the flashlight pass. This looks reasonable. + if ( bFlashlight ) + { + cReflection.rgb *= 0.5f; + } + + //===========================// + // Glint specular highlights // + //===========================// + float3 cSpecularHighlights = 0.0f; + if ( bFlashlight ) + { + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, vFlashlightVector.xyz ) ), 128.0f ) * cFlashlightColorFalloff.rgb * cFlashlightColor.rgb; + } + else // no flashlight + { + if ( nNumLights > 0 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 0 ) ) ), 128.0f ) * i.vLightFalloffCosine01.x * PixelShaderGetLightColor( g_sLightInfo, 0 ); + + if ( nNumLights > 1 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 1 ) ) ), 128.0f ) * i.vLightFalloffCosine01.y * PixelShaderGetLightColor( g_sLightInfo, 1 ); + + if ( nNumLights > 2 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 2 ) ) ), 128.0f ) * i.vLightFalloffCosine23.x * PixelShaderGetLightColor( g_sLightInfo, 2 ); + + if ( nNumLights > 3 ) + cSpecularHighlights.rgb += pow( saturate( dot( vCorneaReflectionVector.xyz, PixelShaderGetLightVector( i.vWorldPosition_ProjPosZ.xyz, g_sLightInfo, 3 ) ) ), 128.0f ) * i.vLightFalloffCosine23.y * PixelShaderGetLightColor( g_sLightInfo, 3 ); + } + + //===============// + // Combine terms // + //===============// + float4 result; + + // Unlit iris, pupil, and sclera color + result.rgb = cIrisColor.rgb; + + // Add in slight cornea noise to help define raised cornea layer for close-ups + result.rgb += fCorneaNoise * 0.1f; + + // Diffuse light (Vertex lighting + extra iris caustic lighting) + result.rgb *= i.cVertexLight.rgb + cIrisLighting.rgb; + + // Environment map + result.rgb += cReflection.rgb * i.cVertexLight.rgb; + + // Local light glints + result.rgb += cSpecularHighlights.rgb; + + // Set alpha to 1.0 by default + result.a = 1.0; + +#if !defined( SHADER_MODEL_PS_2_0 ) + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_vCameraPosition.z, i.vWorldPosition_ProjPosZ.z, i.vWorldPosition_ProjPosZ.w ); + return FinalOutputConst( result, fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR ); +#else + float fogFactor = CalcPixelFogFactor( PIXEL_FOG_TYPE_NONE, g_FogParams, g_vCameraPosition.z, i.vWorldPosition_ProjPosZ.z, i.vWorldPosition_ProjPosZ.w ); + return FinalOutput( result, fogFactor, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +#endif + +} diff --git a/sp/src/materialsystem/stdshaders/eye_refract_vs20.fxc b/sp/src/materialsystem/stdshaders/eye_refract_vs20.fxc new file mode 100644 index 00000000..af975f99 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eye_refract_vs20.fxc @@ -0,0 +1,217 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "INTRO" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..4" +// DYNAMIC: "MORPHING" "0..1" [vs30] + +#include "vortwarp_vs20_helper.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_iFogType = DOWATERFOG; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; + +const float3 g_cEyeOrigin : register( SHADER_SPECIFIC_CONST_0 ); +const float4 g_vIrisProjectionU : register( SHADER_SPECIFIC_CONST_2 ); +const float4 g_vIrisProjectionV : register( SHADER_SPECIFIC_CONST_3 ); +const float4 g_vFlashlightPosition : register( SHADER_SPECIFIC_CONST_4 ); + +#if INTRO +const float4 g_vConst4 : register( SHADER_SPECIFIC_CONST_5 ); +#define g_vModelOrigin g_vConst4.xyz +#define g_flTime g_vConst4.w +#endif + +const float4 g_vFlashlightMatrixRow1 : register( SHADER_SPECIFIC_CONST_6 ); +const float4 g_vFlashlightMatrixRow2 : register( SHADER_SPECIFIC_CONST_7 ); +const float4 g_vFlashlightMatrixRow3 : register( SHADER_SPECIFIC_CONST_8 ); +const float4 g_vFlashlightMatrixRow4 : register( SHADER_SPECIFIC_CONST_9 ); + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates + + // Position deltas + float3 vPosFlex : POSITION1; + +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; // Fixed-function fog factor +#endif + float4 vAmbientOcclUv_fallbackCorneaUv : TEXCOORD0; // Base texture coordinate + float4 cVertexLight : TEXCOORD1; // Vertex-lit color (Note: w is used for flashlight pass) + float4 vTangentViewVector : TEXCOORD2; // Tangent view vector (Note: w is used for flashlight pass) + float4 vWorldPosition_ProjPosZ : TEXCOORD3; + float3 vWorldNormal : TEXCOORD4; // World-space normal + float3 vWorldTangent : TEXCOORD5; // World-space tangent + float4 vLightFalloffCosine01 : TEXCOORD6; // Light falloff and cosine terms for first two local lights + float4 vLightFalloffCosine23 : TEXCOORD7; // Light falloff and cosine terms for next two local lights + + float3 vWorldBinormal : COLOR0; // World-space normal +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + int nNumLights = NUM_LIGHTS; + + float4 vPosition = v.vPos; + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, vPosition.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz ); +#endif + + // Transform the position + float3 vWorldPosition; + SkinPosition( g_bSkinning, vPosition, v.vBoneWeights, v.vBoneIndices, vWorldPosition ); + + // Note: I'm relying on the iris projection vector math not changing or this will break + float3 vEyeSocketUpVector = normalize( -g_vIrisProjectionV.xyz ); + float3 vEyeSocketLeftVector = normalize( -g_vIrisProjectionU.xyz ); + +#if INTRO + float3 dummy = float3( 0.0f, 0.0f, 0.0f ); + WorldSpaceVertexProcess( g_flTime, g_vModelOrigin, vWorldPosition, dummy, dummy, dummy ); +#endif + + o.vWorldPosition_ProjPosZ.xyz = vWorldPosition.xyz; + + // Transform into projection space + //vWorldPosition -= ( vWorldPosition - g_cEyeOrigin ) * 0.9; //Debug to visualize eye origin + float4 vProjPos = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( vWorldPosition, 1.0f ), cViewProjZ ); + + + o.vWorldPosition_ProjPosZ.w = vProjPos.z; + +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( vWorldPosition, vProjPos, g_iFogType ); +#endif + + // Normal = (Pos - Eye origin) + float3 vWorldNormal = normalize( vWorldPosition.xyz - g_cEyeOrigin.xyz ); + o.vWorldNormal.xyz = vWorldNormal.xyz; + + // Tangent & binormal + /* + float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vEyeSocketLeftVector.xyz ) ); + o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f; + + float3 vWorldTangent = normalize( cross( vWorldBinormal.xyz, vWorldNormal.xyz ) ); + o.vWorldTangent.xyz = vWorldTangent.xyz; + //*/ + + //* + float3 vWorldTangent = normalize( cross( vEyeSocketUpVector.xyz, vWorldNormal.xyz ) ); + o.vWorldTangent.xyz = vWorldTangent.xyz; + + float3 vWorldBinormal = normalize( cross( vWorldNormal.xyz, vWorldTangent.xyz ) ); + o.vWorldBinormal.xyz = vWorldBinormal.xyz * 0.5f + 0.5f; + //*/ + + float3 vWorldViewVector = normalize (vWorldPosition.xyz - cEyePos.xyz); + o.vTangentViewVector.xyz = Vec3WorldToTangentNormalized (vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz); + + // AV - I think this will effectively make the eyeball less rounded left to right to help vertext lighting quality + // AV - Note: This probably won't look good if put on an exposed eyeball + //float vNormalDotSideVec = -dot( vWorldNormal, g_vEyeballUp ) * 0.5f; + float vNormalDotSideVec = -dot( vWorldNormal, vEyeSocketLeftVector) * 0.5f; + float3 vBentWorldNormal = normalize(vNormalDotSideVec * vEyeSocketLeftVector + vWorldNormal); + + // Compute vertex lighting + o.cVertexLight.a = 0.0f; //Only used for flashlight pass + o.cVertexLight.rgb = DoLightingUnrolled( vWorldPosition, vBentWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, nNumLights ); + + // Only interpolate ambient light for TF NPR lighting + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + if ( bDoDiffuseWarp ) + { + if( bDynamicLight ) + { + o.cVertexLight.rgb = AmbientLight( vBentWorldNormal.xyz ); + } + else + { + o.cVertexLight.rgb = float3( 0.0f, 0.0f, 0.0f ); + } + } + +// NOTE: it appears that o.vLightFalloffCosine01 and o.vLightFalloffCosine23 are filled in even if +// we don't have enough lights, meaning we pass garbage to the pixel shader which then throws it away + + // Light falloff for first two local lights + o.vLightFalloffCosine01.x = VertexAttenInternal( vWorldPosition.xyz, 0 ); + o.vLightFalloffCosine01.y = VertexAttenInternal( vWorldPosition.xyz, 1 ); + o.vLightFalloffCosine01.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 0, g_bHalfLambert ); + o.vLightFalloffCosine01.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 1, g_bHalfLambert ); + + // Light falloff for next two local lights + o.vLightFalloffCosine23.x = VertexAttenInternal( vWorldPosition.xyz, 2 ); + o.vLightFalloffCosine23.y = VertexAttenInternal( vWorldPosition.xyz, 3 ); + o.vLightFalloffCosine23.z = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 2, g_bHalfLambert ); + o.vLightFalloffCosine23.w = CosineTermInternal( vWorldPosition.xyz, vWorldNormal.xyz, 3, g_bHalfLambert ); + + // Texture coordinates set by artists for ambient occlusion + o.vAmbientOcclUv_fallbackCorneaUv.xy = v.vTexCoord0.xy; + + // Cornea uv for ps.2.0 fallback + float2 vCorneaUv; // Note: Cornea texture is a cropped version of the iris texture + vCorneaUv.x = dot( g_vIrisProjectionU, float4( vWorldPosition, 1.0f ) ); + vCorneaUv.y = dot( g_vIrisProjectionV, float4( vWorldPosition, 1.0f ) ); + float2 vSphereUv = ( vCorneaUv.xy * 0.5f ) + 0.25f; + o.vAmbientOcclUv_fallbackCorneaUv.wz = vCorneaUv.xy; // Note: wz unpacks faster than zw in ps.2.0! + + // Step on the vertex light interpolator for the flashlight tex coords + bool bFlashlight = ( FLASHLIGHT != 0 ) ? true : false; + o.vTangentViewVector.w = 0.0f; + if ( bFlashlight ) + { + o.cVertexLight.x = dot( g_vFlashlightMatrixRow1.xyzw, float4( vWorldPosition, 1.0f ) ); + o.cVertexLight.y = dot( g_vFlashlightMatrixRow2.xyzw, float4( vWorldPosition, 1.0f ) ); + o.cVertexLight.z = dot( g_vFlashlightMatrixRow3.xyzw, float4( vWorldPosition, 1.0f ) ); + o.cVertexLight.w = dot( g_vFlashlightMatrixRow4.xyzw, float4( vWorldPosition, 1.0f ) ); + + o.vTangentViewVector.w = saturate( dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ) ); // Flashlight N.L with modified normal + + // Half lambert version + //o.cVertexLight.z = dot( vBentWorldNormal.xyz, normalize ( g_vFlashlightPosition.xyz - vWorldPosition.xyz ) ); // Flashlight N.L with modified normal + //o.cVertexLight.z = ( o.cVertexLight.z * 0.5f ) + 0.5f; + //o.cVertexLight.z *= o.cVertexLight.z; + } + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/eyeball.cpp b/sp/src/materialsystem/stdshaders/eyeball.cpp new file mode 100644 index 00000000..7113585d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyeball.cpp @@ -0,0 +1,37 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Eyeball shader +// +//=============================================================================// + +#include "BaseVSShader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Eyeball, "Help for EyeBall" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/alyx/pupil_l", "iris texture", 0 ) + SHADER_PARAM_OVERRIDE( BASETEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + // This should be a dead shader... + return "Wireframe"; + } + + SHADER_INIT + { + } + + SHADER_DRAW + { + } + +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/eyeglint_dx9.cpp b/sp/src/materialsystem/stdshaders/eyeglint_dx9.cpp new file mode 100644 index 00000000..d2662e6d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyeglint_dx9.cpp @@ -0,0 +1,66 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Run procedural glint generation inner loop in pixel shader +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "shaderlib/cshader.h" + +#include "eyeglint_vs20.inc" +#include "eyeglint_ps20.inc" +#include "eyeglint_ps20b.inc" + +DEFINE_FALLBACK_SHADER( EyeGlint, EyeGlint_dx9 ) +BEGIN_VS_SHADER( EyeGlint_dx9, "Help for EyeGlint" ) + +BEGIN_SHADER_PARAMS +END_SHADER_PARAMS + +SHADER_INIT +{ +} + +SHADER_FALLBACK +{ + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Wireframe"; + } + return 0; +} + +SHADER_DRAW +{ + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Additive blending + + int pTexCoords[3] = { 2, 2, 3 }; + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, pTexCoords, 0 ); + + pShaderShadow->EnableCulling( false ); + + pShaderShadow->EnableSRGBWrite( false ); // linear texture + + DECLARE_STATIC_VERTEX_SHADER( eyeglint_vs20 ); + SET_STATIC_VERTEX_SHADER( eyeglint_vs20 ); + + SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( eyeglint ); + } + + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( eyeglint_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( eyeglint_vs20 ); + + SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( eyeglint ); + } + Draw(); +} +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/eyeglint_ps2x.fxc b/sp/src/materialsystem/stdshaders/eyeglint_ps2x.fxc new file mode 100644 index 00000000..bc39f079 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyeglint_ps2x.fxc @@ -0,0 +1,32 @@ +// ======= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====== +// +// Run procedural glint generation inner loop in pixel shader (ps_2_0) +// +// ============================================================================= + +struct PS_INPUT +{ + float2 tc : TEXCOORD0; // Interpolated coordinate of current texel + float2 glintCenter : TEXCOORD1; // Uniform value containing center of glint + float3 glintColor : TEXCOORD2; // Uniform value of color of glint +}; + +float GlintGaussSpotCoefficient( float2 d ) +{ + return saturate( exp( -25.0f * dot(d, d) ) ); +} + +float4 main( PS_INPUT i ) : COLOR +{ + float2 uv = i.tc - i.glintCenter; // This texel relative to glint center + + float intensity = GlintGaussSpotCoefficient( uv + float2(-0.25f, -0.25f) ) + + GlintGaussSpotCoefficient( uv + float2( 0.25f, -0.25f) ) + + 5 * GlintGaussSpotCoefficient( uv ) + + GlintGaussSpotCoefficient( uv + float2(-0.25f, 0.25f) ) + + GlintGaussSpotCoefficient( uv + float2( 0.25f, 0.25f) ); + + intensity *= 4.0f/9.0f; + + return float4( intensity * i.glintColor, 1.0f ); +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/eyeglint_vs20.fxc b/sp/src/materialsystem/stdshaders/eyeglint_vs20.fxc new file mode 100644 index 00000000..cf1ccb9b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyeglint_vs20.fxc @@ -0,0 +1,38 @@ +//===== Copyright © 1996-2007, Valve Corporation, All rights reserved. ======// +// +// Vertex shader to pass through texcoords needed to run the +// procedural glint generation inner loop in the pixel shader +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "common_vs_fxc.h" + +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 tc : TEXCOORD0; // Interpolated coordinate of current texel in 3x3 quad + float2 glintCenter : TEXCOORD1; // Uniform value containing center of glint in local 3x3 quad + float3 glintColor : TEXCOORD2; // Uniform value of color of glint +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + float2 tc : TEXCOORD0; // Interpolated coordinate of current texel in 3x3 quad + float2 glintCenter : TEXCOORD1; // Uniform value containing center of glint in local 3x3 quad + float3 glintColor : TEXCOORD2; // Uniform value of color of glint +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + o.projPos = float4( v.vPos, 1.0f ); + o.tc = v.tc; + o.glintCenter = v.glintCenter; + o.glintColor = v.glintColor; + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/eyes.cpp b/sp/src/materialsystem/stdshaders/eyes.cpp new file mode 100644 index 00000000..7aa4738f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes.cpp @@ -0,0 +1,186 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: eye renderer +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "eyes_dx8_dx9_helper.h" +#include "cloak_blended_pass_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( eyes, Eyes_dx8 ) + +BEGIN_VS_SHADER( Eyes_dx8, + "Help for Eyes" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/alyx/eyeball_l", "iris texture", 0 ) + SHADER_PARAM( IRIS, SHADER_PARAM_TYPE_TEXTURE, "models/alyx/pupil_l", "iris texture" ) + SHADER_PARAM( IRISFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame for the iris texture" ) + SHADER_PARAM( GLINT, SHADER_PARAM_TYPE_TEXTURE, "models/humans/male/glint", "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" ) + SHADER_PARAM( DILATION, SHADER_PARAM_TYPE_FLOAT, "0", "Iris dilation" ) + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is eyes in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + END_SHADER_PARAMS + + void SetupVars( Eyes_DX8_DX9_Vars_t &info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nFrame = FRAME; + info.m_nIris = IRIS; + info.m_nIrisFrame = IRISFRAME; + info.m_nGlint = GLINT; + info.m_nEyeOrigin = EYEORIGIN; + info.m_nEyeUp = EYEUP; + info.m_nIrisU = IRISU; + info.m_nIrisV = IRISV; + info.m_nGlintU = GLINTU; + info.m_nGlintV = GLINTV; + info.m_nDilation = DILATION; + info.m_nIntro = INTRO; + info.m_nEntityOrigin = ENTITYORIGIN; + info.m_nWarpParam = WARPPARAM; + } + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + SHADER_INIT_PARAMS() + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + InitParamsEyes_DX8_DX9( this, params, pMaterialName, info ); + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + } + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "Eyes_dx6"; + + return 0; + } + + SHADER_INIT + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + InitEyes_DX8_DX9( this, params, info ); + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + // There is some strangeness in DX8 when trying to skip the main pass, so leave this alone for now + //bDrawStandardPass = false; + } + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + DrawEyes_DX8_DX9( false, this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/eyes.vsh b/sp/src/materialsystem/stdshaders/eyes.vsh new file mode 100644 index 00000000..58ae021d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes.vsh @@ -0,0 +1,80 @@ +vs.1.1 +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0 = eyeball origin +; $SHADER_SPECIFIC_CONST_1 = eyeball up * 0.5 +; $SHADER_SPECIFIC_CONST_2 = iris projection U +; $SHADER_SPECIFIC_CONST_3 = iris projection V +; $SHADER_SPECIFIC_CONST_4 = glint projection U +; $SHADER_SPECIFIC_CONST_5 = glint projection V +;------------------------------------------------------------------------------ + +# STATIC: "HALF_LAMBERT" "0..1" +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "LIGHT_COMBO" "0..21" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending (whacks r1-r7, positions in r7) +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&SkinPosition( $worldPos ); + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ + +&AllocateRegister( \$projPos ); + +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Normal is based on vertex position +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$normalDotUp ); + +sub $worldNormal, $worldPos, $SHADER_SPECIFIC_CONST_0 ; Normal = (Pos - Eye origin) +dp3 $normalDotUp, $worldNormal, $SHADER_SPECIFIC_CONST_1 ; Normal -= 0.5f * (Normal dot Eye Up) * Eye Up +mul $normalDotUp, $normalDotUp, $cHalf +mad $worldNormal, -$normalDotUp, $SHADER_SPECIFIC_CONST_1, $worldNormal + +&FreeRegister( \$normalDotUp ); + +; normalize the normal +&Normalize( $worldNormal ); + +;------------------------------------------------------------------------------ +; Lighting +;------------------------------------------------------------------------------ +&DoLighting( $worldPos, $worldNormal ); + +&FreeRegister( \$worldNormal ); + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ + +&CalcFog( $worldPos, $projPos ); + +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Texture coordinates +; Texture 0 is the base texture +; Texture 1 is a planar projection used for the iris +; Texture 2 is a planar projection used for the glint +;------------------------------------------------------------------------------ + +mov oT0, $vTexCoord0 +dp4 oT1.x, $SHADER_SPECIFIC_CONST_2, $worldPos +dp4 oT1.y, $SHADER_SPECIFIC_CONST_3, $worldPos +dp4 oT2.x, $SHADER_SPECIFIC_CONST_4, $worldPos +dp4 oT2.y, $SHADER_SPECIFIC_CONST_5, $worldPos + +&FreeRegister( \$worldPos ); diff --git a/sp/src/materialsystem/stdshaders/eyes_dx6.cpp b/sp/src/materialsystem/stdshaders/eyes_dx6.cpp new file mode 100644 index 00000000..f5454595 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_dx6.cpp @@ -0,0 +1,251 @@ +//========= 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 + diff --git a/sp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp b/sp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp new file mode 100644 index 00000000..97e6ed32 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp @@ -0,0 +1,550 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "BaseVSShader.h" +#include "tier1/convar.h" +#include "mathlib/vmatrix.h" +#include "eyes_dx8_dx9_helper.h" +#include "cpp_shader_constant_register_map.h" +#include "Eyes.inc" +#include "eyes_flashlight_vs11.inc" +#include "eyes_flashlight_ps11.inc" + +#ifdef STDSHADER_DX9_DLL_EXPORT + +#include "eyes_vs20.inc" +#include "eyes_ps20.inc" +#include "eyes_ps20b.inc" +#include "eyes_flashlight_vs20.inc" +#include "eyes_flashlight_ps20.inc" +#include "eyes_flashlight_ps20b.inc" + +#ifndef _X360 +#include "eyes_vs30.inc" +#include "eyes_ps30.inc" +#include "eyes_flashlight_vs30.inc" +#include "eyes_flashlight_ps30.inc" +#endif + +#endif + +ConVar r_flashlight_version2( "r_flashlight_version2", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ); + +void InitParamsEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, + Eyes_DX8_DX9_Vars_t &info ) +{ + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + Assert( info.m_nIntro != -1 ); + if( info.m_nIntro != -1 && !params[info.m_nIntro]->IsDefined() ) + { + params[info.m_nIntro]->SetIntValue( 0 ); + } +} + +void InitEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, Eyes_DX8_DX9_Vars_t &info ) +{ + pShader->LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nIris, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nGlint ); + + // Be sure dilation is zeroed if undefined + if( !params[info.m_nDilation]->IsDefined() ) + { + params[info.m_nDilation]->SetFloatValue( 0.0f ); + } +} + +static void SetDepthFlashlightParams( CBaseVSShader *pShader, IShaderDynamicAPI *pShaderAPI, const VMatrix& worldToTexture, const FlashlightState_t& flashlightState ) +{ + float atten[4], pos[4], tweaks[4]; + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + + if ( IsX360() ) + { + pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); + } +} + + +static void DrawFlashlight( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + if( pShaderShadow ) + { + pShaderShadow->EnableDepthWrites( false ); + + pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Write over the eyes that were already there + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Spot + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Base + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Normalizing cubemap + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Iris + + // Set stream format (note that this shader supports compression) + int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + +#ifdef STDSHADER_DX9_DLL_EXPORT + if ( bDX9 ) + { + int nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_STATIC_VERTEX_SHADER( eyes_flashlight_vs20 ); + SET_STATIC_VERTEX_SHADER( eyes_flashlight_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( eyes_flashlight_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( eyes_flashlight_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( eyes_flashlight_ps20 ); + SET_STATIC_PIXEL_SHADER( eyes_flashlight_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( eyes_flashlight_vs30 ); + SET_STATIC_VERTEX_SHADER( eyes_flashlight_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( eyes_flashlight_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( eyes_flashlight_ps30 ); + } +#endif + + // On DX9, get the gamma read and write correct + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Spot + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // Base + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); // Iris + pShaderShadow->EnableSRGBWrite( true ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Shadow noise rotation map + } + } + else +#endif + { + // DX8 uses old asm shaders + eyes_flashlight_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "eyes_flashlight_vs11", vshIndex.GetIndex() ); + + eyes_flashlight_ps11_Static_Index pshIndex; + pShaderShadow->SetPixelShader( "eyes_flashlight_ps11", pshIndex.GetIndex() ); + } + + pShader->FogToBlack(); + } + else + { + // 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. + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + if ( !bDX9 ) + { + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 0, true ); + } + + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + pShader->BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture, info.m_nFrame ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP ); + pShader->BindTexture( SHADER_SAMPLER3, info.m_nIris, info.m_nIrisFrame ); + +#ifdef STDSHADER_DX9_DLL_EXPORT + if ( bDX9 ) + { + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs20 ); + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eyes_flashlight_vs30 ); + } +#endif + +// float vPSConst[4] = {params[info.m_nDilation]->GetFloatValue(), 0.0f, 0.0f, 0.0f}; +// pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); + + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); + SET_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20b ); + + SetDepthFlashlightParams( pShader, pShaderAPI, worldToTexture, flashlightState ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps20 ); + } + } +#ifndef _X360 + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) ); + SET_DYNAMIC_PIXEL_SHADER( eyes_flashlight_ps30 ); + + SetDepthFlashlightParams( pShader, pShaderAPI, worldToTexture, flashlightState ); + } +#endif + } + else // older asm shaders for DX8 +#endif + { + eyes_flashlight_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + eyes_flashlight_ps11_Dynamic_Index pshIndex; + pShaderAPI->SetPixelShaderIndex( pshIndex.GetIndex() ); + } + + // This uses from VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 to VERTEX_SHADER_SHADER_SPECIFIC_CONST_5 + pShader->SetFlashlightVertexShaderConstants( false, -1, false, -1, false ); + + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, info.m_nEyeOrigin ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, info.m_nEyeUp ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, info.m_nIrisU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, info.m_nIrisV ); + } + pShader->Draw(); +} + +static void DrawUsingVertexShader( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Iris + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Glint + + // Set stream format (note that this shader supports compression) + int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + pShaderShadow->EnableAlphaWrites( true ); //we end up hijacking destination alpha for opaques most of the time. + +#ifdef STDSHADER_DX9_DLL_EXPORT + if ( bDX9 ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( eyes_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[info.m_nIntro]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( eyes_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( eyes_ps20b ); + SET_STATIC_PIXEL_SHADER( eyes_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( eyes_ps20 ); + SET_STATIC_PIXEL_SHADER( eyes_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( eyes_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[info.m_nIntro]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( eyes_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( eyes_ps30 ); + SET_STATIC_PIXEL_SHADER( eyes_ps30 ); + } +#endif + // On DX9, get the gamma read and write correct + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Base + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // White + pShaderShadow->EnableSRGBWrite( true ); + } + else +#endif + { + eyes_Static_Index vshIndex; + vshIndex.SetHALF_LAMBERT( IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + pShaderShadow->SetVertexShader( "Eyes", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "Eyes_Overbright2" ); + } + + pShader->FogToFogColor(); + } + DYNAMIC_STATE + { + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nFrame ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nIris, info.m_nIrisFrame ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nGlint ); + pShader->SetAmbientCubeDynamicStateVertexShader(); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nEyeOrigin ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nEyeUp ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nIrisU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nIrisV ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nGlintU ); + pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, info.m_nGlintV ); + +#ifdef STDSHADER_DX9_DLL_EXPORT + if( bDX9 ) + { + LightState_t lightState; + pShaderAPI->GetDX9LightState( &lightState ); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( eyes_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( eyes_vs20 ); + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( eyes_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( eyes_vs30 ); + } +#endif + + // Get luminance of ambient cube and saturate it + float fGlintDamping = max(0.0f, min( pShaderAPI->GetAmbientLightCubeLuminance(), 1.0f ) ); + const float fDimGlint = 0.01f; + + // Remap so that glint damping smooth steps to zero for low luminances + if ( fGlintDamping > fDimGlint ) + fGlintDamping = 1.0f; + else + fGlintDamping *= SimpleSplineRemapVal( fGlintDamping, 0.0f, fDimGlint, 0.0f, 1.0f ); + + // Special constant for DX9 eyes: { Dilation, ambient, x, x }; + float vPSConst[4] = {params[info.m_nDilation]->GetFloatValue(), fGlintDamping, 0.0f, 0.0f}; + pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( eyes_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( eyes_ps20 ); + } + } +#ifndef _X360 + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( eyes_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( eyes_ps30 ); + } +#endif + + Assert( info.m_nIntro != -1 ); + if( params[info.m_nIntro]->GetIntValue() ) + { + float curTime = params[info.m_nWarpParam]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + Assert( params[info.m_nEntityOrigin]->IsDefined() ); + params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, timeVec, 1 ); + } + } + else +#endif + { + eyes_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetLIGHT_COMBO( pShaderAPI->GetCurrentLightCombo() ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + pShader->Draw(); +} + +static void DrawEyes_DX8_DX9_Internal( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, bool bHasFlashlight, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + if( !bHasFlashlight ) + { + DrawUsingVertexShader( bDX9, pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + DrawFlashlight( bDX9, pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } +} + +extern ConVar r_flashlight_version2; +void DrawEyes_DX8_DX9( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + DrawEyes_DX8_DX9_Internal( bDX9, pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression ); + if ( pShaderShadow ) + { + pShader->SetInitialShadowState( ); + } + } + DrawEyes_DX8_DX9_Internal( bDX9, pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression ); +} + + diff --git a/sp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.h b/sp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.h new file mode 100644 index 00000000..daf7c124 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.h @@ -0,0 +1,54 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef EYES_DX8_DX9_HELPER_H +#define EYES_DX8_DX9_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct Eyes_DX8_DX9_Vars_t +{ + Eyes_DX8_DX9_Vars_t() { memset( this, 0xFF, sizeof(Eyes_DX8_DX9_Vars_t) ); } + + int m_nBaseTexture; + int m_nFrame; + int m_nIris; + int m_nIrisFrame; + int m_nGlint; + int m_nEyeOrigin; + int m_nEyeUp; + int m_nIrisU; + int m_nIrisV; + int m_nGlintU; + int m_nGlintV; + int m_nDilation; + int m_nIntro; + int m_nEntityOrigin; + int m_nWarpParam; +}; + +void InitParamsEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Eyes_DX8_DX9_Vars_t &info ); +void InitEyes_DX8_DX9( CBaseVSShader *pShader, IMaterialVar** params, Eyes_DX8_DX9_Vars_t &info ); +void DrawEyes_DX8_DX9( bool bDX9, CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Eyes_DX8_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // EYES_DX8_DX9_HELPER_H diff --git a/sp/src/materialsystem/stdshaders/eyes_dx9.cpp b/sp/src/materialsystem/stdshaders/eyes_dx9.cpp new file mode 100644 index 00000000..b33ec804 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_dx9.cpp @@ -0,0 +1,84 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: eye renderer +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "eyes_dx8_dx9_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( eyes, Eyes_dx9 ) + +BEGIN_VS_SHADER( Eyes_dx9, "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" ) + SHADER_PARAM( DILATION, SHADER_PARAM_TYPE_FLOAT, "0", "Pupil dilation (0 is none, 1 is maximal)" ) + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is eyes in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + END_SHADER_PARAMS + + void SetupVars( Eyes_DX8_DX9_Vars_t &info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nFrame = FRAME; + info.m_nIris = IRIS; + info.m_nIrisFrame = IRISFRAME; + info.m_nGlint = GLINT; + info.m_nEyeOrigin = EYEORIGIN; + info.m_nEyeUp = EYEUP; + info.m_nIrisU = IRISU; + info.m_nIrisV = IRISV; + info.m_nGlintU = GLINTU; + info.m_nGlintV = GLINTV; + info.m_nDilation = DILATION; + info.m_nIntro = INTRO; + info.m_nEntityOrigin = ENTITYORIGIN; + info.m_nWarpParam = WARPPARAM; + } + + SHADER_INIT_PARAMS() + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + InitParamsEyes_DX8_DX9( this, params, pMaterialName, info ); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "Eyes_dx8"; + + return 0; + } + + SHADER_INIT + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + InitEyes_DX8_DX9( this, params, info ); + } + + + SHADER_DRAW + { + Eyes_DX8_DX9_Vars_t info; + SetupVars( info ); + DrawEyes_DX8_DX9( true, this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/eyes_flashlight2_ps11.psh b/sp/src/materialsystem/stdshaders/eyes_flashlight2_ps11.psh new file mode 100644 index 00000000..3b02fbb3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_flashlight2_ps11.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw stuff +;------------------------------------------------------------------------------ + +tex t0 ; Contains spotlight +tex t1 ; Contains base texture +tex t2 ; Normalize world pos to light +tex t3 ; Sample iris + +dp3 r0, t2_bx2, v0_bx2 ; r0 = N dot L +lrp r1.rgb, t3.a, t3, t1 ; r1 = lerp( baseColor, irisSample.xyz, irisSample.a ) +mul r0.rgb, r0_sat, r1 ; Saturate ( N dot L )* lerp +mul r0.rgb, r0, v0.a ; *= attenuation +mul_x2 r0.rgb, r0, t0 + ; *= 2 * spotlight +mov r0.a, t1.a diff --git a/sp/src/materialsystem/stdshaders/eyes_flashlight_inc.fxc b/sp/src/materialsystem/stdshaders/eyes_flashlight_inc.fxc new file mode 100644 index 00000000..7629f72f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_flashlight_inc.fxc @@ -0,0 +1,92 @@ +//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + + +const float4 g_vShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); + +sampler SpotSampler : register( s0 ); +sampler BaseTextureSampler : register( s1 ); +sampler IrisSampler : register( s3 ); + +#if FLASHLIGHTSHADOWS && (!SHADER_MODEL_PS_1_1) && (!SHADER_MODEL_PS_1_4) && (!SHADER_MODEL_PS_2_0) +sampler FlashlightDepthSampler : register( s4 ); +sampler RandomRotationSampler : register( s5 ); +#endif + +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + +#else + const float4 g_FogParams : register( PSREG_FOG_PARAMS ); + const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +#endif + +struct PS_INPUT +{ + float4 spotTexCoord : TEXCOORD0; + float2 baseTexCoord : TEXCOORD1; + float2 irisTexCoord : TEXCOORD3; +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + float3 vertAtten : COLOR0; +#else + float3 vertAtten : TEXCOORD4; + float3 worldPos : TEXCOORD5; + float3 projPos : TEXCOORD7; +#endif +}; + +float4 main( PS_INPUT i ) : COLOR +{ +#if defined(SHADER_MODEL_PS_2_0) + float3 spotColor = tex2Dproj( SpotSampler, i.spotTexCoord.xyzw ) * cFlashlightColor; +#elif ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; + float3 spotColor = tex2D( SpotSampler, vProjCoords ) * cFlashlightColor; +#else + float3 spotColor = tex2D( SpotSampler, i.spotTexCoord ); +#endif + + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + float4 irisSample = tex2D( IrisSampler, i.irisTexCoord ); + + float3 outcolor = float3(1,1,1); + +#if !defined( SHADER_MODEL_PS_1_1 ) && !defined( SHADER_MODEL_PS_1_4 ) + if( i.spotTexCoord.w <= 0.0f ) + { + outcolor = float3(0,0,0); + } +#endif + + // Composite the iris and sclera together +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + float3 albedo = lerp( baseSample.xyz, irisSample.xyz, irisSample.a ); +#else + float3 albedo = lerp( baseSample.xyz, irisSample.xyz * 0.5f, irisSample.a ); // dim down the iris in HDR +#endif + + // Do shadow depth mapping... +#if FLASHLIGHTSHADOWS && ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_vShadowTweaks, true ); + float flAttenuated = lerp( flShadow, 1.0f, g_vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = lerp( flAttenuated, flShadow, dot(i.vertAtten, float3(0.30f, 0.59f, 0.11f) ) ); // Blend between shadow and above, according to light attenuation + outcolor *= flShadow * spotColor * albedo; +#else + outcolor *= spotColor * albedo; +#endif + + // NOTE!! This has to be last to avoid loss of range. + outcolor *= i.vertAtten; +#if defined( SHADER_MODEL_PS_1_1 ) || defined ( SHADER_MODEL_PS_1_4 ) + return float4( outcolor, baseSample.a ); +#else + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos.z, i.projPos.z ); + return FinalOutput( float4( outcolor, 1.0f ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +#endif + +} diff --git a/sp/src/materialsystem/stdshaders/eyes_flashlight_ps11.fxc b/sp/src/materialsystem/stdshaders/eyes_flashlight_ps11.fxc new file mode 100644 index 00000000..25e0702e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_flashlight_ps11.fxc @@ -0,0 +1,9 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +#define HDRTYPE HDR_TYPE_NONE + +#include "eyes_flashlight_inc.fxc" diff --git a/sp/src/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc b/sp/src/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc new file mode 100644 index 00000000..eb00fc04 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc @@ -0,0 +1,15 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +#include "eyes_flashlight_inc.fxc" diff --git a/sp/src/materialsystem/stdshaders/eyes_flashlight_vs11.vsh b/sp/src/materialsystem/stdshaders/eyes_flashlight_vs11.vsh new file mode 100644 index 00000000..48c4cd57 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_flashlight_vs11.vsh @@ -0,0 +1,115 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos ); + +alloc $worldPos +alloc $projPos + + +&SkinPosition( $worldPos ); + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 + +;------------------------------------------------------------------------------ +; Normal is based on vertex position +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$normalDotUp ); + +sub $worldNormal, $worldPos, $SHADER_SPECIFIC_CONST_6 ; Normal = (Pos - Eye origin) +dp3 $normalDotUp, $worldNormal, $SHADER_SPECIFIC_CONST_7 ; Normal -= 0.5f * (Normal dot Eye Up) * Eye Up +mul $normalDotUp, $normalDotUp, $cHalf +mad $worldNormal, -$normalDotUp, $SHADER_SPECIFIC_CONST_7, $worldNormal + +&FreeRegister( \$normalDotUp ); + +; normalize the normal +&Normalize( $worldNormal ); + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +; base tex coords +mov oT1.xy, $vTexCoord0 + +; spotlight texcoords +dp4 oT0.x, $worldPos, $SHADER_SPECIFIC_CONST_1 +dp4 oT0.y, $worldPos, $SHADER_SPECIFIC_CONST_2 +dp4 oT0.z, $worldPos, $SHADER_SPECIFIC_CONST_3 +dp4 oT0.w, $worldPos, $SHADER_SPECIFIC_CONST_4 + +local( $worldPosToLightVector, $distFactors ); + +alloc $worldPosToLightVector + +sub $worldPosToLightVector, $SHADER_SPECIFIC_CONST_0.xyz, $worldPos + +local( $distatten ); +alloc $distatten +; $distatten = [ 1, 1/dist, 1/distsquared ] + +; dist squared +dp3 $distatten.z, $worldPosToLightVector, $worldPosToLightVector + +; oodist +rsq $distatten.y, $distatten.z + +mov $distatten.x, $cOne + +local( $dist ); +alloc $dist +mul $dist.x, $distatten.z, $distatten.y + +rcp $distatten.z, $distatten.z ; 1/distsquared + +local( $endFalloffFactor ); +alloc $endFalloffFactor + +; ( dist - farZ ) +sub $endFalloffFactor.x, $dist.x, $SHADER_SPECIFIC_CONST_5.w +; 1 / ( (0.6f * farZ) - farZ) +mul $endFalloffFactor, $endFalloffFactor.x, $SHADER_SPECIFIC_CONST_0.w +max $endFalloffFactor, $endFalloffFactor, $cZero +min $endFalloffFactor, $endFalloffFactor, $cOne + +local( $vertAtten ); +alloc $vertAtten +dp3 $vertAtten, $distatten, $SHADER_SPECIFIC_CONST_5 +mul $vertAtten, $vertAtten, $endFalloffFactor + +; Normalize L +&Normalize( $worldPosToLightVector ); + +; N.L +dp3 $worldNormal, $worldNormal, $worldPosToLightVector + +; Modulate distance attenuation with N.L +mul oD0, $vertAtten, $worldNormal + +; iris +dp4 oT3.x, $SHADER_SPECIFIC_CONST_8, $worldPos +dp4 oT3.y, $SHADER_SPECIFIC_CONST_9, $worldPos + +free $dist +free $endFalloffFactor +free $worldPos +free $worldNormal +free $projPos +free $worldPosToLightVector +free $distatten +free $vertAtten diff --git a/sp/src/materialsystem/stdshaders/eyes_flashlight_vs20.fxc b/sp/src/materialsystem/stdshaders/eyes_flashlight_vs20.fxc new file mode 100644 index 00000000..e2e37dc1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_flashlight_vs20.fxc @@ -0,0 +1,145 @@ +// ------------------------------------------------------------------------------ +// $cLight0Pos = world space light position +// $SHADER_SPECIFIC_CONST_1 = spotlight projection +// $SHADER_SPECIFIC_CONST_2 = spotlight projection +// $SHADER_SPECIFIC_CONST_3 = spotlight projection +// $SHADER_SPECIFIC_CONST_4 = spotlight projection +// $SHADER_SPECIFIC_CONST_5 = far z +// $SHADER_SPECIFIC_CONST_6 = eyeball origin +// $SHADER_SPECIFIC_CONST_7 = eyeball up * 0.5 +// $SHADER_SPECIFIC_CONST_8 = iris projection U +// $SHADER_SPECIFIC_CONST_9 = iris projection V +// ------------------------------------------------------------------------------ + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cLightPosition : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cSpotlightProj1 : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cSpotlightProj2 : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cSpotlightProj3 : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cSpotlightProj4 : register( SHADER_SPECIFIC_CONST_4 ); +const float4 cFlashlighAtten : register( SHADER_SPECIFIC_CONST_5 ); // const, linear, quadratic & farZ +const float4 cIrisProjectionU : register( SHADER_SPECIFIC_CONST_8 ); +const float4 cIrisProjectionV : register( SHADER_SPECIFIC_CONST_9 ); + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vNormal : NORMAL; + float4 vTexCoord0 : TEXCOORD0; // Base (sclera) texture coordinates + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; // Fixed-function fog factor +#endif + float4 spotTexCoord : TEXCOORD0; // Spotlight texture coordinates + float2 baseTexCoord : TEXCOORD1; // Base texture coordinates + float2 irisTexCoord : TEXCOORD3; // Iris texture coordinates + float3 vertAtten : TEXCOORD4; // vertex attenuation + float3 worldPos : TEXCOORD5; + float3 projPosXYZ : TEXCOORD7; +}; + + +float RemapValClamped_01( float val, float A, float B ) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + return cVal; +} + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + DecompressVertex_Normal( v.vNormal, vNormal ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); +#endif + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, vNormal, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + + worldNormal = normalize( worldNormal ); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + o.projPosXYZ = projPos.xyz; + o.worldPos = worldPos.xyz; + +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, o.projPos, g_FogType ); +#endif + + // Base texture coordinates + o.baseTexCoord = v.vTexCoord0; + + // Spotlight texture coordinates + o.spotTexCoord.x = dot( cSpotlightProj1, float4(worldPos, 1) ); + o.spotTexCoord.y = dot( cSpotlightProj2, float4(worldPos, 1) ); + o.spotTexCoord.z = dot( cSpotlightProj3, float4(worldPos, 1) ); + o.spotTexCoord.w = dot( cSpotlightProj4, float4(worldPos, 1) ); + + // Compute vector to light + float3 vWorldPosToLightVector = cLightPosition.xyz - worldPos; + + float3 vDistAtten = float3(1, 1, 1); + vDistAtten.z = dot( vWorldPosToLightVector, vWorldPosToLightVector ); // distsquared + vDistAtten.y = rsqrt( vDistAtten.z ); // 1 / dist + + float flDist = vDistAtten.z * vDistAtten.y; // dist + vDistAtten.z = 1.0f / vDistAtten.z; // 1 / distsquared + + float fFarZ = cFlashlighAtten.w; + + float endFalloffFactor = RemapValClamped_01( flDist, fFarZ, 0.6 * fFarZ ); + o.vertAtten.xyz = endFalloffFactor * dot( vDistAtten, cFlashlighAtten.xyz ); + + o.vertAtten *= dot( normalize( vWorldPosToLightVector ), worldNormal ); + + o.irisTexCoord.x = dot( cIrisProjectionU, float4(worldPos, 1) ); + o.irisTexCoord.y = dot( cIrisProjectionV, float4(worldPos, 1) ); + + return o; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/eyes_ps2x.fxc b/sp/src/materialsystem/stdshaders/eyes_ps2x.fxc new file mode 100644 index 00000000..d71d813f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/eyes_ps2x.fxc @@ -0,0 +1,68 @@ +//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); +sampler IrisSampler : register( s1 ); +sampler GlintSampler : register( s2 ); +const float4 cEyeScalars : register( c0 ); // { Dilation, ambient, x, x } + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float2 irisTexCoord : TEXCOORD1; + float2 glintTexCoord : TEXCOORD2; + float3 vertAtten : TEXCOORD3; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +#define fDilationFactor cEyeScalars.x +#define fGlintDamping cEyeScalars.y + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + float4 glintSample = tex2D( GlintSampler, i.glintTexCoord ); +/* + // Dilate the pupil/iris texture (1 is max dilation, 0 is none) + float2 biasedCoords = i.irisTexCoord * 2.0f - 1.0f; // -1 to +1 range + float fDilatability = saturate(0.8f - sqrt(dot(biasedCoords, biasedCoords) )); // 1 in the center, fading out to 0 at 0.8 from center, since irises are inset into maps + float2 scaledCoords = biasedCoords * (1 + fDilatability); // Maximal dilation + + // Blend undilated and maximally dilated based upon dilation factor + float2 dilatedCoords = lerp( scaledCoords, biasedCoords, 1.0f-saturate(cDilationFactor.x)); + dilatedCoords = dilatedCoords * 0.5f + 0.5f; // Back to 0..1 range +*/ + + float4 irisSample = tex2D( IrisSampler, i.irisTexCoord ); // Sample the iris map using dilated coordinates + + float4 result; + result.rgb = lerp( baseSample.rgb, irisSample.rgb, irisSample.a ); + result.rgb *= i.vertAtten; + result.rgb += glintSample.rgb * fGlintDamping; + result.a = baseSample.a; + + bool bWriteDepthToAlpha = false; + + // ps_2_b and beyond +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) + bWriteDepthToAlpha = WRITE_DEPTH_TO_DESTALPHA != 0; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w ); +} diff --git a/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp new file mode 100644 index 00000000..9b02330a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp @@ -0,0 +1,271 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +/* Example how to plug this into an existing shader: + + In the VMT: + // Flesh Interior Pass + "$FleshInteriorEnabled" "1" // Enables effect + "$FleshInteriorTexture" "models/Alyx/alyx_flesh_color" // Mask in alpha + "$FleshNormalTexture" "models/Alyx/alyx_flesh_normal" + "$FleshBorderTexture1D" "models/Alyx/alyx_flesh_border" + "$FleshInteriorNoiseTexture" "Engine/noise-blur-256x256" + "$FleshSubsurfaceTexture" "models/Alyx/alyx_flesh_subsurface" + "$FleshBorderNoiseScale" "1.5" // Flesh Noise UV scalar for border + "$FleshBorderWidth" "0.3" // Width of flesh border + "$FleshBorderSoftness" "0.42" // Border softness must be greater than 0.0 and up tp 0.5 + "$FleshBorderTint" "[1 1 1]" // Tint / brighten the border 1D texture + "$FleshGlossBrightness" "0.66" // Change the brightness of the glossy layer + "$FleshDebugForceFleshOn" "0" // DEBUG: This will force on full flesh for testing + "$FleshScrollSpeed" "1.0" + "Proxies" + { + "FleshInterior" + { + } + } + + #include "flesh_interior_blended_pass_helper.h" + + In BEGIN_SHADER_PARAMS: + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + Add this above SHADER_INIT_PARAMS() + // Flesh Interior Pass + void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) + { + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + } + + In SHADER_INIT_PARAMS() + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } + + In SHADER_INIT + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } + + At the very end of SHADER_DRAW + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + +==================================================================================================== */ + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "convar.h" +#include "flesh_interior_blended_pass_helper.h" + +// Auto generated inc files +#include "flesh_interior_blended_pass_dx8_vs11.inc" + +void InitParamsFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, FleshInteriorBlendedPassVars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + SET_PARAM_STRING_IF_NOT_DEFINED( info.m_nFleshCubeTexture, "env_cubemap" ); // Default to in-game env map + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderNoiseScale, kDefaultBorderNoiseScale ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflDebugForceFleshOn, kDefaultDebugForceFleshOn ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius1, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius2, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius3, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius4, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncSubsurfaceTint, kDefaultSubsurfaceTint, 4 ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderWidth, kDefaultBorderWidth ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderSoftness, kDefaultBorderSoftness ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncBorderTint, kDefaultBorderTint, 4 ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlobalOpacity, kDefaultGlobalOpacity ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlossBrightness, kDefaultGlossBrightness ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflScrollSpeed, kDefaultScrollSpeed ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nTime, 0.0f ); +} + +void InitFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, FleshInteriorBlendedPassVars_t &info ) +{ + // Load textures + pShader->LoadTexture( info.m_nFleshTexture ); + //pShader->LoadTexture( info.m_nFleshNoiseTexture ); + //pShader->LoadTexture( info.m_nFleshBorderTexture1D ); + //pShader->LoadTexture( info.m_nFleshNormalTexture ); + //pShader->LoadTexture( info.m_nFleshSubsurfaceTexture ); + //pShader->LoadCubeMap( info.m_nFleshCubeTexture ); +} + +void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, FleshInteriorBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + // Reset shadow state manually since we're drawing from two materials + pShader->SetInitialShadowState(); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // Vertex Shader + flesh_interior_blended_pass_dx8_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "flesh_interior_blended_pass_dx8_vs11", vshIndex.GetIndex() ); + + // Pixel Shader + pShaderShadow->SetPixelShader( "flesh_interior_blended_pass_dx8_ps11", 0 ); + + // Textures + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Blending + pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableAlphaTest( true ); + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); + } + DYNAMIC_STATE + { + // Reset render state manually since we're drawing from two materials + pShaderAPI->SetDefaultState(); + + // Set Vertex Shader Combos + flesh_interior_blended_pass_dx8_vs11_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + // Set Vertex Shader Constants + + // Time % 1000 + float flCurrentTime = IS_PARAM_DEFINED( info.m_nTime ) && params[info.m_nTime]->GetFloatValue() > 0.0f ? params[info.m_nTime]->GetFloatValue() : pShaderAPI->CurrentTime(); + flCurrentTime *= IS_PARAM_DEFINED( info.m_nflScrollSpeed ) ? params[info.m_nflScrollSpeed]->GetFloatValue() : kDefaultScrollSpeed; // This is a dirty hack, but it works well enough + + float vVsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vVsConst0[0] = flCurrentTime; + vVsConst0[0] -= (float)( (int)( vVsConst0[0] / 1000.0f ) ) * 1000.0f; + + // Flesh effect centers and radii + float vVsConst1[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius1 ) ) + { + params[info.m_nvEffectCenterRadius1]->GetVecValue( vVsConst1, 4 ); + if ( vVsConst1[3] < 0.001f ) + vVsConst1[3] = 0.001f; + vVsConst1[3] = 1.0f / vVsConst1[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, vVsConst1, 1 ); + + float vVsConst2[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius2 ) ) + { + params[info.m_nvEffectCenterRadius2]->GetVecValue( vVsConst2, 4 ); + if ( vVsConst2[3] < 0.001f ) + vVsConst2[3] = 0.001f; + vVsConst2[3] = 1.0f / vVsConst2[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, vVsConst2, 2 ); + + float vVsConst3[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius3 ) ) + { + params[info.m_nvEffectCenterRadius3]->GetVecValue( vVsConst3, 4 ); + if ( vVsConst3[3] < 0.001f ) + vVsConst3[3] = 0.001f; + vVsConst3[3] = 1.0f / vVsConst3[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vVsConst3, 3 ); + + float vVsConst4[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius4 ) ) + { + params[info.m_nvEffectCenterRadius4]->GetVecValue( vVsConst4, 4 ); + if ( vVsConst4[3] < 0.001f ) + vVsConst4[3] = 0.001f; + vVsConst4[3] = 1.0f / vVsConst4[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, vVsConst4, 4 ); + + // Set Pixel Shader Combos + /* None */ + + // Bind textures + pShader->BindTexture( SHADER_SAMPLER0, info.m_nFleshTexture ); + + // Set Pixel Shader Constants + + // Border color tint + pShaderAPI->SetPixelShaderConstant( 3, IS_PARAM_DEFINED( info.m_ncBorderTint ) ? params[info.m_ncBorderTint]->GetVecValue() : kDefaultBorderTint, 1 ); + + // Global opacity + float vPsConst4[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst4[0] = IS_PARAM_DEFINED( info.m_nflGlobalOpacity ) ? params[info.m_nflGlobalOpacity]->GetFloatValue() : kDefaultGlobalOpacity; + pShaderAPI->SetPixelShaderConstant( 4, vPsConst4, 1 ); + + float vPsConst5[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + pShaderAPI->SetPixelShaderConstant( 5, vPsConst5, 1 ); + } + pShader->Draw(); +} diff --git a/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh new file mode 100644 index 00000000..fc7e32a9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh @@ -0,0 +1,15 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; c5 1, 1, 1, 1 +;------------------------------------------------------------------------------ + +tex t0 ; Base color + +mul r0, v0, v0 ; // Mask^2 +mul r0, r0, r0 ; // Mask^4 +sub r0, c5, r0 ; // 1.0 - Mask^4 + +mul r0.rgb, r0, t0 ; // * Flesh texture color +mul r0.a, r0.a, t0.a ; // * Flesh X-rated mask +mul r0.a, r0.a, v1.a ; // * Fresnel mask diff --git a/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh new file mode 100644 index 00000000..53b6d87d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh @@ -0,0 +1,114 @@ +# DYNAMIC: "SKINNING" "0..1" + +vs.1.1 +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; Vertex blending +;------------------------------------------------------------------------------ +&AllocateRegister( \$worldPos ); +&AllocateRegister( \$worldNormal ); +&AllocateRegister( \$projPos ); + +&SkinPositionAndNormal( $worldPos, $worldNormal ); + +if( $SKINNING == 1 ) +{ + &Normalize( $worldNormal ); +} + +;------------------------------------------------------------------------------ +; Transform the position from world to view space +;------------------------------------------------------------------------------ +dp4 $projPos.x, $worldPos, $cViewProj0 +dp4 $projPos.y, $worldPos, $cViewProj1 +dp4 $projPos.z, $worldPos, $cViewProj2 +dp4 $projPos.w, $worldPos, $cViewProj3 + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog - don't bother with water fog for intro effects +;------------------------------------------------------------------------------ +&DepthFog( $projPos, "oFog" ); +&FreeRegister( \$projPos ); + +;------------------------------------------------------------------------------ +; Flesh area +;------------------------------------------------------------------------------ +; // Store the closest effect intensity +; o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance +; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius1.xyz ) * g_vEffectCenterOoRadius1.w ); +; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius2.xyz ) * g_vEffectCenterOoRadius2.w ); +; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius3.xyz ) * g_vEffectCenterOoRadius3.w ); +; o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius4.xyz ) * g_vEffectCenterOoRadius4.w ); + +alloc $tmp1 +alloc $flEffect + +mov $flEffect, $cTwo +mad $flEffect, $flEffect, $cTwo, $cTwo + +sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_1 +dp3 $tmp1.w, $tmp1, $tmp1 +rsq $tmp1.w, $tmp1.w +rcp $tmp1.w, $tmp1.w +mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_1.w +min $flEffect, $flEffect, $tmp1.w + +sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_2 +dp3 $tmp1.w, $tmp1, $tmp1 +rsq $tmp1.w, $tmp1.w +rcp $tmp1.w, $tmp1.w +mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_2.w +min $flEffect, $flEffect, $tmp1.w + +sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_3 +dp3 $tmp1.w, $tmp1, $tmp1 +rsq $tmp1.w, $tmp1.w +rcp $tmp1.w, $tmp1.w +mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_3.w +min $flEffect, $flEffect, $tmp1.w + +sub $tmp1.xyz, $worldPos, $SHADER_SPECIFIC_CONST_4 +dp3 $tmp1.w, $tmp1, $tmp1 +rsq $tmp1.w, $tmp1.w +rcp $tmp1.w, $tmp1.w +mul $tmp1.w, $tmp1.w, $SHADER_SPECIFIC_CONST_4.w +min $flEffect, $flEffect, $tmp1.w + +mov oD0, $flEffect + +; float3 vWorldViewVector = normalize( vWorldPosition.xyz - cEyePos.xyz ); +; o.flDistanceToEffectCenter_flFresnelEffect.y = pow( saturate( dot( -vWorldViewVector.xyz, vWorldNormal.xyz ) ), 1.5f ); + +sub $tmp1, $worldPos, $cEyePos +&Normalize( $tmp1 ); +dp3 $tmp1, -$tmp1, $worldNormal +max $tmp1, $tmp1, $cZero +mul $tmp1, $tmp1, $tmp1 +mov oD1, $tmp1 + +free $tmp1 +free $flEffect + +;------------------------------------------------------------------------------ +; Texture coordinates +;------------------------------------------------------------------------------ + +mov oT0.xy, $vTexCoord0 + +alloc $tmp2 + +dp4 $tmp2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 +dp4 $tmp2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + +add oT1.xy, $tmp2, $SHADER_SPECIFIC_CONST_4 + +free $tmp2 + +; YUCK! This is to make texcoords continuous for mat_softwaretl +mov oT2, $cZero + +&FreeRegister( \$worldPos ); +&FreeRegister( \$worldNormal ); diff --git a/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp new file mode 100644 index 00000000..03ae509d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp @@ -0,0 +1,355 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +/* Example how to plug this into an existing shader: + + In the VMT: + // Flesh Interior Pass + "$FleshInteriorEnabled" "1" // Enables effect + "$FleshInteriorTexture" "models/Alyx/alyx_flesh_color" // Mask in alpha + "$FleshNormalTexture" "models/Alyx/alyx_flesh_normal" + "$FleshBorderTexture1D" "models/Alyx/alyx_flesh_border" + "$FleshInteriorNoiseTexture" "Engine/noise-blur-256x256" + "$FleshSubsurfaceTexture" "models/Alyx/alyx_flesh_subsurface" + "$FleshBorderNoiseScale" "1.5" // Flesh Noise UV scalar for border + "$FleshBorderWidth" "0.3" // Width of flesh border + "$FleshBorderSoftness" "0.42" // Border softness must be greater than 0.0 and up tp 0.5 + "$FleshBorderTint" "[1 1 1]" // Tint / brighten the border 1D texture + "$FleshGlossBrightness" "0.66" // Change the brightness of the glossy layer + "$FleshDebugForceFleshOn" "0" // DEBUG: This will force on full flesh for testing + "$FleshScrollSpeed" "1.0" + "Proxies" + { + "FleshInterior" + { + } + } + + #include "flesh_interior_blended_pass_helper.h" + + In BEGIN_SHADER_PARAMS: + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + Add this above SHADER_INIT_PARAMS() + // Flesh Interior Pass + void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) + { + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + } + + In SHADER_INIT_PARAMS() + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } + + In SHADER_INIT + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } + + At the very end of SHADER_DRAW + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + +==================================================================================================== */ + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "convar.h" +#include "flesh_interior_blended_pass_helper.h" + +// Auto generated inc files +#include "flesh_interior_blended_pass_vs20.inc" +#include "flesh_interior_blended_pass_ps20.inc" +#include "flesh_interior_blended_pass_ps20b.inc" + +void InitParamsFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, FleshInteriorBlendedPassVars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + SET_PARAM_STRING_IF_NOT_DEFINED( info.m_nFleshCubeTexture, "env_cubemap" ); // Default to in-game env map + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderNoiseScale, kDefaultBorderNoiseScale ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflDebugForceFleshOn, kDefaultDebugForceFleshOn ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius1, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius2, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius3, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_nvEffectCenterRadius4, kDefaultEffectCenterRadius, 4 ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncSubsurfaceTint, kDefaultSubsurfaceTint, 4 ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderWidth, kDefaultBorderWidth ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflBorderSoftness, kDefaultBorderSoftness ); + SET_PARAM_VEC_IF_NOT_DEFINED( info.m_ncBorderTint, kDefaultBorderTint, 4 ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlobalOpacity, kDefaultGlobalOpacity ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflGlossBrightness, kDefaultGlossBrightness ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nflScrollSpeed, kDefaultScrollSpeed ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nTime, 0.0f ); +} + +void InitFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, FleshInteriorBlendedPassVars_t &info ) +{ + // Load textures + pShader->LoadTexture( info.m_nFleshTexture, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nFleshNoiseTexture ); + pShader->LoadTexture( info.m_nFleshBorderTexture1D, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nFleshNormalTexture ); + pShader->LoadTexture( info.m_nFleshSubsurfaceTexture, TEXTUREFLAGS_SRGB ); + pShader->LoadCubeMap( info.m_nFleshCubeTexture, TEXTUREFLAGS_SRGB ); +} + +void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, FleshInteriorBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + // Reset shadow state manually since we're drawing from two materials + pShader->SetInitialShadowState(); + + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + // Vertex Shader + DECLARE_STATIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + + // Pixel Shader + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); + SET_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); + SET_STATIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); + } + + // Textures + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); // Noise texture not sRGB + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false ); // Normal texture not sRGB + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true ); + pShaderShadow->EnableSRGBWrite( true ); + + // Blending + pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableAlphaTest( true ); + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); + } + DYNAMIC_STATE + { + // Reset render state manually since we're drawing from two materials + pShaderAPI->SetDefaultState(); + + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + // Set Vertex Shader Combos + LightState_t lightState = { 0, false, false }; + pShaderAPI->GetDX9LightState( &lightState ); + DECLARE_DYNAMIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( flesh_interior_blended_pass_vs20 ); + + // Set Vertex Shader Constants + pShader->SetAmbientCubeDynamicStateVertexShader(); + + // Time % 1000 + float flCurrentTime = IS_PARAM_DEFINED( info.m_nTime ) && params[info.m_nTime]->GetFloatValue() > 0.0f ? params[info.m_nTime]->GetFloatValue() : pShaderAPI->CurrentTime(); + flCurrentTime *= IS_PARAM_DEFINED( info.m_nflScrollSpeed ) ? params[info.m_nflScrollSpeed]->GetFloatValue() : kDefaultScrollSpeed; // This is a dirty hack, but it works well enough + + float vVsConst0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vVsConst0[0] = flCurrentTime; + vVsConst0[0] -= (float)( (int)( vVsConst0[0] / 1000.0f ) ) * 1000.0f; + + // Noise UV scroll + vVsConst0[1] = flCurrentTime / 100.0f; + vVsConst0[1] -= (float)( (int)( vVsConst0[1] ) ); + + // Border noise scale + vVsConst0[2] = IS_PARAM_DEFINED( info.m_nflBorderNoiseScale ) ? params[info.m_nflBorderNoiseScale]->GetFloatValue() : kDefaultBorderNoiseScale; + + // Debug force flesh on + vVsConst0[3] = IS_PARAM_DEFINED( info.m_nflDebugForceFleshOn ) ? params[info.m_nflDebugForceFleshOn]->GetFloatValue() : kDefaultDebugForceFleshOn; + + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, vVsConst0, 1 ); + + // Flesh effect centers and radii + float vVsConst1[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius1 ) ) + { + params[info.m_nvEffectCenterRadius1]->GetVecValue( vVsConst1, 4 ); + if ( vVsConst1[3] < 0.001f ) + vVsConst1[3] = 0.001f; + vVsConst1[3] = 1.0f / vVsConst1[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, vVsConst1, 1 ); + + float vVsConst2[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius2 ) ) + { + params[info.m_nvEffectCenterRadius2]->GetVecValue( vVsConst2, 4 ); + if ( vVsConst2[3] < 0.001f ) + vVsConst2[3] = 0.001f; + vVsConst2[3] = 1.0f / vVsConst2[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, vVsConst2, 2 ); + + float vVsConst3[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius3 ) ) + { + params[info.m_nvEffectCenterRadius3]->GetVecValue( vVsConst3, 4 ); + if ( vVsConst3[3] < 0.001f ) + vVsConst3[3] = 0.001f; + vVsConst3[3] = 1.0f / vVsConst3[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vVsConst3, 3 ); + + float vVsConst4[4] = { kDefaultEffectCenterRadius[0], kDefaultEffectCenterRadius[1], kDefaultEffectCenterRadius[2], kDefaultEffectCenterRadius[3] }; + if ( IS_PARAM_DEFINED( info.m_nvEffectCenterRadius4 ) ) + { + params[info.m_nvEffectCenterRadius4]->GetVecValue( vVsConst4, 4 ); + if ( vVsConst4[3] < 0.001f ) + vVsConst4[3] = 0.001f; + vVsConst4[3] = 1.0f / vVsConst4[3]; // Pass 1.0/radius so we do a mul instead of a divide in the shader + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, vVsConst4, 4 ); + + // Set Pixel Shader Combos + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( flesh_interior_blended_pass_ps20 ); + } + + // Bind textures + pShader->BindTexture( SHADER_SAMPLER0, info.m_nFleshTexture ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nFleshNoiseTexture ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nFleshBorderTexture1D ); + pShader->BindTexture( SHADER_SAMPLER3, info.m_nFleshNormalTexture ); + pShader->BindTexture( SHADER_SAMPLER4, info.m_nFleshSubsurfaceTexture ); + pShader->BindTexture( SHADER_SAMPLER5, info.m_nFleshCubeTexture ); + + // Set Pixel Shader Constants + + // Subsurface tint + pShaderAPI->SetPixelShaderConstant( 0, IS_PARAM_DEFINED( info.m_ncSubsurfaceTint ) ? params[info.m_ncSubsurfaceTint]->GetVecValue() : kDefaultSubsurfaceTint, 1 ); + + // Border width + float vPsConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst1[0] = IS_PARAM_DEFINED( info.m_nflBorderWidth ) ? params[info.m_nflBorderWidth]->GetFloatValue() : kDefaultBorderWidth; + vPsConst1[0] = 1.0f / vPsConst1[0]; // ( 1.0f / g_flBorderWidthFromVmt ) + vPsConst1[1] = vPsConst1[0] - 1.0f; // ( 1.0f / g_flBorderWidthFromVmt ) - 1.0f + pShaderAPI->SetPixelShaderConstant( 1, vPsConst1, 1 ); + + // Border softness + float vPsConst2[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst2[0] = IS_PARAM_DEFINED( info.m_nflBorderSoftness ) ? params[info.m_nflBorderSoftness]->GetFloatValue() : kDefaultBorderSoftness; + if ( vPsConst2[0] < 0.01f ) + vPsConst2[0] = 0.01f; + else if ( vPsConst2[0] > 0.5f ) + vPsConst2[0] = 0.5f; + pShaderAPI->SetPixelShaderConstant( 2, vPsConst2, 1 ); + + // Border color tint + pShaderAPI->SetPixelShaderConstant( 3, IS_PARAM_DEFINED( info.m_ncBorderTint ) ? params[info.m_ncBorderTint]->GetVecValue() : kDefaultBorderTint, 1 ); + + // Global opacity + float vPsConst4[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst4[0] = IS_PARAM_DEFINED( info.m_nflGlobalOpacity ) ? params[info.m_nflGlobalOpacity]->GetFloatValue() : kDefaultGlobalOpacity; + pShaderAPI->SetPixelShaderConstant( 4, vPsConst4, 1 ); + + // Gloss brightness + float vPsConst5[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPsConst5[0] = IS_PARAM_DEFINED( info.m_nflGlossBrightness ) ? params[info.m_nflGlossBrightness]->GetFloatValue() : kDefaultGlossBrightness; + pShaderAPI->SetPixelShaderConstant( 5, vPsConst5, 1 ); + } + pShader->Draw(); +} diff --git a/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.h b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.h new file mode 100644 index 00000000..92b8d57a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.h @@ -0,0 +1,68 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef FLESH_INTERIOR_BLENDED_PASS_HELPER_H +#define FLESH_INTERIOR_BLENDED_PASS_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct FleshInteriorBlendedPassVars_t +{ + FleshInteriorBlendedPassVars_t() { memset( this, 0xFF, sizeof(FleshInteriorBlendedPassVars_t) ); } + + int m_nFleshTexture; + int m_nFleshNoiseTexture; + int m_nFleshBorderTexture1D; + int m_nFleshNormalTexture; + int m_nFleshSubsurfaceTexture; + int m_nFleshCubeTexture; + + int m_nflBorderNoiseScale; + int m_nflDebugForceFleshOn; + int m_nvEffectCenterRadius1; + int m_nvEffectCenterRadius2; + int m_nvEffectCenterRadius3; + int m_nvEffectCenterRadius4; + + int m_ncSubsurfaceTint; + int m_nflBorderWidth; + int m_nflBorderSoftness; // > 0.0f && < 0.5f ! + int m_ncBorderTint; + int m_nflGlobalOpacity; + int m_nflGlossBrightness; + int m_nflScrollSpeed; + + int m_nTime; +}; + +// Default values (Arrays should only be vec[4]) +static const float kDefaultBorderNoiseScale = 1.5f; +static const float kDefaultDebugForceFleshOn = 0.0f; +static const float kDefaultEffectCenterRadius[4] = { 0.0f, 0.0f, 0.0f, 0.0001f }; // Disabled by default +static const float kDefaultSubsurfaceTint[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; // Disabled by default +static const float kDefaultBorderWidth = 0.3f; +static const float kDefaultBorderSoftness = 0.42f; // > 0.0f && < 0.5f ! +static const float kDefaultBorderTint[4] = { 1.0f, 1.0f, 1.0f, 0.0f }; +static const float kDefaultGlobalOpacity = 1.0f; +static const float kDefaultGlossBrightness = 0.66f; +static const float kDefaultScrollSpeed = 1.0f; + +void InitParamsFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, FleshInteriorBlendedPassVars_t &info ); +void InitFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, FleshInteriorBlendedPassVars_t &info ); +void DrawFleshInteriorBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, FleshInteriorBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // FLESH_INTERIOR_BLENDED_PASS_HELPER_H diff --git a/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc new file mode 100644 index 00000000..3e288e56 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc @@ -0,0 +1,127 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// +// Includes ======================================================================================= +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +#include "common_vertexlitgeneric_dx9.h" + +// Texture Samplers =============================================================================== +sampler g_tBaseSampler : register( s0 ); +sampler g_tNoiseSampler : register( s1 ); +sampler g_tBorder1DSampler : register( s2 ); +sampler g_tNormalSampler : register( s3 ); +sampler g_tSubsurfaceSampler: register( s4 ); +sampler g_tCubeSampler : register( s5 ); + +// Shaders Constants and Globals ================================================================== +const float3 g_cSubsurfaceTint : register( c0 ); +const float2 g_flBorderWidth : register( c1 ); //{ 1.0f / g_flBorderWidthFromVmt, ( 1.0f / g_flBorderWidthFromVmt ) - 1.0f }; +const float g_flBorderSoftness : register( c2 ); +const float3 g_cBorderTint : register( c3 ); +const float g_flGlobalOpacity : register( c4 ); +const float g_flGlossBrightness : register( c5 ); + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float2 vTexCoord0 : TEXCOORD0; + float2 flDistanceToEffectCenter_flFresnelEffect : TEXCOORD1; + float4 vNoiseTexCoord : TEXCOORD2; + float3 vTangentViewVector : TEXCOORD3; + float3 cVertexLight : TEXCOORD4; + float3x3 mTangentSpaceTranspose : TEXCOORD5; + // second row : TEXCOORD6; + // third row : TEXCOORD7; +}; + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + // Color texture + float4 cBaseColor = tex2D( g_tBaseSampler, i.vTexCoord0.xy ); + float flFleshMaskFromTexture = cBaseColor.a; + + // Subsurface colors + float4 cSubsurfaceColor = tex2D( g_tSubsurfaceSampler, i.vTexCoord0.xy ); + cBaseColor.rgb += cBaseColor.rgb * cSubsurfaceColor.rgb * g_cSubsurfaceTint.rgb; + + // Scroll noise textures to ripple border of opening + float flNoise0 = tex2D( g_tNoiseSampler, i.vNoiseTexCoord.xy ).g; // Use green so we can DXT1 if we want + float flNoise1 = tex2D( g_tNoiseSampler, i.vNoiseTexCoord.wz ).g; // Use green so we can DXT1 if we want + float flNoise = ( flNoise0 + flNoise1 ) * 0.5f; + + // Generate 0-1 mask from distance computed in the VS + float flClampedInputMask = 0.0f; + flClampedInputMask = 1.0f - saturate( i.flDistanceToEffectCenter_flFresnelEffect.x ); + flClampedInputMask *= i.flDistanceToEffectCenter_flFresnelEffect.y; + flClampedInputMask *= flFleshMaskFromTexture; + + // Noise mask - Only apply noise around border of sphere + float flBorderMask = saturate( ( 1.0f - flClampedInputMask ) * g_flBorderWidth.x - g_flBorderWidth.y ); + float flNoiseMask = 1.0f - abs( ( flBorderMask * 2.0f ) - 1.0f ); + + // This is used to lerp in the 1D border texture over the flesh color + float flBorderMaskWithNoise = ( 1.0f - smoothstep( flNoiseMask - g_flBorderSoftness, flNoiseMask + g_flBorderSoftness, flNoise.r ) ) * flNoiseMask; + + // Border color + float vBorderUv = ( sign( flBorderMask - 0.5 ) * (1.0f - pow( flBorderMaskWithNoise, 4.0f )) * 0.5f ) + 0.5f; + float4 cBorderColor = 2.0f * tex2D( g_tBorder1DSampler, vBorderUv ); + cBorderColor.rgb *= g_cBorderTint; + cBorderColor.rgb *= flNoise; + + // Normal map + float4 vNormalMapValue = tex2D( g_tNormalSampler, i.vTexCoord0.xy ); + float3 vTangentNormal = ( vNormalMapValue.xyz * 2.0f ) - 1.0f; + vTangentNormal.xy += ( flNoise * 1.5f ) - 0.75f; // NOTE: This will denormalize the normal. + //float3 vWorldNormal = mul( i.mTangentSpaceTranspose, vTangentNormal.xyz ); + + // Specular gloss layer + float3 vTangentReflectionVector = reflect( i.vTangentViewVector.xyz, vTangentNormal.xyz ); + //vTangentReflectionVector.xy += ( flNoise * 1.5f ) - 0.75f; + float3 vWorldReflectionVector = mul( i.mTangentSpaceTranspose, vTangentReflectionVector.xyz ); + float3 cGlossLayer = ENV_MAP_SCALE * texCUBE( g_tCubeSampler, vWorldReflectionVector.xyz ).rgb; + cGlossLayer.rgb *= g_flGlossBrightness; + + // Gloss mask is just hard-coded fresnel for now + float flGlossMask = pow( saturate( dot( vTangentNormal.xyz, -i.vTangentViewVector.xyz ) ), 8.0f ); + + // Opacity + float flOpacity = 1.0f; + flOpacity = max( flBorderMaskWithNoise, step( flBorderMask, 0.5f ) ); + + // Apply global opacity + flOpacity *= g_flGlobalOpacity; + + //===============// + // Combine terms // + //===============// + float4 result; + result.rgb = cBaseColor.rgb * i.cVertexLight.rgb; + result.rgb += cGlossLayer.rgb * flGlossMask; + result.rgb *= pow( 1.0f - flBorderMaskWithNoise, 2.0f ); // Darken near border + result.rgb = lerp( result.rgb, cBorderColor.rgb, saturate( vBorderUv * 2.0f ) ); // bring in transition 1D texture + + //result.rgb = flClampedInputMask; + //result.rgb = flBorderMask; + //result.rgb = saturate( flClampedInputMask * 2.0f ); + //result.rgb = i.flDistanceToEffectCenter_flFresnelEffect.x;// * i.flDistanceToEffectCenter_flFresnelEffect.y; + //result.rgb = i.flDistanceToEffectCenter_flFresnelEffect.y * g_flBorderWidth.x - g_flBorderWidth.y; + //result.rgb = flNoiseMask; + //result.rgb = flBorderMaskWithNoise; + //result.rgb = flOpacity; + //result.rgb = flBorderUv; + //result.rgb = cBorderColor; + //result.rgb = -i.vTangentViewVector.z; + //result.rgb = vNormalMapValue.xyz; + //result.rgb = vTangentNormal.xyz; + //result.rgb = flGlossLayer; + //result.rgb = i.cVertexLight.rgb; + //result.rgb = texCUBE( g_tCubeSampler, vTangentNormal.xyz ).rgb; + //result.rgb = i.vTangentViewVector.x; + //result.rgb = cGlossLayer.rgb; + + // Set alpha for blending + result.a = flOpacity; + //result.a = 1.0f; + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +} diff --git a/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc new file mode 100644 index 00000000..2a361b01 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc @@ -0,0 +1,155 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +// Includes +#include "common_vs_fxc.h" + +// Globals +static const int g_iFogType = DOWATERFOG; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 g_vConst0 : register( SHADER_SPECIFIC_CONST_0 ); +#define g_flTime g_vConst0.x +#define g_flNoiseUvScroll g_vConst0.y +#define g_flBorderNoiseScale g_vConst0.z +#define g_flDebugForceFleshOn g_vConst0.w + +const float4 g_vEffectCenterOoRadius1 : register( SHADER_SPECIFIC_CONST_1 ); //= { -295.0f, -5.0f, 40.0f, 1.0f/20.0f }; +const float4 g_vEffectCenterOoRadius2 : register( SHADER_SPECIFIC_CONST_2 ); //= { -295.0f, 15.0f, 40.0f, 1.0f/10.0f }; +const float4 g_vEffectCenterOoRadius3 : register( SHADER_SPECIFIC_CONST_3 ); //= { -295.0f, 35.0f, 40.0f, 1.0f/10.0f }; +const float4 g_vEffectCenterOoRadius4 : register( SHADER_SPECIFIC_CONST_4 ); //= { -295.0f, 55.0f, 40.0f, 1.0f/10.0f }; + +// Structs +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vNormal : NORMAL; // Normal + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base texture coordinates + float3 vPosFlex : POSITION1; // Delta positions for flexing + float4 vTangent : TANGENT; +}; + +struct VS_OUTPUT +{ + float4 vProjPosition : POSITION; // Projection-space position + float2 vTexCoord0 : TEXCOORD0; + float2 flDistanceToEffectCenter_flFresnelEffect : TEXCOORD1; + float4 vNoiseTexCoord : TEXCOORD2; + float3 vTangentViewVector : TEXCOORD3; + float3 cVertexLight : TEXCOORD4; + float3x3 mTangentSpaceTranspose : TEXCOORD5; + // second row : TEXCOORD6; + // third row : TEXCOORD7; + +}; + +// Main +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + + // Flexes coming in from a separate stream (contribution masked by cFlexScale.x) + float4 vObjPosition = i.vPos; + vObjPosition.xyz += i.vPosFlex.xyz * cFlexScale.x; + + float3 vObjNormal; + float4 vObjTangent; + DecompressVertex_NormalTangent( i.vNormal, i.vTangent, vObjNormal, vObjTangent ); + + // Transform the position + float3 vWorldPosition = { 0.0f, 0.0f, 0.0f }; + float3 vWorldNormal = { 0.0f, 0.0f, 0.0f }; + float3 vWorldTangent = { 0.0f, 0.0f, 0.0f }; + float3 vWorldBinormal = { 0.0f, 0.0f, 0.0f }; + SkinPositionNormalAndTangentSpace( g_bSkinning, vObjPosition, vObjNormal, vObjTangent, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal, vWorldTangent, vWorldBinormal ); + + // Transform into projection space + float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.vProjPosition = vProjPosition; + + // Pass through tex coords + o.vTexCoord0.xy = i.vTexCoord0.xy; + + // Store the closest effect intensity + o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius1.xyz ) * g_vEffectCenterOoRadius1.w ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius2.xyz ) * g_vEffectCenterOoRadius2.w ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius3.xyz ) * g_vEffectCenterOoRadius3.w ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - g_vEffectCenterOoRadius4.xyz ) * g_vEffectCenterOoRadius4.w ); + + /* + // Test values for development in Alyx_interior map + o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance + float3 vTestPosition = { -295.0f, -5.0f, 40.0f }; + float flMinY = -5.0f; + float flMaxY = 66.0f; + vTestPosition.y = lerp( flMinY, flMaxY, ( abs( frac( g_flTime / 20.0f ) * 2.0 - 1.0 ) ) ); + //vTestPosition.y = lerp( flMinY, flMaxY, 0.65f ); + + //1.0f - saturate( i.flDistanceToEffectCenter_flFresnelEffect.x * 4.0f - 3.0f ) + + //o.flDistanceToEffectCenter_flFresnelEffect.x = 9999.0f; // A very large distance + + const float g_flInteriorRadius = 20.0f; + if ( g_flInteriorRadius ) + { + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - vTestPosition.xyz ) / g_flInteriorRadius ); + } + + const float g_flInteriorRadius2 = 14.0f; + if ( g_flInteriorRadius2 ) + { + vTestPosition.y = lerp( flMinY, flMaxY, 0.65f ); + //vTestPosition.z = lerp( 37, 45, ( abs( frac( g_flTime / 4.0f ) * 2.0 - 1.0 ) ) ); + o.flDistanceToEffectCenter_flFresnelEffect.x = min( o.flDistanceToEffectCenter_flFresnelEffect.x, length( vWorldPosition.xyz - vTestPosition.xyz ) / g_flInteriorRadius2 ); + } + //*/ + + if ( g_flDebugForceFleshOn ) + { + o.flDistanceToEffectCenter_flFresnelEffect.x = 0.0f; + } + + // Fresnel mask + float3 vWorldViewVector = normalize( vWorldPosition.xyz - cEyePos.xyz ); + o.flDistanceToEffectCenter_flFresnelEffect.y = pow( saturate( dot( -vWorldViewVector.xyz, vWorldNormal.xyz ) ), 1.5f ); + + // Noise UV + o.vNoiseTexCoord.xy = o.vTexCoord0.xy * g_flBorderNoiseScale + g_flNoiseUvScroll; + o.vNoiseTexCoord.zw = o.vTexCoord0.xy * g_flBorderNoiseScale - g_flNoiseUvScroll; // Will fetch as wz to avoid matching layers + + // Tangent view vector + o.vTangentViewVector.xyz = Vec3WorldToTangentNormalized( vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + // Compute vertex lighting + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + +#if ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) + o.cVertexLight.rgb = DoLighting( vWorldPosition, vWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert ); +#else + o.cVertexLight.rgb = DoLightingUnrolled( vWorldPosition, vWorldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); +#endif + + // Tangent space transform + o.mTangentSpaceTranspose[0] = float3( vWorldTangent.x, vWorldBinormal.x, vWorldNormal.x ); + o.mTangentSpaceTranspose[1] = float3( vWorldTangent.y, vWorldBinormal.y, vWorldNormal.y ); + o.mTangentSpaceTranspose[2] = float3( vWorldTangent.z, vWorldBinormal.z, vWorldNormal.z ); + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh new file mode 100644 index 00000000..fbb4393f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r1, t2, 1-t3.a ; envmap * envmapmask alpha +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh new file mode 100644 index 00000000..9380ec63 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh @@ -0,0 +1,9 @@ +ps.1.1 + +tex t0 ; base 1 +tex t1 ; base 2 + +mov r1, t1 +lrp r0, 1-v0.a, t0, r1 +mul r0, r0, c0 + diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_decal.cpp b/sp/src/materialsystem/stdshaders/lightmappedgeneric_decal.cpp new file mode 100644 index 00000000..9e74b5cf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_decal.cpp @@ -0,0 +1,135 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "lightmappedgeneric_decal.inc" +#include "mathlib/bumpvects.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +BEGIN_VS_SHADER( LightmappedGeneric_Decal, + "Help for LightmappedGeneric_Decal" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + SET_FLAGS( MATERIAL_VAR_DECAL ); + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); + + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if ( !params[BASETEXTURE]->GetTextureValue()->IsTranslucent() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + } + + void DrawDecal( IMaterialVar **params, IShaderDynamicAPI *pShaderAPI, IShaderShadow *pShaderShadow ) + { + if( IsSnapshotting() ) + { + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + SetNormalBlendingShadowState( BASETEXTURE, true ); + + int pTexCoords[3] = { 2, 2, 1 }; + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION | VERTEX_COLOR, 3, pTexCoords, 0 ); + + lightmappedgeneric_decal_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "LightmappedGeneric_Decal", vshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( "LightmappedGeneric_Decal" ); + FogToFogColor(); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + // Load the z^2 components of the lightmap coordinate axes only + // This is (N dot basis)^2 + Vector vecZValues( g_localBumpBasis[0].z, g_localBumpBasis[1].z, g_localBumpBasis[2].z ); + vecZValues *= vecZValues; + + Vector4D basis[3]; + basis[0].Init( vecZValues.x, vecZValues.x, vecZValues.x, 0.0f ); + basis[1].Init( vecZValues.y, vecZValues.y, vecZValues.y, 0.0f ); + basis[2].Init( vecZValues.z, vecZValues.z, vecZValues.z, 0.0f ); + pShaderAPI->SetPixelShaderConstant( 0, (float*)basis, 3 ); + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + SetModulationPixelShaderDynamicState( 3 ); + + lightmappedgeneric_decal_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + SHADER_DRAW + { + if( UsingFlashlight( params ) ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, false, -1, -1, -1, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 ); + } + else + { + DrawDecal( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc b/sp/src/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc new file mode 100644 index 00000000..fd457be8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc @@ -0,0 +1,59 @@ +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); +sampler LightMap0Sampler : register( s1 ); +sampler LightMap1Sampler : register( s2 ); +sampler LightMap2Sampler : register( s3 ); + +const float4 g_LightMap0Color : register( c0 ); +const float4 g_LightMap1Color : register( c1 ); +const float4 g_LightMap2Color : register( c2 ); +const float4 g_ModulationColor : register( c3 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + + +struct PS_INPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + float2 vTexCoord3 : TEXCOORD3; + float4 worldPos_projPosZ : TEXCOORD4; // Necessary for pixel fog + + float4 vColor : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 resultColor; + + // output = lightmapColor[0] * ( ( N dot basis[0] )^2 ) + + // lightmapColor[1] * ( ( N dot basis[1] )^2 ) + + // lightmapColor[2] * ( ( N dot basis[2] )^2 ) + + resultColor = tex2D( LightMap0Sampler, i.vTexCoord1 ) * g_LightMap0Color; + resultColor = (tex2D( LightMap1Sampler, i.vTexCoord2 ) * g_LightMap1Color) + resultColor; + resultColor = (tex2D( LightMap2Sampler, i.vTexCoord3 ) * g_LightMap2Color) + resultColor; + + // Modulate by decal texture + float4 decalColor = tex2D( BaseTextureSampler, i.vTexCoord0 ); + resultColor.rgb = resultColor * decalColor; + resultColor.a = decalColor.a; + + // Modulate by constant color + resultColor = resultColor * g_ModulationColor; + + // Modulate by per-vertex factor + resultColor = resultColor * i.vColor; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( resultColor, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc b/sp/src/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc new file mode 100644 index 00000000..0b7db284 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc @@ -0,0 +1,74 @@ +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; + +const float4 cShaderConst0 : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cShaderConst1 : register( SHADER_SPECIFIC_CONST_1 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + + float4 vColor : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + float2 vTexCoord3 : TEXCOORD3; + + float4 worldPos_projPosZ : TEXCOORD4; // Necessary for pixel fog + + float4 vColor : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul( v.vPos, cModel[0] ); + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + + // Compute the texture coordinates given the offset between + // each bumped lightmap + float2 offset; + offset.x = v.vTexCoord2.x; + offset.y = 0.0f; + + o.vTexCoord0.x = dot( v.vTexCoord0, cShaderConst0 ); + o.vTexCoord0.y = dot( v.vTexCoord0, cShaderConst1 ); + + o.vTexCoord1 = offset + v.vTexCoord1.xy; + o.vTexCoord2 = (offset * 2.0) + v.vTexCoord1.xy; + o.vTexCoord3 = (offset * 3.0) + v.vTexCoord1.xy; + + o.vColor = v.vColor; + + return o; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp new file mode 100644 index 00000000..f55f8883 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp @@ -0,0 +1,288 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( LightmappedGeneric, LightmappedGeneric_DX6 ) + +BEGIN_SHADER( LightmappedGeneric_DX6, + "Help for LightmappedGeneric_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "90", "Do specular pass only on dxlevel or higher (ie.80, 81, 90)" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + if( params[BASETEXTURE]->IsDefined() ) + { + if( !IS_FLAG_SET(MATERIAL_VAR_MULTIPASS) ) + { + params[ENVMAP]->SetUndefined(); + params[ENVMAPMASK]->SetUndefined(); + } + } + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + + SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + LoadCubeMap( ENVMAP ); + } + else + { + LoadTexture( ENVMAP ); + } + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + { + LoadTexture( ENVMAPMASK ); + } + } + } + + SHADER_FALLBACK + { + return 0; + } + + int GetDrawFlagsPass1(IMaterialVar** params) + { + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD0; + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + flags |= SHADER_DRAW_COLOR; + if (params[BASETEXTURE]->IsTexture()) + flags |= SHADER_DRAW_TEXCOORD1; + return flags; + } + + void DrawLightmapOnly( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); + + SetModulationShadowState(); + SetDefaultBlendingShadowState( ); + pShaderShadow->DrawFlags( GetDrawFlagsPass1( params ) ); + DefaultFog(); + } + DYNAMIC_STATE + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + SetModulationDynamicState(); + } + Draw(); + } + + void DrawBaseTimesLightmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // Base times lightmap + SHADOW_STATE + { + // alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // Alpha blending + SetDefaultBlendingShadowState( BASETEXTURE, true ); + + // Independenly configure alpha and color + pShaderShadow->EnableAlphaPipe( true ); + + // color channel + + // base + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // lightmap + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); + + pShaderShadow->EnableConstantColor( IsColorModulating() ); + + // alpha channel + pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); + if ((! IsColorModulating()) && ( ! IsAlphaModulating())) + pShaderShadow->EnableVertexAlpha( IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA) ); + pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, TextureIsTranslucent(BASETEXTURE, true) ); + pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE1, false ); + + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD1; + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + { + if ( (! IsColorModulating()) && ( ! IsAlphaModulating())) + flags |= SHADER_DRAW_COLOR; + + } + if (params[BASETEXTURE]->IsTexture()) + { + flags |= SHADER_DRAW_TEXCOORD0; + } + + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + } + DYNAMIC_STATE + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + SetModulationDynamicState(); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableAlphaPipe( false ); + } + } + + void DrawMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // Pass 1 : Base * lightmap or just lightmap + if ( params[BASETEXTURE]->IsTexture() ) + { + DrawBaseTimesLightmap( params, pShaderAPI, pShaderShadow ); + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + + // Draw the selfillum pass + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) + { + FixedFunctionSelfIlluminationPass( + SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); + } + } + else + { + DrawLightmapOnly( params, pShaderAPI, pShaderShadow ); + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + + // Pass 2 : Masked environment map + if (params[ENVMAP]->IsTexture()) + { + FixedFunctionAdditiveMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + } + + SHADER_DRAW + { + bool hasFlashlight = UsingFlashlight( params ); + + if( hasFlashlight ) + { + DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + } + else + { + // Base * Lightmap + env + DrawMode1( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER + + +//----------------------------------------------------------------------------- +// This allows us to use a block labelled 'Water_DX60' in the water materials +//----------------------------------------------------------------------------- +BEGIN_INHERITED_SHADER( Water_DX60, LightmappedGeneric_DX6, "Help for Water_DX60" ) +END_INHERITED_SHADER + diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp new file mode 100644 index 00000000..8464f94f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp @@ -0,0 +1,802 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + + +#include "lightmappedgeneric_vs11.inc" +#include "unlitgeneric_vs11.inc" +#include "worldvertextransition_seamless.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); + +DEFINE_FALLBACK_SHADER( LightmappedGeneric, LightmappedGeneric_DX8 ) + +BEGIN_VS_SHADER( LightmappedGeneric_DX8, + "Help for LightmappedGeneric_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "amount of detail texture to apply" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_INTEGER, "90", "Do specular pass only on dxlevel or higher (ie.80, 81, 90)" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_BOOL, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( FORCEBUMP, SHADER_PARAM_TYPE_BOOL, "0", "0 == Do bumpmapping if the card says it can handle it. 1 == Always do bumpmapping." ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + END_SHADER_PARAMS + + virtual bool ShouldUseBumpmapping( IMaterialVar **params ) + { + return g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined(); + } + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. + if( ShouldUseBumpmapping( params ) && params[ALBEDO]->IsDefined() && + params[BASETEXTURE]->IsDefined() && + !( params[NODIFFUSEBUMPLIGHTING]->IsDefined() && params[NODIFFUSEBUMPLIGHTING]->GetIntValue() ) ) + { + params[BASETEXTURE]->SetStringValue( params[ALBEDO]->GetStringValue() ); + } + + if( IsUsingGraphics() && params[ENVMAP]->IsDefined() && !CanUseEditorMaterials() ) + { + if( stricmp( params[ENVMAP]->GetStringValue(), "env_cubemap" ) == 0 ) + { + Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); + params[ENVMAP]->SetUndefined(); + } + } + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + { + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + } + + if( !params[ENVMAPTINT]->IsDefined() ) + { + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[SELFILLUMTINT]->IsDefined() ) + { + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[DETAILSCALE]->IsDefined() ) + { + params[DETAILSCALE]->SetFloatValue( 4.0f ); + } + + if( !params[DETAILBLENDFACTOR]->IsDefined() ) + { + params[DETAILBLENDFACTOR]->SetFloatValue( 1.0f ); + } + + if( !params[FRESNELREFLECTION]->IsDefined() ) + { + params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); + } + + if( !params[ENVMAPMASKFRAME]->IsDefined() ) + { + params[ENVMAPMASKFRAME]->SetIntValue( 0 ); + } + + if( !params[ENVMAPFRAME]->IsDefined() ) + { + params[ENVMAPFRAME]->SetIntValue( 0 ); + } + + if( !params[BUMPFRAME]->IsDefined() ) + { + params[BUMPFRAME]->SetIntValue( 0 ); + } + + if( !params[ENVMAPCONTRAST]->IsDefined() ) + { + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + } + + if( !params[ENVMAPSATURATION]->IsDefined() ) + { + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + } + + if( !params[ALPHATESTREFERENCE]->IsDefined() ) + { + params[ALPHATESTREFERENCE]->SetFloatValue( 0.0f ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( ShouldUseBumpmapping( params ) && (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0) ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && (params[ENVMAPOPTIONAL]->GetIntValue() > g_pHardwareConfig->GetDXSupportLevel()) ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + + if( params[SEAMLESS_SCALE]->IsDefined() && params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) + { + if( params[BUMPMAP]->IsDefined() ) + { + Warning( "Can't use $bumpmap with $seamless_scale for lightmappedgeneric_dx8. Implicitly disabling $bumpmap: %s\n", pMaterialName ); + params[BUMPMAP]->SetUndefined(); + } + if( params[ENVMAP]->IsDefined() ) + { + Warning( "Can't use $envmap with $seamless_scale for lightmappedgeneric_dx8. Implicitly disabling $envmap: %s\n", pMaterialName ); + params[ENVMAP]->SetUndefined(); + } + } + + if ( !params[SEAMLESS_SCALE]->IsDefined() ) + { + // zero means don't do seamless mapping. + params[SEAMLESS_SCALE]->SetFloatValue( 0.0f ); + } + + // Get rid of envmap if we aren't using bumpmapping + // *and* we have normalmapalphaenvmapmask *and* we don't have envmapmask elsewhere + if ( params[ENVMAP]->IsDefined() && params[BUMPMAP]->IsDefined() && IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ) && !ShouldUseBumpmapping( params ) ) + { + if ( !IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) && !params[ENVMAPMASK]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + } + } + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80) + return "LightmappedGeneric_DX6"; + + if ( IsPC() && g_pHardwareConfig->PreferReducedFillrate() ) + return "LightmappedGeneric_NoBump_DX8"; + + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + + if( ShouldUseBumpmapping( params ) ) + { + LoadBumpMap( BUMPMAP ); + } + + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + LoadCubeMap( ENVMAP ); + else + LoadTexture( ENVMAP ); + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + LoadTexture( ENVMAPMASK ); + } + + if( ShouldUseBumpmapping( params ) ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + } + +#ifndef USE_HLSL_PIXEL_SHADERS + inline const char *GetPixelShaderName( IMaterialVar** params, bool bBumpedEnvMap ) + { + static char const* s_pPixelShaders[] = + { + // Unmasked + "LightmappedGeneric_EnvMapV2", + "LightmappedGeneric_SelfIlluminatedEnvMapV2", + + "LightmappedGeneric_BaseAlphaMaskedEnvMapV2", + "LightmappedGeneric_SelfIlluminatedEnvMapV2", + + // Env map mask + "LightmappedGeneric_MaskedEnvMapV2", + "LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2", + + "LightmappedGeneric_MaskedEnvMapV2", + "LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2", + }; + + if (!params[BASETEXTURE]->IsTexture()) + { + if (params[ENVMAP]->IsTexture() && !bBumpedEnvMap ) + { + if (!params[ENVMAPMASK]->IsDefined() ) + { + return "LightmappedGeneric_EnvmapNoTexture"; + } + else + { + return "LightmappedGeneric_MaskedEnvmapNoTexture"; + } + } + else + { + return "LightmappedGeneric_NoTexture"; + } + } + else + { + if (params[ENVMAP]->IsTexture() && !bBumpedEnvMap ) + { + int pshIndex = 0; + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + pshIndex |= 0x1; + if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + pshIndex |= 0x2; + if (params[ENVMAPMASK]->IsTexture()) + pshIndex |= 0x4; + return s_pPixelShaders[pshIndex]; + } + else + { + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + return "LightmappedGeneric_SelfIlluminated"; + else + return "LightmappedGeneric"; + } + } + } +#endif + + void DrawUnbumpedUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap ) + { + bool hasEnvmap = params[ENVMAP]->IsTexture() && !bBumpedEnvMap; + bool hasBaseTexture = params[BASETEXTURE]->IsTexture(); + bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool hasEnvmapCameraSpace = IS_FLAG_SET( MATERIAL_VAR_ENVMAPCAMERASPACE ); + bool hasEnvmapSphere = IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ); + + if ( hasEnvmap || hasBaseTexture || hasVertexColor || !bBumpedEnvMap ) + { + SHADOW_STATE + { + // Alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + if ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); + } + + // Base texture on stage 0 + if (params[BASETEXTURE]->IsTexture()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + } + + // Lightmap on stage 1 + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + int fmt = VERTEX_POSITION; + + if ( hasEnvmap ) + { + fmt |= VERTEX_NORMAL; + + // envmap on stage 2 + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // envmapmask on stage 3 + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + } + + if (params[BASETEXTURE]->IsTexture() || bBumpedEnvMap) + { + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + else + { + SetDefaultBlendingShadowState( ENVMAPMASK, false ); + } + + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + { + fmt |= VERTEX_COLOR; + } + + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( false ); + vshIndex.SetENVMAP( hasEnvmap ); + vshIndex.SetENVMAPCAMERASPACE( hasEnvmap && hasEnvmapCameraSpace ); + vshIndex.SetENVMAPSPHERE( hasEnvmap && hasEnvmapSphere ); + vshIndex.SetVERTEXCOLOR( hasVertexColor ); + pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + const char *pshName = GetPixelShaderName( params, bBumpedEnvMap ); + pShaderShadow->SetPixelShader( pshName ); + DefaultFog(); + } + DYNAMIC_STATE + { + if (hasBaseTexture) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + if ( hasEnvmap ) + { + BindTexture( SHADER_SAMPLER2, ENVMAP, ENVMAPFRAME ); + + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + if (params[ENVMAPMASK]->IsTexture() ) + BindTexture( SHADER_SAMPLER3, ENVMAPMASK, ENVMAPMASKFRAME ); + else + BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME ); + + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); + } + + if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || + IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) + { + LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); + } + SetEnvMapTintPixelShaderDynamicState( 2, ENVMAPTINT, -1 ); + } + + if ( !hasEnvmap || hasBaseTexture || hasVertexColor ) + { + SetModulationVertexShaderDynamicState(); + } + EnablePixelShaderOverbright( 0, true, true ); + SetPixelShaderConstant( 1, SELFILLUMTINT ); + + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + if ( bBumpedEnvMap ) + { + DrawWorldBumpedSpecularLighting( + BUMPMAP, ENVMAP, BUMPFRAME, ENVMAPFRAME, + ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, + BUMPTRANSFORM, FRESNELREFLECTION, + hasEnvmap || hasBaseTexture || hasVertexColor ); + } + } + + void DrawDetailNoEnvmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doSelfIllum ) + { + SHADOW_STATE + { + // Alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // Base texture on stage 0 + if (params[BASETEXTURE]->IsTexture()) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Lightmap on stage 1 + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + // Detail on stage 2 + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + int fmt = VERTEX_POSITION; + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + fmt |= VERTEX_COLOR; + + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( true ); + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + vshIndex.SetVERTEXCOLOR( IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); + pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + if (!params[BASETEXTURE]->IsTexture()) + { + pShaderShadow->SetPixelShader("LightmappedGeneric_DetailNoTexture"); + } + else + { + if (!IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || (!doSelfIllum)) + { + pShaderShadow->SetPixelShader("LightmappedGeneric_Detail"); + } + else + { + pShaderShadow->SetPixelShader("LightmappedGeneric_DetailSelfIlluminated"); + } + } + DefaultFog(); + } + DYNAMIC_STATE + { + if (params[BASETEXTURE]->IsTexture()) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + BindTexture( SHADER_SAMPLER2, DETAIL, FRAME ); + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); + + SetModulationVertexShaderDynamicState(); + EnablePixelShaderOverbright( 0, true, true ); + + if (doSelfIllum) + { + SetPixelShaderConstant( 1, SELFILLUMTINT ); + } + float c2[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + c2[0] = c2[1] = c2[2] = c2[3] = params[DETAILBLENDFACTOR]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); + + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + inline const char *GetAdditiveEnvmapPixelShaderName( bool usingMask, + bool usingBaseTexture, bool usingBaseAlphaEnvmapMask ) + { + static char const* s_pPixelShaders[] = + { + "LightmappedGeneric_AddEnvmapNoTexture", + "LightmappedGeneric_AddEnvmapMaskNoTexture", + }; + + if ( !usingMask && usingBaseTexture && usingBaseAlphaEnvmapMask ) + return "LightmappedGeneric_AddBaseAlphaMaskedEnvMap"; + + int pshIndex = 0; + if (usingMask) + pshIndex |= 0x1; + return s_pPixelShaders[pshIndex]; + } + + void DrawAdditiveEnvmap( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + bool usingBaseTexture = params[BASETEXTURE]->IsTexture(); + bool usingMask = params[ENVMAPMASK]->IsTexture(); + bool usingBaseAlphaEnvmapMask = IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK); + SHADOW_STATE + { + // Alpha test + pShaderShadow->EnableAlphaTest( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); + + // envmap on stage 2 + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // envmapmask on stage 3 + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + + if (params[BASETEXTURE]->IsTexture()) + { + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + } + else + { + SetAdditiveBlendingShadowState( ENVMAPMASK, false ); + } + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + // Compute the vertex shader index. + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( false ); + vshIndex.SetENVMAP( true ); + vshIndex.SetENVMAPCAMERASPACE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) ); + vshIndex.SetENVMAPSPHERE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ); + vshIndex.SetVERTEXCOLOR( false ); + s_pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + const char *pshName = GetAdditiveEnvmapPixelShaderName( usingMask, + usingBaseTexture, usingBaseAlphaEnvmapMask ); + pShaderShadow->SetPixelShader( pshName ); + FogToBlack(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER2, ENVMAP, ENVMAPFRAME ); + + if (usingMask || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + { + if (usingMask) + BindTexture( SHADER_SAMPLER3, ENVMAPMASK, ENVMAPMASKFRAME ); + else + BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME ); + + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); + } + + SetPixelShaderConstant( 2, ENVMAPTINT ); + + if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) + { + LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); + } + + SetModulationVertexShaderDynamicState(); + + // Compute the vertex shader index. + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + void DrawDetailMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap ) + { + // Mode 1 : + // Pass 1 : B * L * D + Self Illum + // Pass 2 : Add E * M + + // Draw the detail w/ no envmap + DrawDetailNoEnvmap( params, pShaderAPI, pShaderShadow, true ); + + if ( !bBumpedEnvMap ) + { + DrawAdditiveEnvmap( params, pShaderAPI, pShaderShadow ); + } + else + { + DrawWorldBumpedSpecularLighting( + BUMPMAP, ENVMAP, BUMPFRAME, ENVMAPFRAME, + ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, + BUMPTRANSFORM, FRESNELREFLECTION, + true ); + } + } + + void DrawDetailUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBumpedEnvMap ) + { + // We don't have enough textures; gotta do this in two passes if there's envmapping + if (!params[ENVMAP]->IsTexture()) + { + DrawDetailNoEnvmap( params, pShaderAPI, pShaderShadow, IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) ); + } + else + { + if (!params[BASETEXTURE]->IsTexture()) + { + // If there's an envmap but no base texture, ignore detail + DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); + } + else + { + DrawDetailMode1( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); + } + } + } + + void DrawUnbumpedSeamlessUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // This is the seamless_scale version, which doesn't use $detail or $bumpmap + SHADOW_STATE + { + // three copies of the base texture for seamless blending + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + // lightmap + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + worldvertextransition_seamless_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition_Seamless", vshIndex.GetIndex() ); + + int pshIndex = 0; + pShaderShadow->SetPixelShader( "WorldVertexTransition_Seamless", pshIndex ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + // Texture 0..2 + if( bLightingOnly ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); + } + else + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); + } + + // Texture 3 = lightmap + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); + + EnablePixelShaderOverbright( 0, true, true ); + + float fSeamlessScale = params[SEAMLESS_SCALE]->GetFloatValue(); + float map_scale[4]= { fSeamlessScale, fSeamlessScale, fSeamlessScale, fSeamlessScale }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale ); + + worldvertextransition_seamless_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + SHADER_DRAW + { + bool hasFlashlight = UsingFlashlight( params ); + bool bBump = ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture() && + (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0); + bool bSSBump = bBump && ( params[SSBUMP]->GetIntValue() != 0 ); + + if( hasFlashlight ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 ); + } + else if( bBump ) + { + DrawWorldBumpedUsingVertexShader( + BASETEXTURE, BASETEXTURETRANSFORM, + BUMPMAP, BUMPFRAME, BUMPTRANSFORM, ENVMAPMASK, ENVMAPMASKFRAME, ENVMAP, + ENVMAPFRAME, ENVMAPTINT, COLOR, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, FRAME, FRESNELREFLECTION, + false, -1, -1, -1, bSSBump ); + } + else + { + bool bBumpedEnvMap = ShouldUseBumpmapping( params ) && params[BUMPMAP]->IsTexture() && params[ENVMAP]->IsTexture(); + if (!params[DETAIL]->IsTexture()) + { + if( params[SEAMLESS_SCALE]->GetFloatValue() != 0.0f ) + { + DrawUnbumpedSeamlessUsingVertexShader( params, pShaderAPI, pShaderShadow ); + } + else + { + DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); + } + } + else + { + DrawDetailUsingVertexShader( params, pShaderAPI, pShaderShadow, bBumpedEnvMap ); + } + } + } +END_SHADER + + +//----------------------------------------------------------------------------- +// Version that doesn't do bumpmapping +//----------------------------------------------------------------------------- +BEGIN_INHERITED_SHADER( LightmappedGeneric_NoBump_DX8, LightmappedGeneric_DX8, + "Help for LightmappedGeneric_NoBump_DX8" ) + + SHADER_FALLBACK + { + if (g_pHardwareConfig->GetDXSupportLevel() < 80) + return "LightmappedGeneric_DX6"; + + return 0; + } + + virtual bool ShouldUseBumpmapping( IMaterialVar **params ) + { + if ( !g_pConfig->UseBumpmapping() ) + return false; + + if ( !params[BUMPMAP]->IsDefined() ) + return false; + + return ( params[FORCEBUMP]->GetIntValue() != 0 ); + } + +END_INHERITED_SHADER diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp new file mode 100644 index 00000000..bac124a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp @@ -0,0 +1,164 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "convar.h" +#include "lightmappedgeneric_dx9_helper.h" + +static LightmappedGeneric_DX9_Vars_t s_info; + + +BEGIN_VS_SHADER( LightmappedGeneric, + "Help for LightmappedGeneric" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + + SHADER_PARAM( ALPHA2, SHADER_PARAM_TYPE_FLOAT, "1", "" ) + + // detail (multi-) texturing + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( BUMPMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( BUMPMASK, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/lightmappedtexture", "Blended texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $basetexture2" ) + SHADER_PARAM( BASETEXTURENOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( BASETEXTURE2NOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "light munging lookup texture" ) + SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) + SHADER_PARAM( MASKEDBLENDING, SHADER_PARAM_TYPE_INTEGER, "0", "blend using texture with no vertex alpha. For using texture blending on non-displacements" ) + SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + + SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.") + SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha."); + SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha."); + + SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") + SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) + SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline") + SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") + SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") + SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") + SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") +END_SHADER_PARAMS + + void SetupVars( LightmappedGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + + info.m_nAlpha2 = ALPHA2; + + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTint = DETAILTINT; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nFresnelReflection = FRESNELREFLECTION; + info.m_nNoDiffuseBumpLighting = NODIFFUSEBUMPLIGHTING; + info.m_nBumpmap2 = BUMPMAP2; + info.m_nBumpFrame2 = BUMPFRAME2; + info.m_nBumpTransform2 = BUMPTRANSFORM2; + info.m_nBumpMask = BUMPMASK; + info.m_nBaseTexture2 = BASETEXTURE2; + info.m_nBaseTexture2Frame = FRAME2; + info.m_nBaseTextureNoEnvmap = BASETEXTURENOENVMAP; + info.m_nBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP; + info.m_nDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nLightWarpTexture = LIGHTWARPTEXTURE; + info.m_nBlendModulateTexture = BLENDMODULATETEXTURE; + info.m_nMaskedBlending = MASKEDBLENDING; + info.m_nBlendMaskTransform = BLENDMASKTRANSFORM; + info.m_nSelfShadowedBumpFlag = SSBUMP; + info.m_nSeamlessMappingScale = SEAMLESS_SCALE; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + + info.m_nSoftEdges = SOFTEDGES; + info.m_nEdgeSoftnessStart = EDGESOFTNESSSTART; + info.m_nEdgeSoftnessEnd = EDGESOFTNESSEND; + info.m_nOutline = OUTLINE; + info.m_nOutlineColor = OUTLINECOLOR; + info.m_nOutlineAlpha = OUTLINEALPHA; + info.m_nOutlineStart0 = OUTLINESTART0; + info.m_nOutlineStart1 = OUTLINESTART1; + info.m_nOutlineEnd0 = OUTLINEEND0; + info.m_nOutlineEnd1 = OUTLINEEND1; + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "LightmappedGeneric_DX8"; + + return 0; + } + + // Set up anything that is necessary to make decisions in SHADER_FALLBACK. + SHADER_INIT_PARAMS() + { + SetupVars( s_info ); + InitParamsLightmappedGeneric_DX9( this, params, pMaterialName, s_info ); + } + + SHADER_INIT + { + SetupVars( s_info ); + InitLightmappedGeneric_DX9( this, params, s_info ); + } + + SHADER_DRAW + { + DrawLightmappedGeneric_DX9( this, params, pShaderAPI, pShaderShadow, s_info, pContextDataPtr ); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp new file mode 100644 index 00000000..9da6716d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp @@ -0,0 +1,1085 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Lightmap only shader +// +// $Header: $ +// $NoKeywords: $ +//============================================================================= + +#include "lightmappedgeneric_dx9_helper.h" +#include "BaseVSShader.h" +#include "commandbuilder.h" +#include "convar.h" +#include "lightmappedgeneric_ps20.inc" +#include "lightmappedgeneric_vs20.inc" +#include "lightmappedgeneric_ps20b.inc" + +#include "tier0/memdbgon.h" + +ConVar mat_disable_lightwarp( "mat_disable_lightwarp", "0" ); +ConVar mat_disable_fancy_blending( "mat_disable_fancy_blending", "0" ); +ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); +ConVar my_mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); +extern ConVar r_flashlight_version2; + +class CLightmappedGeneric_DX9_Context : public CBasePerMaterialContextData +{ +public: + uint8 *m_pStaticCmds; + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; + + bool m_bVertexShaderFastPath; + bool m_bPixelShaderFastPath; + bool m_bPixelShaderForceFastPathBecauseOutline; + bool m_bFullyOpaque; + bool m_bFullyOpaqueWithoutAlphaTest; + + void ResetStaticCmds( void ) + { + if ( m_pStaticCmds ) + { + delete[] m_pStaticCmds; + m_pStaticCmds = NULL; + } + } + + CLightmappedGeneric_DX9_Context( void ) + { + m_pStaticCmds = NULL; + } + + ~CLightmappedGeneric_DX9_Context( void ) + { + ResetStaticCmds(); + } + +}; + + +void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info ) +{ + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. + if( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() && + !( params[info.m_nNoDiffuseBumpLighting]->IsDefined() && params[info.m_nNoDiffuseBumpLighting]->GetIntValue() ) ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + if( pShader->IsUsingGraphics() && params[info.m_nEnvmap]->IsDefined() && !pShader->CanUseEditorMaterials() ) + { + if( stricmp( params[info.m_nEnvmap]->GetStringValue(), "env_cubemap" ) == 0 ) + { + Warning( "env_cubemap used on world geometry without rebuilding map. . ignoring: %s\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + } + + if ( (mat_disable_lightwarp.GetBool() ) && + (info.m_nLightWarpTexture != -1) ) + { + params[info.m_nLightWarpTexture]->SetUndefined(); + } + if ( (mat_disable_fancy_blending.GetBool() ) && + (info.m_nBlendModulateTexture != -1) ) + { + params[info.m_nBlendModulateTexture]->SetUndefined(); + } + + if( !params[info.m_nEnvmapTint]->IsDefined() ) + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[info.m_nNoDiffuseBumpLighting]->IsDefined() ) + params[info.m_nNoDiffuseBumpLighting]->SetIntValue( 0 ); + + if( !params[info.m_nSelfIllumTint]->IsDefined() ) + params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[info.m_nDetailScale]->IsDefined() ) + params[info.m_nDetailScale]->SetFloatValue( 4.0f ); + + if ( !params[info.m_nDetailTint]->IsDefined() ) + params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f, 1.0f ); + + InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + InitIntParam( info.m_nDetailTextureCombineMode, params, 0 ); + + if( !params[info.m_nFresnelReflection]->IsDefined() ) + params[info.m_nFresnelReflection]->SetFloatValue( 1.0f ); + + if( !params[info.m_nEnvmapMaskFrame]->IsDefined() ) + params[info.m_nEnvmapMaskFrame]->SetIntValue( 0 ); + + if( !params[info.m_nEnvmapFrame]->IsDefined() ) + params[info.m_nEnvmapFrame]->SetIntValue( 0 ); + + if( !params[info.m_nBumpFrame]->IsDefined() ) + params[info.m_nBumpFrame]->SetIntValue( 0 ); + + if( !params[info.m_nDetailFrame]->IsDefined() ) + params[info.m_nDetailFrame]->SetIntValue( 0 ); + + if( !params[info.m_nEnvmapContrast]->IsDefined() ) + params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f ); + + if( !params[info.m_nEnvmapSaturation]->IsDefined() ) + params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f ); + + InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if( params[info.m_nBumpmap]->IsDefined() ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0) ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nEnvmap]->SetUndefined(); + } + + if( !params[info.m_nBaseTextureNoEnvmap]->IsDefined() ) + { + params[info.m_nBaseTextureNoEnvmap]->SetIntValue( 0 ); + } + if( !params[info.m_nBaseTexture2NoEnvmap]->IsDefined() ) + { + params[info.m_nBaseTexture2NoEnvmap]->SetIntValue( 0 ); + } + + if( ( info.m_nSelfShadowedBumpFlag != -1 ) && + ( !params[info.m_nSelfShadowedBumpFlag]->IsDefined() ) + ) + { + params[info.m_nSelfShadowedBumpFlag]->SetIntValue( 0 ); + } + // handle line art parms + InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); + InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); + InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); +} + +void InitLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedGeneric_DX9_Vars_t &info ) +{ + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + } + + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpmap2]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap2 ); + } + + if ( g_pConfig->UseBumpmapping() && params[info.m_nBumpMask]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpMask ); + } + + if (params[info.m_nBaseTexture]->IsDefined()) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + + if (!params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[info.m_nBaseTexture2]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture2, TEXTUREFLAGS_SRGB ); + } + + if (params[info.m_nLightWarpTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nLightWarpTexture ); + } + + if ((info.m_nBlendModulateTexture != -1) && + (params[info.m_nBlendModulateTexture]->IsDefined()) ) + { + pShader->LoadTexture( info.m_nBlendModulateTexture ); + } + + if (params[info.m_nDetail]->IsDefined()) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode; + + pShader->LoadTexture( info.m_nDetail, nDetailBlendMode != 0 ? TEXTUREFLAGS_SRGB : 0 ); + } + + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if (params[info.m_nEnvmap]->IsDefined()) + { + if ( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + else + { + pShader->LoadTexture( info.m_nEnvmap ); + } + + if ( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if ( params[info.m_nEnvmapMask]->IsDefined() ) + { + pShader->LoadTexture( info.m_nEnvmapMask ); + } + } + else + { + params[info.m_nEnvmapMask]->SetUndefined(); + } + + // We always need this because of the flashlight. + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); +} + +void DrawLightmappedGeneric_DX9_Internal(CBaseVSShader *pShader, IMaterialVar** params, bool hasFlashlight, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + LightmappedGeneric_DX9_Vars_t &info, + CBasePerMaterialContextData **pContextDataPtr + ) +{ + CLightmappedGeneric_DX9_Context *pContextData = reinterpret_cast< CLightmappedGeneric_DX9_Context *> ( *pContextDataPtr ); + if ( pShaderShadow || ( ! pContextData ) || pContextData->m_bMaterialVarsChanged || hasFlashlight ) + { + bool hasBaseTexture = params[info.m_nBaseTexture]->IsTexture(); + int nAlphaChannelTextureVar = hasBaseTexture ? (int)info.m_nBaseTexture : (int)info.m_nEnvmapMask; + BlendType_t nBlendType = pShader->EvaluateBlendRequirements( nAlphaChannelTextureVar, hasBaseTexture ); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bFullyOpaqueWithoutAlphaTest = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && (!hasFlashlight || IsX360()); //dest alpha is free for special use + bool bFullyOpaque = bFullyOpaqueWithoutAlphaTest && !bIsAlphaTested; + bool bNeedRegenStaticCmds = (! pContextData ) || pShaderShadow; + + if ( ! pContextData ) // make sure allocated + { + pContextData = new CLightmappedGeneric_DX9_Context; + *pContextDataPtr = pContextData; + } + + bool hasBump = ( params[info.m_nBumpmap]->IsTexture() ) && ( !g_pHardwareConfig->PreferReducedFillrate() ); + bool hasSSBump = hasBump && (info.m_nSelfShadowedBumpFlag != -1) && ( params[info.m_nSelfShadowedBumpFlag]->GetIntValue() ); + bool hasBaseTexture2 = hasBaseTexture && params[info.m_nBaseTexture2]->IsTexture(); + bool hasLightWarpTexture = params[info.m_nLightWarpTexture]->IsTexture(); + bool hasBump2 = hasBump && params[info.m_nBumpmap2]->IsTexture(); + bool hasDetailTexture = params[info.m_nDetail]->IsTexture(); + bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + bool hasBumpMask = hasBump && hasBump2 && params[info.m_nBumpMask]->IsTexture() && !hasSelfIllum && + !hasDetailTexture && !hasBaseTexture2 && (params[info.m_nBaseTextureNoEnvmap]->GetIntValue() == 0); + bool bHasBlendModulateTexture = + (info.m_nBlendModulateTexture != -1) && + (params[info.m_nBlendModulateTexture]->IsTexture() ); + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + + if ( hasFlashlight && !IsX360() ) + { + // !!speed!! do this in the caller so we don't build struct every time + CBaseVSShader::DrawFlashlight_dx90_Vars_t vars; + vars.m_bBump = hasBump; + vars.m_nBumpmapVar = info.m_nBumpmap; + vars.m_nBumpmapFrame = info.m_nBumpFrame; + vars.m_nBumpTransform = info.m_nBumpTransform; + vars.m_nFlashlightTextureVar = info.m_nFlashlightTexture; + vars.m_nFlashlightTextureFrameVar = info.m_nFlashlightTextureFrame; + vars.m_bLightmappedGeneric = true; + vars.m_bWorldVertexTransition = hasBaseTexture2; + vars.m_nBaseTexture2Var = info.m_nBaseTexture2; + vars.m_nBaseTexture2FrameVar = info.m_nBaseTexture2Frame; + vars.m_nBumpmap2Var = info.m_nBumpmap2; + vars.m_nBumpmap2Frame = info.m_nBumpFrame2; + vars.m_nBump2Transform = info.m_nBumpTransform2; + vars.m_nAlphaTestReference = info.m_nAlphaTestReference; + vars.m_bSSBump = hasSSBump; + vars.m_nDetailVar = info.m_nDetail; + vars.m_nDetailScale = info.m_nDetailScale; + vars.m_nDetailTextureCombineMode = info.m_nDetailTextureCombineMode; + vars.m_nDetailTextureBlendFactor = info.m_nDetailTextureBlendFactor; + vars.m_nDetailTint = info.m_nDetailTint; + + if ( ( info.m_nSeamlessMappingScale != -1 ) ) + vars.m_fSeamlessScale = params[info.m_nSeamlessMappingScale]->GetFloatValue(); + else + vars.m_fSeamlessScale = 0.0; + pShader->DrawFlashlight_dx90( params, pShaderAPI, pShaderShadow, vars ); + return; + } + + pContextData->m_bFullyOpaque = bFullyOpaque; + pContextData->m_bFullyOpaqueWithoutAlphaTest = bFullyOpaqueWithoutAlphaTest; + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( hasBump && g_pHardwareConfig->SupportsNormalMapCompression() && g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + ITexture *pBumpTex = params[info.m_nBumpmap]->GetTextureValue(); + if ( pBumpTex ) + { + nNormalDecodeMode = pBumpTex->GetNormalDecodeMode(); + + if ( hasBump2 ) // Check encoding of secondary normal if there is oneg + { + ITexture *pBumpTex2 = params[info.m_nBumpmap]->GetTextureValue(); + if ( pBumpTex2 && ( pBumpTex2->GetNormalDecodeMode() != nNormalDecodeMode ) ) + { + DevMsg("LightmappedGeneric: Primary and Secondary normal map compression formats don't match. This is unsupported!\n"); + Assert(0); + } + } + } + } + + int nNormalMaskDecodeMode = 0; + if ( hasBumpMask && g_pHardwareConfig->SupportsNormalMapCompression() && g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + ITexture *pBumpMaskTex = params[info.m_nBumpMask]->GetTextureValue(); + if ( pBumpMaskTex ) + { + nNormalMaskDecodeMode = pBumpMaskTex->GetNormalDecodeMode(); + } + } + + bool bHasOutline = IsBoolSet( info.m_nOutline, params ); + pContextData->m_bPixelShaderForceFastPathBecauseOutline = bHasOutline; + bool bHasSoftEdges = IsBoolSet( info.m_nSoftEdges, params ); + bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); + + + float fDetailBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + + if ( pShaderShadow || bNeedRegenStaticCmds ) + { + bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool hasDiffuseBumpmap = hasBump && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0); + + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + + bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && + ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); + + if ( bNeedRegenStaticCmds ) + { + pContextData->ResetStaticCmds(); + CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; + + + if( !hasBaseTexture ) + { + if( hasEnvmap ) + { + // if we only have an envmap (no basetexture), then we want the albedo to be black. + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); + } + else + { + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + } + staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + if ( bSeamlessMapping ) + { + staticCmdsBuf.SetVertexShaderConstant4( + VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, + params[info.m_nSeamlessMappingScale]->GetFloatValue(),0,0,0 ); + } + staticCmdsBuf.StoreEyePosInPixelShaderConstant( 10 ); + staticCmdsBuf.SetPixelShaderFogParams( 11 ); + staticCmdsBuf.End(); + // now, copy buf + pContextData->m_pStaticCmds = new uint8[staticCmdsBuf.Size()]; + memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); + } + if ( pShaderShadow ) + { + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + pShader->SetDefaultBlendingShadowState( nAlphaChannelTextureVar, hasBaseTexture ); + + unsigned int flags = VERTEX_POSITION; + + // base texture + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + if ( hasLightWarpTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false ); + } + if ( bHasBlendModulateTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false ); + } + + if ( hasBaseTexture2 ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true ); + } +// if( hasLightmap ) + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + else + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + } + + if( hasEnvmap || ( IsX360() && hasFlashlight ) ) + { + if( hasEnvmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + } + } + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL; + } + + int nDetailBlendMode = 0; + if ( hasDetailTexture ) + { + nDetailBlendMode = GetIntParam( info.m_nDetailTextureCombineMode, params ); + ITexture *pDetailTexture = params[info.m_nDetail]->GetTextureValue(); + if ( pDetailTexture->GetFlags() & TEXTUREFLAGS_SSBUMP ) + { + if ( hasBump ) + nDetailBlendMode = 10; // ssbump + else + nDetailBlendMode = 11; // ssbump_nobump + } + } + + if( hasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); + bool bSRGBState = ( nDetailBlendMode == 1 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER12, bSRGBState ); + } + + if( hasBump || hasNormalMapAlphaEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Normal map alpha, in the compressed normal case + } + } + if( hasBump2 ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // Secondary normal alpha, in the compressed normal case + } + } + if( hasBumpMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); + if ( nNormalMaskDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Normal mask alpha, in the compressed normal case + } + } + if( hasEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + } + + if( hasFlashlight && IsX360() ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER14 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER15, true ); + } + + if( hasVertexColor || hasBaseTexture2 || hasBump2 ) + { + flags |= VERTEX_COLOR; + } + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 2; + if( hasBump ) + { + numTexCoords = 3; + } + + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + // Pre-cache pixel shaders + bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + + int bumpmap_variant=(hasSSBump) ? 2 : hasBump; + bool bMaskedBlending=( (info.m_nMaskedBlending != -1) && + (params[info.m_nMaskedBlending]->GetIntValue() != 0) ); + + DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask ); + SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, params[info.m_nEnvmap]->IsTexture() ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, hasBaseTexture2 || hasBump2 ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, hasBumpMask ); + + bool bReliefMapping = false; //( bumpmap_variant == 2 ) && ( ! bSeamlessMapping ); + SET_STATIC_VERTEX_SHADER_COMBO( RELIEF_MAPPING, false );//bReliefMapping ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); +#ifdef _X360 + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight); +#endif + SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); + SET_STATIC_PIXEL_SHADER_COMBO( RELIEF_MAPPING, bReliefMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, (int) nNormalMaskDecodeMode ); +#ifdef _X360 + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight); +#endif + SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, 0 ); // No normal compression with ps_2_0 (yikes!) + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMASK_DECODE_MODE, 0 ); // No normal compression with ps_2_0 + SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps20 ); + } + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff and writing depth to dest alpha + // But only do it if we're not using the alpha already for translucency + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + + pShaderShadow->EnableSRGBWrite( true ); + + pShader->DefaultFog(); + + + } // end shadow state + } // end shadow || regen display list + if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) + { + // need to regenerate the semistatic cmds + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_bMaterialVarsChanged = false; + + bool bHasBlendMaskTransform= ( + (info.m_nBlendMaskTransform != -1) && + (info.m_nMaskedBlending != -1) && + (params[info.m_nMaskedBlending]->GetIntValue() ) && + ( ! (params[info.m_nBumpTransform]->MatrixIsIdentity() ) ) ); + + // If we don't have a texture transform, we don't have + // to set vertex shader constants or run vertex shader instructions + // for the texture transform. + bool bHasTextureTransform = + !( params[info.m_nBaseTextureTransform]->MatrixIsIdentity() && + params[info.m_nBumpTransform]->MatrixIsIdentity() && + params[info.m_nBumpTransform2]->MatrixIsIdentity() && + params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ); + + bHasTextureTransform |= bHasBlendMaskTransform; + + pContextData->m_bVertexShaderFastPath = !bHasTextureTransform; + + if( params[info.m_nDetail]->IsTexture() ) + { + pContextData->m_bVertexShaderFastPath = false; + } + if (bHasBlendMaskTransform) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( + VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, info.m_nBlendMaskTransform ); + } + + if ( ! pContextData->m_bVertexShaderFastPath ) + { + bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && + ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); + bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture(); + if (!bSeamlessMapping ) + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + // If we have a detail texture, then the bump texcoords are the same as the base texcoords. + if( hasBump && !hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); + } + if( hasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform ); + } + else if ( hasBump2 ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBumpTransform2 ); + } + } + pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicState( 0, info.m_nEnvmapTint ); + // set up shader modulation color + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + pShader->ComputeModulationColor( color ); + float flLScale = pShaderAPI->GetLightMapScaleFactor(); + color[0] *= flLScale; + color[1] *= flLScale; + color[2] *= flLScale; + + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + color[3] *= ( IS_PARAM_DEFINED( info.m_nAlpha2 ) && params[ info.m_nAlpha2 ]->GetFloatValue() > 0.0f ) ? params[ info.m_nAlpha2 ]->GetFloatValue() : 1.0f; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 12, color ); + + if ( hasDetailTexture ) + { + float detailTintAndBlend[4] = {1, 1, 1, 1}; + + if ( info.m_nDetailTint != -1 ) + { + params[info.m_nDetailTint]->GetVecValue( detailTintAndBlend, 3 ); + } + + detailTintAndBlend[3] = fDetailBlendFactor; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 8, detailTintAndBlend ); + } + + float envmapTintVal[4]; + float selfIllumTintVal[4]; + params[info.m_nEnvmapTint]->GetVecValue( envmapTintVal, 3 ); + params[info.m_nSelfIllumTint]->GetVecValue( selfIllumTintVal, 3 ); + float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); + float envmapSaturation = params[info.m_nEnvmapSaturation]->GetFloatValue(); + float fresnelReflection = params[info.m_nFresnelReflection]->GetFloatValue(); + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + + pContextData->m_bPixelShaderFastPath = true; + bool bUsingContrast = hasEnvmap && ( (envmapContrast != 0.0f) && (envmapContrast != 1.0f) ) && (envmapSaturation != 1.0f); + bool bUsingFresnel = hasEnvmap && (fresnelReflection != 1.0f); + bool bUsingSelfIllumTint = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && (selfIllumTintVal[0] != 1.0f || selfIllumTintVal[1] != 1.0f || selfIllumTintVal[2] != 1.0f); + if ( bUsingContrast || bUsingFresnel || bUsingSelfIllumTint || !g_pConfig->bShowSpecular ) + { + pContextData->m_bPixelShaderFastPath = false; + } + if( !pContextData->m_bPixelShaderFastPath ) + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstants( 2, 3 ); + pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapContrast]->GetVecValue() ); + pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapSaturation]->GetVecValue() ); + float flFresnel = params[info.m_nFresnelReflection]->GetFloatValue(); + // [ 0, 0, 1-R(0), R(0) ] + pContextData->m_SemiStaticCmdsOut.OutputConstantData4( 0., 0., 1.0 - flFresnel, flFresnel ); + + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, params[info.m_nSelfIllumTint]->GetVecValue() ); + } + else + { + if ( bHasOutline ) + { + float flOutlineParms[8] = { GetFloatParam( info.m_nOutlineStart0, params ), + GetFloatParam( info.m_nOutlineStart1, params ), + GetFloatParam( info.m_nOutlineEnd0, params ), + GetFloatParam( info.m_nOutlineEnd1, params ), + 0,0,0, + GetFloatParam( info.m_nOutlineAlpha, params ) }; + if ( info.m_nOutlineColor != -1 ) + { + params[info.m_nOutlineColor]->GetVecValue( flOutlineParms + 4, 3 ); + } + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 2, flOutlineParms, 2 ); + } + + if ( bHasSoftEdges ) + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( + 4, GetFloatParam( info.m_nEdgeSoftnessStart, params ), + GetFloatParam( info.m_nEdgeSoftnessEnd, params ), + 0,0 ); + } + } + // texture binds + if( hasBaseTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + // handle mat_fullbright 2 + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + if( bLightingOnly ) + { + // BASE TEXTURE + if( hasSelfIllum ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + // BASE TEXTURE 2 + if( hasBaseTexture2 ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER7, TEXTURE_GREY ); + } + + // DETAIL TEXTURE + if( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_GREY ); + } + + // disable color modulation + float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + // turn off environment mapping + envmapTintVal[0] = 0.0f; + envmapTintVal[1] = 0.0f; + envmapTintVal[2] = 0.0f; + } + + // always set the transform for detail textures since I'm assuming that you'll + // always have a detailscale. + if( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBaseTextureTransform, info.m_nDetailScale ); + } + + if( hasBaseTexture2 ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER7, info.m_nBaseTexture2, info.m_nBaseTexture2Frame ); + } + if( hasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER12, info.m_nDetail, info.m_nDetailFrame ); + } + + if( hasBump || hasNormalMapAlphaEnvmapMask ) + { + if( !g_pConfig->m_bFastNoBump ) + { + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pContextData->m_SemiStaticCmdsOut.BindMultiTexture( pShader, SHADER_SAMPLER4, SHADER_SAMPLER9, info.m_nBumpmap, info.m_nBumpFrame ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nBumpmap, info.m_nBumpFrame ); + } + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALMAP_FLAT ); + } + } + if( hasBump2 ) + { + if( !g_pConfig->m_bFastNoBump ) + { + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pContextData->m_SemiStaticCmdsOut.BindMultiTexture( pShader, SHADER_SAMPLER5, SHADER_SAMPLER10, info.m_nBumpmap2, info.m_nBumpFrame2 ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nBumpmap2, info.m_nBumpFrame2 ); + } + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALMAP_FLAT ); + } + } + if( hasBumpMask ) + { + if( !g_pConfig->m_bFastNoBump ) + { + if ( nNormalMaskDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + Assert(0); + //pContextData->m_SemiStaticCmdsOut.BindTexture( SHADER_SAMPLER8, SHADER_SAMPLER11, info.m_nBumpMask ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER8, info.m_nBumpMask, -1 ); + } + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER8, TEXTURE_NORMALMAP_FLAT ); + } + } + + if( hasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); + } + + if ( hasLightWarpTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER6, info.m_nLightWarpTexture, -1 ); + } + + if ( bHasBlendModulateTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBlendModulateTexture, -1 ); + } + + pContextData->m_SemiStaticCmdsOut.End(); + } + } + DYNAMIC_STATE + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); + + if( hasEnvmap ) + { + DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + int nFixedLightingMode = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ); + + bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath; + + if( nFixedLightingMode != 0 ) + { + if ( pContextData->m_bPixelShaderForceFastPathBecauseOutline ) + nFixedLightingMode = 0; + else + bVertexShaderFastPath = false; + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( + LIGHTING_PREVIEW, + (nFixedLightingMode)?1:0 + ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_vs20 ); + + bool bPixelShaderFastPath = pContextData->m_bPixelShaderFastPath; + if( nFixedLightingMode !=0 ) + { + bPixelShaderFastPath = false; + } + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if( pContextData->m_bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedgeneric_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath || pContextData->m_bPixelShaderForceFastPathBecauseOutline ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nFixedLightingMode ); + + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedgeneric_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nFixedLightingMode ); + + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_ps20 ); + } + + if( hasFlashlight && IsX360() ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + + DynamicCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture.Base(), 4 ); + + SetFlashLightColorFromState( flashlightState, pShaderAPI ); + + float atten[4], pos[4]; + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + DynamicCmdsOut.SetPixelShaderConstant( 13, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + DynamicCmdsOut.SetPixelShaderConstant( 14, pos, 1 ); + + pShader->BindTexture( SHADER_SAMPLER13, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER14, pFlashlightDepthTexture, 0 ); + DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER15, TEXTURE_SHADOW_NOISE_2D ); + + // Tweaks associated with a given flashlight + float tweaks[4]; + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + DynamicCmdsOut.SetPixelShaderConstant( 19, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + DynamicCmdsOut.SetPixelShaderConstant( 31, vScreenScale, 1 ); + } + } + + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + pShader->Draw(); + + if( IsPC() && (IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0) && pContextData->m_bFullyOpaqueWithoutAlphaTest ) + { + //Alpha testing makes it so we can't write to dest alpha + //Writing to depth makes it so later polygons can't write to dest alpha either + //This leads to situations with garbage in dest alpha. + + //Fix it now by converting depth to dest alpha for any pixels that just wrote. + pShader->DrawEqualDepthToDestAlpha(); + } +} + +void DrawLightmappedGeneric_DX9(CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + LightmappedGeneric_DX9_Vars_t &info, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool hasFlashlight = pShader->UsingFlashlight( params ); + if ( !IsX360() && !r_flashlight_version2.GetInt() ) + { + DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); + return; + } + + DrawLightmappedGeneric_DX9_Internal( pShader, params, hasFlashlight, pShaderAPI, pShaderShadow, info, pContextDataPtr ); +} diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h new file mode 100644 index 00000000..00375b9f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h @@ -0,0 +1,99 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef LIGHTMAPPEDGENERIC_DX9_HELPER_H +#define LIGHTMAPPEDGENERIC_DX9_HELPER_H + +#include +#include "BaseVSShader.h" + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct LightmappedGeneric_DX9_Vars_t +{ + LightmappedGeneric_DX9_Vars_t() { memset( this, 0xFF, sizeof(LightmappedGeneric_DX9_Vars_t) ); } + + int m_nBaseTexture; + int m_nBaseTextureFrame; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nSelfIllumTint; + + int m_nAlpha2; // Hack for DoD srgb blend issues on overlays + + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + int m_nDetailTint; + + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nBumpFrame; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nFresnelReflection; + int m_nNoDiffuseBumpLighting; + int m_nBumpmap2; + int m_nBumpFrame2; + int m_nBumpTransform2; + int m_nBumpMask; + int m_nBaseTexture2; + int m_nBaseTexture2Frame; + int m_nBaseTextureNoEnvmap; + int m_nBaseTexture2NoEnvmap; + int m_nDetailAlphaMaskBaseTexture; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + int m_nLightWarpTexture; + int m_nBlendModulateTexture; + int m_nMaskedBlending; + int m_nBlendMaskTransform; + int m_nSelfShadowedBumpFlag; + int m_nSeamlessMappingScale; + int m_nAlphaTestReference; + + int m_nSoftEdges; + int m_nEdgeSoftnessStart; + int m_nEdgeSoftnessEnd; + + int m_nOutline; + int m_nOutlineColor; + int m_nOutlineAlpha; + int m_nOutlineStart0; + int m_nOutlineStart1; + int m_nOutlineEnd0; + int m_nOutlineEnd1; + +}; + +void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info ); +void InitLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, LightmappedGeneric_DX9_Vars_t &info ); +void DrawLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + LightmappedGeneric_DX9_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr ); + + +#endif // LIGHTMAPPEDGENERIC_DX9_HELPER_H diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_envmap.psh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_envmap.psh new file mode 100644 index 00000000..1e4a2bc4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_envmap.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) +mul r0.rgb, t1, r0 ; fold in lightmap (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc b/sp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc new file mode 100644 index 00000000..3a0d059d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc @@ -0,0 +1,122 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "NORMALMAP" "0..1" +// STATIC: "WORLDVERTEXTRANSITION" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +const float3 g_FlashlightPos : register( SHADER_SPECIFIC_CONST_0 ); +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_1 ); +const float4 g_FlashlightAttenuationFactors : register( SHADER_SPECIFIC_CONST_5 ); + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cNormalMapTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_8 ); + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + // If this is float4, and the input is float3, the w component default to one. + float4 vPos : POSITION; + float3 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; +#if NORMALMAP + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +#endif + float4 vColor : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float4 spotTexCoord : TEXCOORD0; + float2 baseTexCoord : TEXCOORD1; +#if NORMALMAP + float3 tangentPosToLightVector : TEXCOORD2; + float2 normalMapTexCoord : TEXCOORD3; +#else + float3 worldPosToLightVector : TEXCOORD2; + float3 normal : TEXCOORD3; +#endif + float4 vertAtten : COLOR0; +}; + +float RemapValClamped( float val, float A, float B ) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + return cVal; +} + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + float4 projPos; + float3 worldPos; + float3 worldNormal; + float3 eyeVector; + + projPos = mul( v.vPos, cModelViewProj ); + o.projPos = projPos; + + worldPos = mul( v.vPos, cModel[0] ); + worldNormal = mul( v.vNormal, ( float3x3 )cModel[0] ); + +#if NORMALMAP + float3 worldTangentS = mul( v.vTangentS, cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, cModel[0] ); +#endif + +#if !defined( _X360 ) + o.fog = CalcFog( worldPos, projPos, g_FogType ); +#endif + + o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; + o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; + + float4 spotTexCoord = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); + o.spotTexCoord = spotTexCoord.xyzw; + + float3 worldPosToLightVector = g_FlashlightPos - worldPos; +#if NORMALMAP + o.normalMapTexCoord.x = dot( v.vBaseTexCoord, cNormalMapTexCoordTransform[0] ) + cNormalMapTexCoordTransform[0].w; + o.normalMapTexCoord.y = dot( v.vBaseTexCoord, cNormalMapTexCoordTransform[1] ) + cNormalMapTexCoordTransform[1].w; + + o.tangentPosToLightVector.x = dot( worldPosToLightVector, worldTangentS ); + o.tangentPosToLightVector.y = dot( worldPosToLightVector, worldTangentT ); + o.tangentPosToLightVector.z = dot( worldPosToLightVector, worldNormal ); +#else + o.worldPosToLightVector = worldPosToLightVector; + o.normal = worldNormal; +#endif + + float3 delta = worldPosToLightVector; + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); + float farZ = g_FlashlightAttenuationFactors.w; + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6 * farZ ); + o.vertAtten.xyz = saturate( endFalloffFactor * dot( g_FlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + +#if WORLDVERTEXTRANSITION + o.vertAtten.w = 1 - v.vColor.w; +#else +#if VERTEXCOLOR + o.vertAtten.w = v.vColor.w; +#else + o.vertAtten.w = 1.0f; +#endif +#endif + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc b/sp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc new file mode 100644 index 00000000..7d23bb95 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc @@ -0,0 +1,184 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "NORMALMAP" "0..1" +// STATIC: "WORLDVERTEXTRANSITION" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "DETAIL" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +const float3 g_FlashlightPos : register( SHADER_SPECIFIC_CONST_0 ); +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_1 ); +const float4 g_FlashlightAttenuationFactors : register( SHADER_SPECIFIC_CONST_5 ); + +#if SEAMLESS +const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_6 ); +#define SEAMLESS_SCALE (SeamlessScale.x) +#endif +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cNormalMapOrDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_8 ); + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + float3 vPos : POSITION; //This HAS to match lightmappedgeneric_vs20.fxc's position input. Otherwise depth fighting errors occur on the 360 + float4 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; +#if WORLDVERTEXTRANSITION + float2 vLightmapTexCoord : TEXCOORD1; + float4 vColor : COLOR0; +#endif +#if NORMALMAP + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + + float4 spotTexCoord : TEXCOORD0; + +#if SEAMLESS + float3 SeamlessTexCoord : TEXCOORD1; +#else + float2 baseTexCoord : TEXCOORD1; +#endif + +#if NORMALMAP + float3 tangentPosToLightVector : TEXCOORD2; + float2 normalMapTexCoord : TEXCOORD3; +#else + float3 worldPosToLightVector : TEXCOORD2; + float3 normal : TEXCOORD3; +#endif + + float2 detailCoords : TEXCOORD4; + float4 worldPos_worldTransition : TEXCOORD5; + float3 vProjPos : TEXCOORD6; + float4 fogFactorW : TEXCOORD7; +}; + +float RemapValClamped( float val, float A, float B, float C, float D) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + + return C + (D - C) * cVal; +} + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float4 projPos; + float3 worldPos; + float3 worldNormal; + float3 eyeVector; + + //Projection math HAS to match lightmappedgeneric_vs20.fxc's math exactly. Otherwise depth fighting errors occur on the 360 + projPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + o.projPos = projPos; + o.vProjPos.xyz = projPos.xyw; + + worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); + worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + + o.worldPos_worldTransition = float4( worldPos.xyz, 1.0f ); + + o.fogFactorW = CalcFog( worldPos, projPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW.w; +#endif + +#if NORMALMAP + float3 worldTangentS = mul( v.vTangentS, cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, cModel[0] ); +#endif +#if SEAMLESS + float3 vNormal=normalize( worldNormal ); + o.fogFactorW.xyz = vNormal * vNormal; // sums to 1. + o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos; + + // Generate new tangent and binormal with seamless projection + #if NORMALMAP + // Brute-force for prototype - This must match the projection in the pixel shader! + //float3 vVecX = { 1.0f, 0.0f, 0.0f }; + //float3 vVecY = { 0.0f, 1.0f, 0.0f }; + //float3 vVecZ = { 0.0f, 0.0f, 1.0f }; + //worldTangentS.xyz = normalize( ( o.fogFactorW.x * vVecZ.xyz ) + ( o.fogFactorW.y * vVecX.xyz ) + ( o.fogFactorW.z * vVecX.xyz ) ); + //worldTangentT.xyz = normalize( ( o.fogFactorW.x * vVecY.xyz ) + ( o.fogFactorW.y * vVecZ.xyz ) + ( o.fogFactorW.z * vVecY.xyz ) ); + + // Optimized version - This must match the projection in the pixel shader! + worldTangentS.xyz = normalize( float3( o.fogFactorW.y + o.fogFactorW.z, 0.0f, o.fogFactorW.x ) ); + worldTangentT.xyz = normalize( float3( 0.0f, o.fogFactorW.x + o.fogFactorW.z, o.fogFactorW.y ) ); + #endif +#else +#if (SEAMLESS == 0 ) + o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; + o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; +#endif +#endif + + float4 spotTexCoord = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); + o.spotTexCoord = spotTexCoord.xyzw; + + float3 worldPosToLightVector = g_FlashlightPos - worldPos; +#if NORMALMAP + +#if (DETAIL == 0) + o.normalMapTexCoord.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w; + o.normalMapTexCoord.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w; +#else + +#if SEAMLESS + o.normalMapTexCoord = v.vBaseTexCoord; +#else + o.normalMapTexCoord = o.baseTexCoord; +#endif + +#endif + + o.tangentPosToLightVector.x = dot( worldPosToLightVector, worldTangentS ); + o.tangentPosToLightVector.y = dot( worldPosToLightVector, worldTangentT ); + o.tangentPosToLightVector.z = dot( worldPosToLightVector, worldNormal ); +#else + o.worldPosToLightVector = worldPosToLightVector; + o.normal = worldNormal; +#endif + +#if DETAIL + o.detailCoords.x = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[0] ) + cNormalMapOrDetailTexCoordTransform[0].w; + o.detailCoords.y = dot( v.vBaseTexCoord, cNormalMapOrDetailTexCoordTransform[1] ) + cNormalMapOrDetailTexCoordTransform[1].w; +#else + o.detailCoords = float2(0,0); +#endif + + //float3 delta = worldPosToLightVector; + //float distSquared = dot( delta, delta ); + //float dist = sqrt( distSquared ); + //float farZ = g_FlashlightAttenuationFactors.w; + //float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + //o.projPos_atten.w = endFalloffFactor * dot( g_FlashlightAttenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ); + //o.projPos_atten.w = saturate( o.projPos_atten.w ); + +#if WORLDVERTEXTRANSITION + o.worldPos_worldTransition.w = v.vColor.w; +#endif + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_inc.vsh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_inc.vsh new file mode 100644 index 00000000..a5d12a81 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_inc.vsh @@ -0,0 +1,110 @@ +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform +; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform +; $SHADER_SPECIFIC_CONST_4 = Modulation color +;------------------------------------------------------------------------------ + +sub LightmappedGeneric +{ + local( $detail ) = shift; + local( $envmap ) = shift; + local( $envmapcameraspace ) = shift; + local( $envmapsphere ) = shift; + local( $vertexcolor ) = shift; + + local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + + &AllocateRegister( \$projPos ); + + dp4 $projPos.x, $vPos, $cModelViewProj0 + dp4 $projPos.y, $vPos, $cModelViewProj1 + dp4 $projPos.z, $vPos, $cModelViewProj2 + dp4 $projPos.w, $vPos, $cModelViewProj3 + mov oPos, $projPos + + &AllocateRegister( \$worldPos ); + + if( $DOWATERFOG == 1 ) + { + ; Get the worldpos z component only since that's all we need for height fog + dp4 $worldPos.z, $vPos, $cModel2 + } + &CalcFog( $worldPos, $projPos ); + &FreeRegister( \$projPos ); + + ;------------------------------------------------------------------------------ + ; Texture coordinates + ;------------------------------------------------------------------------------ + ; base texcoords + dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 + dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + ; lightmap texcoords + mov oT1, $vTexCoord1 + + if( $envmap ) + { + &AllocateRegister( \$worldNormal ); + + ; Transform the position + normal to world space + dp4 $worldPos.x, $vPos, $cModel0 + dp4 $worldPos.y, $vPos, $cModel1 + if( $DOWATERFOG ne 1 ) + { + dp4 $worldPos.z, $vPos, $cModel2 + } + + dp3 $worldNormal.x, $vNormal, $cModel0 + dp3 $worldNormal.y, $vNormal, $cModel1 + dp3 $worldNormal.z, $vNormal, $cModel2 + + if( $envmapcameraspace ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + ; transform reflection vector into view space + dp3 oT2.x, $reflectionVector, $cViewModel0 + dp3 oT2.y, $reflectionVector, $cViewModel1 + dp3 oT2.z, $reflectionVector, $cViewModel2 + &FreeRegister( \$reflectionVector ); + } + elsif( $envmapsphere ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + &ComputeSphereMapTexCoords( $reflectionVector, "oT2" ); + &FreeRegister( \$reflectionVector ); + } + else + { + &ComputeReflectionVector( $worldPos, $worldNormal, "oT2" ); + } + ; envmap mask + dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 ; FIXME + dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 ; FIXME + +# &FreeRegister( \$worldPos ); + &FreeRegister( \$worldNormal ); + } + + &FreeRegister( \$worldPos ); # garymcthack + + if( $detail ) + { + dp4 oT2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 ; FIXME + dp4 oT2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 ; FIXME + } + + if( $vertexcolor ) + { + ; Modulation color + mul oD0, $vColor, $cModulationColor + } + else + { + ; Modulation color + mov oD0, $cModulationColor + } +} diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc b/sp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc new file mode 100644 index 00000000..1dbb8b2f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc @@ -0,0 +1,12 @@ +sampler TextureSampler : register( s1 ); + +struct PS_INPUT +{ + float4 vColor0 : COLOR0; + float2 vTexCoord1 : TEXCOORD1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return tex2D( TextureSampler, i.vTexCoord1 ); +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc b/sp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc new file mode 100644 index 00000000..afee6c9c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc @@ -0,0 +1,51 @@ +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord1 : TEXCOORD1; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + + float4 vDiffuse : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul4x3( v.vPos, cModel[0] ); + + o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + + o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + // YUCK! This is to make texcoords continuous for mat_softwaretl + o.vTexCoord0 = 0.0f; + o.vTexCoord1 = v.vTexCoord1; + + o.vDiffuse = 1.0f; + + return o; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh new file mode 100644 index 00000000..4f72286f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh @@ -0,0 +1,22 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0, t0, v0 ; base times vertex color (with alpha) +mul r1, t2, t3 ; envmap * envmapmask +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh new file mode 100644 index 00000000..a525a7b2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh @@ -0,0 +1,24 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 + +; Blend between grey and lightmap color based on total alpha + +def c0 0.5f 0.5f 0.5f 1.0f + +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mul r1.a, t0, v0 ; base times vertex alpha +; GR - workaround for const/lerp issues +mul r0.rgb, c1, t0 ; Self illum * tint ++mul_sat r0.a, c1, t0 +lrp r1.rgb, t0.a, r1, r0 ; Blend between self-illum + lightmap +lrp r0, r1.a, r1, c0 ; interpolate between grey + color diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh new file mode 100644 index 00000000..77b05b9f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh @@ -0,0 +1,20 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 +tex t1 + +; Blend between grey and lightmap color based on total alpha + +def c2, 0.5f, 0.5f, 0.5f, 1.0f + +mul_x2 r1.rgb, c0, t1 ; Apply overbright to lightmap ++ mov r1.a, v0 ; vertex alpha +lrp r0, r1.a, r1, c2 ; interpolate between grey + color diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc b/sp/src/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc new file mode 100644 index 00000000..d5be9e5f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc @@ -0,0 +1,122 @@ +// STATIC: "BASETEXTURE" "0..1" +// STATIC: "ENVMAP" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" + +// SKIP: !$ENVMAP && ( $BASEALPHAENVMAPMASK || $ENVMAPMASK ) +// SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK +// SKIP: $SELFILLUM && $BASEALPHAENVMAPMASK +// SKIP: !$BASETEXTURE && $SELFILLUM + +const float3 g_OverbrightFactor : register( c0 ); +const float3 g_SelfIllumTint : register( c1 ); +const float3 g_EnvmapTint : register( c2 ); + +sampler BaseTextureSampler : register( s0 ); +sampler LightmapSampler : register( s1 ); +sampler EnvmapSampler : register( s2 ); +sampler EnvmapMaskSampler : register( s3 ); + +//sampler DetailSampler : register( s3 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float2 lightmapTexCoord : TEXCOORD1; + float3 envmapTexCoord : TEXCOORD2; + float2 envmapMaskTexCoord : TEXCOORD3; + float4 vertexColor : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bBaseTexture = BASETEXTURE ? true : false; + bool bEnvmap = ENVMAP ? true : false; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + +#if 1 + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + if( bBaseTexture ) + { + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); + } + + float3 specularFactor = 1.0f; + + if( bEnvmapMask ) + { + specularFactor *= tex2D( EnvmapMaskSampler, i.envmapMaskTexCoord ).xyz; + } + if( bBaseAlphaEnvmapMask ) + { + specularFactor *= 1.0 - baseColor.a; // this blows! + } + + float3 diffuseLighting = tex2D( LightmapSampler, i.lightmapTexCoord ); + + float3 albedo = float3( 1.0f, 1.0f, 1.0f ); + float alpha = 1.0f; + if( bBaseTexture ) + { + albedo *= baseColor; + if( !bBaseAlphaEnvmapMask && !bSelfIllum ) + { + alpha *= baseColor.a; + } + } + + // The vertex color contains the modulation color + vertex color combined + albedo *= i.vertexColor; + alpha *= i.vertexColor.a; // not sure about this one + + float3 diffuseComponent = ( albedo * diffuseLighting * 2.0f ) * g_OverbrightFactor; + + if( bSelfIllum ) + { + float3 selfIllumComponent = g_SelfIllumTint * albedo; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + } + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); + + if( bEnvmap ) + { + specularLighting = tex2D( EnvmapSampler, i.envmapTexCoord ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint; + } + + float3 result = diffuseComponent + specularLighting; + return float4( result, alpha ); +#endif + +#if 0 + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + float3 diffuseLighting = tex2D( LightmapSampler, i.lightmapTexCoord ); + + float3 albedo = float3( 1.0f, 1.0f, 1.0f ); + float alpha = 1.0f; + albedo *= i.vertexColor; + alpha *= i.vertexColor.a; // not sure about this one + + float3 diffuseComponent = ( albedo * diffuseLighting * 2.0f ) * g_OverbrightFactor; + float3 result = diffuseComponent; + return float4( result, alpha ); +#endif + +#if 0 + float4 result; + + result.rgb = tex2D( LightmapSampler, i.lightmapTexCoord ).rgb * i.vertexColor.rgb; + result.a = i.vertexColor.a; + result.rgb = ( result.rgb * g_OverbrightFactor ) * 2.0f; + return result; +#endif +} + + diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h b/sp/src/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h new file mode 100644 index 00000000..585ea1f6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h @@ -0,0 +1,583 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// SKIP: $BUMPMAP2 && $WARPLIGHTING +// SKIP: $WARPLIGHTING && $DETAILTEXTURE +// SKIP: $ENVMAPMASK && $BUMPMAP +// SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK +// SKIP: $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM +// SKIP: !$FASTPATH && $FASTPATHENVMAPCONTRAST +// SKIP: !$FASTPATH && $FASTPATHENVMAPTINT +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: !$BUMPMAP && $BUMPMAP2 +// SKIP: $ENVMAPMASK && $BUMPMAP2 +// SKIP: $BASETEXTURENOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) +// SKIP: $BASETEXTURE2NOENVMAP && ( !$BASETEXTURE2 || !$CUBEMAP ) +// SKIP: $BASEALPHAENVMAPMASK && $BUMPMAP +// SKIP: $PARALLAXMAP && $DETAILTEXTURE +// SKIP: $SEAMLESS && $RELIEF_MAPPING +// SKIP: $SEAMLESS && $DETAILTEXTURE +// SKIP: $SEAMLESS && $MASKEDBLENDING +// SKIP: $BUMPMASK && ( $SEAMLESS || $DETAILTEXTURE || $SELFILLUM || $BASETEXTURENOENVMAP || $BASETEXTURE2 ) +// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 1) +// SKIP: !$BUMPMAP && ($NORMAL_DECODE_MODE == 2) +// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 1) +// SKIP: !$BUMPMAP && ($NORMALMASK_DECODE_MODE == 2) +// NOSKIP: $FANCY_BLENDING && (!$FASTPATH) + +// 360 compiler craps out on some combo in this family. Content doesn't use blendmode 10 anyway +// SKIP: $FASTPATH && $PIXELFOGTYPE && $BASETEXTURE2 && $DETAILTEXTURE && $CUBEMAP && ($DETAIL_BLEND_MODE == 10 ) [XBOX] + +// debug crap: +// NOSKIP: $DETAILTEXTURE +// NOSKIP: $CUBEMAP +// NOSKIP: $ENVMAPMASK +// NOSKIP: $BASEALPHAENVMAPMASK +// NOSKIP: $SELFILLUM + +#define USE_32BIT_LIGHTMAPS_ON_360 //uncomment to use 32bit lightmaps, be sure to keep this in sync with the same #define in materialsystem/cmatlightmaps.cpp + +#include "common_ps_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_lightmappedgeneric_fxc.h" + +#if SEAMLESS +#define USE_FAST_PATH 1 +#else +#define USE_FAST_PATH FASTPATH +#endif + +const HALF4 g_EnvmapTint : register( c0 ); + +#if USE_FAST_PATH == 1 + +# if FASTPATHENVMAPCONTRAST == 0 +static const HALF3 g_EnvmapContrast = { 0.0f, 0.0f, 0.0f }; +# else +static const HALF3 g_EnvmapContrast = { 1.0f, 1.0f, 1.0f }; +# endif +static const HALF3 g_EnvmapSaturation = { 1.0f, 1.0f, 1.0f }; +static const HALF g_FresnelReflection = 1.0f; +static const HALF g_OneMinusFresnelReflection = 0.0f; +static const HALF4 g_SelfIllumTint = { 1.0f, 1.0f, 1.0f, 1.0f }; +# if OUTLINE +const float4 g_OutlineParams : register( c2 ); +#define OUTLINE_MIN_VALUE0 g_OutlineParams.x +#define OUTLINE_MIN_VALUE1 g_OutlineParams.y +#define OUTLINE_MAX_VALUE0 g_OutlineParams.z +#define OUTLINE_MAX_VALUE1 g_OutlineParams.w + +const float4 g_OutlineColor : register( c3 ); +#define OUTLINE_COLOR g_OutlineColor + +# endif +# if SOFTEDGES +const float4 g_EdgeSoftnessParms : register( c4 ); +#define SOFT_MASK_MIN g_EdgeSoftnessParms.x +#define SOFT_MASK_MAX g_EdgeSoftnessParms.y +# endif +#else + +const HALF3 g_EnvmapContrast : register( c2 ); +const HALF3 g_EnvmapSaturation : register( c3 ); +const HALF4 g_FresnelReflectionReg : register( c4 ); +#define g_FresnelReflection g_FresnelReflectionReg.a +#define g_OneMinusFresnelReflection g_FresnelReflectionReg.b +const HALF4 g_SelfIllumTint : register( c7 ); +#endif + +const float4 g_DetailTint_and_BlendFactor : register( c8 ); +#define g_DetailTint (g_DetailTint_and_BlendFactor.rgb) +#define g_DetailBlendFactor (g_DetailTint_and_BlendFactor.w) + +const HALF3 g_EyePos : register( c10 ); +const HALF4 g_FogParams : register( c11 ); +const float4 g_TintValuesAndLightmapScale : register( c12 ); + +#define g_flAlpha2 g_TintValuesAndLightmapScale.w + +const float4 g_FlashlightAttenuationFactors : register( c13 ); +const float3 g_FlashlightPos : register( c14 ); +const float4x4 g_FlashlightWorldToTexture : register( c15 ); // through c18 +const float4 g_ShadowTweaks : register( c19 ); + + +sampler BaseTextureSampler : register( s0 ); +sampler LightmapSampler : register( s1 ); +sampler EnvmapSampler : register( s2 ); +#if FANCY_BLENDING +sampler BlendModulationSampler : register( s3 ); +#endif + +#if DETAILTEXTURE +sampler DetailSampler : register( s12 ); +#endif + +sampler BumpmapSampler : register( s4 ); +#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA +sampler AlphaMapSampler : register( s9 ); // alpha +#else +#define AlphaMapSampler BumpmapSampler +#endif + +#if BUMPMAP2 == 1 +sampler BumpmapSampler2 : register( s5 ); +#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA +sampler AlphaMapSampler2 : register( s10 ); // alpha +#else +#define AlphaMapSampler2 BumpmapSampler2 +#endif +#else +sampler EnvmapMaskSampler : register( s5 ); +#endif + + +#if WARPLIGHTING +sampler WarpLightingSampler : register( s6 ); +#endif +sampler BaseTextureSampler2 : register( s7 ); + +#if BUMPMASK == 1 +sampler BumpMaskSampler : register( s8 ); +#if NORMALMASK_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA +sampler AlphaMaskSampler : register( s11 ); // alpha +#else +#define AlphaMaskSampler BumpMaskSampler +#endif +#endif + +#if defined( _X360 ) && FLASHLIGHT +sampler FlashlightSampler : register( s13 ); +sampler ShadowDepthSampler : register( s14 ); +sampler RandRotSampler : register( s15 ); +#endif + +struct PS_INPUT +{ +#if SEAMLESS + float3 SeamlessTexCoord : TEXCOORD0; // zy xz + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask +#else + HALF2 baseTexCoord : TEXCOORD0; + // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. +#if ( RELIEF_MAPPING == 0 ) + HALF4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; +#endif +#endif +// CENTROID: TEXCOORD2 + HALF4 lightmapTexCoord1And2 : TEXCOORD2; +// CENTROID: TEXCOORD3 + HALF4 lightmapTexCoord3 : TEXCOORD3; + HALF4 worldPos_projPosZ : TEXCOORD4; + HALF3x3 tangentSpaceTranspose : TEXCOORD5; + // tangentSpaceTranspose : TEXCOORD6 + // tangentSpaceTranspose : TEXCOORD7 + HALF4 vertexColor : COLOR; + float4 vertexBlendX_fogFactorW : COLOR1; + + // Extra iterators on 360, used in flashlight combo +#if defined( _X360 ) && FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; + float4 vProjPos : TEXCOORD9; +#endif +}; + +#if LIGHTING_PREVIEW == 2 +LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR +#else +HALF4 main( PS_INPUT i ) : COLOR +#endif +{ + bool bBaseTexture2 = BASETEXTURE2 ? true : false; + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBumpmap = BUMPMAP ? true : false; + bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; + bool bBaseTextureNoEnvmap = BASETEXTURENOENVMAP ? true : false; + bool bBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP ? true : false; + + float4 baseColor = 0.0f; + float4 baseColor2 = 0.0f; + float4 vNormal = float4(0, 0, 1, 1); + float3 baseTexCoords = float3(0,0,0); + +#if SEAMLESS + baseTexCoords = i.SeamlessTexCoord.xyz; +#else + baseTexCoords.xy = i.baseTexCoord.xy; +#endif + + GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpmapSampler, bBaseTexture2, bBumpmap || bNormalMapAlphaEnvmapMask, + baseTexCoords, i.vertexColor.rgb, baseColor, baseColor2, vNormal ); + +#if BUMPMAP == 1 // not ssbump + vNormal.xyz = vNormal.xyz * 2.0f - 1.0f; // make signed if we're not ssbump +#endif + + HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); +#if LIGHTING_PREVIEW == 0 + if( bBumpmap && bDiffuseBumpmap ) + { + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); + lightmapColor2 = LightMapSample( LightmapSampler, bumpCoord2 ); + lightmapColor3 = LightMapSample( LightmapSampler, bumpCoord3 ); + } + else + { + HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); + lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 ); + } +#endif + +#if RELIEF_MAPPING + // in the parallax case, all texcoords must be the same in order to free + // up an iterator for the tangent space view vector + HALF2 detailTexCoord = i.baseTexCoord.xy; + HALF2 bumpmapTexCoord = i.baseTexCoord.xy; + HALF2 envmapMaskTexCoord = i.baseTexCoord.xy; +#else + + #if ( DETAILTEXTURE == 1 ) + HALF2 detailTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; + HALF2 bumpmapTexCoord = i.baseTexCoord.xy; + #elif ( BUMPMASK == 1 ) + HALF2 detailTexCoord = 0.0f; + HALF2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; + HALF2 bumpmap2TexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz; + #else + HALF2 detailTexCoord = 0.0f; + HALF2 bumpmapTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.xy; + #endif + + HALF2 envmapMaskTexCoord = i.detailOrBumpAndEnvmapMaskTexCoord.wz; +#endif // !RELIEF_MAPPING + + HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); +#if DETAILTEXTURE + +#if SHADER_MODEL_PS_2_0 + detailColor = tex2D( DetailSampler, detailTexCoord ); +#else + detailColor = float4( g_DetailTint, 1.0f ) * tex2D( DetailSampler, detailTexCoord ); +#endif + +#endif + +#if ( OUTLINE || SOFTEDGES ) + float distAlphaMask = baseColor.a; + +# if OUTLINE + if ( ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && + ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) + { + float oFactor=1.0; + if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) + { + oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); + } + else + { + oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); + } + baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); + } +# endif +# if SOFTEDGES + baseColor.a *= smoothstep( SOFT_MASK_MAX, SOFT_MASK_MIN, distAlphaMask ); +# else + baseColor.a *= distAlphaMask >= 0.5; +# endif +#endif + + +#if LIGHTING_PREVIEW == 2 + baseColor.xyz=GammaToLinear(baseColor.xyz); +#endif + + float blendedAlpha = baseColor.a; + +#if MASKEDBLENDING + float blendfactor=0.5; +#else + float blendfactor=i.vertexBlendX_fogFactorW.r; +#endif + + if( bBaseTexture2 ) + { +#if (SELFILLUM == 0) && (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (FANCY_BLENDING) + float4 modt=tex2D(BlendModulationSampler,i.lightmapTexCoord3.zw); +#if MASKEDBLENDING + // FXC is unable to optimize this, despite blendfactor=0.5 above + //float minb=modt.g-modt.r; + //float maxb=modt.g+modt.r; + //blendfactor=smoothstep(minb,maxb,blendfactor); + blendfactor=modt.g; +#else + float minb=saturate(modt.g-modt.r); + float maxb=saturate(modt.g+modt.r); + blendfactor=smoothstep(minb,maxb,blendfactor); +#endif +#endif + baseColor.rgb = lerp( baseColor, baseColor2.rgb, blendfactor ); + blendedAlpha = lerp( baseColor.a, baseColor2.a, blendfactor ); + } + + HALF3 specularFactor = 1.0f; + float4 vNormalMask = float4(0, 0, 1, 1); + if( bBumpmap ) + { + if( bBaseTextureNoEnvmap ) + { + vNormal.a = 0.0f; + } + +#if ( BUMPMAP2 == 1 ) + { + #if ( BUMPMASK == 1 ) + HALF2 b2TexCoord = bumpmap2TexCoord; + #else + HALF2 b2TexCoord = bumpmapTexCoord; + #endif + + HALF4 vNormal2; + if ( BUMPMAP == 2 ) + vNormal2 = tex2D( BumpmapSampler2, b2TexCoord ); + else + vNormal2 = DecompressNormal( BumpmapSampler2, b2TexCoord, NORMAL_DECODE_MODE, AlphaMapSampler2 ); // Bump 2 coords + + if( bBaseTexture2NoEnvmap ) + { + vNormal2.a = 0.0f; + } + + #if ( BUMPMASK == 1 ) + float3 vNormal1 = DecompressNormal( BumpmapSampler, i.detailOrBumpAndEnvmapMaskTexCoord.xy, NORMALMASK_DECODE_MODE, AlphaMapSampler ); + + vNormal.xyz = normalize( vNormal1.xyz + vNormal2.xyz ); + + // Third normal map...same coords as base + vNormalMask = DecompressNormal( BumpMaskSampler, i.baseTexCoord.xy, NORMALMASK_DECODE_MODE, AlphaMaskSampler ); + + vNormal.xyz = lerp( vNormalMask.xyz, vNormal.xyz, vNormalMask.a ); // Mask out normals from vNormal + specularFactor = vNormalMask.a; + #else // BUMPMASK == 0 + if ( FANCY_BLENDING && bNormalMapAlphaEnvmapMask ) + { + vNormal = lerp( vNormal, vNormal2, blendfactor); + } + else + { + vNormal.xyz = lerp( vNormal.xyz, vNormal2.xyz, blendfactor); + } + + #endif + + } + +#endif // BUMPMAP2 == 1 + + if( bNormalMapAlphaEnvmapMask ) + { + specularFactor *= vNormal.a; + } + } + else if ( bNormalMapAlphaEnvmapMask ) + { + specularFactor *= vNormal.a; + } + +#if ( BUMPMAP2 == 0 ) + if( bEnvmapMask ) + { + specularFactor *= tex2D( EnvmapMaskSampler, envmapMaskTexCoord ).xyz; + } +#endif + + if( bBaseAlphaEnvmapMask ) + { + specularFactor *= 1.0 - blendedAlpha; // Reversing alpha blows! + } + float4 albedo = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + float alpha = 1.0f; + albedo *= baseColor; + if( !bBaseAlphaEnvmapMask && !bSelfIllum ) + { + alpha *= baseColor.a; + } + + if( bDetailTexture ) + { + albedo = TextureCombine( albedo, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); + } + + // The vertex color contains the modulation color + vertex color combined +#if ( SEAMLESS == 0 ) + albedo.xyz *= i.vertexColor; +#endif + alpha *= i.vertexColor.a * g_flAlpha2; // not sure about this one + + // Save this off for single-pass flashlight, since we'll still need the SSBump vector, not a real normal + float3 vSSBumpVector = vNormal.xyz; + + HALF3 diffuseLighting; + if( bBumpmap && bDiffuseBumpmap ) + { + +// ssbump +#if ( BUMPMAP == 2 ) + diffuseLighting = vNormal.x * lightmapColor1 + + vNormal.y * lightmapColor2 + + vNormal.z * lightmapColor3; + diffuseLighting *= g_TintValuesAndLightmapScale.rgb; + + // now, calculate vNormal for reflection purposes. if vNormal isn't needed, hopefully + // the compiler will eliminate these calculations + vNormal.xyz = normalize( bumpBasis[0]*vNormal.x + bumpBasis[1]*vNormal.y + bumpBasis[2]*vNormal.z); +#else + float3 dp; + dp.x = saturate( dot( vNormal, bumpBasis[0] ) ); + dp.y = saturate( dot( vNormal, bumpBasis[1] ) ); + dp.z = saturate( dot( vNormal, bumpBasis[2] ) ); + dp *= dp; + +#if ( DETAIL_BLEND_MODE == TCOMBINE_SSBUMP_BUMP ) + dp *= 2*detailColor; +#endif + diffuseLighting = dp.x * lightmapColor1 + + dp.y * lightmapColor2 + + dp.z * lightmapColor3; + float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); + diffuseLighting *= g_TintValuesAndLightmapScale.rgb / sum; +#endif + } + else + { + diffuseLighting = lightmapColor1 * g_TintValuesAndLightmapScale.rgb; + } + +#if WARPLIGHTING && ( SEAMLESS == 0 ) + float len=0.5*length(diffuseLighting); + // FIXME: 8-bit lookup textures like this need a "nice filtering" VTF option, which converts + // them to 16-bit on load or does filtering in the shader (since most hardware - 360 + // included - interpolates 8-bit textures at 8-bit precision, which causes banding) + diffuseLighting *= 2.0*tex2D(WarpLightingSampler,float2(len,0)); +#endif + +#if CUBEMAP || LIGHTING_PREVIEW || ( defined( _X360 ) && FLASHLIGHT ) + float3 worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); +#endif + + float3 diffuseComponent = albedo.xyz * diffuseLighting; + +#if defined( _X360 ) && FLASHLIGHT + + // ssbump doesn't pass a normal to the flashlight...it computes shadowing a different way +#if ( BUMPMAP == 2 ) + bool bHasNormal = false; + + float3 worldPosToLightVector = g_FlashlightPos - i.worldPos_projPosZ.xyz; + + float3 tangentPosToLightVector; + tangentPosToLightVector.x = dot( worldPosToLightVector, i.tangentSpaceTranspose[0] ); + tangentPosToLightVector.y = dot( worldPosToLightVector, i.tangentSpaceTranspose[1] ); + tangentPosToLightVector.z = dot( worldPosToLightVector, i.tangentSpaceTranspose[2] ); + + tangentPosToLightVector = normalize( tangentPosToLightVector ); + + float nDotL = saturate( vSSBumpVector.x*dot( tangentPosToLightVector, bumpBasis[0]) + + vSSBumpVector.y*dot( tangentPosToLightVector, bumpBasis[1]) + + vSSBumpVector.z*dot( tangentPosToLightVector, bumpBasis[2]) ); +#else + bool bHasNormal = true; + float nDotL = 1.0f; +#endif + + float fFlashlight = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, i.flashlightSpacePos, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, 0, true, false, i.vProjPos.xy / i.vProjPos.w, false, g_ShadowTweaks, bHasNormal ); + + diffuseComponent = albedo.xyz * ( diffuseLighting + ( fFlashlight * nDotL ) ); +#endif + + if( bSelfIllum ) + { + float3 selfIllumComponent = g_SelfIllumTint * albedo.xyz; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + } + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); +#if CUBEMAP + if( bCubemap ) + { + float3 worldVertToEyeVector = g_EyePos - i.worldPos_projPosZ.xyz; + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldVertToEyeVector ); + + // Calc Fresnel factor + half3 eyeVect = normalize(worldVertToEyeVector); + HALF fresnel = 1.0 - dot( worldSpaceNormal, eyeVect ); + fresnel = pow( fresnel, 5.0 ); + fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection; + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + + specularLighting *= g_EnvmapTint; +#if FANCY_BLENDING == 0 + HALF3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); + HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); +#endif + specularLighting *= fresnel; + } +#endif + + HALF3 result = diffuseComponent + specularLighting; + +#if LIGHTING_PREVIEW + worldSpaceNormal = mul( vNormal, i.tangentSpaceTranspose ); +# if LIGHTING_PREVIEW == 1 + float dotprod = 0.7+0.25 * dot( worldSpaceNormal, normalize( float3( 1, 2, -.5 ) ) ); + return FinalOutput( HALF4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +# else + LPREVIEW_PS_OUT ret; + ret.color = float4( albedo.xyz,alpha ); + ret.normal = float4( worldSpaceNormal,alpha ); + ret.position = float4( i.worldPos_projPosZ.xyz, alpha ); + ret.flags = float4( 1, 1, 1, alpha ); + + return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +# endif +#else // == end LIGHTING_PREVIEW == + + bool bWriteDepthToAlpha = false; + + // ps_2_b and beyond +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) + bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + +#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; +#endif + + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w ); + +#endif +} + diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc b/sp/src/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc new file mode 100644 index 00000000..599d16a4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc @@ -0,0 +1,59 @@ +// STATIC: "MASKEDBLENDING" "0..1" +// STATIC: "BASETEXTURE2" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "BUMPMAP" "0..2" +// STATIC: "BUMPMAP2" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "BASETEXTURENOENVMAP" "0..1" +// STATIC: "BASETEXTURE2NOENVMAP" "0..1" +// STATIC: "WARPLIGHTING" "0..1" +// STATIC: "FANCY_BLENDING" "0..1" +// STATIC: "RELIEF_MAPPING" "0..0" [ps20b] +// STATIC: "SEAMLESS" "0..1" +// STATIC: "OUTLINE" "0..1" +// STATIC: "SOFTEDGES" "0..1" +// STATIC: "BUMPMASK" "0..1" +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] +// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMALMASK_DECODE_MODE" "0..0" [PC] +// STATIC: "DETAIL_BLEND_MODE" "0..11" +// STATIC: "FLASHLIGHT" "0..1" [ps20b] [XBOX] + +// DYNAMIC: "FASTPATHENVMAPCONTRAST" "0..1" +// DYNAMIC: "FASTPATH" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// SKIP: $SEAMLESS && $RELIEF_MAPPING [ps20b] + +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// SKIP: $SEAMLESS && ( $OUTLINE || $SOFTEDGES) +// SKIP: $BASETEXTURE2 && ( $OUTLINE || $SOFTEDGES) +// SKIP: $BUMPMAP2 && ( $OUTLINE || $SOFTEDGES) +// SKIP: $SELFILLUM && ( $OUTLINE || $SOFTEDGES) +// SKIP: $MASKEDBLENDING && ( $OUTLINE || $SOFTEDGES) +// SKIP: $FANCY_BLENDING && ( $OUTLINE || $SOFTEDGES) +// SKIP: $LIGHTING_PREVIEW && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($FASTPATH == 0) && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($DETAILTEXTURE && $BUMPMAP) && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($WARPLIGHTING) && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($BUMPMAP) && ( $OUTLINE || $SOFTEDGES) +// SKIP: ($DETAIL_BLEND_MODE == 2 ) || ($DETAIL_BLEND_MODE == 3 ) || ($DETAIL_BLEND_MODE == 4 ) +// SKIP: ($DETAIL_BLEND_MODE == 5 ) || ($DETAIL_BLEND_MODE == 6 ) || ($DETAIL_BLEND_MODE == 7 ) +// SKIP: ($DETAIL_BLEND_MODE == 8 ) || ($DETAIL_BLEND_MODE == 9 ) +// SKIP ($DETAIL_BLEND_MODE == 10 ) && ($BUMPMAP == 0 ) +// SKIP ($DETAIL_BLEND_MODE == 11 ) && ($BUMPMAP != 0 ) + +#include "lightmappedgeneric_ps2_3_x.h" + diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh new file mode 100644 index 00000000..84b56437 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 + +mul r0.rgb, t0, v0 + ; base times vertex color (no alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mad r0.rgb, t2, c2, r0 ; + envmap * envmaptint (color only) + +mul r0.rgb, t1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh new file mode 100644 index 00000000..b4893363 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh @@ -0,0 +1,27 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; c1 - self-illum tint +; c2 - envmap tint +;------------------------------------------------------------------------------ + +tex t0 +tex t1 +tex t2 +tex t3 + +mul r0.rgb, t0, v0 + ; base times vertex color (with alpha) +mov r0.a, v0.a ; Grab alpha from vertex color + +mul r1, t2, t3 ; envmap * envmapmask +mad r0.rgb, r1, c2, r0 ; + envmap * envmapmask * envmaptint (color only) + +mul r1, c1, t0.a ; Self illum alpha * tint +mad r1, t0, r1, t1 ; Self illum * tint + lightmap +mul r0.rgb, r1, r0 ; fold in lighting (color only) +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh b/sp/src/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh new file mode 100644 index 00000000..cc1dd1f8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh @@ -0,0 +1,20 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# STATIC: "DETAIL" "0..1" +# STATIC: "ENVMAP" "0..1" +# STATIC: "ENVMAPCAMERASPACE" "0..0" +# STATIC: "ENVMAPSPHERE" "0..1" +# STATIC: "VERTEXCOLOR" "0..1" + +# can't have envmapshere or envmapcameraspace without envmap +# SKIP: !$ENVMAP && ( $ENVMAPSPHERE || $ENVMAPCAMERASPACE ) + +# can't have both envmapsphere and envmapcameraspace +# SKIP: $ENVMAPSPHERE && $ENVMAPCAMERASPACE + +#include "LightmappedGeneric_inc.vsh" + +&LightmappedGeneric( $DETAIL, $ENVMAP, $ENVMAPCAMERASPACE, $ENVMAPSPHERE, + $VERTEXCOLOR ); + diff --git a/sp/src/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc b/sp/src/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc new file mode 100644 index 00000000..362eb668 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc @@ -0,0 +1,254 @@ +// STATIC: "ENVMAP_MASK" "0..1" +// STATIC: "TANGENTSPACE" "0..1" +// STATIC: "BUMPMAP" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "VERTEXALPHATEXBLENDFACTOR" "0..1" +// STATIC: "RELIEF_MAPPING" "0..0" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "BUMPMASK" "0..1" +// STATIC: "FLASHLIGHT" "0..1" [XBOX] + +// DYNAMIC: "FASTPATH" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] + +// This should not be a combo since I'm a moron with the tangent space and the flashlight. +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: $SEAMLESS && $RELIEF_MAPPING +// SKIP: $BUMPMASK && $RELIEF_MAPPING +// SKIP: $BUMPMASK && $SEAMLESS + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_UseSeparateEnvmapMask = ENVMAP_MASK; +static const bool g_bTangentSpace = TANGENTSPACE; +static const bool g_bBumpmap = BUMPMAP; +static const bool g_bBumpmapDiffuseLighting = DIFFUSEBUMPMAP; +static const bool g_bVertexColor = VERTEXCOLOR; +static const bool g_bVertexAlphaTexBlendFactor = VERTEXALPHATEXBLENDFACTOR; +static const bool g_BumpMask = BUMPMASK; + +#if SEAMLESS +const float4 SeamlessScale : register( SHADER_SPECIFIC_CONST_0 ); +#define SEAMLESS_SCALE (SeamlessScale.x) +#else +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cDetailOrBumpTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); +#endif +// This should be identity if we are bump mapping, otherwise we'll screw up the lightmapTexCoordOffset. +const float4 cEnvmapMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cBlendMaskTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_10 ); // not contiguous with the rest! + +struct VS_INPUT +{ + float3 vPos : POSITION; + float4 vNormal : NORMAL; + float2 vBaseTexCoord : TEXCOORD0; + float2 vLightmapTexCoord : TEXCOORD1; + float2 vLightmapTexCoordOffset : TEXCOORD2; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vColor : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + +#if SEAMLESS + float3 SeamlessTexCoord : TEXCOORD0; // x y z + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; // envmap mask +#else + float2 baseTexCoord : TEXCOORD0; + // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. +#if RELIEF_MAPPING + float3 TangentSpaceViewRay : TEXCOORD1; +#else + float4 detailOrBumpAndEnvmapMaskTexCoord : TEXCOORD1; +#endif +#endif + float4 lightmapTexCoord1And2 : TEXCOORD2; + float4 lightmapTexCoord3 : TEXCOORD3; // and basetexcoord*mask_scale + float4 worldPos_projPosZ : TEXCOORD4; + +#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) + float3x3 tangentSpaceTranspose : TEXCOORD5; // and 6 and 7 +#endif + + float4 vertexColor : COLOR; // in seamless, r g b = blend weights + float4 vertexBlendX_fogFactorW : COLOR1; + + // Extra iterators on 360, used in flashlight combo +#if defined( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; + float4 vProjPos : TEXCOORD9; +#endif +#endif + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 vObjNormal; + DecompressVertex_Normal( v.vNormal, vObjNormal ); + + float3 worldPos = mul( float4( v.vPos, 1 ), cModel[0] ); + + float4 vProjPos = mul( float4( v.vPos, 1 ), cModelViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( v.vPos, 1 ), cModelViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); + + float3 worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] ); + +#if TANGENTSPACE || (LIGHTING_PREVIEW) || defined( _X360 ) + float3 worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] ); + float3 worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] ); + + #if SEAMLESS && BUMPMAP && defined( _X360 ) + float3 n = normalize( worldNormal ); + float3 n2 = n * n; // sums to 1. + + o.tangentSpaceTranspose[0] = normalize( float3( n2.y + n2.z, 0.0f, n2.x ) ); + o.tangentSpaceTranspose[1] = normalize( float3( 0.0f, n2.x + n2.z, n2.y ) ); + o.tangentSpaceTranspose[2] = worldNormal; + #else + o.tangentSpaceTranspose[0] = worldTangentS; + o.tangentSpaceTranspose[1] = worldTangentT; + o.tangentSpaceTranspose[2] = worldNormal; + #endif + +#endif + + float3 worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + +#if SEAMLESS + { + // we need to fill in the texture coordinate projections + o.SeamlessTexCoord = SEAMLESS_SCALE*worldPos; + } +#else + { + if (FASTPATH) + { + o.baseTexCoord.xy = v.vBaseTexCoord; + } + else + { + o.baseTexCoord.x = dot( v.vBaseTexCoord, cBaseTexCoordTransform[0] ) + cBaseTexCoordTransform[0].w; + o.baseTexCoord.y = dot( v.vBaseTexCoord, cBaseTexCoordTransform[1] ) + cBaseTexCoordTransform[1].w; + } +#if ( RELIEF_MAPPING == 0 ) + { + // calculate detailorbumptexcoord + if ( FASTPATH ) + o.detailOrBumpAndEnvmapMaskTexCoord.xy = v.vBaseTexCoord.xy; + else + { + o.detailOrBumpAndEnvmapMaskTexCoord.x = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[0] ) + cDetailOrBumpTexCoordTransform[0].w; + o.detailOrBumpAndEnvmapMaskTexCoord.y = dot( v.vBaseTexCoord, cDetailOrBumpTexCoordTransform[1] ) + cDetailOrBumpTexCoordTransform[1].w; + } + } +#endif + } +#endif + if ( FASTPATH ) + { + o.lightmapTexCoord3.zw = v.vBaseTexCoord; + } + else + { + o.lightmapTexCoord3.z = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[0] ) + cBlendMaskTexCoordTransform[0].w; + o.lightmapTexCoord3.w = dot( v.vBaseTexCoord, cBlendMaskTexCoordTransform[1] ) + cBlendMaskTexCoordTransform[1].w; + } + + // compute lightmap coordinates + if( g_bBumpmap && g_bBumpmapDiffuseLighting ) + { + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord + v.vLightmapTexCoordOffset; + + float2 lightmapTexCoord2 = o.lightmapTexCoord1And2.xy + v.vLightmapTexCoordOffset; + float2 lightmapTexCoord3 = lightmapTexCoord2 + v.vLightmapTexCoordOffset; + + // reversed component order + o.lightmapTexCoord1And2.w = lightmapTexCoord2.x; + o.lightmapTexCoord1And2.z = lightmapTexCoord2.y; + + o.lightmapTexCoord3.xy = lightmapTexCoord3; + } + else + { + o.lightmapTexCoord1And2.xy = v.vLightmapTexCoord; + } + +#if ( RELIEF_MAPPING == 0) + if( g_UseSeparateEnvmapMask || g_BumpMask ) + { + // reversed component order +# if FASTPATH + o.detailOrBumpAndEnvmapMaskTexCoord.wz = v.vBaseTexCoord.xy; +# else + o.detailOrBumpAndEnvmapMaskTexCoord.w = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[0] ) + cEnvmapMaskTexCoordTransform[0].w; + o.detailOrBumpAndEnvmapMaskTexCoord.z = dot( v.vBaseTexCoord, cEnvmapMaskTexCoordTransform[1] ) + cEnvmapMaskTexCoordTransform[1].w; +# endif + } +#endif + + o.vertexBlendX_fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.vertexBlendX_fogFactorW; +#endif + + if (!g_bVertexColor) + { + o.vertexColor = float4( 1.0f, 1.0f, 1.0f, cModulationColor.a ); + } + else + { +#if FASTPATH + o.vertexColor = v.vColor; +#else + if ( g_bVertexAlphaTexBlendFactor ) + { + o.vertexColor.rgb = v.vColor.rgb; + o.vertexColor.a = cModulationColor.a; + } + else + { + o.vertexColor = v.vColor; + o.vertexColor.a *= cModulationColor.a; + } +#endif + } +#if SEAMLESS + // compute belnd weights in rgb + float3 vNormal=normalize( worldNormal ); + o.vertexColor.xyz = vNormal * vNormal; // sums to 1. +#endif + +// On 360, we have extra iterators and can fold the flashlight into this shader +#if defined( _X360 ) + #if FLASHLIGHT + o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); + o.vProjPos = vProjPos; + #endif +#endif + + if ( g_bVertexAlphaTexBlendFactor ) + { + o.vertexBlendX_fogFactorW.r = v.vColor.a; + } + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/refract.cpp b/sp/src/materialsystem/stdshaders/refract.cpp new file mode 100644 index 00000000..852e93a5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/refract.cpp @@ -0,0 +1,111 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "convar.h" +#include "refract_dx9_helper.h" + +DEFINE_FALLBACK_SHADER( Refract, Refract_DX90 ) + +BEGIN_VS_SHADER( Refract_DX90, "Help for Refract" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" ) + SHADER_PARAM( NORMALMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $normalmap" ) + SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $normalmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$normalmap texcoord transform" ) + SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$normalmap texcoord transform" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0f", "" ) + SHADER_PARAM( BLURAMOUNT, SHADER_PARAM_TYPE_INTEGER, "1", "0, 1, or 2 for how much blur you want" ) + SHADER_PARAM( FADEOUTONSILHOUETTE, SHADER_PARAM_TYPE_BOOL, "1", "0 for no fade out on silhouette, 1 for fade out on sillhouette" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( REFRACTTINTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shield", "" ) + SHADER_PARAM( REFRACTTINTTEXTUREFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( NOWRITEZ, SHADER_PARAM_TYPE_INTEGER, "0", "0 == write z, 1 = no write z" ) + SHADER_PARAM( MASKED, SHADER_PARAM_TYPE_BOOL, "0", "mask using dest alpha" ) + SHADER_PARAM( VERTEXCOLORMODULATE, SHADER_PARAM_TYPE_BOOL, "0","Use the vertex color to effect refract color. alpha will adjust refract amount" ) + SHADER_PARAM( FORCEALPHAWRITE, SHADER_PARAM_TYPE_BOOL, "0","Force the material to write alpha to the dest buffer" ) + END_SHADER_PARAMS +// FIXME: doesn't support Fresnel! + + void SetupVars( Refract_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nFrame = FRAME; + info.m_nRefractAmount = REFRACTAMOUNT; + info.m_nRefractTint = REFRACTTINT; + info.m_nNormalMap = NORMALMAP; + info.m_nNormalMap2 = NORMALMAP2; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpFrame2 = BUMPFRAME2; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nBumpTransform2 = BUMPTRANSFORM2; + info.m_nBlurAmount = BLURAMOUNT; + info.m_nFadeOutOnSilhouette = FADEOUTONSILHOUETTE; + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nRefractTintTexture = REFRACTTINTTEXTURE; + info.m_nRefractTintTextureFrame = REFRACTTINTTEXTUREFRAME; + info.m_nFresnelReflection = FRESNELREFLECTION; + info.m_nNoWriteZ = NOWRITEZ; + info.m_nMasked = MASKED; + info.m_nVertexColorModulate = VERTEXCOLORMODULATE; + info.m_nForceAlphaWrite = FORCEALPHAWRITE; + } + + SHADER_INIT_PARAMS() + { + Refract_DX9_Vars_t info; + SetupVars( info ); + InitParamsRefract_DX9( this, params, pMaterialName, info ); + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 82 ) + return "Refract_DX80"; + + return 0; + } + + SHADER_INIT + { + Refract_DX9_Vars_t info; + SetupVars( info ); + InitRefract_DX9( this, params, info ); + } + + SHADER_DRAW + { + Refract_DX9_Vars_t info; + SetupVars( info ); + + // If ( snapshotting ) or ( we need to draw this frame ) + bool bHasFlashlight = this->UsingFlashlight( params ); + if ( ( pShaderShadow != NULL ) || ( bHasFlashlight == false ) ) + { + DrawRefract_DX9( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + Draw( false ); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/refract_dx60.cpp b/sp/src/materialsystem/stdshaders/refract_dx60.cpp new file mode 100644 index 00000000..2ca7a83c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/refract_dx60.cpp @@ -0,0 +1,16 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// FIXME: This is a placeholder. . need to do something for real here. +DEFINE_FALLBACK_SHADER( Refract, Refract_DX60 ) +DEFINE_FALLBACK_SHADER( Refract_DX60, UnlitGeneric ) + + diff --git a/sp/src/materialsystem/stdshaders/refract_dx80.cpp b/sp/src/materialsystem/stdshaders/refract_dx80.cpp new file mode 100644 index 00000000..b6e6e5a0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/refract_dx80.cpp @@ -0,0 +1,317 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + + +#include "BaseVSShader.h" + +#include "refract_model_vs11.inc" +#include "refract_world_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define MAXBLUR 1 + +DEFINE_FALLBACK_SHADER( Refract, Refract_DX80 ) + +BEGIN_VS_SHADER( Refract_DX80, + "Help for Refract_DX80" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_COLOR, "{255 255 255}", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( DUDVMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_dudv", "dudv bump map" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( DUDVFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $dudvmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0f", "" ) + SHADER_PARAM( BLURAMOUNT, SHADER_PARAM_TYPE_INTEGER, "1", "0, 1, or 2 for how much blur you want" ) + SHADER_PARAM( FADEOUTONSILHOUETTE, SHADER_PARAM_TYPE_BOOL, "1", "0 for no fade out on silhouette, 1 for fade out on sillhouette" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( REFRACTTINTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shield", "" ) + SHADER_PARAM( REFRACTTINTTEXTUREFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( FALLBACK, SHADER_PARAM_TYPE_STRING, "", "Name of the fallback shader" ) + SHADER_PARAM( FORCEREFRACT, SHADER_PARAM_TYPE_BOOL, "0", "Forces refraction on boards that have poor performance" ) + SHADER_PARAM( NOWRITEZ, SHADER_PARAM_TYPE_INTEGER, "0", "0 == write z, 1 = no write z" ) + SHADER_PARAM( MASKED, SHADER_PARAM_TYPE_BOOL, "0", "mask using dest alpha" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + if( !params[ENVMAPTINT]->IsDefined() ) + { + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + if( !params[ENVMAPCONTRAST]->IsDefined() ) + { + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + } + if( !params[ENVMAPSATURATION]->IsDefined() ) + { + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + } + if( !params[ENVMAPFRAME]->IsDefined() ) + { + params[ENVMAPFRAME]->SetIntValue( 0 ); + } + if( !params[FRESNELREFLECTION]->IsDefined() ) + { + params[FRESNELREFLECTION]->SetFloatValue( 1.0f ); + } + if( !params[MASKED]->IsDefined() ) + { + params[MASKED]->SetIntValue( 0 ); + } + if( !params[BLURAMOUNT]->IsDefined() ) + { + params[BLURAMOUNT]->SetIntValue( 0 ); + } + if( !params[FADEOUTONSILHOUETTE]->IsDefined() ) + { + params[FADEOUTONSILHOUETTE]->SetIntValue( 0 ); + } + SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + SHADER_FALLBACK + { + if ( IsPC() ) + { + const char *pFallback = (params && params[FALLBACK]->IsDefined()) ? params[FALLBACK]->GetStringValue() : ""; + if (!pFallback[0]) + { + pFallback = "Refract_DX60"; + } + + if( g_pHardwareConfig->GetDXSupportLevel() < 80 || !g_pHardwareConfig->HasProjectedBumpEnv() ) + return pFallback; + + if ( g_pHardwareConfig->PreferReducedFillrate() && (params && (params[FORCEREFRACT]->GetIntValue() == 0)) ) + return pFallback; + } + + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE ); + } + if (params[DUDVMAP]->IsDefined() ) + { + LoadTexture( DUDVMAP ); + } + if (params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + if( params[ENVMAP]->IsDefined() ) + { + LoadCubeMap( ENVMAP ); + } + if( params[REFRACTTINTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTINTTEXTURE ); + } + } + + inline int ComputePixelShaderIndex( bool bRefractTintTexture, bool bNormalMapAlpha ) + { + // "REFRACTTINTTEXTURE" "0..1" + // "NORMALMAPALPHA" "0..1" + int pshIndex = 0; + if( bRefractTintTexture ) pshIndex |= 0x1; + if( bNormalMapAlpha ) pshIndex |= 0x2; + return pshIndex; + } + + SHADER_DRAW + { + bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL ); + bool bHasEnvmap = params[ENVMAP]->IsTexture(); + int blurAmount = params[BLURAMOUNT]->GetIntValue(); + bool bRefractTintTexture = params[REFRACTTINTTEXTURE]->IsTexture(); + if( blurAmount < 0 ) + { + blurAmount = 0; + } + else if( blurAmount > MAXBLUR ) + { + blurAmount = MAXBLUR; + } + bool bMasked = (params[MASKED]->GetIntValue() != 0); + + SHADOW_STATE + { + if ( params[NOWRITEZ]->GetIntValue() != 0 ) + { + pShaderShadow->EnableDepthWrites( false ); + } + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // If envmap is not specified, the alpha channel is the translucency + // (If envmap *is* specified, alpha channel is the reflection amount) + bool bNormalMapAlpha = false; + if ( params[NORMALMAP]->IsTexture() && !bHasEnvmap ) + { + SetDefaultBlendingShadowState( NORMALMAP, false ); + if ( !bMasked && TextureIsTranslucent( NORMALMAP, false ) ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + bNormalMapAlpha = true; + } + } + + // dudv map + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // renderable texture for refraction + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + if( bRefractTintTexture ) + { + // refract tint texture + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + int userDataSize = 0; + if( bIsModel ) + { + userDataSize = 4; + } + else + { + fmt |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, userDataSize ); + + if( bIsModel ) + { + refract_model_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Refract_model_vs11", vshIndex.GetIndex() ); + } + else + { + refract_world_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Refract_world_vs11", vshIndex.GetIndex() ); + } + + int pshIndex; + pshIndex = ComputePixelShaderIndex( bRefractTintTexture, bNormalMapAlpha ); + pShaderShadow->SetPixelShader( "Refract_ps11", pshIndex ); + + if( bMasked ) + { + EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + } + DefaultFog(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); + + if ( params[DUDVFRAME]->GetIntValue() == 0 ) + { + BindTexture( SHADER_SAMPLER0, DUDVMAP, BUMPFRAME ); + } + else + { + BindTexture( SHADER_SAMPLER0, DUDVMAP, DUDVFRAME ); + } + + if ( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); + } + + if( bRefractTintTexture ) + { + BindTexture( SHADER_SAMPLER2, REFRACTTINTTEXTURE, REFRACTTINTTEXTUREFRAME ); + } + + if ( params[NORMALMAP]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER3, NORMALMAP, BUMPFRAME ); + } + + float fRefractionAmount = params[REFRACTAMOUNT]->GetFloatValue(); + pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fRefractionAmount, 0.0f, 0.0f, fRefractionAmount ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + // used to invert y + // xboxfixme - move this into defined constants + float c[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); + + SetPixelShaderConstant( 0, REFRACTTINT ); + if( bIsModel ) + { + refract_model_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + else + { + refract_world_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + + Draw(); + + if( bHasEnvmap ) + { + bool bNoWriteZ = (params[NOWRITEZ]->GetIntValue() != 0); + const bool bBlendSpecular = true; + if( bIsModel ) + { + DrawModelBumpedSpecularLighting( NORMALMAP, BUMPFRAME, + ENVMAP, ENVMAPFRAME, + ENVMAPTINT, ALPHA, + ENVMAPCONTRAST, ENVMAPSATURATION, + BUMPTRANSFORM, + bBlendSpecular, bNoWriteZ ); + } + else + { + DrawWorldBumpedSpecularLighting( NORMALMAP, ENVMAP, + BUMPFRAME, ENVMAPFRAME, + ENVMAPTINT, ALPHA, + ENVMAPCONTRAST, ENVMAPSATURATION, + BUMPTRANSFORM, FRESNELREFLECTION, + bBlendSpecular, bNoWriteZ ); + } + } + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/refract_dx9_helper.cpp b/sp/src/materialsystem/stdshaders/refract_dx9_helper.cpp new file mode 100644 index 00000000..f436e62a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/refract_dx9_helper.cpp @@ -0,0 +1,342 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "refract_dx9_helper.h" +#include "convar.h" +#include "Refract_vs20.inc" +#include "Refract_ps20.inc" +#include "Refract_ps20b.inc" +#include "cpp_shader_constant_register_map.h" + +#define MAXBLUR 1 + +// FIXME: doesn't support fresnel! +void InitParamsRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, Refract_DX9_Vars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + if( !params[info.m_nEnvmapTint]->IsDefined() ) + { + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + if( !params[info.m_nEnvmapContrast]->IsDefined() ) + { + params[info.m_nEnvmapContrast]->SetFloatValue( 0.0f ); + } + if( !params[info.m_nEnvmapSaturation]->IsDefined() ) + { + params[info.m_nEnvmapSaturation]->SetFloatValue( 1.0f ); + } + if( !params[info.m_nEnvmapFrame]->IsDefined() ) + { + params[info.m_nEnvmapFrame]->SetIntValue( 0 ); + } + if( !params[info.m_nFresnelReflection]->IsDefined() ) + { + params[info.m_nFresnelReflection]->SetFloatValue( 1.0f ); + } + if( !params[info.m_nMasked]->IsDefined() ) + { + params[info.m_nMasked]->SetIntValue( 0 ); + } + if( !params[info.m_nBlurAmount]->IsDefined() ) + { + params[info.m_nBlurAmount]->SetIntValue( 0 ); + } + if( !params[info.m_nFadeOutOnSilhouette]->IsDefined() ) + { + params[info.m_nFadeOutOnSilhouette]->SetIntValue( 0 ); + } + if( !params[info.m_nForceAlphaWrite]->IsDefined() ) + { + params[info.m_nForceAlphaWrite]->SetIntValue( 0 ); + } + SET_FLAGS2( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); +} + +void InitRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, Refract_DX9_Vars_t &info ) +{ + if (params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + } + if (params[info.m_nNormalMap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nNormalMap ); + } + if (params[info.m_nNormalMap2]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nNormalMap2 ); + } + if( params[info.m_nEnvmap]->IsDefined() ) + { + pShader->LoadCubeMap( info.m_nEnvmap, TEXTUREFLAGS_SRGB ); + } + if( params[info.m_nRefractTintTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nRefractTintTexture, TEXTUREFLAGS_SRGB ); + } +} + +void DrawRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Refract_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) +{ + bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL ); + bool bHasEnvmap = params[info.m_nEnvmap]->IsTexture(); + bool bRefractTintTexture = params[info.m_nRefractTintTexture]->IsTexture(); + bool bFadeOutOnSilhouette = params[info.m_nFadeOutOnSilhouette]->GetIntValue() != 0; + int blurAmount = params[info.m_nBlurAmount]->GetIntValue(); + bool bMasked = (params[info.m_nMasked]->GetIntValue() != 0); + bool bSecondaryNormal = ( ( info.m_nNormalMap2 != -1 ) && ( params[info.m_nNormalMap2]->IsTexture() ) ); + bool bColorModulate = ( ( info.m_nVertexColorModulate != -1 ) && ( params[info.m_nVertexColorModulate]->GetIntValue() ) ); + bool bWriteZ = params[info.m_nNoWriteZ]->GetIntValue() == 0; + + if( blurAmount < 0 ) + { + blurAmount = 0; + } + else if( blurAmount > MAXBLUR ) + { + blurAmount = MAXBLUR; + } + + BlendType_t nBlendType = pShader->EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + bFullyOpaque &= !bMasked; + + bool bTranslucentNormal = pShader->TextureIsTranslucent( info.m_nNormalMap, false ); + bFullyOpaque &= (! bTranslucentNormal ); + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( g_pHardwareConfig->SupportsNormalMapCompression() ) + { + ITexture *pBumpTex = params[info.m_nNormalMap]->GetTextureValue(); + if ( pBumpTex ) + { + nNormalDecodeMode = pBumpTex->GetNormalDecodeMode(); + + if ( bSecondaryNormal ) // Check encoding of secondary normal if there is one + { + ITexture *pBumpTex2 = params[info.m_nNormalMap2]->GetTextureValue(); + if ( pBumpTex2 && ( pBumpTex2->GetNormalDecodeMode() != nNormalDecodeMode ) ) + { + DevMsg("Refract: Primary and Secondary normal map compression formats don't match. This is unsupported!\n"); + Assert(0); + } + } + } + } + + SHADOW_STATE + { + pShader->SetInitialShadowState( ); + + pShaderShadow->EnableDepthWrites( bWriteZ ); + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // If envmap is not specified, the alpha channel is the translucency + // (If envmap *is* specified, alpha channel is the reflection amount) + if ( params[info.m_nNormalMap]->IsTexture() && !bHasEnvmap ) + { + pShader->SetDefaultBlendingShadowState( info.m_nNormalMap, false ); + } + + // source render target that contains the image that we are warping. + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Normal map alpha, in the compressed normal case + } + + if ( bSecondaryNormal ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Secondary normal map alpha, in the compressed normal case + } + } + + if( bHasEnvmap ) + { + // envmap + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); + } + if( bRefractTintTexture ) + { + // refract tint texture + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true ); + } + + pShaderShadow->EnableSRGBWrite( true ); + + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; + int userDataSize = 0; + int nTexCoordCount = 1; + if( bIsModel ) + { + userDataSize = 4; + } + else + { + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; + } + + if ( bColorModulate ) + { + flags |= VERTEX_COLOR; + } + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + DECLARE_STATIC_VERTEX_SHADER( refract_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel ); + SET_STATIC_VERTEX_SHADER_COMBO( COLORMODULATE, bColorModulate ); + SET_STATIC_VERTEX_SHADER( refract_vs20 ); + + // We have to do this in the shader on R500 or Leopard + bool bShaderSRGBConvert = IsOSX() && ( g_pHardwareConfig->FakeSRGBWrite() || !g_pHardwareConfig->CanDoSRGBReadFromRTs() ); + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // always send OpenGL down the ps2b path + { + DECLARE_STATIC_PIXEL_SHADER( refract_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( BLUR, blurAmount ); + SET_STATIC_PIXEL_SHADER_COMBO( FADEOUTONSILHOUETTE, bFadeOutOnSilhouette ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTTINTTEXTURE, bRefractTintTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKED, bMasked ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORMODULATE, bColorModulate ); + SET_STATIC_PIXEL_SHADER_COMBO( SECONDARY_NORMAL, bSecondaryNormal ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSRGBConvert ); + SET_STATIC_PIXEL_SHADER( refract_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( refract_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLUR, blurAmount ); + SET_STATIC_PIXEL_SHADER_COMBO( FADEOUTONSILHOUETTE, bFadeOutOnSilhouette ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTTINTTEXTURE, bRefractTintTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( MASKED, bMasked ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORMODULATE, bColorModulate ); + SET_STATIC_PIXEL_SHADER_COMBO( SECONDARY_NORMAL, bSecondaryNormal ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( refract_ps20 ); + } + pShader->DefaultFog(); + if( bMasked ) + { + pShader->EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + } + + bool bAlphaWrites = bFullyOpaque || ( params[ info.m_nForceAlphaWrite ]->GetIntValue() != 0 ); + pShaderShadow->EnableAlphaWrites( bAlphaWrites ); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + if ( params[info.m_nBaseTexture]->IsTexture() ) + { + pShader->BindTexture( SHADER_SAMPLER2, info.m_nBaseTexture, info.m_nFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); + } + + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShader->BindTexture( SHADER_SAMPLER3, SHADER_SAMPLER6, info.m_nNormalMap, info.m_nBumpFrame ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER3, info.m_nNormalMap, info.m_nBumpFrame ); + } + + if ( bSecondaryNormal ) + { + if ( nNormalDecodeMode == NORMAL_DECODE_ATI2N_ALPHA ) + { + pShader->BindTexture( SHADER_SAMPLER1, SHADER_SAMPLER7, info.m_nNormalMap2, info.m_nBumpFrame2 ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nNormalMap2, info.m_nBumpFrame2 ); + } + } + + if( bHasEnvmap ) + { + pShader->BindTexture( SHADER_SAMPLER4, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + if( bRefractTintTexture ) + { + pShader->BindTexture( SHADER_SAMPLER5, info.m_nRefractTintTexture, info.m_nRefractTintTextureFrame ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( refract_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( refract_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // always send Posix down the ps2b path + { + DECLARE_DYNAMIC_PIXEL_SHADER( refract_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteZ && bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( refract_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( refract_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( refract_ps20 ); + } + + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, info.m_nBumpTransform ); // 1 & 2 + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nBumpTransform2 ); // 3 & 4 + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + pShader->SetPixelShaderConstantGammaToLinear( 0, info.m_nEnvmapTint ); + pShader->SetPixelShaderConstantGammaToLinear( 1, info.m_nRefractTint ); + pShader->SetPixelShaderConstant( 2, info.m_nEnvmapContrast ); + pShader->SetPixelShaderConstant( 3, info.m_nEnvmapSaturation ); + float c5[4] = { params[info.m_nRefractAmount]->GetFloatValue(), + params[info.m_nRefractAmount]->GetFloatValue(), 0.0f, 0.0f }; + + // Time % 1000 + c5[3] = pShaderAPI->CurrentTime(); + c5[3] -= (float)( (int)( c5[3] / 1000.0f ) ) * 1000.0f; + pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); + + float cVs3[4] = { c5[3], 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, cVs3, 1 ); + } + pShader->Draw(); +} + diff --git a/sp/src/materialsystem/stdshaders/refract_dx9_helper.h b/sp/src/materialsystem/stdshaders/refract_dx9_helper.h new file mode 100644 index 00000000..69d6116f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/refract_dx9_helper.h @@ -0,0 +1,62 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef REFRACT_DX9_HELPER_H +#define REFRACT_DX9_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct Refract_DX9_Vars_t +{ + Refract_DX9_Vars_t() { memset( this, 0xFF, sizeof( *this ) ); } + + int m_nBaseTexture; + int m_nFrame; + int m_nRefractAmount; + int m_nRefractTint; + int m_nNormalMap; + int m_nNormalMap2; + int m_nBumpFrame; + int m_nBumpFrame2; + int m_nBumpTransform; + int m_nBumpTransform2; + int m_nBlurAmount; + int m_nFadeOutOnSilhouette; + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapTint; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nRefractTintTexture; + int m_nRefractTintTextureFrame; + int m_nFresnelReflection; + int m_nNoWriteZ; + int m_nMasked; + int m_nVertexColorModulate; + int m_nForceAlphaWrite; +}; + +void InitParamsRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, + Refract_DX9_Vars_t &info ); +void InitRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, Refract_DX9_Vars_t &info ); +void DrawRefract_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, Refract_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // REFRACT_DX9_HELPER_H diff --git a/sp/src/materialsystem/stdshaders/refract_ps2x.fxc b/sp/src/materialsystem/stdshaders/refract_ps2x.fxc new file mode 100644 index 00000000..2f974230 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/refract_ps2x.fxc @@ -0,0 +1,250 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. ======= +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "BLUR" "0..1" +// STATIC: "FADEOUTONSILHOUETTE" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "REFRACTTINTTEXTURE" "0..1" +// STATIC: "MASKED" "0..1" +// STATIC: "COLORMODULATE" "0..1" +// STATIC: "SECONDARY_NORMAL" "0..1" +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] +// STATIC: "SHADER_SRGB_READ" "0..1" [ps20b] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// SKIP: $MASKED && $BLUR + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler NormalSampler2 : register( s1 ); +sampler RefractSampler : register( s2 ); +sampler NormalSampler : register( s3 ); +#if CUBEMAP +sampler EnvmapSampler : register( s4 ); +#endif +#if REFRACTTINTTEXTURE +sampler RefractTintSampler : register( s5 ); +#endif + +#if NORMAL_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA +sampler AlphaMapSampler : register( s6 ); // alpha +sampler AlphaMapSampler2 : register( s7 ); +#else +#define AlphaMapSampler2 NormalSampler +#define AlphaMapSampler NormalSampler2 +#endif + +const float3 g_EnvmapTint : register( c0 ); +const float3 g_RefractTint : register( c1 ); +const float3 g_EnvmapContrast : register( c2 ); +const float3 g_EnvmapSaturation : register( c3 ); +const float4 g_c5 : register( c5 ); +#define g_RefractScale g_c5.x +#define g_flTime g_c5.w + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +static const int g_BlurCount = BLUR; +static const float g_BlurFraction = 1.0f / 512.0f; +static const float g_HalfBlurFraction = 0.5 * g_BlurFraction; +static const float4 g_BlurFractionVec = float4( g_BlurFraction, g_HalfBlurFraction, + -g_BlurFraction,-g_HalfBlurFraction ); + +struct PS_INPUT +{ + float4 vBumpTexCoord : TEXCOORD0; // NormalMap1 in xy, NormalMap2 in wz + float3 vTangentVertToEyeVector : TEXCOORD1; + float3 vWorldNormal : TEXCOORD2; + float3 vWorldTangent : TEXCOORD3; + float3 vWorldBinormal : TEXCOORD4; + float3 vRefractXYW : TEXCOORD5; + float3 vWorldViewVector : TEXCOORD6; +#if COLORMODULATE + float4 ColorModulate : COLOR0; +#endif + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 result; + + float pixelFogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + +#if FADEOUTONSILHOUETTE + //float blend = -i.projNormal.z; + float blend = saturate( dot( -i.vWorldViewVector.xyz, i.vWorldNormal.xyz ) ); + blend = blend * blend * blend; +#else + float blend = 1.0f; +#endif + + // Decompress normal + float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord.xy, NORMAL_DECODE_MODE, AlphaMapSampler ); + +#if SECONDARY_NORMAL + float3 vNormal2 = DecompressNormal( NormalSampler2, i.vBumpTexCoord.wz, NORMAL_DECODE_MODE, AlphaMapSampler2 ); + vNormal.xyz = normalize( vNormal.xyz + vNormal2.xyz ); +#endif + +#if REFRACTTINTTEXTURE + float3 refractTintColor = 2.0 * g_RefractTint * tex2D( RefractTintSampler, i.vBumpTexCoord.xy ); +#else + float3 refractTintColor = g_RefractTint; +#endif + +#if COLORMODULATE + refractTintColor *= i.ColorModulate.rgb; +#endif + + // Perform division by W only once + float ooW = 1.0f / i.vRefractXYW.z; + + // Compute coordinates for sampling refraction + float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW; + float2 vRefractTexCoord = vNormal.xy; + float scale = vNormal.a * g_RefractScale; +#if COLORMODULATE + scale *= i.ColorModulate.a; +#endif + vRefractTexCoord *= scale; + vRefractTexCoord += vRefractTexCoordNoWarp; + +#if (BLUR==1) // use polyphase magic to convert 9 lookups into 4 + + // basic principle behind this transformation: + // [ A B C ] + // [ D E F ] + // [ G H I ] + // use bilinear filtering hardware to weight upper 2x2 samples evenly (0.25* [A + B + D + E]). + // scale the upper 2x2 by 4/9 (total area of kernel occupied) + // use bilinear filtering hardware to weight right 1x2 samples evenly (0.5*[C + F]) + // scale right 1x2 by 2/9 + // use bilinear filtering hardware to weight lower 2x1 samples evenly (0.5*[G + H]) + // scale bottom 2x1 by 2/9 + // fetch last sample (I) and scale by 1/9. + + float2 upper_2x2_loc = vRefractTexCoord.xy - float2(g_HalfBlurFraction, g_HalfBlurFraction); + float2 right_1x2_loc = vRefractTexCoord.xy + float2(g_BlurFraction, -g_HalfBlurFraction); + float2 lower_2x1_loc = vRefractTexCoord.xy + float2(-g_HalfBlurFraction, g_BlurFraction); + float2 singleton_loc = vRefractTexCoord.xy + float2(g_BlurFraction, g_BlurFraction); + result = tex2D(RefractSampler, upper_2x2_loc) * 0.4444444; + result += tex2D(RefractSampler, right_1x2_loc) * 0.2222222; + result += tex2D(RefractSampler, lower_2x1_loc) * 0.2222222; + result += tex2D(RefractSampler, singleton_loc) * 0.1111111; + + #if ( SHADER_SRGB_READ == 1 ) + { + // Just do this once rather than after every blur step, which is wrong, but much more efficient + result = GammaToLinear( result ); + } + #endif + + float3 unblurredColor = tex2D(RefractSampler, vRefractTexCoordNoWarp.xy); + #if ( SHADER_SRGB_READ == 1 ) + { + unblurredColor = GammaToLinear( unblurredColor ); + } + #endif + + result = lerp(unblurredColor, result * refractTintColor, blend); + +#elif (BLUR>0) // iteratively step through render target + int x, y; + + result = float3( 0.0f, 0.0f, 0.0f ); + for( x = -g_BlurCount; x <= g_BlurCount; x++ ) + { + for( y = -g_BlurCount; y <= g_BlurCount; y++ ) + { + result += tex2D( RefractSampler, vRefractTexCoord.xy + float2( g_BlurFraction * x, g_BlurFraction * y ) ); + } + } + + int width = g_BlurCount * 2 + 1; + result *= 1.0f / ( width * width ); + + #if ( SHADER_SRGB_READ == 1 ) + { + // Just do this once rather than after every blur step, which is wrong, but much more efficient + result = GammaToLinear( result ); + } + #endif + + // result is the blurred one now. . .now lerp. + float3 unblurredColor = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + unblurredColor = GammaToLinear( unblurredColor ); + } + #endif + + result = lerp( unblurredColor, result * refractTintColor, blend ); +#else +# if MASKED + float4 fMaskedResult = tex2D( RefractSampler, vRefractTexCoord.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + fMaskedResult = GammaToLinear( fMaskedResult ); + } + #endif + + return FinalOutput( fMaskedResult, pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE ); +# else + float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + colorWarp = GammaToLinear( colorWarp ); + } + #endif + float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy ); + #if ( SHADER_SRGB_READ == 1 ) + { + colorNoWarp = GammaToLinear( colorNoWarp ); + } + #endif + + colorWarp *= refractTintColor; + result = lerp( colorNoWarp, colorWarp, blend ); +# endif +#endif + +#if CUBEMAP + float specularFactor = vNormal.a; + + float3 worldSpaceNormal = Vec3TangentToWorld( vNormal.xyz, i.vWorldNormal, i.vWorldTangent, i.vWorldBinormal ); + + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vTangentVertToEyeVector ); + float3 specularLighting = texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint; + float3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast ); + float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); + result += specularLighting; +#endif + +#if COLORMODULATE + float resultAlpha = i.ColorModulate.a * vNormal.a; +#else + float resultAlpha = vNormal.a; +#endif + + return FinalOutput( float4( result, resultAlpha ), pixelFogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/sp/src/materialsystem/stdshaders/shadowmodel_dx8.cpp b/sp/src/materialsystem/stdshaders/shadowmodel_dx8.cpp new file mode 100644 index 00000000..e7d7228a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/shadowmodel_dx8.cpp @@ -0,0 +1,97 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "shadowmodel.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( ShadowModel, ShadowModel_DX8 ) + +BEGIN_VS_SHADER_FLAGS( ShadowModel_DX8, "Help for ShadowModel", SHADER_NOT_EDITABLE ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) + SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) + SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) + SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) + SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + if (!params[BASETEXTURESCALE]->IsDefined()) + { + Vector2D scale(1, 1); + params[BASETEXTURESCALE]->SetVecValue( scale.Base(), 2 ); + } + + if (!params[FALLOFFDISTANCE]->IsDefined()) + params[FALLOFFDISTANCE]->SetFloatValue( 100.0f ); + + if (!params[FALLOFFAMOUNT]->IsDefined()) + params[FALLOFFAMOUNT]->SetFloatValue( 0.9f ); + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + // Base texture on stage 0 + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Multiplicative blending state... + EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + shadowmodel_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "ShadowModel", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "ShadowModel" ); + + // We need to fog to *white* regardless of overbrighting... + FogToWhite(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderMatrix3x4( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, BASETEXTUREOFFSET ); + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURESCALE ); + + Vector4D shadow; + shadow[0] = params[FALLOFFOFFSET]->GetFloatValue(); + shadow[1] = params[FALLOFFDISTANCE]->GetFloatValue() + shadow[0]; + if (shadow[1] != 0.0f) + shadow[1] = 1.0f / shadow[1]; + shadow[2] = params[FALLOFFAMOUNT]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, shadow.Base(), 1 ); + + // The constant color is the shadow color... + SetModulationVertexShaderDynamicState(); + + shadowmodel_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw( ); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/shadowmodel_dx9.cpp b/sp/src/materialsystem/stdshaders/shadowmodel_dx9.cpp new file mode 100644 index 00000000..0198e86f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/shadowmodel_dx9.cpp @@ -0,0 +1,154 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +//Note: Not upgraded to vs/ps 2.0 fxc's because this shader is unused and there are no test cases to verify against. +#include "BaseVSShader.h" + +#if !defined( _X360 ) +#include "shadowmodel_ps20.inc" +#include "shadowmodel_vs20.inc" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( ShadowModel, ShadowModel_DX9 ) + + +#if !defined( _X360 ) //not used for anything at time of 360 ship, and we want to avoid storing/loading assembly shaders + +//PC version +BEGIN_VS_SHADER_FLAGS( ShadowModel_DX9, "Help for ShadowModel", SHADER_NOT_EDITABLE ) + +BEGIN_SHADER_PARAMS +SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) +SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) +SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) +SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) +SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) +END_SHADER_PARAMS + +SHADER_INIT_PARAMS() +{ + if (!params[BASETEXTURESCALE]->IsDefined()) + { + Vector2D scale(1, 1); + params[BASETEXTURESCALE]->SetVecValue( scale.Base(), 2 ); + } + + if (!params[FALLOFFDISTANCE]->IsDefined()) + params[FALLOFFDISTANCE]->SetFloatValue( 100.0f ); + + if (!params[FALLOFFAMOUNT]->IsDefined()) + params[FALLOFFAMOUNT]->SetFloatValue( 0.9f ); +} + +SHADER_FALLBACK +{ + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "ShadowModel_DX8"; + + return 0; +} + +SHADER_INIT +{ + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + } +} + +SHADER_DRAW +{ + SHADOW_STATE + { + // Base texture on stage 0 + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + // Multiplicative blending state... + EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( shadowmodel_vs20 ); + SET_STATIC_VERTEX_SHADER( shadowmodel_vs20 ); + + DECLARE_STATIC_PIXEL_SHADER( shadowmodel_ps20 ); + SET_STATIC_PIXEL_SHADER( shadowmodel_ps20 ); + + // We need to fog to *white* regardless of overbrighting... + FogToWhite(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderMatrix3x4( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, BASETEXTUREOFFSET ); + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURESCALE ); + + Vector4D shadow; + shadow[0] = params[FALLOFFOFFSET]->GetFloatValue(); + shadow[1] = params[FALLOFFDISTANCE]->GetFloatValue() + shadow[0]; + if (shadow[1] != 0.0f) + shadow[1] = 1.0f / shadow[1]; + shadow[2] = params[FALLOFFAMOUNT]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, shadow.Base(), 1 ); + + // The constant color is the shadow color... + SetModulationVertexShaderDynamicState(); + + DECLARE_DYNAMIC_VERTEX_SHADER( shadowmodel_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER( shadowmodel_vs20 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( shadowmodel_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( shadowmodel_ps20 ); + } + Draw( ); +} +END_SHADER + + +#else + +//360 version + +BEGIN_VS_SHADER_FLAGS( ShadowModel_DX9, "Help for ShadowModel", SHADER_NOT_EDITABLE ) + +BEGIN_SHADER_PARAMS +SHADER_PARAM( BASETEXTUREOFFSET, SHADER_PARAM_TYPE_VEC2, "[0 0]", "$baseTexture texcoord offset" ) +SHADER_PARAM( BASETEXTURESCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "$baseTexture texcoord scale" ) +SHADER_PARAM( FALLOFFOFFSET, SHADER_PARAM_TYPE_FLOAT, "0", "Distance at which shadow starts to fade" ) +SHADER_PARAM( FALLOFFDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100", "Max shadow distance" ) +SHADER_PARAM( FALLOFFAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.9", "Amount to brighten the shadow at max dist" ) +END_SHADER_PARAMS + +SHADER_INIT_PARAMS() +{ +} + +SHADER_FALLBACK +{ + return 0; +} + +SHADER_INIT +{ +} + +SHADER_DRAW +{ + Draw( false ); +} +END_SHADER + +#endif \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/shadowmodel_ps20.fxc b/sp/src/materialsystem/stdshaders/shadowmodel_ps20.fxc new file mode 100644 index 00000000..d0aedda9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/shadowmodel_ps20.fxc @@ -0,0 +1,20 @@ + +struct PS_INPUT +{ + float4 T0 : TEXCOORD0; + float3 T1 : TEXCOORD1; + float3 T2 : TEXCOORD2; + float T3 : TEXCOORD3; + float3 vColor : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + // Kill pixel against various fields computed in vertex shader + clip ( i.T1 ); + clip ( i.T2 ); + clip ( i.T3 ); // Backface cull + + // i.T0.a is uninitialized by the vs, but this is how the original asm shader was written???? + return float4( lerp( float3(1,1,1), i.vColor.xyz, i.T0.a ), 1 ); +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/shadowmodel_vs20.fxc b/sp/src/materialsystem/stdshaders/shadowmodel_vs20.fxc new file mode 100644 index 00000000..9d1ff02c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/shadowmodel_vs20.fxc @@ -0,0 +1,81 @@ +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cShadowTextureMatrix[3] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cTexOrigin : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cTexScale : register( SHADER_SPECIFIC_CONST_4 ); + +// { Shadow falloff offset, 1/Shadow distance, Shadow scale, 0 } +const float3 cShadowConstants : register( SHADER_SPECIFIC_CONST_5 ); +#define flShadowFalloffOffset cShadowConstants.x +#define flOneOverShadowDist cShadowConstants.y +#define flShadowScale cShadowConstants.z + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float3 vNormal : NORMAL; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position + float3 T0 : TEXCOORD0; // PS wants this to be 4D but VS doesn't? (see original asm sources) + float3 T1 : TEXCOORD1; + float3 T2 : TEXCOORD2; + float T3 : TEXCOORD3; + float4 vColor : COLOR0; + float fog : FOG; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( g_bSkinning, v.vPos, v.vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + + // Transform into projection space + o.projPos = mul( float4( worldPos, 1 ), cViewProj ); + + // Compute fog + o.fog = CalcFog( worldPos, o.projPos, g_FogType ); + + // Transform position into texture space (from 0 to 1) + float3 vTexturePos; + vTexturePos.x = dot( worldPos.xyz, cShadowTextureMatrix[0].xyz ); + vTexturePos.y = dot( worldPos.xyz, cShadowTextureMatrix[1].xyz ); + vTexturePos.z = dot( worldPos.xyz, cShadowTextureMatrix[2].xyz ); + + // Figure out the shadow fade amount + float flShadowFade = ( vTexturePos.z - flShadowFalloffOffset ) * flOneOverShadowDist; + + // Offset it into the texture + o.T0 = vTexturePos * cTexScale + cTexOrigin; + + // We're doing clipping by using texkill + o.T1.xyz = vTexturePos.xyz; // Also clips when shadow z < 0 ! + o.T2.xyz = float3( 1.0f, 1.0f, 1.0f ) - vTexturePos.xyz; + o.T2.z = 1.0f - flShadowFade; // Clips when shadow z > shadow distance + + // We're doing backface culling by using texkill also (wow yucky) + // -------------------------------------------------------------- + // Transform z component of normal in texture space + // If it's negative, then don't draw the pixel + o.T3 = dot( worldNormal, -cShadowTextureMatrix[2] ); + + // Shadow color, falloff + o.vColor.xyz = cModulationColor.xyz; + o.vColor.w = flShadowFade * flShadowScale; + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/skin_dx9_helper.cpp b/sp/src/materialsystem/stdshaders/skin_dx9_helper.cpp new file mode 100644 index 00000000..1e2d30f3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/skin_dx9_helper.cpp @@ -0,0 +1,977 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "BaseVSShader.h" +#include "skin_dx9_helper.h" +#include "convar.h" +#include "cpp_shader_constant_register_map.h" +#include "skin_vs20.inc" +#include "skin_ps20b.inc" +#include "commandbuilder.h" + +#ifndef _X360 +#include "skin_vs30.inc" +#include "skin_ps30.inc" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT ); +static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT ); +static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT ); + +// Textures may be bound to the following samplers: +// SHADER_SAMPLER0 Base (Albedo) / Gloss in alpha +// SHADER_SAMPLER1 Specular warp (including iridescence) +// SHADER_SAMPLER2 Diffuse Lighting warp texture +// SHADER_SAMPLER3 Normal Map +// SHADER_SAMPLER4 Flashlight Shadow Depth Map +// SHADER_SAMPLER5 Normalization cube map +// SHADER_SAMPLER6 Flashlight Cookie +// SHADER_SAMPLER7 Specular exponent +// SHADER_SAMPLER8 Cubic environment map +// SHADER_SAMPLER9 Compressed wrinklemap +// SHADER_SAMPLER10 Stretched wrinklemap +// SHADER_SAMPLER11 Compressed wrinkle normal map +// SHADER_SAMPLER12 Stretched wrinkle normal map +// SHADER_SAMPLER13 Detail texture + + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VertexLitGeneric_DX9_Vars_t &info ) +{ + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + Assert( info.m_nFlashlightTexture >= 0 ); + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping. + if( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + // This shader can be used with hw skinning + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + // No texture means no env mask in base alpha + if ( !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + // Lots of reasons to want tangent space, since we bind a flat normal map in many cases where we don't have a bump map + bool bBump = (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined(); + bool bEnvMap = (info.m_nEnvmap != -1) && params[info.m_nEnvmap]->IsDefined(); + bool bDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined(); + bool bPhong = (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined(); + if( bBump || bEnvMap || bDiffuseWarp || bPhong ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + } + + if ( ( info.m_nSelfIllumFresnel != -1 ) && ( !params[info.m_nSelfIllumFresnel]->IsDefined() ) ) + { + params[info.m_nSelfIllumFresnel]->SetIntValue( 0 ); + } + + if ( ( info.m_nSelfIllumFresnelMinMaxExp != -1 ) && ( !params[info.m_nSelfIllumFresnelMinMaxExp]->IsDefined() ) ) + { + params[info.m_nSelfIllumFresnelMinMaxExp]->SetVecValue( 0.0f, 1.0f, 1.0f ); + } + + if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && ( !params[info.m_nBaseMapAlphaPhongMask]->IsDefined() ) ) + { + params[info.m_nBaseMapAlphaPhongMask]->SetIntValue( 0 ); + } + + if ( ( info.m_nEnvmapFresnel != -1 ) && ( !params[info.m_nEnvmapFresnel]->IsDefined() ) ) + { + params[info.m_nEnvmapFresnel]->SetFloatValue( 0 ); + } +} + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- +void InitSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, VertexLitGeneric_DX9_Vars_t &info ) +{ + Assert( info.m_nFlashlightTexture >= 0 ); + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + + bool bIsBaseTextureTranslucent = false; + if ( params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + + if ( ( info.m_nWrinkle != -1 ) && ( info.m_nStretch != -1 ) && + params[info.m_nWrinkle]->IsDefined() && params[info.m_nStretch]->IsDefined() ) + { + pShader->LoadTexture( info.m_nWrinkle, TEXTUREFLAGS_SRGB ); + pShader->LoadTexture( info.m_nStretch, TEXTUREFLAGS_SRGB ); + } + } + + bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined(); + + // No alpha channel in any of the textures? No self illum or envmapmask + if ( !bIsBaseTextureTranslucent ) + { + bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + // Can still be self illum with no base alpha if using one of these alternate modes + if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsDefined() && + (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nPhongExponentTexture ); + } + + if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() && + (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); + } + + if ( (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsDefined() && + (info.m_nPhong != -1) && params[info.m_nPhong]->IsDefined() ) + { + pShader->LoadTexture( info.m_nPhongWarpTexture ); + } + + if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() ) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + if ( nDetailBlendMode == 0 ) // Mod2X + pShader->LoadTexture( info.m_nDetail ); + else + pShader->LoadTexture( info.m_nDetail, TEXTUREFLAGS_SRGB ); + } + + if ( g_pConfig->UseBumpmapping() ) + { + if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + + if ( ( info.m_nNormalWrinkle != -1 ) && ( info.m_nNormalStretch != -1 ) && + params[info.m_nNormalWrinkle]->IsDefined() && params[info.m_nNormalStretch]->IsDefined() ) + { + pShader->LoadTexture( info.m_nNormalWrinkle ); + pShader->LoadTexture( info.m_nNormalStretch ); + } + } + } + + if ( params[info.m_nEnvmap]->IsDefined() ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + + if ( bHasSelfIllumMask ) + { + pShader->LoadTexture( info.m_nSelfIllumMask ); + } +} + +class CSkin_DX9_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + bool m_bFastPath; + +}; + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +void DrawSkin_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bHasFlashlight, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) +{ + bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture(); + bool bHasBump = (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsTexture(); + + bool bHasBaseTextureWrinkle = bHasBaseTexture && + (info.m_nWrinkle != -1) && params[info.m_nWrinkle]->IsTexture() && + (info.m_nStretch != -1) && params[info.m_nStretch]->IsTexture(); + + bool bHasBumpWrinkle = bHasBump && + (info.m_nNormalWrinkle != -1) && params[info.m_nNormalWrinkle]->IsTexture() && + (info.m_nNormalStretch != -1) && params[info.m_nNormalStretch]->IsTexture(); + + bool bHasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool bHasVertexAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bHasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) != 0; + bool bHasSelfIllumFresnel = ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + bool bHasSelfIllumMask = ( bHasSelfIllum ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsTexture(); + + // Tie these to specular + bool bHasPhong = (info.m_nPhong != -1) && ( params[info.m_nPhong]->GetIntValue() != 0 ); + bool bHasSpecularExponentTexture = (info.m_nPhongExponentTexture != -1) && params[info.m_nPhongExponentTexture]->IsTexture(); + bool bHasPhongTintMap = bHasSpecularExponentTexture && (info.m_nPhongAlbedoTint != -1) && ( params[info.m_nPhongAlbedoTint]->GetIntValue() != 0 ); + bool bHasDiffuseWarp = (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture(); + bool bHasPhongWarp = (info.m_nPhongWarpTexture != -1) && params[info.m_nPhongWarpTexture]->IsTexture(); + bool bHasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + +#if !defined( _X360 ) + bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL ); +#endif + + // Rimlight must be set to non-zero to trigger rim light combo (also requires Phong) + bool bHasRimLight = r_rimlight.GetBool() && bHasPhong && (info.m_nRimLight != -1) && ( params[info.m_nRimLight]->GetIntValue() != 0 ); + bool bHasRimMaskMap = bHasSpecularExponentTexture && bHasRimLight && (info.m_nRimMask != -1) && ( params[info.m_nRimMask]->GetIntValue() != 0 ); + + float fBlendFactor=( info.m_nDetailTextureBlendFactor == -1 )? 1 : params[info.m_nDetailTextureBlendFactor]->GetFloatValue(); + bool hasDetailTexture = ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsTexture(); + int nDetailBlendMode = ( hasDetailTexture && info.m_nDetailTextureCombineMode != -1 ) ? params[info.m_nDetailTextureCombineMode]->GetIntValue() : 0; + + bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ) && !bHasSelfIllum; // Pixel shader can't do both BLENDTINTBYBASEALPHA and SELFILLUM, so let selfillum win + + float flTintReplacementAmount = GetFloatParam( info.m_nTintReplacesBaseColor, params ); + + BlendType_t nBlendType= pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true ); + + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && !bHasFlashlight; //dest alpha is free for special use + + CSkin_DX9_Context *pContextData = reinterpret_cast< CSkin_DX9_Context *> ( *pContextDataPtr ); + if ( ! pContextData ) + { + pContextData = new CSkin_DX9_Context; + *pContextDataPtr = pContextData; + } + + if( pShader->IsSnapshotting() ) + { + // look at color and alphamod stuff. + // Unlit generic never uses the flashlight + bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture(); + bool bHasNormal = params[info.m_nBumpmap]->IsTexture(); + bool bCanUseBaseAlphaPhongMaskFastPath = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 ); + + if ( ! ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) ) + bCanUseBaseAlphaPhongMaskFastPath = true; + + pContextData->m_bFastPath = + (! bHasBump ) && + (! bHasSpecularExponentTexture ) && + (! bHasPhongTintMap ) && + (! bHasPhongWarp ) && + (! bHasRimLight ) && + (! hasDetailTexture ) && + bCanUseBaseAlphaPhongMaskFastPath && + (! bHasSelfIllum ) && + (! bBlendTintByBaseAlpha ); + + // Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + + if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + int nShadowFilterMode = 0; + if( bHasFlashlight ) + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + + if( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + else // not flashlight pass + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); + } + + if ( bHasEnvmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Cubic environment map + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true ); + } + } + } + + unsigned int flags = VERTEX_POSITION; + if( bHasNormal ) + { + flags |= VERTEX_NORMAL; + } + + int userDataSize = 0; + + // Always enable...will bind white if nothing specified... + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Base (albedo) compression map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER9, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // Base (albedo) expansion map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER10, true ); + } + + if( bHasDiffuseWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Diffuse warp texture + } + + if( bHasPhongWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Specular warp texture + } + + // Specular exponent map or dummy + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Specular exponent map + + if( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true ); + userDataSize = 4; // tangent S + } + + // Always enable, since flat normal will be bound + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map + userDataSize = 4; // tangent S + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map + + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // Normal compression map + pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); // Normal expansion map + } + + if ( hasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER13, true ); + } + + if ( bHasSelfIllum ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); + } + + if( bHasVertexColor || bHasVertexAlpha ) + { + flags |= VERTEX_COLOR; + } + + pShaderShadow->EnableSRGBWrite( true ); + + // texcoord0 : base texcoord, texcoord2 : decal hw morph delta + int pTexCoordDim[3] = { 2, 0, 3 }; + int nTexCoordCount = 1; + +#ifndef _X360 + // Special morphed decal information + if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() ) + { + nTexCoordCount = 3; + } +#endif + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( skin_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( skin_vs20 ); + + // Assume we're only going to get in here if we support 2b + DECLARE_STATIC_PIXEL_SHADER( skin_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, bHasPhongWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( RIMLIGHT, bHasRimLight ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FASTPATH_NOBUMP, pContextData->m_bFastPath ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( skin_ps20b ); + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( skin_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); + SET_STATIC_VERTEX_SHADER( skin_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( skin_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel && !bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( PHONGWARPTEXTURE, bHasPhongWarp && bHasPhong ); + SET_STATIC_PIXEL_SHADER_COMBO( WRINKLEMAP, bHasBaseTextureWrinkle || bHasBumpWrinkle ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( RIMLIGHT, bHasRimLight ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( FASTPATH_NOBUMP, pContextData->m_bFastPath ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( skin_ps30 ); + } +#endif + + if( bHasFlashlight ) + { + pShader->FogToBlack(); + } + else + { + pShader->DefaultFog(); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + else // not snapshotting -- begin dynamic state + { + bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + bool bHasEnvmap = !bHasFlashlight && params[info.m_nEnvmap]->IsTexture(); + + if( bHasBaseTexture ) + { + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + + if ( bHasBaseTextureWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER9, info.m_nWrinkle, info.m_nBaseTextureFrame ); + pShader->BindTexture( SHADER_SAMPLER10, info.m_nStretch, info.m_nBaseTextureFrame ); + } + else if ( bHasBumpWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER9, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + pShader->BindTexture( SHADER_SAMPLER10, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + + if( bHasDiffuseWarp && bHasPhong ) + { + if ( r_lightwarpidentity.GetBool() ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_IDENTITY_LIGHTWARP ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER2, info.m_nDiffuseWarpTexture ); + } + } + + if( bHasPhongWarp ) + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nPhongWarpTexture ); + } + + if( bHasSpecularExponentTexture && bHasPhong ) + { + pShader->BindTexture( SHADER_SAMPLER7, info.m_nPhongExponentTexture ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER7, TEXTURE_WHITE ); + } + + if( !g_pConfig->m_bFastNoBump ) + { + if( bHasBump ) + pShader->BindTexture( SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); + else + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + + if ( bHasBumpWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER11, info.m_nNormalWrinkle, info.m_nBumpFrame ); + pShader->BindTexture( SHADER_SAMPLER12, info.m_nNormalStretch, info.m_nBumpFrame ); + } + else if ( bHasBaseTextureWrinkle ) + { + pShader->BindTexture( SHADER_SAMPLER11, info.m_nBumpmap, info.m_nBumpFrame ); + pShader->BindTexture( SHADER_SAMPLER12, info.m_nBumpmap, info.m_nBumpFrame ); + } + } + else + { + if( bHasBump ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + if ( bHasBaseTextureWrinkle || bHasBumpWrinkle ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER11, TEXTURE_NORMALMAP_FLAT ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER12, TEXTURE_NORMALMAP_FLAT ); + } + } + + if ( hasDetailTexture ) + { + pShader->BindTexture( SHADER_SAMPLER13, info.m_nDetail, info.m_nDetailFrame ); + } + + if ( bHasSelfIllum ) + { + if ( bHasSelfIllumMask ) // Separate texture for self illum? + { + pShader->BindTexture( SHADER_SAMPLER14, info.m_nSelfIllumMask ); // Bind it + } + else // else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER14, TEXTURE_BLACK ); // Bind dummy + } + } + + LightState_t lightState = { 0, false, false }; + bool bFlashlightShadows = false; + if( bHasFlashlight ) + { + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D ); + } + } + else // no flashlight + { + if ( bHasEnvmap ) + { + pShader->BindTexture( SHADER_SAMPLER8, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + // don't have an easy way to get this through to GLM, so just print it old school + //printf("\n-D- DrawSkin_DX9_Internal numBones is %d", numBones ); + + bool bWriteDepthToAlpha = false; + bool bWriteWaterFogToAlpha = false; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( skin_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( skin_vs20 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( skin_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( skin_ps20b ); + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( skin_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( skin_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( skin_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( skin_ps30 ); + + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } +#endif + + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + + if( bHasBump ) + { + pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); + } + + if ( hasDetailTexture ) + { + if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) ) + pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, + info.m_nDetailTextureTransform, + info.m_nDetailScale ); + else + pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, + info.m_nBaseTextureTransform, + info.m_nDetailScale ); + } + + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + pShader->SetPixelShaderConstant_W( PSREG_SELFILLUMTINT, info.m_nSelfIllumTint, fBlendFactor ); + bool bInvertPhongMask = ( info.m_nInvertPhongMask != -1 ) && ( params[info.m_nInvertPhongMask]->GetIntValue() != 0 ); + float fInvertPhongMask = bInvertPhongMask ? 1 : 0; + + bool bHasBaseAlphaPhongMask = (info.m_nBaseMapAlphaPhongMask != -1) && ( params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 0 ); + float fHasBaseAlphaPhongMask = bHasBaseAlphaPhongMask ? 1 : 0; + // Controls for lerp-style paths through shader code + float vShaderControls[4] = { fHasBaseAlphaPhongMask, 0.0f/*unused*/, flTintReplacementAmount, fInvertPhongMask }; + pShaderAPI->SetPixelShaderConstant( PSREG_CONSTANT_27, vShaderControls, 1 ); + + if ( hasDetailTexture ) + { +#if 0 // needs constant change + if ( info.m_nDetailTint != -1 ) + pShader->SetPixelShaderConstantGammaToLinear( 10, info.m_nDetailTint ); + else + { + float boring_tint[4]={1,1,1,1}; + pShaderAPI->SetPixelShaderConstant( 10, boring_tint, 1 ); + } +#endif + } + + if ( bHasSelfIllumFresnel && !bHasFlashlight ) + { + float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; + float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f; + float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f; + float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f; + + vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias + vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale + vConstScaleBiasExp[2] = flExp; // Exp + vConstScaleBiasExp[3] = flMax; // Brightness + + pShaderAPI->SetPixelShaderConstant( PSREG_SELFILLUM_SCALE_BIAS_EXP, vConstScaleBiasExp, 1 ); + } + + pShader->SetAmbientCubeDynamicStateVertexShader(); + + if( !bHasFlashlight ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + // Setting .x to 1 means to apply Fresnel to env map. Setting w to 1 means use separate selfillummask + float vEnvMapFresnel_SelfIllumMask[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + vEnvMapFresnel_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f; + + if( bHasEnvmap ) + { + float vEnvMapTint_MaskControl[4] = {1.0f, 1.0f, 1.0f, 0.0f}; + + // If we have a tint, grab it + if ( (info.m_nEnvmapTint != -1) && params[info.m_nEnvmapTint]->IsDefined() ) + params[info.m_nEnvmapTint]->GetVecValue(vEnvMapTint_MaskControl, 3); + + // Set control for source of env map mask (normal alpha or base alpha) + vEnvMapTint_MaskControl[3] = bHasNormalMapAlphaEnvmapMask ? 1.0f : 0.0f; + + if ( (info.m_nEnvmapFresnel != -1) && params[info.m_nEnvmapFresnel]->IsDefined() ) + vEnvMapFresnel_SelfIllumMask[0] = params[info.m_nEnvmapFresnel]->GetFloatValue(); + + // Handle mat_fullbright 2 (diffuse lighting only with 50% gamma space basetexture) + if( bLightingOnly ) + { + vEnvMapTint_MaskControl[0] = vEnvMapTint_MaskControl[1] = vEnvMapTint_MaskControl[2] = 0.0f; + } + + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, vEnvMapTint_MaskControl, 1 ); + } + + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_FRESNEL__SELFILLUMMASK, vEnvMapFresnel_SelfIllumMask, 1 ); + } + + pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight ); // Force to black if not bAmbientLight + pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); + + // Pack Phong exponent in with the eye position + float vEyePos_SpecExponent[4], vFresnelRanges_SpecBoost[4] = {1, 0.5, 1, 1}, vRimBoost[4] = {1, 1, 1, 1}; + float vSpecularTint[4] = {1, 1, 1, 4}; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + + // Use the alpha channel of the normal map for the exponent by default + vEyePos_SpecExponent[3] = -1.f; + if ( (info.m_nPhongExponent != -1) && params[info.m_nPhongExponent]->IsDefined() ) + { + float fValue = params[info.m_nPhongExponent]->GetFloatValue(); + if ( fValue > 0.f ) + { + // Nonzero value in material overrides map channel + vEyePos_SpecExponent[3] = fValue; + } + } + + // Get the tint parameter + if ( (info.m_nPhongTint != -1) && params[info.m_nPhongTint]->IsDefined() ) + { + params[info.m_nPhongTint]->GetVecValue(vSpecularTint, 3); + } + + // Get the rim light power (goes in w of Phong tint) + if ( bHasRimLight && (info.m_nRimLightPower != -1) && params[info.m_nRimLightPower]->IsDefined() ) + { + vSpecularTint[3] = params[info.m_nRimLightPower]->GetFloatValue(); + vSpecularTint[3] = max(vSpecularTint[3], 1.0f); // Make sure this is at least 1 + } + + // Get the rim boost (goes in w of flashlight position) + if ( bHasRimLight && (info.m_nRimLightBoost != -1) && params[info.m_nRimLightBoost]->IsDefined() ) + { + vRimBoost[3] = params[info.m_nRimLightBoost]->GetFloatValue(); + } + + if ( !bHasFlashlight ) + { + float vRimMaskControl[4] = {0, 0, 0, 0}; // Only x is relevant in shader code + vRimMaskControl[0] = bHasRimMaskMap ? params[info.m_nRimMask]->GetFloatValue() : 0.0f; + + // Rim mask...if this is true, use alpha channel of spec exponent texture to mask the rim term + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, vRimMaskControl, 1 ); + } + + // If it's all zeros, there was no constant tint in the vmt + if ( (vSpecularTint[0] == 0.0f) && (vSpecularTint[1] == 0.0f) && (vSpecularTint[2] == 0.0f) ) + { + if ( bHasPhongTintMap ) // If we have a map to use, tell the shader + { + vSpecularTint[0] = -1; + } + else // Otherwise, just tint with white + { + vSpecularTint[0] = 1.0f; + vSpecularTint[1] = 1.0f; + vSpecularTint[2] = 1.0f; + } + } + + // handle mat_fullbright 2 (diffuse lighting only) + if( bLightingOnly ) + { + // BASETEXTURE + if( bHasSelfIllum && !bHasFlashlight ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + + // DETAILTEXTURE + if ( hasDetailTexture ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER13, TEXTURE_GREY ); + } + + // turn off specularity + vSpecularTint[0] = vSpecularTint[1] = vSpecularTint[2] = 0.0f; + } + + if ( (info.m_nPhongFresnelRanges != -1) && params[info.m_nPhongFresnelRanges]->IsDefined() ) + { + params[info.m_nPhongFresnelRanges]->GetVecValue( vFresnelRanges_SpecBoost, 3 ); // Grab optional Fresnel range parameters + // Change fresnel range encoding from (min, mid, max) to ((mid-min)*2, mid, (max-mid)*2) + vFresnelRanges_SpecBoost[0] = (vFresnelRanges_SpecBoost[1] - vFresnelRanges_SpecBoost[0]) * 2; + vFresnelRanges_SpecBoost[2] = (vFresnelRanges_SpecBoost[2] - vFresnelRanges_SpecBoost[1]) * 2; + } + + if ( (info.m_nPhongBoost != -1 ) && params[info.m_nPhongBoost]->IsDefined()) // Grab optional Phong boost param + vFresnelRanges_SpecBoost[3] = params[info.m_nPhongBoost]->GetFloatValue(); + else + vFresnelRanges_SpecBoost[3] = 1.0f; + + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + pShaderAPI->SetPixelShaderConstant( PSREG_FRESNEL_SPEC_PARAMS, vFresnelRanges_SpecBoost, 1 ); + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vRimBoost, 1 ); // Rim boost in w on non-flashlight pass + + pShaderAPI->SetPixelShaderConstant( PSREG_SPEC_RIM_PARAMS, vSpecularTint, 1 ); + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + // flashlightfixme: put this in common code. + if( bHasFlashlight ) + { + VMatrix worldToTexture; + float atten[4], pos[4], tweaks[4]; + + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // steps on rim boost + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + + if ( IsX360() ) + { + pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); + } + } + } + pShader->Draw(); +} + + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +extern ConVar r_flashlight_version2; +void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) + +{ + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + DrawSkin_DX9_Internal( pShader, params, pShaderAPI, + pShaderShadow, false, info, vertexCompression, pContextDataPtr++ ); + if ( pShaderShadow ) + { + pShader->SetInitialShadowState( ); + } + } + DrawSkin_DX9_Internal( pShader, params, pShaderAPI, + pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} diff --git a/sp/src/materialsystem/stdshaders/skin_dx9_helper.h b/sp/src/materialsystem/stdshaders/skin_dx9_helper.h new file mode 100644 index 00000000..414e8dd2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/skin_dx9_helper.h @@ -0,0 +1,35 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef SKIN_DX9_HELPER_H +#define SKIN_DX9_HELPER_H + +#include + +#include "vertexlitgeneric_dx9_helper.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +void InitParamsSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, + const char *pMaterialName, VertexLitGeneric_DX9_Vars_t &info ); +void InitSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, + VertexLitGeneric_DX9_Vars_t &info ); + +void DrawSkin_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, + VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ); + + + +#endif // SKIN_DX9_HELPER_H diff --git a/sp/src/materialsystem/stdshaders/skin_ps20b.fxc b/sp/src/materialsystem/stdshaders/skin_ps20b.fxc new file mode 100644 index 00000000..20c3eef9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/skin_ps20b.fxc @@ -0,0 +1,371 @@ +//======= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====== +// STATIC: "CONVERT_TO_SRGB" "0..0" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "SELFILLUMFRESNEL" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" +// STATIC: "PHONGWARPTEXTURE" "0..1" +// STATIC: "WRINKLEMAP" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..6" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "RIMLIGHT" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "FASTPATH_NOBUMP" "0..1" +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" + +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..4" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + + +// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0) + +// blend mode doesn't matter if we only have one texture +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// Only need self illum fresnel when self illum enabled +// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) + +// BlendTintByBaseAlpha and self illum and are opposing meanings for alpha channel +// SKIP: ( $BLENDTINTBYBASEALPHA ) && ( $SELFILLUM ) + +// fastpath means: +// no bumpmap +// basealphaenvmapmask (not inverted) +// no spec expmap +// no spectint +// no specwarp +// no rimlight +// no selfillum +// no detail +// no BlendTintByBaseAlpha + +// SKIP: $FASTPATH_NOBUMP && ( $RIMLIGHT || $DETAILTEXTURE || $PHONGWARPTEXTURE || $SELFILLUM || $BLENDTINTBYBASEALPHA ) + + + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +const float4 g_SelfIllumTint_and_DetailBlendFactor : register( PSREG_SELFILLUMTINT ); +#if ( SELFILLUMFRESNEL == 1 ) +const float4 g_SelfIllumScaleBiasExpBrightness : register( PSREG_SELFILLUM_SCALE_BIAS_EXP ); +#endif +const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION ); +const float4 g_EnvmapTint_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); // w controls spec mask +const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); +const float4 g_EnvMapFresnel : register( PSREG_ENVMAP_FRESNEL__SELFILLUMMASK ); // x is envmap fresnel ... w is selfillummask control +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_FlashlightAttenuationFactors_RimMask : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass, x has rim mask control +const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); +const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); +const float4 g_FresnelSpecParams : register( PSREG_FRESNEL_SPEC_PARAMS ); // xyz are fresnel, w is specular boost +const float4 g_SpecularRimParams : register( PSREG_SPEC_RIM_PARAMS ); // xyz are specular tint color, w is rim power +PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total (4th light spread across w's) + +// TODO: give this a better name. For now, I don't want to touch shader_constant_register_map.h since I don't want to trigger a recompile of everything... +const float4 g_ShaderControls : register( PSREG_CONSTANT_27 ); // x is basemap alpgha phong mask, y is 1 - blendtintbybasealpha, z is tint overlay amount, w controls "INVERTPHONGMASK" +#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz +#define g_fRimBoost g_FlashlightPos_RimBoost.w +#define g_FresnelRanges g_FresnelSpecParams.xyz +#define g_SpecularBoost g_FresnelSpecParams.w +#define g_SpecularTint g_SpecularRimParams.xyz +#define g_RimExponent g_SpecularRimParams.w +#define g_FlashlightAttenuationFactors g_FlashlightAttenuationFactors_RimMask +#define g_RimMaskControl g_FlashlightAttenuationFactors_RimMask.x +#define g_SelfIllumMaskControl g_EnvMapFresnel.w +#define g_fBaseMapAlphaPhongMask g_ShaderControls.x +#define g_fTintReplacementControl g_ShaderControls.z +#define g_fInvertPhongMask g_ShaderControls.w + +sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha +sampler SpecularWarpSampler : register( s1 ); // Specular warp sampler (for iridescence etc) +sampler DiffuseWarpSampler : register( s2 ); // Lighting warp sampler (1D texture for diffuse lighting modification) +sampler NormalMapSampler : register( s3 ); // Normal map, specular mask in alpha +sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler +sampler NormalizeRandRotSampler : register( s5 ); // Normalization / RandomRotation samplers +sampler FlashlightSampler : register( s6 ); // Flashlight cookie +sampler SpecExponentSampler : register( s7 ); // Specular exponent map +sampler EnvmapSampler : register( s8 ); // Cubic environment map + +#if WRINKLEMAP +sampler WrinkleSampler : register( s9 ); // Compression base +sampler StretchSampler : register( s10 ); // Expansion base +sampler NormalWrinkleSampler : register( s11 ); // Compression base +sampler NormalStretchSampler : register( s12 ); // Expansion base +#endif + +#if DETAILTEXTURE +sampler DetailSampler : register( s13 ); // detail texture +#endif + +sampler SelfIllumMaskSampler : register( s14 ); // selfillummask + + +struct PS_INPUT +{ + float4 baseTexCoordDetailTexCoord : TEXCOORD0; // xy=base zw=detail + float3 lightAtten : TEXCOORD1; // Scalar light attenuation factors for FOUR lights + float3 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3x3 tangentSpaceTranspose : TEXCOORD3; + // second row : TEXCOORD4; + // third row : TEXCOORD5; + float4 worldPos_atten3 : TEXCOORD6; + float4 projPos_fWrinkleWeight : TEXCOORD7; +}; + + + +float4 main( PS_INPUT i ) : COLOR +{ + bool bWrinkleMap = WRINKLEMAP ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + bool bDoSpecularWarp = PHONGWARPTEXTURE ? true : false; + bool bDoAmbientOcclusion = false; + bool bFlashlight = (FLASHLIGHT!=0) ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bDoRimLighting = RIMLIGHT ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + int nNumLights = NUM_LIGHTS; + + // Unpacking for convenience + float fWrinkleWeight = i.projPos_fWrinkleWeight.w; + float3 vProjPos = i.projPos_fWrinkleWeight.xyz; + float3 vWorldPos = i.worldPos_atten3.xyz; + float atten3 = i.worldPos_atten3.w; + + float4 vLightAtten = float4( i.lightAtten, atten3 ); + +#if WRINKLEMAP + float flWrinkleAmount = saturate( -fWrinkleWeight ); // One of these two is zero + float flStretchAmount = saturate( fWrinkleWeight ); // while the other is in the 0..1 range + + float flTextureAmount = 1.0f - flWrinkleAmount - flStretchAmount; // These should sum to one +#endif + + float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoordDetailTexCoord.xy ); +#if WRINKLEMAP + float4 wrinkleColor = tex2D( WrinkleSampler, i.baseTexCoordDetailTexCoord.xy ); + float4 stretchColor = tex2D( StretchSampler, i.baseTexCoordDetailTexCoord.xy ); + + // Apply wrinkle blend to only RGB. Alpha comes from the base texture + baseColor.rgb = flTextureAmount * baseColor + flWrinkleAmount * wrinkleColor + flStretchAmount * stretchColor; +#endif + +#if DETAILTEXTURE + float4 detailColor = tex2D( DetailSampler, i.baseTexCoordDetailTexCoord.zw ); + baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_SelfIllumTint_and_DetailBlendFactor.w ); +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, vWorldPos.z, vProjPos.z ); + + float3 vEyeDir = normalize(i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz); + float3 vRimAmbientCubeColor = PixelShaderAmbientLight(vEyeDir, cAmbientCube); + + float3 worldSpaceNormal, tangentSpaceNormal; + float fSpecMask = 1.0f; + float4 normalTexel = tex2D( NormalMapSampler, i.baseTexCoordDetailTexCoord.xy ); + +#if WRINKLEMAP + float4 wrinkleNormal = tex2D( NormalWrinkleSampler, i.baseTexCoordDetailTexCoord.xy ); + float4 stretchNormal = tex2D( NormalStretchSampler, i.baseTexCoordDetailTexCoord.xy ); + normalTexel = flTextureAmount * normalTexel + flWrinkleAmount * wrinkleNormal + flStretchAmount * stretchNormal; +#endif + +#if (FASTPATH_NOBUMP == 0 ) + tangentSpaceNormal = lerp( 2.0f * normalTexel.xyz - 1.0f, float3(0, 0, 1), g_fBaseMapAlphaPhongMask ); + fSpecMask = lerp( normalTexel.a, baseColor.a, g_fBaseMapAlphaPhongMask ); +#else + tangentSpaceNormal = float3(0, 0, 1); + fSpecMask = baseColor.a; +#endif + + // We need a normal if we're doing any lighting + worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) ); + + float fFresnelRanges = Fresnel( worldSpaceNormal, vEyeDir, g_FresnelRanges ); + float fRimFresnel = Fresnel4( worldSpaceNormal, vEyeDir ); + + // Break down reflect so that we can share dot(worldSpaceNormal,vEyeDir) with fresnel terms + float3 vReflect = 2 * worldSpaceNormal * dot(worldSpaceNormal, vEyeDir) - vEyeDir; + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + float3 envMapColor = float3( 0.0f, 0.0f, 0.0f ); + if( !bFlashlight ) + { + // Summation of diffuse illumination from all local lights + diffuseLighting = PixelShaderDoLighting( vWorldPos, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, true, vLightAtten, + cAmbientCube, NormalizeRandRotSampler, nNumLights, cLightInfo, true, + + // These parameters aren't passed by generic shaders: + false, 1.0f, + bDoDiffuseWarp, DiffuseWarpSampler ); + + if( bCubemap ) + { + // Mask is either normal map alpha or base map alpha +#if ( SELFILLUMFRESNEL == 1 ) // This is to match the 2.0 version of vertexlitgeneric + float fEnvMapMask = lerp( baseColor.a, g_fInvertPhongMask, g_EnvmapTint_ShadowTweaks.w ); +#else + float fEnvMapMask = lerp( baseColor.a, fSpecMask, g_EnvmapTint_ShadowTweaks.w ); +#endif + + envMapColor = (ENV_MAP_SCALE * + lerp(1, fFresnelRanges, g_EnvMapFresnel.x) * + lerp(fEnvMapMask, 1-fEnvMapMask, g_fInvertPhongMask)) * + texCUBE( EnvmapSampler, vReflect ) * + g_EnvmapTint_ShadowTweaks.xyz; + } + } + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); + float3 rimLighting = float3( 0.0f, 0.0f, 0.0f ); + + float3 vSpecularTint = 1; + float fRimMask = 0; + float fSpecExp = 1; + +#if ( FASTPATH_NOBUMP == 0 ) + float4 vSpecExpMap = tex2D( SpecExponentSampler, i.baseTexCoordDetailTexCoord.xy ); + + if ( !bFlashlight ) + { + fRimMask = lerp( 1.0f, vSpecExpMap.a, g_RimMaskControl ); // Select rim mask + } + + // If the exponent passed in as a constant is zero, use the value from the map as the exponent +#if defined( _X360 ) + [flatten] +#endif + + fSpecExp = (g_EyePos_SpecExponent.w >= 0.0) ? g_EyePos_SpecExponent.w : (1.0f + 149.0f * vSpecExpMap.r); + + // If constant tint is negative, tint with albedo, based upon scalar tint map +#if defined( _X360 ) + [flatten] +#endif + vSpecularTint = lerp( float3(1.0f, 1.0f, 1.0f), baseColor.rgb, vSpecExpMap.g ); + vSpecularTint = (g_SpecularTint.r >= 0.0) ? g_SpecularTint.rgb : vSpecularTint; + +#else + fSpecExp = max(g_EyePos_SpecExponent.w, 0); +#endif + + float3 albedo = baseColor.rgb; + + if ( !bFlashlight ) + { + // Summation of specular from all local lights besides the flashlight + PixelShaderDoSpecularLighting( vWorldPos, worldSpaceNormal, + fSpecExp, vEyeDir, vLightAtten, + nNumLights, cLightInfo, false, 1.0f, bDoSpecularWarp, + SpecularWarpSampler, fFresnelRanges, bDoRimLighting, g_RimExponent, + + // Outputs + specularLighting, rimLighting ); + } + else + { + float4 flashlightSpacePosition = mul( float4( vWorldPos, 1.0f ), g_FlashlightWorldToTexture ); + + DoSpecularFlashlight( g_FlashlightPos, vWorldPos, flashlightSpacePosition, worldSpaceNormal, + g_FlashlightAttenuationFactors.xyz, g_FlashlightAttenuationFactors.w, + FlashlightSampler, ShadowDepthSampler, NormalizeRandRotSampler, FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, vProjPos.xy / vProjPos.z, + fSpecExp, vEyeDir, bDoSpecularWarp, SpecularWarpSampler, fFresnelRanges, g_EnvmapTint_ShadowTweaks, + + // These two values are output + diffuseLighting, specularLighting ); + } + + // If we didn't already apply Fresnel to specular warp, modulate the specular + if ( !bDoSpecularWarp ) + fSpecMask *= fFresnelRanges; + + // Modulate with spec mask, boost and tint + specularLighting *= fSpecMask * g_SpecularBoost; + + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_fTintReplacementControl); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + + float3 diffuseComponent = albedo * diffuseLighting; + if ( bSelfIllum && !bFlashlight ) + { +#if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file + // This will apply a Fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look + float3 vVertexNormal = normalize( float3( i.tangentSpaceTranspose[0].z, i.tangentSpaceTranspose[1].z, i.tangentSpaceTranspose[2].z ) ); + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, vEyeDir.xyz ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo * g_SelfIllumScaleBiasExpBrightness.w, baseColor.a * saturate( flSelfIllumFresnel ) ); +#else + float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoordDetailTexCoord.xy ); + vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint_and_DetailBlendFactor.rgb * albedo, vSelfIllumMask ); +#endif + + diffuseComponent = max( 0.0f, diffuseComponent ); + } + +#if DETAILTEXTURE + diffuseComponent = TextureCombinePostLighting( diffuseComponent, detailColor, + DETAIL_BLEND_MODE, g_SelfIllumTint_and_DetailBlendFactor.w ); +#endif + + if ( bDoRimLighting && !bFlashlight ) + { + float fRimMultiply = fRimMask * fRimFresnel; // both unit range: [0, 1] + + // Add in rim light modulated with tint, mask and traditional Fresnel (not using Fresnel ranges) + rimLighting *= fRimMultiply; + + // Fold rim lighting into specular term by using the max so that we don't really add light twice... + specularLighting = max( specularLighting, rimLighting ); + + // Add in view-ray lookup from ambient cube + specularLighting += (vRimAmbientCubeColor * g_fRimBoost) * saturate(fRimMultiply * worldSpaceNormal.z); + } + + float3 result = specularLighting*vSpecularTint + envMapColor + diffuseComponent; + +#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) + float alpha = fogFactor; +#else + float alpha = g_DiffuseModulation.a; + if ( !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha = lerp( baseColor.a * alpha, alpha, g_fBaseMapAlphaPhongMask ); + } +#endif + + bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 ); + + //FIXME: need to take dowaterfog into consideration + return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, vProjPos.z ); +} diff --git a/sp/src/materialsystem/stdshaders/skin_vs20.fxc b/sp/src/materialsystem/stdshaders/skin_vs20.fxc new file mode 100644 index 00000000..9b04b7aa --- /dev/null +++ b/sp/src/materialsystem/stdshaders/skin_vs20.fxc @@ -0,0 +1,173 @@ +//======= Copyright (c) 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "DECAL" "0..1" [vs30] +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +//----------------------------------------------------------------------------- +// Input vertex format +//----------------------------------------------------------------------------- +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vUserData : TANGENT; + + // Position and normal/tangent deltas + float4 vPosFlex : POSITION1; + float4 vNormalFlex : NORMAL1; + +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + // Stuff that isn't seen by the pixel shader + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + // Stuff that is seen by the pixel shader + float4 baseTexCoord : TEXCOORD0; // includes detail tex coord + float3 lightAtten : TEXCOORD1; + float3 worldVertToEyeVector : TEXCOORD2; + float3x3 tangentSpaceTranspose : TEXCOORD3; + // second row : TEXCOORD4; + // third row : TEXCOORD5; + float4 worldPos_atten3 : TEXCOORD6; + float4 projPos_fWrinkleWeight : TEXCOORD7; +}; + +//----------------------------------------------------------------------------- +// Main shader entry point +//----------------------------------------------------------------------------- +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, + vPosition.xyz, vNormal, vTangent.xyz, o.projPos_fWrinkleWeight.w ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, v.vTexCoord2, + vPosition.xyz, vNormal, vTangent.xyz, o.projPos_fWrinkleWeight.w ); +#endif + + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, worldPos, + worldNormal, worldTangentS, worldTangentT ); + + // Always normalize since flex path is controlled by runtime + // constant not a shader combo and will always generate the normalization + worldNormal = normalize( worldNormal ); + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + +#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.projPos_fWrinkleWeight.xyz = vProjPos.xyz; + +#if !defined( _X360 ) + o.fog = CalcFog( worldPos, vProjPos.xyz, g_FogType ); +#endif + // Needed for water fog alpha and diffuse lighting + // FIXME: we shouldn't have to compute this all the time. + o.worldPos_atten3.xyz = worldPos; + + // Needed for specular + o.worldVertToEyeVector = VSHADER_VECT_SCALE * (cEyePos - worldPos); + + // Compute bumped lighting + // FIXME: We shouldn't have to compute this for unlit materials +#if defined ( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) + o.lightAtten.xyz = float3(0,0,0); + o.worldPos_atten3.w = 0.0f; + #if ( NUM_LIGHTS > 0 ) + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false ); + #endif + #if ( NUM_LIGHTS > 1 ) + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false ); + #endif + #if ( NUM_LIGHTS > 2 ) + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false ); + #endif + #if ( NUM_LIGHTS > 3 ) + o.worldPos_atten3.w = GetVertexAttenForLight( worldPos, 3, false ); + #endif +#else + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, true ); + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, true ); + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, true ); + o.worldPos_atten3.w = GetVertexAttenForLight( worldPos, 3, true ); +#endif + + // Base texture coordinate transform + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + o.baseTexCoord.z = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); + o.baseTexCoord.w = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); + + // Tangent space transform + o.tangentSpaceTranspose[0] = float3( worldTangentS.x, worldTangentT.x, worldNormal.x ); + o.tangentSpaceTranspose[1] = float3( worldTangentS.y, worldTangentT.y, worldNormal.y ); + o.tangentSpaceTranspose[2] = float3( worldTangentS.z, worldTangentT.z, worldNormal.z ); + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/sky_dx6.cpp b/sp/src/materialsystem/stdshaders/sky_dx6.cpp new file mode 100644 index 00000000..15bdc553 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sky_dx6.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Teeth renderer +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Sky, UnlitGeneric ) +DEFINE_FALLBACK_SHADER( Sky_dx6, UnlitGeneric ) + diff --git a/sp/src/materialsystem/stdshaders/sky_dx9.cpp b/sp/src/materialsystem/stdshaders/sky_dx9.cpp new file mode 100644 index 00000000..93eb6115 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sky_dx9.cpp @@ -0,0 +1,126 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "BaseVSShader.h" +#include "sky_vs20.inc" +#include "sky_ps20.inc" +#include "sky_ps20b.inc" + +#include "convar.h" + +BEGIN_VS_SHADER( Sky_DX9, "Help for Sky_DX9 shader" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) + SHADER_PARAM_OVERRIDE( ALPHA, SHADER_PARAM_TYPE_FLOAT, "1.0", "unused", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "sky_dx6"; + } + return 0; + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NOFOG ); + SET_FLAGS( MATERIAL_VAR_IGNOREZ ); + } + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + ImageFormat fmt = params[BASETEXTURE]->GetTextureValue()->GetImageFormat(); + LoadTexture( BASETEXTURE, (fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616) ? 0 : TEXTUREFLAGS_SRGB ); + } + } + SHADER_DRAW + { + SHADOW_STATE + { + SetInitialShadowState(); + +// pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,true); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sky_vs20 ); + SET_STATIC_VERTEX_SHADER( sky_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_ps20 ); + } + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableAlphaWrites( true ); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + float c1[4]={0,0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); + + float c0[4]={1,1,1,1}; + if (params[COLOR]->IsDefined()) + { + memcpy(c0,params[COLOR]->GetVecValue(),3*sizeof(float)); + } + ITexture *txtr=params[BASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( + (fmt==IMAGE_FORMAT_RGBA16161616) || + ( (fmt==IMAGE_FORMAT_RGBA16161616F) && + (g_pHardwareConfig->GetHDRType()==HDR_TYPE_INTEGER)) + ) + { + c0[0]*=16.0; + c0[1]*=16.0; + c0[2]*=16.0; + } + pShaderAPI->SetPixelShaderConstant(0,c0,1); + DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + + // Texture coord transform + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BASETEXTURETRANSFORM ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + } + } + Draw( ); + } + +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc b/sp/src/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc new file mode 100644 index 00000000..8e54d21f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc @@ -0,0 +1,29 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +#include "common_ps_fxc.h" + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +sampler ExposureTextureSampler0 : register( s0 ); +sampler ExposureTextureSampler1 : register( s1 ); +sampler ExposureTextureSampler2 : register( s2 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + HALF3 color0 = 0.25*tex2D( ExposureTextureSampler0, i.baseTexCoord ); + HALF3 color1 = 2.0*tex2D( ExposureTextureSampler1, i.baseTexCoord ); + HALF3 color2 = 16.0*tex2D( ExposureTextureSampler2, i.baseTexCoord ); + + // This is never fogged. +// return FinalOutput( float4( max(max(color0,color1),color2), 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate + return FinalOutput( float4(1,0,0,1 ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/sp/src/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc b/sp/src/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc new file mode 100644 index 00000000..4871da56 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc @@ -0,0 +1,81 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +#include "common_ps_fxc.h" + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +sampler RGBSTextureSampler : register( s0 ); +HALF4 InputScale : register( c0 ); + +float2 texWidthHeight : register( c1 ); + +float4 texOffsets : register( c2 ); + +struct PS_INPUT +{ +//#if defined( _X360 ) +// float2 baseTexCoord : TEXCOORD0; +//#else + float2 baseTexCoord00 : TEXCOORD0; + float2 baseTexCoord01 : TEXCOORD1; + float2 baseTexCoord10 : TEXCOORD2; + float2 baseTexCoord11 : TEXCOORD3; + float2 baseTexCoord_In_Pixels: TEXCOORD4; +//#endif +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float3 result; + +//#if defined( _X360 ) //360 has a cheaper way to handle RGBscale +// float4 Weights; +// float4 samples_0; //no arrays allowed in inline assembly +// float4 samples_1; +// float4 samples_2; +// float4 samples_3; +// float2 vTexCoord = i.baseTexCoord; +// +// asm { +// tfetch2D samples_0, vTexCoord.xy, RGBSTextureSampler, OffsetX = -0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false +// tfetch2D samples_1, vTexCoord.xy, RGBSTextureSampler, OffsetX = 0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false +// tfetch2D samples_2, vTexCoord.xy, RGBSTextureSampler, OffsetX = -0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false +// tfetch2D samples_3, vTexCoord.xy, RGBSTextureSampler, OffsetX = 0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false +// +// getWeights2D Weights, vTexCoord.xy, RGBSTextureSampler +// }; +// +// Weights = float4( (1-Weights.x)*(1-Weights.y), Weights.x*(1-Weights.y), (1-Weights.x)*Weights.y, Weights.x*Weights.y ); +// +// result.rgb = samples_0.rgb * (samples_0.a * Weights.x); +// result.rgb += samples_1.rgb * (samples_1.a * Weights.y); +// result.rgb += samples_2.rgb * (samples_2.a * Weights.z); +// result.rgb += samples_3.rgb * (samples_3.a * Weights.w); +// +//#else + float4 s00 = tex2D(RGBSTextureSampler, i.baseTexCoord00); + float4 s10 = tex2D(RGBSTextureSampler, i.baseTexCoord10); + float4 s01 = tex2D(RGBSTextureSampler, i.baseTexCoord01); + float4 s11 = tex2D(RGBSTextureSampler, i.baseTexCoord11); + + float2 fracCoord = frac(i.baseTexCoord_In_Pixels); + + s00.rgb*=s00.a; + s10.rgb*=s10.a; + + s00.xyz = lerp(s00, s10, fracCoord.x); + + s01.rgb*=s01.a; + s11.rgb*=s11.a; + s01.xyz = lerp(s01, s11, fracCoord.x); + + result = lerp(s00, s01, fracCoord.y); +//#endif + + // This is never fogged. + return FinalOutput( float4( InputScale*result, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/sp/src/materialsystem/stdshaders/sky_hdr_dx9.cpp b/sp/src/materialsystem/stdshaders/sky_hdr_dx9.cpp new file mode 100644 index 00000000..285879c0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sky_hdr_dx9.cpp @@ -0,0 +1,297 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// +#include "BaseVSShader.h" +#include "sky_vs20.inc" +#include "sky_ps20.inc" +#include "sky_ps20b.inc" +#include "sky_hdr_compressed_ps20.inc" +#include "sky_hdr_compressed_ps20b.inc" +#include "sky_hdr_compressed_rgbs_ps20.inc" +#include "sky_hdr_compressed_rgbs_ps20b.inc" + +#include "convar.h" + +static ConVar mat_use_compressed_hdr_textures( "mat_use_compressed_hdr_textures", "1" ); + +DEFINE_FALLBACK_SHADER( Sky, Sky_HDR_DX9 ) + +BEGIN_VS_SHADER( Sky_HDR_DX9, "Help for Sky_HDR_DX9 shader" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( HDRBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture when running with HDR enabled" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "base texture (compressed) for hdr compression method A" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE0, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture0 for hdr compression method B" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE1, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture1 for hdr compression method B" ) + SHADER_PARAM( HDRCOMPRESSEDTEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "compressed base texture2 for hdr compression method B" ) + SHADER_PARAM_OVERRIDE( COLOR, SHADER_PARAM_TYPE_VEC3, "[ 1 1 1]", "color multiplier", SHADER_PARAM_NOT_EDITABLE ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + return "Sky_DX9"; + } + return 0; + } + + SHADER_INIT_PARAMS() + { + SET_FLAGS( MATERIAL_VAR_NOFOG ); + SET_FLAGS( MATERIAL_VAR_IGNOREZ ); + } + SHADER_INIT + { + // First figure out if sampler zero wants to be sRGB + int nSamplerZeroFlags = 0; + if ( (params[HDRCOMPRESSEDTEXTURE]->IsDefined()) && mat_use_compressed_hdr_textures.GetBool() ) + { + nSamplerZeroFlags = 0; + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + nSamplerZeroFlags = 0; + } + else + { + nSamplerZeroFlags = TEXTUREFLAGS_SRGB; + + if ( params[HDRBASETEXTURE]->IsDefined() && params[HDRBASETEXTURE]->IsTexture() ) + { + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( ( fmt == IMAGE_FORMAT_RGBA16161616F ) || ( fmt == IMAGE_FORMAT_RGBA16161616 ) ) + { + nSamplerZeroFlags = 0; + } + } + } + } + + // Next, figure out which texture will be on sampler zero + int nSampler0 = HDRCOMPRESSEDTEXTURE; + if ( params[HDRCOMPRESSEDTEXTURE]->IsDefined() && mat_use_compressed_hdr_textures.GetBool() ) + { + nSampler0 = HDRCOMPRESSEDTEXTURE; + } + else + { + if ( params[HDRCOMPRESSEDTEXTURE0]->IsDefined() ) + { + nSampler0 = HDRCOMPRESSEDTEXTURE0; + } + else + { + nSampler0 = HDRBASETEXTURE; + } + } + + // Load the appropriate textures, making sure that the texture set on sampler 0 is sRGB if necessary + if ( params[HDRCOMPRESSEDTEXTURE]->IsDefined() && (mat_use_compressed_hdr_textures.GetBool() ) ) + { + LoadTexture( HDRCOMPRESSEDTEXTURE, HDRCOMPRESSEDTEXTURE == nSampler0 ? nSamplerZeroFlags : 0 ); + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + LoadTexture( HDRCOMPRESSEDTEXTURE0, HDRCOMPRESSEDTEXTURE0 == nSampler0 ? nSamplerZeroFlags : 0 ); + if ( params[HDRCOMPRESSEDTEXTURE1]->IsDefined() ) + { + LoadTexture( HDRCOMPRESSEDTEXTURE1, HDRCOMPRESSEDTEXTURE1 == nSampler0 ? nSamplerZeroFlags : 0 ); + } + if ( params[HDRCOMPRESSEDTEXTURE2]->IsDefined()) + { + LoadTexture( HDRCOMPRESSEDTEXTURE2, HDRCOMPRESSEDTEXTURE2 == nSampler0 ? nSamplerZeroFlags : 0 ); + } + } + else + { + if ( params[HDRBASETEXTURE]->IsDefined() ) + { + LoadTexture( HDRBASETEXTURE, HDRBASETEXTURE == nSampler0 ? nSamplerZeroFlags : 0 ); + } + } + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + SetInitialShadowState(); + +// pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 1, NULL, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sky_vs20 ); + SET_STATIC_VERTEX_SHADER( sky_vs20 ); + + if ( (params[HDRCOMPRESSEDTEXTURE]->IsDefined()) && + mat_use_compressed_hdr_textures.GetBool() ) + { + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + } + } + else + { + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER1,false); + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER2,false); + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + } + } + else + { + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ((fmt==IMAGE_FORMAT_RGBA16161616F) || (fmt==IMAGE_FORMAT_RGBA16161616)) + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,false); + else + pShaderShadow->EnableSRGBRead(SHADER_SAMPLER0,true); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20b ); + SET_STATIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sky_ps20 ); + SET_STATIC_PIXEL_SHADER( sky_ps20 ); + } + } + } + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableAlphaWrites( true ); + } + + DYNAMIC_STATE + { + DECLARE_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( sky_vs20 ); + + // Texture coord transform + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BASETEXTURETRANSFORM ); + + float c0[4]={1,1,1,1}; + if (params[COLOR]->IsDefined()) + { + memcpy(c0,params[COLOR]->GetVecValue(),3*sizeof(float)); + } + if ( + params[HDRCOMPRESSEDTEXTURE]->IsDefined() && + mat_use_compressed_hdr_textures.GetBool() + ) + { + // set up data needs for pixel shader interpolation + ITexture *txtr=params[HDRCOMPRESSEDTEXTURE]->GetTextureValue(); + float w=txtr->GetActualWidth(); + float h=txtr->GetActualHeight(); + float FUDGE=0.01/max(w,h); // per ATI + float c1[4]={0.5/w-FUDGE, 0.5/h-FUDGE, w, h }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); + + BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE, FRAME ); + c0[0]*=8.0; + c0[1]*=8.0; + c0[2]*=8.0; + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_rgbs_ps20 ); + } + } + else + { + float c1[4]={0,0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, c1); + + if (params[HDRCOMPRESSEDTEXTURE0]->IsDefined() ) + { + BindTexture( SHADER_SAMPLER0, HDRCOMPRESSEDTEXTURE0, FRAME ); + BindTexture( SHADER_SAMPLER1, HDRCOMPRESSEDTEXTURE1, FRAME ); + BindTexture( SHADER_SAMPLER2, HDRCOMPRESSEDTEXTURE2, FRAME ); + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_hdr_compressed_ps20 ); + } + + } + else + { + BindTexture( SHADER_SAMPLER0, HDRBASETEXTURE, FRAME ); + ITexture *txtr=params[HDRBASETEXTURE]->GetTextureValue(); + ImageFormat fmt=txtr->GetImageFormat(); + if ( + (fmt==IMAGE_FORMAT_RGBA16161616) || + ( (fmt==IMAGE_FORMAT_RGBA16161616F) && + (g_pHardwareConfig->GetHDRType()==HDR_TYPE_INTEGER)) + ) + { + c0[0]*=16.0; + c0[1]*=16.0; + c0[2]*=16.0; + } + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( sky_ps20 ); + } + } + } + pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); + } + Draw( ); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/sky_ps2x.fxc b/sp/src/materialsystem/stdshaders/sky_ps2x.fxc new file mode 100644 index 00000000..563fddbb --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sky_ps2x.fxc @@ -0,0 +1,27 @@ +// HDRFIXME: Make this work with nonHDR +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +#include "common_ps_fxc.h" + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +sampler BaseTextureSampler : register( s0 ); +HALF4 InputScale : register( c0 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + HALF4 color = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); + color.rgb *= InputScale.rgb; + + // This is never fogged. + return FinalOutput( color, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR, WRITE_DEPTH_TO_DESTALPHA, 1e20 ); //when writing depth to dest alpha, write a value guaranteed to saturate +} diff --git a/sp/src/materialsystem/stdshaders/sky_vs20.fxc b/sp/src/materialsystem/stdshaders/sky_vs20.fxc new file mode 100644 index 00000000..1bc2a3e6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sky_vs20.fxc @@ -0,0 +1,64 @@ +#include "common_vs_fxc.h" + +const float4 g_vTextureSizeInfo : register( SHADER_SPECIFIC_CONST_0 ); +const float4 g_mBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); + //SHADER_SPECIFIC_CONST_2 + +#define TEXEL_XINCR (g_vTextureSizeInfo.x) +#define TEXEL_YINCR (g_vTextureSizeInfo.y) +#define U_TO_PIXEL_COORD_SCALE (g_vTextureSizeInfo.z) +#define V_TO_PIXEL_COORD_SCALE (g_vTextureSizeInfo.w) + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + +//#if defined( _X360 ) +// float2 baseTexCoord : TEXCOORD0; +//#else + float2 baseTexCoord00 : TEXCOORD0; + float2 baseTexCoord01 : TEXCOORD1; + float2 baseTexCoord10 : TEXCOORD2; + float2 baseTexCoord11 : TEXCOORD3; + float2 baseTexCoord_In_Pixels: TEXCOORD4; +//#endif +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + o.projPos = mul( v.vPos, cModelViewProj ); + + float4 vTexCoordInput = { v.vTexCoord0.x, v.vTexCoord0.y, 0.0f, 1.0f }; + float2 vTexCoord; + vTexCoord.x = dot( vTexCoordInput.xyzw, g_mBaseTexCoordTransform[0] ); + vTexCoord.y = dot( vTexCoordInput.xyzw, g_mBaseTexCoordTransform[1] ); + +//#if defined( _X360 ) +// o.baseTexCoord.xy = vTexCoord.xy; +//#else + // Compute quantities needed for pixel shader texture lerping + o.baseTexCoord00.x = vTexCoord.x - TEXEL_XINCR; + o.baseTexCoord00.y = vTexCoord.y - TEXEL_YINCR; + o.baseTexCoord10.x = vTexCoord.x + TEXEL_XINCR; + o.baseTexCoord10.y = vTexCoord.y - TEXEL_YINCR; + + o.baseTexCoord01.x = vTexCoord.x - TEXEL_XINCR; + o.baseTexCoord01.y = vTexCoord.y + TEXEL_YINCR; + o.baseTexCoord11.x = vTexCoord.x + TEXEL_XINCR; + o.baseTexCoord11.y = vTexCoord.y + TEXEL_YINCR; + + o.baseTexCoord_In_Pixels.xy = o.baseTexCoord00.xy; + o.baseTexCoord_In_Pixels.x *= U_TO_PIXEL_COORD_SCALE; + o.baseTexCoord_In_Pixels.y *= V_TO_PIXEL_COORD_SCALE; +//#endif + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/sprite.cpp b/sp/src/materialsystem/stdshaders/sprite.cpp new file mode 100644 index 00000000..77934f57 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sprite.cpp @@ -0,0 +1,379 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +// Implementation of the sprite shader +//=============================================================================// + +#include "BaseVSShader.h" +#include +#include "const.h" +#include "sprite_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// WARNING! Change these in engine/SpriteGn.h if you change them here! +#define SPR_VP_PARALLEL_UPRIGHT 0 +#define SPR_FACING_UPRIGHT 1 +#define SPR_VP_PARALLEL 2 +#define SPR_ORIENTED 3 +#define SPR_VP_PARALLEL_ORIENTED 4 + + +DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX8 ) + +BEGIN_VS_SHADER( Sprite_DX8, + "Help for Sprite_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) + SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) + SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) + SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "Sprite_DX6"; + return 0; + } + + SHADER_INIT_PARAMS() + { + // FIXME: This can share code with sprite.cpp + // FIXME: Not sure if this is the best solution, but it's a very] + // easy one. When graphics aren't enabled, we oftentimes need to get + // at the parameters of a shader. Therefore, we must set the default + // values in a separate phase from when we load resources. + + if (!params[ALPHA]->IsDefined()) + params[ ALPHA ]->SetFloatValue( 1.0f ); + + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); + SET_FLAGS( MATERIAL_VAR_VERTEXALPHA ); + + // translate from a string orientation to an enumeration + if (params[SPRITEORIENTATION]->IsDefined()) + { + const char *orientationString = params[SPRITEORIENTATION]->GetStringValue(); + if( stricmp( orientationString, "parallel_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + else if( stricmp( orientationString, "facing_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT ); + } + else if( stricmp( orientationString, "vp_parallel" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL ); + } + else if( stricmp( orientationString, "oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED ); + } + else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED ); + } + else + { + Warning( "error with $spriteOrientation\n" ); + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + else + { + // default case + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + +#define SHADER_USE_VERTEX_COLOR 1 +#define SHADER_USE_CONSTANT_COLOR 2 + + void SetSpriteCommonShadowState( unsigned int shaderFlags ) + { + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + + unsigned int flags = VERTEX_POSITION; + if( shaderFlags & SHADER_USE_VERTEX_COLOR ) + { + flags |= VERTEX_COLOR; + } + s_pShaderShadow->VertexShaderVertexFormat( flags, 1, 0, 0 ); + + sprite_vs11_Static_Index vshIndex; + bool vertexColor = ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false; + vshIndex.SetVERTEXCOLOR( vertexColor ); + s_pShaderShadow->SetVertexShader( "sprite_vs11", vshIndex.GetIndex() ); + + // "VERTEXCOLOR" "0..1" + // "CONSTANTCOLOR" "0..1" + int pshIndex = 0; + if ( shaderFlags & SHADER_USE_VERTEX_COLOR ) pshIndex |= 0x1; + if ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) pshIndex |= 0x2; + s_pShaderShadow->SetPixelShader( "sprite_ps11", pshIndex ); + } + + void SetSpriteCommonDynamicState( unsigned int shaderFlags ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + sprite_vs11_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( 0 ); + vshIndex.SetDOWATERFOG( fogIndex ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + s_pShaderAPI->SetPixelShaderIndex( 0 ); + if ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) + { + SetPixelShaderConstant( 0, COLOR, ALPHA ); + } + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + // identity base texture transorm + float ident[2][4] = { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f } + }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &ident[0][0], 2 ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableCulling( false ); + } + + switch( params[SPRITERENDERMODE]->GetIntValue() ) + { + case kRenderNormal: + SHADOW_STATE + { + FogToFogColor(); + SetSpriteCommonShadowState( 0 ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( 0 ); + } + Draw(); + break; + case kRenderTransColor: + case kRenderTransTexture: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderGlow: + case kRenderWorldGlow: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_ALWAYS ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlpha: + // untested cut and past from kRenderTransAlphaAdd . . same as first pass of that. + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlphaAdd: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + + SHADOW_STATE + { + SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + + case kRenderTransAdd: + { + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( flags ); + } + } + Draw(); + break; + case kRenderTransAddFrameBlend: + { + float flFrame = params[FRAME]->GetFloatValue(); + float flFade = params[ALPHA]->GetFloatValue(); + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + sprite_vs11_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( 0 ); + vshIndex.SetDOWATERFOG( fogIndex ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + s_pShaderAPI->SetPixelShaderIndex( 0 ); + + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + s_pShaderAPI->SetPixelShaderConstant( 0, color ); + + + // identity base texture transorm + float ident[2][4] = { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f } + }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &ident[0][0], 2 ); + } + Draw(); + SHADOW_STATE + { + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + int numAnimationFrames = pTexture->GetNumAnimationFrames(); + BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + sprite_vs11_Dynamic_Index vshIndex; + vshIndex.SetSKINNING( 0 ); + vshIndex.SetDOWATERFOG( fogIndex ); + s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + + s_pShaderAPI->SetPixelShaderIndex( 0 ); + + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + s_pShaderAPI->SetPixelShaderConstant( 0, color ); + + // identity base texture transorm + float ident[2][4] = { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f } + }; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, &ident[0][0], 2 ); + } + Draw(); + } + break; + default: + ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); + break; + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/sprite_dx6.cpp b/sp/src/materialsystem/stdshaders/sprite_dx6.cpp new file mode 100644 index 00000000..15ba22a6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sprite_dx6.cpp @@ -0,0 +1,289 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +// Implementation of the sprite shader +//=============================================================================// + +#include "shaderlib/cshader.h" +#include +#include "const.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// WARNING! Change these in engine/SpriteGn.h if you change them here! +#define SPR_VP_PARALLEL_UPRIGHT 0 +#define SPR_FACING_UPRIGHT 1 +#define SPR_VP_PARALLEL 2 +#define SPR_ORIENTED 3 +#define SPR_VP_PARALLEL_ORIENTED 4 + + +DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX6 ) + +BEGIN_SHADER( Sprite_DX6, + "Help for Sprite_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) + SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) + SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) + SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + // FIXME: This can share code with sprite.cpp + // FIXME: Not sure if this is the best solution, but it's a very] + // easy one. When graphics aren't enabled, we oftentimes need to get + // at the parameters of a shader. Therefore, we must set the default + // values in a separate phase from when we load resources. + + if (!params[ALPHA]->IsDefined()) + params[ ALPHA ]->SetFloatValue( 1.0f ); + + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); + SET_FLAGS( MATERIAL_VAR_VERTEXALPHA ); + + // translate from a string orientation to an enumeration + if (params[SPRITEORIENTATION]->IsDefined()) + { + const char *orientationString = params[SPRITEORIENTATION]->GetStringValue(); + if( stricmp( orientationString, "parallel_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + else if( stricmp( orientationString, "facing_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT ); + } + else if( stricmp( orientationString, "vp_parallel" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL ); + } + else if( stricmp( orientationString, "oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED ); + } + else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED ); + } + else + { + Warning( "error with $spriteOrientation\n" ); + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + else + { + // default case + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableCulling( false ); + } + + switch( params[SPRITERENDERMODE]->GetIntValue() ) + { + case kRenderNormal: + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransColor: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransTexture: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderGlow: + case kRenderWorldGlow: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableDepthTest( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToBlack(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransAlpha: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransAlphaAdd: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + FogToBlack(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + + case kRenderTransAdd: + SHADOW_STATE + { + if( params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + } + else + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + } + pShaderShadow->EnableConstantColor( true ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + FogToBlack(); + } + DYNAMIC_STATE + { + SetColorState( COLOR, ALPHA ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + break; + case kRenderTransAddFrameBlend: + { + float flFrame = params[FRAME]->GetFloatValue(); + float flFade = params[ALPHA]->GetFloatValue(); + SHADOW_STATE + { + if( params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + } + else + { + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_COLOR ); + } + pShaderShadow->EnableConstantColor( true ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + FogToBlack(); + } + DYNAMIC_STATE + { + float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame ); + pShaderAPI->Color3f( flFade * frameBlendAlpha, flFade * frameBlendAlpha, flFade * frameBlendAlpha ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); + } + Draw(); + SHADOW_STATE + { + FogToBlack(); + } + DYNAMIC_STATE + { + float frameBlendAlpha = ( flFrame - ( int )flFrame ); + pShaderAPI->Color3f( flFade * frameBlendAlpha, flFade * frameBlendAlpha, flFade * frameBlendAlpha ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + int numAnimationFrames = pTexture->GetNumAnimationFrames(); + BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); + } + Draw(); + } + + break; + default: + ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); + break; + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/sprite_dx9.cpp b/sp/src/materialsystem/stdshaders/sprite_dx9.cpp new file mode 100644 index 00000000..0a0bb9f4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sprite_dx9.cpp @@ -0,0 +1,490 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "BaseVSShader.h" +#include +#include "const.h" + +#include "cpp_shader_constant_register_map.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#include "sprite_vs20.inc" +#include "sprite_ps20.inc" +#include "sprite_ps20b.inc" + +// WARNING! Change these in engine/SpriteGn.h if you change them here! +#define SPR_VP_PARALLEL_UPRIGHT 0 +#define SPR_FACING_UPRIGHT 1 +#define SPR_VP_PARALLEL 2 +#define SPR_ORIENTED 3 +#define SPR_VP_PARALLEL_ORIENTED 4 + + +DEFINE_FALLBACK_SHADER( Sprite, Sprite_DX9 ) + +BEGIN_VS_SHADER( Sprite_DX9, + "Help for Sprite_DX9" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( SPRITEORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "sprite origin" ) + SHADER_PARAM( SPRITEORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "sprite orientation" ) + SHADER_PARAM( SPRITERENDERMODE, SHADER_PARAM_TYPE_INTEGER, "0", "sprite rendermode" ) + SHADER_PARAM( IGNOREVERTEXCOLORS, SHADER_PARAM_TYPE_BOOL, "1", "ignore vertex colors" ) + SHADER_PARAM( NOSRGB, SHADER_PARAM_TYPE_BOOL, "0", "do not operate in srgb space" ) + SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if (g_pHardwareConfig->GetDXSupportLevel() < 90) + return "Sprite_DX8"; + return 0; + } + SHADER_INIT_PARAMS() + { + // FIXME: This can share code with sprite.cpp + if (!params[ALPHA]->IsDefined()) + { + params[ALPHA]->SetFloatValue( 1.0f ); + } + + if (!params[HDRCOLORSCALE]->IsDefined()) + { + params[HDRCOLORSCALE]->SetFloatValue( 1.0f ); + } + + if ( !params[NOSRGB]->IsDefined() ) + { + // Disable sRGB reads and writes by default + params[NOSRGB]->SetIntValue( 1 ); + } + + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + SET_FLAGS( MATERIAL_VAR_VERTEXCOLOR ); + SET_FLAGS( MATERIAL_VAR_VERTEXALPHA ); + + // translate from a string orientation to an enumeration + if (params[SPRITEORIENTATION]->IsDefined()) + { + const char *orientationString = params[SPRITEORIENTATION]->GetStringValue(); + if( stricmp( orientationString, "parallel_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + else if( stricmp( orientationString, "facing_upright" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_FACING_UPRIGHT ); + } + else if( stricmp( orientationString, "vp_parallel" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL ); + } + else if( stricmp( orientationString, "oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_ORIENTED ); + } + else if( stricmp( orientationString, "vp_parallel_oriented" ) == 0 ) + { + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_ORIENTED ); + } + else + { + Warning( "error with $spriteOrientation\n" ); + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + else + { + // default case + params[SPRITEORIENTATION]->SetIntValue( SPR_VP_PARALLEL_UPRIGHT ); + } + } + + SHADER_INIT + { + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + LoadTexture( BASETEXTURE, bSRGB ? TEXTUREFLAGS_SRGB : 0 ); + } + +#define SHADER_USE_VERTEX_COLOR 1 +#define SHADER_USE_CONSTANT_COLOR 2 + + void SetSpriteCommonShadowState( unsigned int shaderFlags ) + { + IShaderShadow *pShaderShadow = s_pShaderShadow; + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, bSRGB ); + + // Only enabling this on OSX() - it causes GL mode's light glow sprites to be much darker vs. D3D9 under Linux/Win GL. + bool bSRGBOutputAdapter = ( IsOSX() && !g_pHardwareConfig->FakeSRGBWrite() ) && !bSRGB; + + unsigned int flags = VERTEX_POSITION; + if( shaderFlags & SHADER_USE_VERTEX_COLOR ) + { + flags |= VERTEX_COLOR; + } + int numTexCoords = 1; + s_pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + DECLARE_STATIC_VERTEX_SHADER( sprite_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_VERTEX_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_VERTEX_SHADER( sprite_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path + { + DECLARE_STATIC_PIXEL_SHADER( sprite_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( CONSTANTCOLOR, ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB_OUTPUT_ADAPTER, bSRGBOutputAdapter ); + SET_STATIC_PIXEL_SHADER( sprite_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( sprite_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, ( shaderFlags & SHADER_USE_VERTEX_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( CONSTANTCOLOR, ( shaderFlags & SHADER_USE_CONSTANT_COLOR ) ? true : false ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB, bSRGB ); + SET_STATIC_PIXEL_SHADER( sprite_ps20 ); + } + + // OSX always has to sRGB write (don't do this on Linux/Win GL - it causes glow sprites to be way too dark) + s_pShaderShadow->EnableSRGBWrite( bSRGB || ( IsOSX() && !g_pHardwareConfig->FakeSRGBWrite() ) ); + } + + void SetSpriteCommonDynamicState( unsigned int shaderFlags ) + { + IShaderDynamicAPI *pShaderAPI = s_pShaderAPI; + bool bSRGB = s_ppParams[NOSRGB]->GetIntValue() == 0; + + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + if( shaderFlags & SHADER_USE_CONSTANT_COLOR ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 0, COLOR, ALPHA ); + else + SetPixelShaderConstant( 0, COLOR, ALPHA ); + } + + if( IsHDREnabled() ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); + else + SetPixelShaderConstant( 1, HDRCOLORSCALE ); + } + } + + SHADER_DRAW + { + bool bSRGB = params[NOSRGB]->GetIntValue() == 0; + + SHADOW_STATE + { + pShaderShadow->EnableCulling( false ); + } + + switch( params[SPRITERENDERMODE]->GetIntValue() ) + { + case kRenderNormal: + SHADOW_STATE + { + FogToFogColor(); + + SetSpriteCommonShadowState( 0 ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( 0 ); + } + Draw(); + break; + case kRenderTransColor: + case kRenderTransTexture: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderGlow: + case kRenderWorldGlow: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableDepthTest( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlpha: + // untested cut and past from kRenderTransAlphaAdd . . same as first pass of that. + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + case kRenderTransAlphaAdd: + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + FogToFogColor(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + + SHADOW_STATE + { + SetInitialShadowState(); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( SHADER_USE_VERTEX_COLOR ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( SHADER_USE_VERTEX_COLOR ); + } + Draw(); + break; + + case kRenderTransAdd: + { + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + SetSpriteCommonDynamicState( flags ); + } + } + Draw(); + break; + case kRenderTransAddFrameBlend: + { + float flFrame = params[FRAME]->GetFloatValue(); + float flFade = params[ALPHA]->GetFloatValue(); + unsigned int flags = SHADER_USE_CONSTANT_COLOR; + if( !params[ IGNOREVERTEXCOLORS ]->GetIntValue() ) + { + flags |= SHADER_USE_VERTEX_COLOR; + } + SHADOW_STATE + { + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = 1.0f - ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + BindTexture( SHADER_SAMPLER0, pTexture, ( int )flFrame ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + float color[4]; + if ( bSRGB ) + color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); + else + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + s_pShaderAPI->SetPixelShaderConstant( 0, color ); + if( IsHDREnabled() ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); + else + SetPixelShaderConstant( 1, HDRCOLORSCALE ); + } + } + Draw(); + SHADOW_STATE + { + FogToBlack(); + + SetSpriteCommonShadowState( flags ); + } + DYNAMIC_STATE + { + float frameBlendAlpha = ( flFrame - ( int )flFrame ); + ITexture *pTexture = params[BASETEXTURE]->GetTextureValue(); + int numAnimationFrames = pTexture->GetNumAnimationFrames(); + BindTexture( SHADER_SAMPLER0, pTexture, ( ( int )flFrame + 1 ) % numAnimationFrames ); + + MaterialFogMode_t fogType = s_pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + DECLARE_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER( sprite_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL down this path + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( sprite_ps20 ); + } + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + float color[4]; + if ( bSRGB ) + color[0] = color[1] = color[2] = GammaToLinear( flFade * frameBlendAlpha ); + else + color[0] = color[1] = color[2] = flFade * frameBlendAlpha; + color[3] = 1.0f; + s_pShaderAPI->SetPixelShaderConstant( 0, color ); + if( IsHDREnabled() ) + { + if ( bSRGB ) + SetPixelShaderConstantGammaToLinear( 1, HDRCOLORSCALE ); + else + SetPixelShaderConstant( 1, HDRCOLORSCALE ); + } + } + Draw(); + } + + break; + default: + ShaderWarning( "shader Sprite: Unknown sprite render mode\n" ); + break; + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/sprite_ps11.psh b/sp/src/materialsystem/stdshaders/sprite_ps11.psh new file mode 100644 index 00000000..5f5def5b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sprite_ps11.psh @@ -0,0 +1,15 @@ +; STATIC: "VERTEXCOLOR" "0..1" +; STATIC: "CONSTANTCOLOR" "0..1" + +ps.1.1 + +tex t0 +mov r0, t0 + +#if VERTEXCOLOR +mul r0, r0, v0 +#endif + +#if CONSTANTCOLOR +mul r0, r0, c0 +#endif \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/sprite_ps2x.fxc b/sp/src/materialsystem/stdshaders/sprite_ps2x.fxc new file mode 100644 index 00000000..83a7ab08 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sprite_ps2x.fxc @@ -0,0 +1,61 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "CONSTANTCOLOR" "0..1" +// STATIC: "HDRTYPE" "0..2" +// STATIC: "SRGB" "0..1" +// STATIC: "SRGB_OUTPUT_ADAPTER" "0..1" [ps20b] + +// DYNAMIC: "HDRENABLED" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +const HALF4 g_Color : register( c0 ); +const float g_HDRColorScale : register( c1 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +sampler TexSampler : register( s0 ); + +struct PS_INPUT +{ + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 result, sample = tex2D( TexSampler, i.baseTexCoord ); + +#if VERTEXCOLOR + sample *= i.color; +#endif + +#if CONSTANTCOLOR + sample *= g_Color; +#endif + +#if HDRTYPE && HDRENABLED + sample.xyz *= g_HDRColorScale; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); +#if SRGB + result = FinalOutput( sample, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +#else + result = FinalOutput( sample, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_GAMMA ); +#endif + + // On Posix, we're being forced through a linear-to-gamma curve but don't want it, so we do the opposite here first +#if SRGB_OUTPUT_ADAPTER + result = GammaToLinear( result ); +#endif + + return result; +} + diff --git a/sp/src/materialsystem/stdshaders/sprite_vs11.vsh b/sp/src/materialsystem/stdshaders/sprite_vs11.vsh new file mode 100644 index 00000000..5ffa45f1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sprite_vs11.vsh @@ -0,0 +1,9 @@ +vs.1.1 + +# STATIC: "VERTEXCOLOR" "0..1" +# DYNAMIC: "SKINNING" "0..0" +# DYNAMIC: "DOWATERFOG" "0..1" + +#include "UnlitGeneric_inc.vsh" + +&UnlitGeneric( 0, 0, 0, 0, $VERTEXCOLOR ); diff --git a/sp/src/materialsystem/stdshaders/sprite_vs20.fxc b/sp/src/materialsystem/stdshaders/sprite_vs20.fxc new file mode 100644 index 00000000..5e427c19 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/sprite_vs20.fxc @@ -0,0 +1,65 @@ +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "SRGB" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bVertexColor = VERTEXCOLOR ? true : false; + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vColor : COLOR0; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; +#endif + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + worldPos = mul4x3( v.vPos, cModel[0] ); + + // Transform into projection space + float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = projPos; + projPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, projPos.z ); + +#if !defined( _X360 ) + o.fog = CalcFog( worldPos, projPos, g_FogType ); +#endif + if ( g_bVertexColor ) + { + // Assume that this is unlitgeneric if you are using vertex color. +#if SRGB + o.color.rgba = GammaToLinear( v.vColor.rgba ); +#else + o.color.rgba = v.vColor.rgba; +#endif + } + + // Base texture coordinates + o.baseTexCoord.xy = v.vTexCoord0.xy; + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/spritecard.cpp b/sp/src/materialsystem/stdshaders/spritecard.cpp new file mode 100644 index 00000000..850c357a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/spritecard.cpp @@ -0,0 +1,484 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: shader for drawing sprites as cards, with animation frame lerping +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "convar.h" + +// STDSHADER_DX9_DLL_EXPORT +#include "spritecard_ps20.inc" +#include "spritecard_ps20b.inc" +#include "spritecard_vs20.inc" +#include "splinecard_vs20.inc" + +#if SUPPORT_DX8 +// STDSHADER_DX8_DLL_EXPORT +#include "spritecard_vs11.inc" +#include "spritecard_ps11.inc" +#include "splinecard_vs11.inc" +#endif + +#include "tier0/icommandline.h" //command line + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define DEFAULT_PARTICLE_FEATHERING_ENABLED 1 + +#ifdef STDSHADER_DX8_DLL_EXPORT +DEFINE_FALLBACK_SHADER( Spritecard, Spritecard_DX8 ) +#endif + +int GetDefaultDepthFeatheringValue( void ) //Allow the command-line to go against the default soft-particle value +{ + static int iRetVal = -1; + + if( iRetVal == -1 ) + { +# if( DEFAULT_PARTICLE_FEATHERING_ENABLED == 1 ) + { + if( CommandLine()->CheckParm( "-softparticlesdefaultoff" ) ) + iRetVal = 0; + else + iRetVal = 1; + } +# else + { + if( CommandLine()->CheckParm( "-softparticlesdefaulton" ) ) + iRetVal = 1; + else + iRetVal = 0; + } +# endif + } + + // On low end parts on the Mac, we reduce particles and shut off depth blending here + static ConVarRef mat_reduceparticles( "mat_reduceparticles" ); + if ( mat_reduceparticles.GetBool() ) + { + iRetVal = 0; + } + + return iRetVal; +} + + +#ifdef STDSHADER_DX9_DLL_EXPORT +BEGIN_VS_SHADER_FLAGS( Spritecard, "Help for Spritecard", SHADER_NOT_EDITABLE ) +#else +BEGIN_VS_SHADER_FLAGS( Spritecard_DX8, "Help for Spritecard_DX8", SHADER_NOT_EDITABLE ) +#endif + +BEGIN_SHADER_PARAMS +SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" ) +SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) +SHADER_PARAM( ORIENTATION, SHADER_PARAM_TYPE_INTEGER, "0", "0 = always face camera, 1 = rotate around z, 2= parallel to ground" ) +SHADER_PARAM( ADDBASETEXTURE2, SHADER_PARAM_TYPE_FLOAT, "0.0", "amount to blend second texture into frame by" ) +SHADER_PARAM( OVERBRIGHTFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "overbright factor for texture. For HDR effects.") +SHADER_PARAM( DUALSEQUENCE, SHADER_PARAM_TYPE_INTEGER, "0", "blend two separate animated sequences.") +SHADER_PARAM( SEQUENCE_BLEND_MODE, SHADER_PARAM_TYPE_INTEGER, "0", "defines the blend mode between the images un dual sequence particles. 0 = avg, 1=alpha from first, rgb from 2nd, 2= first over second" ) +SHADER_PARAM( MAXLUMFRAMEBLEND1, SHADER_PARAM_TYPE_INTEGER, "0", "instead of blending between animation frames for the first sequence, select pixels based upon max luminance" ) +SHADER_PARAM( MAXLUMFRAMEBLEND2, SHADER_PARAM_TYPE_INTEGER, "0", "instead of blending between animation frames for the 2nd sequence, select pixels based upon max luminance" ) +SHADER_PARAM( RAMPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "if specified, then the red value of the image is used to index this ramp to produce the output color" ) +SHADER_PARAM( ZOOMANIMATESEQ2, SHADER_PARAM_TYPE_FLOAT, "1.0", "amount to gradually zoom between frames on the second sequence. 2.0 will double the size of a frame over its lifetime.") +SHADER_PARAM( EXTRACTGREENALPHA, SHADER_PARAM_TYPE_INTEGER, "0", "grayscale data sitting in green/alpha channels") +SHADER_PARAM( ADDOVERBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "use ONE:INVSRCALPHA blending") +SHADER_PARAM( ADDSELF, SHADER_PARAM_TYPE_FLOAT, "0.0", "amount of base texture to additively blend in" ) +SHADER_PARAM( BLENDFRAMES, SHADER_PARAM_TYPE_BOOL, "1", "whether or not to smoothly blend between animated frames" ) +SHADER_PARAM( MINSIZE, SHADER_PARAM_TYPE_FLOAT, "0.0", "minimum screen fractional size of particle") +SHADER_PARAM( STARTFADESIZE, SHADER_PARAM_TYPE_FLOAT, "10.0", "screen fractional size to start fading particle out") +SHADER_PARAM( ENDFADESIZE, SHADER_PARAM_TYPE_FLOAT, "20.0", "screen fractional size to finish fading particle out") +SHADER_PARAM( MAXSIZE, SHADER_PARAM_TYPE_FLOAT, "20.0", "maximum screen fractional size of particle") +SHADER_PARAM( USEINSTANCING, SHADER_PARAM_TYPE_BOOL, "1", "whether to use GPU vertex instancing (submit 1 vert per particle quad)") +SHADER_PARAM( SPLINETYPE, SHADER_PARAM_TYPE_INTEGER, "0", "spline type 0 = none, 1=ctamull rom") +SHADER_PARAM( MAXDISTANCE, SHADER_PARAM_TYPE_FLOAT, "100000.0", "maximum distance to draw particles at") +SHADER_PARAM( FARFADEINTERVAL, SHADER_PARAM_TYPE_FLOAT, "400.0", "interval over which to fade out far away particles") +END_SHADER_PARAMS + +SHADER_INIT_PARAMS() +{ + INIT_FLOAT_PARM( MAXDISTANCE, 100000.0); + INIT_FLOAT_PARM( FARFADEINTERVAL, 400.0); + INIT_FLOAT_PARM( MAXSIZE, 20.0 ); + INIT_FLOAT_PARM( ENDFADESIZE, 20.0 ); + INIT_FLOAT_PARM( STARTFADESIZE, 10.0 ); + INIT_FLOAT_PARM( DEPTHBLENDSCALE, 50.0 ); + INIT_FLOAT_PARM( OVERBRIGHTFACTOR, 1.0 ); + INIT_FLOAT_PARM( ADDBASETEXTURE2, 0.0 ); + INIT_FLOAT_PARM( ADDSELF, 0.0 ); + INIT_FLOAT_PARM( ZOOMANIMATESEQ2, 0.0 ); + + if ( !params[DEPTHBLEND]->IsDefined() ) + { + params[ DEPTHBLEND ]->SetIntValue( GetDefaultDepthFeatheringValue() ); + } + if ( !g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + params[ DEPTHBLEND ]->SetIntValue( 0 ); + } + if ( !params[DUALSEQUENCE]->IsDefined() ) + { + params[DUALSEQUENCE]->SetIntValue( 0 ); + } + if ( !params[MAXLUMFRAMEBLEND1]->IsDefined() ) + { + params[MAXLUMFRAMEBLEND1]->SetIntValue( 0 ); + } + if ( !params[MAXLUMFRAMEBLEND2]->IsDefined() ) + { + params[MAXLUMFRAMEBLEND2]->SetIntValue( 0 ); + } + if ( !params[EXTRACTGREENALPHA]->IsDefined() ) + { + params[EXTRACTGREENALPHA]->SetIntValue( 0 ); + } + if ( !params[ADDOVERBLEND]->IsDefined() ) + { + params[ADDOVERBLEND]->SetIntValue( 0 ); + } + if ( !params[BLENDFRAMES]->IsDefined() ) + { + params[ BLENDFRAMES ]->SetIntValue( 1 ); + } + if ( !params[USEINSTANCING]->IsDefined() ) + { + params[ USEINSTANCING ]->SetIntValue( IsX360() ? 1 : 0 ); + } + SET_FLAGS2( MATERIAL_VAR2_IS_SPRITECARD ); +} + +SHADER_FALLBACK +{ +#ifdef STDSHADER_DX9_DLL_EXPORT + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "SpriteCard_DX8"; +#endif +#ifdef STDSHADER_DX8_DLL_EXPORT + // STDSHADER_DX8_DLL_EXPORT + if ( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "Wireframe"; +#endif + return 0; +} + +SHADER_INIT +{ +#ifdef STDSHADER_DX9_DLL_EXPORT + const bool bDX8 = false; +#endif +#ifdef STDSHADER_DX8_DLL_EXPORT + const bool bDX8 = true; +#endif + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + if ( params[BASETEXTURE]->IsDefined() ) + { + bool bExtractGreenAlpha = false; + if ( params[EXTRACTGREENALPHA]->IsDefined() ) + { + bExtractGreenAlpha = params[EXTRACTGREENALPHA]->GetIntValue() != 0; + } + + LoadTexture( BASETEXTURE, !bExtractGreenAlpha && !bDX8 ? TEXTUREFLAGS_SRGB : 0 ); + } + if ( params[RAMPTEXTURE]->IsDefined() ) + { + LoadTexture( RAMPTEXTURE, TEXTUREFLAGS_SRGB ); + } +} + +SHADER_DRAW +{ +#ifdef STDSHADER_DX9_DLL_EXPORT + const bool bDX8 = false; +#endif +#ifdef STDSHADER_DX8_DLL_EXPORT + const bool bDX8 = true; +#endif + bool bUseRampTexture = (! bDX8 ) && ( params[RAMPTEXTURE]->IsDefined() ); + bool bZoomSeq2 = (! bDX8 ) && ( ( params[ZOOMANIMATESEQ2]->GetFloatValue()) > 1.0 ); + bool bDepthBlend = (! bDX8 ) && ( params[DEPTHBLEND]->GetIntValue() != 0 ); + bool bAdditive2ndTexture = params[ADDBASETEXTURE2]->GetFloatValue() != 0.0; + int nSplineType = params[SPLINETYPE]->GetIntValue(); + + SHADOW_STATE + { + bool bSecondSequence = params[DUALSEQUENCE]->GetIntValue() != 0; + bool bAddOverBlend = params[ADDOVERBLEND]->GetIntValue() != 0; + bool bExtractGreenAlpha = (! bDX8 ) && ( params[EXTRACTGREENALPHA]->GetIntValue() != 0 ); + bool bBlendFrames = (! bDX8 ) && ( params[BLENDFRAMES]->GetIntValue() != 0 ); + if ( nSplineType ) + { + bBlendFrames = false; + } + bool bAddSelf = params[ADDSELF]->GetFloatValue() != 0.0; + bool bUseInstancing = IsX360() ? ( params[ USEINSTANCING ]->GetIntValue() != 0 ) : false; + if ( nSplineType ) + bUseInstancing = false; + + // draw back-facing because of yaw spin + pShaderShadow->EnableCulling( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + if ( bDX8 ) + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + if ( bAdditive2ndTexture && bDX8 ) + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + if ( bUseRampTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + + if ( bDepthBlend ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + + if ( bAdditive2ndTexture || bAddSelf ) + pShaderShadow->EnableAlphaTest( false ); + else + pShaderShadow->EnableAlphaTest( true ); + + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.01f ); + + if ( bAdditive2ndTexture || bAddOverBlend || bAddSelf ) + { + EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + else + { + if ( IS_FLAG_SET(MATERIAL_VAR_ADDITIVE) ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + } + + unsigned int flags = VERTEX_POSITION | VERTEX_COLOR; + static int s_TexCoordSize[8]={4, // 0 = sheet bounding uvs, frame0 + 4, // 1 = sheet bounding uvs, frame 1 + 4, // 2 = frame blend, rot, radius, ??? + 2, // 3 = corner identifier ( 0/0,1/0,1/1, 1/0 ) + 4, // 4 = texture 2 bounding uvs + 4, // 5 = second sequence bounding uvs, frame0 + 4, // 6 = second sequence bounding uvs, frame1 + 4, // 7 = second sequence frame blend, ?,?,? + }; + static int s_TexCoordSizeSpline[]={4, // 0 = sheet bounding uvs, frame0 + 4, // 1 = sheet bounding uvs, frame 1 + 4, // 2 = frame blend, rot, radius, ??? + 4, // 3 = corner identifier ( 0/0,1/0,1/1, 1/0 ) + 4, // 4 = texture 2 bounding uvs + 4, // 5 = second sequence bounding uvs, frame0 + 4, // 6 = second sequence bounding uvs, frame1 + 4, // 7 = second sequence frame blend, ?,?,? + }; + + int numTexCoords = 4; + if ( true /* bAdditive2ndTexture */ ) // there is no branch for 2nd texture in the VS! -henryg + { + numTexCoords = 5; + } + if ( bSecondSequence ) + { + // the whole shebang - 2 sequences, with a possible multi-image sequence first + numTexCoords = 8; + } + pShaderShadow->VertexShaderVertexFormat( flags, + numTexCoords, + nSplineType? s_TexCoordSizeSpline : s_TexCoordSize, 0 ); + + if ( bDX8 ) + { +#if SUPPORT_DX8 + if ( nSplineType ) + { + DECLARE_STATIC_VERTEX_SHADER( splinecard_vs11 ); + SET_STATIC_VERTEX_SHADER( splinecard_vs11 ); + } + else + { + DECLARE_STATIC_VERTEX_SHADER( spritecard_vs11 ); + if ( bSecondSequence ) + bAdditive2ndTexture = false; + SET_STATIC_VERTEX_SHADER_COMBO( DUALSEQUENCE, false ); + SET_STATIC_VERTEX_SHADER_COMBO( ZOOM_ANIMATE_SEQ2, false ); + SET_STATIC_VERTEX_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha ); + SET_STATIC_VERTEX_SHADER( spritecard_vs11 ); + } + + DECLARE_STATIC_PIXEL_SHADER( spritecard_ps11 ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDSELF, bAddSelf ); + SET_STATIC_PIXEL_SHADER_COMBO( USEALPHAASRGB, bSecondSequence ); + SET_STATIC_PIXEL_SHADER( spritecard_ps11 ); +#endif + } + else + { + if ( nSplineType ) + { + DECLARE_STATIC_VERTEX_SHADER( splinecard_vs20 ); + SET_STATIC_VERTEX_SHADER( splinecard_vs20 ); + } + else + { + DECLARE_STATIC_VERTEX_SHADER( spritecard_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( DUALSEQUENCE, bSecondSequence ); + SET_STATIC_VERTEX_SHADER_COMBO( ZOOM_ANIMATE_SEQ2, bZoomSeq2 ); + SET_STATIC_VERTEX_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_INSTANCING, bUseInstancing ); + SET_STATIC_VERTEX_SHADER( spritecard_vs20 ); + } + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( spritecard_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDSELF, bAddSelf ); + SET_STATIC_PIXEL_SHADER_COMBO( ANIMBLEND, bBlendFrames ); + SET_STATIC_PIXEL_SHADER_COMBO( DUALSEQUENCE, bSecondSequence ); + SET_STATIC_PIXEL_SHADER_COMBO( SEQUENCE_BLEND_MODE, bSecondSequence ? params[SEQUENCE_BLEND_MODE]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND1, params[MAXLUMFRAMEBLEND1]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND2, bSecondSequence? params[MAXLUMFRAMEBLEND1]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORRAMP, bUseRampTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDepthBlend ); + SET_STATIC_PIXEL_SHADER( spritecard_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( spritecard_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDBASETEXTURE2, bAdditive2ndTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DUALSEQUENCE, bSecondSequence ); + SET_STATIC_PIXEL_SHADER_COMBO( ADDSELF, bAddSelf ); + SET_STATIC_PIXEL_SHADER_COMBO( ANIMBLEND, bBlendFrames ); + SET_STATIC_PIXEL_SHADER_COMBO( SEQUENCE_BLEND_MODE, bSecondSequence ? params[SEQUENCE_BLEND_MODE]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND1, params[MAXLUMFRAMEBLEND1]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MAXLUMFRAMEBLEND2, bSecondSequence? params[MAXLUMFRAMEBLEND1]->GetIntValue() : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( COLORRAMP, bUseRampTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( EXTRACTGREENALPHA, bExtractGreenAlpha ); + SET_STATIC_PIXEL_SHADER( spritecard_ps20 ); + } + + if ( !bDX8 ) + pShaderShadow->EnableSRGBWrite( true ); + + if( !bExtractGreenAlpha && !bDX8 ) + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + if ( bDX8 ) // bind on 2nd sampelr so we can lerp + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + + if ( bDX8 && bAdditive2ndTexture ) + BindTexture( SHADER_SAMPLER3, BASETEXTURE, FRAME ); + + if ( bUseRampTexture && ( !bDX8 ) ) + { + BindTexture( SHADER_SAMPLER1, RAMPTEXTURE, FRAME ); + } + + if ( bDepthBlend ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_DEPTH ); + } + + LoadViewportTransformScaledIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10 ); + + int nOrientation = params[ORIENTATION]->GetIntValue(); + nOrientation = clamp( nOrientation, 0, 2 ); + + // We need these only when screen-orienting + if ( nOrientation == 0 ) + { + LoadModelViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 ); + LoadProjectionMatrixIntoVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 ); + } + + if ( bZoomSeq2 ) + { + float flZScale=1.0/(params[ZOOMANIMATESEQ2]->GetFloatValue()); + float C0[4]={ 0.5*(1.0+flZScale), flZScale, 0, 0 }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, C0, + ARRAYSIZE(C0)/4 ); + } + + // set fade constants in vsconsts 8 and 9 + float flMaxDistance = params[MAXDISTANCE]->GetFloatValue(); + float flStartFade = max( 1.0, flMaxDistance - params[FARFADEINTERVAL]->GetFloatValue() ); + + float VC0[8]={ params[MINSIZE]->GetFloatValue(), params[MAXSIZE]->GetFloatValue(), + params[STARTFADESIZE]->GetFloatValue(), params[ENDFADESIZE]->GetFloatValue(), + flStartFade, 1.0/(flMaxDistance-flStartFade), + 0,0 }; + + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, VC0, ARRAYSIZE(VC0)/4 ); + + pShaderAPI->SetDepthFeatheringPixelShaderConstant( 2, params[DEPTHBLENDSCALE]->GetFloatValue() ); + + float C0[4]={ params[ADDBASETEXTURE2]->GetFloatValue(), + params[OVERBRIGHTFACTOR]->GetFloatValue(), + params[ADDSELF]->GetFloatValue(), + 0.0f }; + + if ( bDX8 && ( !bAdditive2ndTexture ) ) // deal with 0..1 limit for pix shader constants + { + C0[2] *= 0.25; + C0[1] *= 0.25; + } + + pShaderAPI->SetPixelShaderConstant( 0, C0, ARRAYSIZE(C0)/4 ); + + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { +#if SUPPORT_DX8 + if ( nSplineType ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( splinecard_vs11 ); + SET_DYNAMIC_VERTEX_SHADER( splinecard_vs11 ); + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( spritecard_vs11 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( ORIENTATION, nOrientation ); + SET_DYNAMIC_VERTEX_SHADER( spritecard_vs11 ); + } +#endif + } + else + { + if ( nSplineType ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( splinecard_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( splinecard_vs20 ); + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( spritecard_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( ORIENTATION, nOrientation ); + SET_DYNAMIC_VERTEX_SHADER( spritecard_vs20 ); + } + } + } + Draw( ); +} +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/spritecard_ps11.fxc b/sp/src/materialsystem/stdshaders/spritecard_ps11.fxc new file mode 100644 index 00000000..624362cb --- /dev/null +++ b/sp/src/materialsystem/stdshaders/spritecard_ps11.fxc @@ -0,0 +1,72 @@ +// STATIC: "ADDBASETEXTURE2" "0..1" +// STATIC: "ADDSELF" "0..1" +// STATIC: "USEALPHAASRGB" "0..1" +// SKIP: $USEALPHAASRGB && $ADDSELF +// SKIP: $USEALPHAASRGB && $ADDBASETEXTURE2 + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; +#if ADDBASETEXTURE2 + float2 texCoord2 : TEXCOORD3; +#endif + float4 vScreenPos : TEXCOORD7; +}; + +sampler BaseTextureSampler : register( s0 ); + +#if ADDBASETEXTURE2 +sampler BaseTextureSampler2 : register( s3 ); +#endif + +sampler BaseTextureSampler1 : register( s1 ); +const float4 g_Parameters : register( c0 ); +const float4 g_ColorPowers : register( c1 ); + +#define fAdditiveBlendWeight g_Parameters.x +#define fOverbrightFactor g_Parameters.y +#define fAdditiveSelfBlendWeight g_Parameters.z +#define fSoftParticleBlendScale g_Parameters.w + +#pragma warning( disable : 4707 4704 ) +float4 main( PS_INPUT i ) : COLOR +{ + // Sample frames from texture 0 +#if ( ! ADDSELF ) && ( ! ADDBASETEXTURE2 ) + float4 baseTex0 = tex2D( BaseTextureSampler, i.texCoord0 ); + float4 baseTex1 = tex2D( BaseTextureSampler1, i.texCoord1 ); + float4 blended_rgb = lerp( baseTex0, baseTex1, i.blendfactor0.x ); +#else + float4 blended_rgb = tex2D( BaseTextureSampler, i.texCoord0 ); +#endif +#if USEALPHAASRGB + blended_rgb.rgb = blended_rgb.a; +#endif + +#if ADDBASETEXTURE2 + blended_rgb.a *= i.argbcolor.a; + + // In this case, we don't really want to pre-multiply by alpha + float4 color2 = tex2D( BaseTextureSampler2, i.texCoord2 ); + blended_rgb.rgb *= blended_rgb.a; + blended_rgb.rgb += fOverbrightFactor * fAdditiveBlendWeight * i.argbcolor.a * color2; + blended_rgb.rgb *= 2 * i.argbcolor.rgb; +#else +#if ADDSELF + blended_rgb.a *= i.argbcolor.a; + blended_rgb.rgb *= blended_rgb.a; + blended_rgb.rgb += fOverbrightFactor * 8 * fAdditiveSelfBlendWeight * blended_rgb; + blended_rgb.rgb *= 2 * i.argbcolor.rgb; +#else + blended_rgb *= i.argbcolor; +#endif +#endif + return blended_rgb; +} + diff --git a/sp/src/materialsystem/stdshaders/spritecard_ps2x.fxc b/sp/src/materialsystem/stdshaders/spritecard_ps2x.fxc new file mode 100644 index 00000000..1281d33a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/spritecard_ps2x.fxc @@ -0,0 +1,194 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "DUALSEQUENCE" "0..1" +// STATIC: "SEQUENCE_BLEND_MODE" "0..2" +// STATIC: "ADDBASETEXTURE2" "0..1" +// STATIC: "MAXLUMFRAMEBLEND1" "0..1" +// STATIC: "MAXLUMFRAMEBLEND2" "0..1" +// STATIC: "EXTRACTGREENALPHA" "0..1" +// STATIC: "COLORRAMP" "0..1" +// STATIC: "ANIMBLEND" "0..1" +// STATIC: "ADDSELF" "0..1" +// STATIC: "DEPTHBLEND" "0..1" [ps20b] + +#define COMBINE_MODE_AVERAGE 0 +#define COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND 1 +#define COMBINE_MODE_USE_FIRST_OVER_SECOND 2 + +#define HDRTYPE HDR_TYPE_NONE +#include "common_ps_fxc.h" + +const float4 g_Parameters : register( c0 ); +const float4 g_DepthFeatheringConstants : register( c2 ); + +#define fAdditiveBlendWeight g_Parameters.x +#define fOverbrightFactor g_Parameters.y +#define fAdditiveSelfBlendWeight g_Parameters.z + +struct PS_INPUT +{ + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; +#if ADDBASETEXTURE2 + float2 texCoord2 : TEXCOORD3; +#endif +#if EXTRACTGREENALPHA + float4 blendfactor1 : TEXCOORD4; +#endif + +#if DUALSEQUENCE + float2 vSeq2TexCoord0 : TEXCOORD5; + float2 vSeq2TexCoord1 : TEXCOORD6; +#endif + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vScreenPos_ReverseZ : TEXCOORD7; +#else + float4 vScreenPos : TEXCOORD7; +#endif +}; + +sampler BaseTextureSampler : register( s0 ); +sampler ColorRampSampler : register( s1 ); +sampler DepthSampler : register( s2 ); + +float4 main( PS_INPUT i ) : COLOR +{ + bool bMaxLumFrameBlend1 = MAXLUMFRAMEBLEND1 ? true : false; + bool bMaxLumFrameBlend2 = MAXLUMFRAMEBLEND2 ? true : false; + bool bExtractGreenAlpha = EXTRACTGREENALPHA ? true : false; + bool bAddBaseTexture2 = ADDBASETEXTURE2 ? true : false; + bool bDualSequence = DUALSEQUENCE ? true : false; + bool bColorRamp = COLORRAMP ? true : false; +#ifdef DEPTHBLEND + bool bDepthBlend = DEPTHBLEND ? true : false; +#endif + int nSequenceBlendMode = SEQUENCE_BLEND_MODE; + + // Sample frames from texture 0 + float4 baseTex0 = tex2D( BaseTextureSampler, i.texCoord0 ); + + float4 baseTex1 = tex2D( BaseTextureSampler, i.texCoord1 ); + + // Blend by default (may override with bMaxLumFrameBlend1 or bExtractGreenAlpha) +#if ANIMBLEND + float4 blended_rgb = lerp( baseTex0, baseTex1, i.blendfactor0.x ); +#else + float4 blended_rgb = baseTex0; +#endif + + if ( bMaxLumFrameBlend1 ) + { + // Blend between animation frames based upon max luminance + float lum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); + float lum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); + + if ( lum0 > lum1 ) + blended_rgb = baseTex0; + else + blended_rgb = baseTex1; + } + else if( bExtractGreenAlpha ) + { +#if EXTRACTGREENALPHA + // Weight Green/Alphas from the two frames for a scalar result + blended_rgb = dot( baseTex0, i.blendfactor0 ) + dot( baseTex1, i.blendfactor1 ); +#endif + } + +#if DUALSEQUENCE + if ( bDualSequence ) + { + baseTex0 = tex2D( BaseTextureSampler, i.vSeq2TexCoord0 ); + baseTex1 = tex2D( BaseTextureSampler, i.vSeq2TexCoord1 ); + + // Blend by default (may override with bMaxLumFrameBlend2) + float4 rgb2 = lerp( baseTex0, baseTex1, i.blendfactor0.z ); + + if ( bMaxLumFrameBlend2 ) + { + // blend between animation frames based upon max luminance + float tlum0 = dot( float3(.3, .59, .11), baseTex0.rgb * (1-i.blendfactor0.x)); + float tlum1 = dot( float3(.3, .59, .11), baseTex1.rgb * i.blendfactor0.x); + + if ( tlum0 > tlum1 ) + rgb2 = baseTex0; + else + rgb2 = baseTex1; + } + + if ( nSequenceBlendMode == COMBINE_MODE_AVERAGE ) + { + blended_rgb = 0.5 * ( blended_rgb + rgb2 ); + } + else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_AS_ALPHA_MASK_ON_SECOND ) + { + blended_rgb.rgb = rgb2.rgb; + } + else if ( nSequenceBlendMode == COMBINE_MODE_USE_FIRST_OVER_SECOND ) + { + blended_rgb.rgb = lerp( blended_rgb.rgb, rgb2.rgb, rgb2.a ); + } + } // bDualSequence +#endif + + // Optional color ramp + if ( bColorRamp ) + { + blended_rgb.rgb = tex2D( ColorRampSampler, float2( blended_rgb.r, blended_rgb.g ) ); + } + + // Overbright + blended_rgb.rgb *= fOverbrightFactor; + + //Soft Particles FTW +# if (DEPTHBLEND == 1) +# if defined( _X360 ) + float fDepthBlend = DepthFeathering( DepthSampler, i.vScreenPos_ReverseZ.xy / i.vScreenPos_ReverseZ.w, i.vScreenPos_ReverseZ.z, i.vScreenPos_ReverseZ.w, g_DepthFeatheringConstants ); +# else + float fDepthBlend = DepthFeathering( DepthSampler, i.vScreenPos.xy / i.vScreenPos.w, i.vScreenPos.z, i.vScreenPos.w, g_DepthFeatheringConstants ); +# endif + i.argbcolor.a *= fDepthBlend; +# endif + + // Premultiply the alpha for a ONE:INVALPHA blend +#if ADDBASETEXTURE2 + if ( bAddBaseTexture2 ) + { + blended_rgb.a *= i.argbcolor.a; + + // In this case, we don't really want to pre-multiply by alpha + if ( !bColorRamp ) + { + blended_rgb.rgb *= blended_rgb.a; + } + + if ( bExtractGreenAlpha ) + { + blended_rgb.rgb += fAdditiveBlendWeight * i.argbcolor.a * blended_rgb.rgb; + } + else + { + blended_rgb.rgb += fOverbrightFactor * fAdditiveBlendWeight * i.argbcolor.a * tex2D( BaseTextureSampler, i.texCoord2 ); + } + + blended_rgb.rgb *= i.argbcolor.rgb; + } + else +#endif + { +#if ADDSELF + blended_rgb.a *= i.argbcolor.a; + blended_rgb.rgb *= blended_rgb.a; + blended_rgb.rgb += fOverbrightFactor * fAdditiveSelfBlendWeight * i.argbcolor.a * blended_rgb; + blended_rgb.rgb *= i.argbcolor.rgb; +#else + blended_rgb *= i.argbcolor; +#endif + } + + return FinalOutput( blended_rgb, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +} + diff --git a/sp/src/materialsystem/stdshaders/spritecard_vsxx.fxc b/sp/src/materialsystem/stdshaders/spritecard_vsxx.fxc new file mode 100644 index 00000000..6f670101 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/spritecard_vsxx.fxc @@ -0,0 +1,347 @@ +// STATIC: "ZOOM_ANIMATE_SEQ2" "0..1" [vs20] +// STATIC: "DUALSEQUENCE" "0..1" [vs20] +// STATIC: "EXTRACTGREENALPHA" "0..1" [vs20] + +// STATIC: "ZOOM_ANIMATE_SEQ2" "0..0" [vs11] +// STATIC: "DUALSEQUENCE" "0..0" [vs11] +// STATIC: "EXTRACTGREENALPHA" "0..0" [vs11] + +// STATIC: "USE_INSTANCING" "0..1" [vs20] +// DYNAMIC: "ORIENTATION" "0..2" + + +#include "common_vs_fxc.h" + +const float4x3 cModelView : register(SHADER_SPECIFIC_CONST_0); +const float4x4 cProj : register(SHADER_SPECIFIC_CONST_3); + +#if ZOOM_ANIMATE_SEQ2 +const float4 ScaleParms : register(SHADER_SPECIFIC_CONST_7); +#define OLDFRM_SCALE_START (ScaleParms.x) +#define OLDFRM_SCALE_END (ScaleParms.y) +#endif + +const float4 SizeParms : register(SHADER_SPECIFIC_CONST_8); +const float4 SizeParms2 : register(SHADER_SPECIFIC_CONST_9); +const float4 ViewportTransformScaled : register(SHADER_SPECIFIC_CONST_10); + +#define MINIMUM_SIZE_FACTOR (SizeParms.x) +#define MAXIMUM_SIZE_FACTOR (SizeParms.y) + +#define START_FADE_SIZE_FACTOR (SizeParms.z) +#define END_FADE_SIZE_FACTOR (SizeParms.w) + +// alpha fade w/ distance +#define START_FAR_FADE ( SizeParms2.x ) +#define FAR_FADE_FACTOR ( SizeParms2.y ) // alpha = 1-min(1,max(0, (dist-start_fade)*factor)) + +// Define stuff for instancing on 360 +#if ( defined( _X360 ) && defined( SHADER_MODEL_VS_2_0 ) ) +#define CONST_PC +#define VERTEX_INDEX_PARAM_360 ,int Index:INDEX +#define DO_INSTANCING 1 +#else +#define CONST_PC const +#define VERTEX_INDEX_PARAM_360 +#endif + + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vTint : COLOR; + float4 vPos : POSITION; + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vParms : TEXCOORD2; // frame blend, rot, radius, yaw + // FIXME: remove this vertex element for (USE_INSTANCING == 1), need to shuffle the following elements down + float2 vCornerID : TEXCOORD3; // 0,0 1,0 1,1 0,1 + float4 vTexCoord2 : TEXCOORD4; +#if DUALSEQUENCE + float4 vSeq2TexCoord0 : TEXCOORD5; + float4 vSeq2TexCoord1 : TEXCOORD6; + float4 vParms1 : TEXCOORD7; // second frame blend, ?,?,? +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; + + float2 texCoord0 : TEXCOORD0; + float2 texCoord1 : TEXCOORD1; + float4 argbcolor : COLOR; + float4 blendfactor0 : TEXCOORD2; + float2 texCoord2 : TEXCOORD3; +#if !defined( SHADER_MODEL_VS_1_1 ) + float4 blendfactor1 : TEXCOORD4; // for extracting green/alpha +#endif +#if DUALSEQUENCE + float2 vSeq2TexCoord0 : TEXCOORD5; + float2 vSeq2TexCoord1 : TEXCOORD6; +#endif + +#if defined( _X360 ) + float4 vScreenPos_ReverseZ : TEXCOORD7; +#else + float4 vScreenPos : TEXCOORD7; +#endif +}; + +#define BLENDFACTOR v.vParms.x +#define ROTATION v.vParms.y +#define RADIUS v.vParms.z +#define YAW (v.vParms.w) + +#if ( ZOOM_ANIMATE_SEQ2 ) +float getlerpscaled( float l_in, float s0, float s1, float ts ) +{ + l_in = 2.0*(l_in-.5); + l_in *= lerp(s0,s1,ts); + return 0.5+0.5*l_in; +} + +float getlerpscale_for_old_frame( float l_in, float ts ) +{ + return getlerpscaled( l_in, OLDFRM_SCALE_START, OLDFRM_SCALE_END, ts); +} + +float getlerpscale_for_new_frame( float l_in, float ts ) +{ + return getlerpscaled( l_in, 1.0, OLDFRM_SCALE_START, ts ); +} +#endif // ZOOM_ANIMATE_SEQ2 + +#ifdef DO_INSTANCING +void InstancedVertexRead( inout VS_INPUT v, int index ) +{ + // Duplicate each VB vertex 4 times (and generate vCornerID - the only thing that varies per-corner) + float4 vTint; + float4 vPos; + float4 vTexCoord0; + float4 vTexCoord1; + float4 vParms; + float4 vTexCoord2; + float4 vSeq_TexCoord0; // NOTE: April XDK compiler barfs on var names which have a number in the middle! (i.e. vSeq2TexCoord0) + float4 vSeq_TexCoord1; + float4 vParms1; + + int spriteIndex = index / 4; + int cornerIndex = index - 4*spriteIndex; + asm + { + vfetch vTint, spriteIndex, color0; + vfetch vPos, spriteIndex, position0; + vfetch vTexCoord0, spriteIndex, texcoord0; + vfetch vTexCoord1, spriteIndex, texcoord1; + vfetch vParms, spriteIndex, texcoord2; + vfetch vTexCoord2, spriteIndex, texcoord4; +#if DUALSEQUENCE + vfetch vSeq_TexCoord0, spriteIndex, texcoord5; + vfetch vSeq_TexCoord1, spriteIndex, texcoord6; + vfetch vParms1, spriteIndex, texcoord7; +#endif + }; + + v.vTint = vTint; + v.vPos = vPos; + v.vTexCoord0 = vTexCoord0; + v.vTexCoord1 = vTexCoord1; + v.vParms = vParms; + v.vTexCoord2 = vTexCoord2; +#if DUALSEQUENCE + v.vSeq2TexCoord0 = vSeq_TexCoord0; + v.vSeq2TexCoord1 = vSeq_TexCoord1; + v.vParms1 = vParms1; +#endif + + // Compute vCornerID - order is: (0,0) (1,0) (1,1) (0,1) + // float2 IDs[4] = { {0,0}, {1,0}, {1,1}, {0,1} }; + // v.vCornerID.xy = IDs[ cornerIndex ]; + // This compiles to 2 ops on 360 (MADDs with abs/sat register read/write modifiers): + v.vCornerID.xy = float2( 1.5f, 0.0f ) + cornerIndex*float2( -1.0f, 1.0f ); + v.vCornerID.xy = saturate( float2(1.5f, -3.0f) + float2( -1.0f, 2.0f )*abs( v.vCornerID.xy ) ); +} +#endif + +VS_OUTPUT main( CONST_PC VS_INPUT v + VERTEX_INDEX_PARAM_360 ) +{ + VS_OUTPUT o; + +#ifdef DO_INSTANCING + if ( USE_INSTANCING ) + { + InstancedVertexRead( v, Index ); + } +#endif + +#if SHADER_MODEL_VS_1_1 + float4 tint = v.vTint; +#else + float4 tint = GammaToLinear( v.vTint ); +#endif + + float2 sc_yaw; + sincos( YAW, sc_yaw.y, sc_yaw.x ); + + float2 sc; + sincos( ROTATION, sc.y, sc.x ); + + float2 ix=2*v.vCornerID.xy-1; + float x1=dot(ix,sc); + float y1=sc.x*ix.y-sc.y*ix.x; + + float4 projPos; + float3 worldPos; + worldPos = mul4x3( v.vPos, cModel[0] ); + + float rad = RADIUS; + float3 v2p = ( worldPos - cEyePos ); + float l = length(v2p); + rad=max(rad, MINIMUM_SIZE_FACTOR * l); + // now, perform fade out +#ifndef SHADER_MODEL_VS_1_1 + if ( rad > START_FADE_SIZE_FACTOR * l ) + { + if ( rad > END_FADE_SIZE_FACTOR *l ) + { + tint = 0; + rad = 0; // cull so we emit 0-sized sprite + } + else + { + tint *= 1-(rad-START_FADE_SIZE_FACTOR*l)/(END_FADE_SIZE_FACTOR*l-START_FADE_SIZE_FACTOR*l); + } + } +#endif + + +#ifndef SHADER_MODEL_VS_1_1 + // perform far fade + float tscale = 1-min(1, max(0, (l-START_FAR_FADE)*FAR_FADE_FACTOR) ); + tint *= tscale; + + if ( tscale <= 0) + rad = 0; // cull so we emit 0-sized sprite +#endif + + rad=min(rad, MAXIMUM_SIZE_FACTOR * l); + +#if ORIENTATION == 0 + // Screen-aligned case + float3 viewPos; + viewPos = mul4x3( v.vPos, cModelView ); + + float3 disp=float3( -x1,y1,0); + float tmpx=disp.x*sc_yaw.x+disp.z*sc_yaw.y; + disp.z = disp.z*sc_yaw.x-disp.x*sc_yaw.y; + disp.x=tmpx; + + viewPos.xyz += disp * rad; + + projPos = mul( float4(viewPos, 1.0f), cProj ); +#endif + +#if ORIENTATION == 1 + // Z-aligned case + if (l > rad/2) + { + float3 up = float3(0,0,1); + float3 right = normalize(cross(up, v2p)); + float tmpx=right.x*sc_yaw.x+right.y*sc_yaw.y; + right.y = right.y*sc_yaw.x-right.x*sc_yaw.y; + right.x=tmpx; + + worldPos += (x1*rad)*right; + worldPos.z += (y1*rad)*up.z; + +#ifndef SHADER_MODEL_VS_1_1 + if (l < rad*2 ) + { + tint *= smoothstep(rad/2,rad,l); + } +#endif + + } + projPos = mul( float4(worldPos, 1.0f), cViewProj ); +#endif + +#if ORIENTATION == 2 + // aligned with z plane case - easy + float3 wpos=v.vPos+RADIUS*float3( y1,x1,0); + projPos = mul( float4(wpos, 1.0f), cModelViewProj ); +#endif + + o.blendfactor0 = float4( v.vParms.x, 0, 0, 0 ); + o.projPos = projPos; + o.texCoord0.x = lerp( v.vTexCoord0.z, v.vTexCoord0.x, v.vCornerID.x ); + o.texCoord0.y = lerp( v.vTexCoord0.w, v.vTexCoord0.y, v.vCornerID.y ); + o.texCoord1.x = lerp( v.vTexCoord1.z, v.vTexCoord1.x, v.vCornerID.x ); + o.texCoord1.y = lerp( v.vTexCoord1.w, v.vTexCoord1.y, v.vCornerID.y ); + o.texCoord2.x = lerp( v.vTexCoord2.z, v.vTexCoord2.x, v.vCornerID.x ); + o.texCoord2.y = lerp( v.vTexCoord2.w, v.vTexCoord2.y, v.vCornerID.y ); + +#if ( DUALSEQUENCE ) + float2 lerpold = v.vCornerID.xy; + float2 lerpnew = v.vCornerID.xy; + +#if ( ZOOM_ANIMATE_SEQ2 ) + lerpold.x = getlerpscale_for_old_frame( v.vCornerID.x, v.vParms1.x ); + lerpold.y = getlerpscale_for_old_frame( v.vCornerID.y, v.vParms1.x ); + lerpnew.x = getlerpscale_for_new_frame( v.vCornerID.x, v.vParms1.x ); + lerpnew.y = getlerpscale_for_new_frame( v.vCornerID.y, v.vParms1.x ); +#endif + + o.vSeq2TexCoord0.xy = lerp( v.vSeq2TexCoord0.zw, v.vSeq2TexCoord0.xy, lerpold.xy ); + o.vSeq2TexCoord1.xy = lerp( v.vSeq2TexCoord1.zw, v.vSeq2TexCoord1.xy, lerpnew.xy ); + + o.blendfactor0.z = v.vParms1.x; +#endif + + +#if !defined( SHADER_MODEL_VS_1_1 ) + + o.blendfactor1 = float4( 0.0f, 0.0f, 0.0f, 0.0f ); + +#if ( EXTRACTGREENALPHA ) + // Input range Output range + if ( v.vParms.x < 0.25f ) // 0.0 .. 0.25 + { + o.blendfactor0.a = v.vParms.x * 2 + 0.5f; // 0.5 .. 1.0 + o.blendfactor0.g = 1 - o.blendfactor0.a; // 0.5 .. 0.0 + } + else if ( v.vParms.x < 0.75f ) // 0.25 .. 0.75 + { + o.blendfactor1.g = v.vParms.x * 2 - 0.5f; // 0.0 .. 1.0 + o.blendfactor0.a = 1 - o.blendfactor1.g; // 1.0 .. 0.0 + } + else // 0.75 .. 1.0 + { + o.blendfactor1.a = v.vParms.x * 2 - 1.5f; // 0.0 .. 0.5 + o.blendfactor1.g = 1 - o.blendfactor1.a; // 1.0 .. 0.5 + } +#endif + +#endif + + // Map projected position to the refraction texture + float2 vScreenPos; + vScreenPos.x = projPos.x; + vScreenPos.y = -projPos.y; // invert Y + vScreenPos = (vScreenPos + projPos.w) * 0.5f; + + // Need to also account for the viewport transform, which matters when rendering with mat_viewportscale != 1.0 + vScreenPos = (vScreenPos * ViewportTransformScaled.xy) + (projPos.w * ViewportTransformScaled.zw); + +#if defined( _X360 ) + o.vScreenPos_ReverseZ = float4(vScreenPos.x, vScreenPos.y, projPos.w - projPos.z, projPos.w ); +#else + o.vScreenPos = float4(vScreenPos.x, vScreenPos.y, projPos.z, projPos.w ); +#endif + + o.argbcolor = tint; + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/teeth.cpp b/sp/src/materialsystem/stdshaders/teeth.cpp new file mode 100644 index 00000000..a3168822 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/teeth.cpp @@ -0,0 +1,578 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "BaseVSShader.h" +#include "cpp_shader_constant_register_map.h" + +#include "teeth_vs20.inc" +#include "teeth_flashlight_vs20.inc" +#include "teeth_bump_vs20.inc" +#include "teeth_ps20.inc" +#include "teeth_ps20b.inc" +#include "teeth_flashlight_ps20.inc" +#include "teeth_flashlight_ps20b.inc" +#include "teeth_bump_ps20.inc" +#include "teeth_bump_ps20b.inc" + +#ifndef _X360 +#include "teeth_vs30.inc" +#include "teeth_ps30.inc" +#include "teeth_bump_vs30.inc" +#include "teeth_bump_ps30.inc" +#include "teeth_flashlight_vs30.inc" +#include "teeth_flashlight_ps30.inc" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX9 ) + +extern ConVar r_flashlight_version2; +BEGIN_VS_SHADER( Teeth_DX9, "Help for Teeth_DX9" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" ) + SHADER_PARAM( FORWARD, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Forward direction vector for teeth lighting" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "100", "phong exponent" ) + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is teeth in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[INTRO]->IsDefined() ) + { + params[INTRO]->SetIntValue( 0 ); + } + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pConfig->bSoftwareLighting ) + { + return "Teeth_dx8"; + } + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + + if( params[BUMPMAP]->IsDefined() ) + { + LoadTexture( BUMPMAP ); + } + } + + void DrawUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, VertexCompressionType_t vertexCompression ) + { + bool hasBump = params[BUMPMAP]->IsTexture(); + + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base map + + int flags = VERTEX_POSITION | VERTEX_NORMAL; + int nTexCoordCount = 1; + int userDataSize = 0; + + if ( hasBump ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Bump map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Normalization sampler for per-pixel lighting + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, false ); + userDataSize = 4; // tangent S + } + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + if ( hasBump ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( teeth_bump_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( teeth_bump_vs20 ); + + // ps_2_b version which does phong + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps20b ); + SET_STATIC_PIXEL_SHADER( teeth_bump_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps20 ); + SET_STATIC_PIXEL_SHADER( teeth_bump_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( teeth_bump_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( teeth_bump_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( teeth_bump_ps30 ); + SET_STATIC_PIXEL_SHADER( teeth_bump_ps30 ); + } +#endif + } + else + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( teeth_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( teeth_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( teeth_ps20b ); + SET_STATIC_PIXEL_SHADER( teeth_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( teeth_ps20 ); + SET_STATIC_PIXEL_SHADER( teeth_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( teeth_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( teeth_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( teeth_ps30 ); + SET_STATIC_PIXEL_SHADER( teeth_ps30 ); + } +#endif + } + + // On DX9, do sRGB + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBWrite( true ); + + FogToFogColor(); + + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + if ( hasBump ) + { + BindTexture( SHADER_SAMPLER1, BUMPMAP ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE ); + pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY ); + + Vector4D lighting; + params[FORWARD]->GetVecValue( lighting.Base(), 3 ); + lighting[3] = params[ILLUMFACTOR]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() ); + + LightState_t lightState; + pShaderAPI->GetDX9LightState( &lightState ); + + pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); + + float vEyePos_SpecExponent[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent ); + vEyePos_SpecExponent[3] = 0.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 ); + + if ( hasBump ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs20 ); + + // ps_2_b version which does Phong + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + Vector4D vSpecExponent; + vSpecExponent[3] = params[PHONGEXPONENT]->GetFloatValue(); + + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vSpecExponent.Base(), 1 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps20 ); + } + } +#ifndef _X360 + else + { + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( teeth_bump_vs30 ); + + Vector4D vSpecExponent; + vSpecExponent[3] = params[PHONGEXPONENT]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vSpecExponent.Base(), 1 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_bump_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_bump_ps30 ); + } +#endif + } + else + { + // For non-bumped case, ambient cube is computed in the vertex shader + SetAmbientCubeDynamicStateVertexShader(); + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER( teeth_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_ps20 ); + } + } +#ifndef _X360 + else + { + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( teeth_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_ps30 ); + } +#endif + } + + if( params[INTRO]->GetIntValue() ) + { + float curTime = params[WARPPARAM]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + Assert( params[ENTITYORIGIN]->IsDefined() ); + params[ENTITYORIGIN]->GetVecValue( timeVec, 3 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, timeVec, 1 ); + } + } + Draw(); + } + + void DrawFlashlight( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, VertexCompressionType_t vertexCompression ) + { + SHADOW_STATE + { + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base map + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Flashlight spot + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + + // Additive blend the teeth, lit by the flashlight + s_pShaderShadow->EnableAlphaTest( false ); + s_pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + s_pShaderShadow->EnableBlending( true ); + + // Set stream format (note that this shader supports compression) + int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + int nShadowFilterMode = 0; + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // shadow depth map + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER2 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // shadow noise + + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_STATIC_VERTEX_SHADER( teeth_flashlight_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( teeth_flashlight_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps20 ); + SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( INTRO, params[INTRO]->GetIntValue() ? 1 : 0 ); + SET_STATIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( teeth_flashlight_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( teeth_flashlight_ps30 ); + } +#endif + // On DX9, do sRGB + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBWrite( true ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + + // State for spotlight projection, attenuation etc + SetFlashlightVertexShaderConstants( false, -1, false, -1, true ); + + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + bool bFlashlightShadows = g_pHardwareConfig->SupportsPixelShaders_2_b() ? state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) : false; + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + BindTexture( SHADER_SAMPLER2, pFlashlightDepthTexture, 0 ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_SHADOW_NOISE_2D ); + } + + Vector4D lighting; + params[FORWARD]->GetVecValue( lighting.Base(), 3 ); + lighting[3] = params[ILLUMFACTOR]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, lighting.Base() ); + + float atten[4], pos[4], tweaks[4]; + + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR ); + + BindTexture( SHADER_SAMPLER1, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); + + pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); // steps on rim boost + + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); + + // Tweaks associated with a given flashlight + tweaks[0] = ShadowFilterFromState( flashlightState ); + tweaks[1] = ShadowAttenFromState( flashlightState ); + HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); + + float vFlashlightPos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( vFlashlightPos ); + pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, vFlashlightPos, 1 ); + + if ( IsX360() ) + { + pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps20 ); + } + } +#ifndef _X360 + else + { + SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( teeth_flashlight_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( teeth_flashlight_ps30 ); + } +#endif + + if( params[INTRO]->GetIntValue() ) + { + float curTime = params[WARPPARAM]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + Assert( params[ENTITYORIGIN]->IsDefined() ); + params[ENTITYORIGIN]->GetVecValue( timeVec, 3 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_9, timeVec, 1 ); + } + } + Draw(); + } + + SHADER_DRAW + { + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + bool hasFlashlight = UsingFlashlight( params ); + if ( !hasFlashlight || ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + DrawUsingVertexShader( params, pShaderAPI, pShaderShadow, vertexCompression ); + SHADOW_STATE + { + SetInitialShadowState(); + } + } + if( hasFlashlight ) + { + DrawFlashlight( params, pShaderAPI, pShaderShadow, vertexCompression ); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/teeth_bump_ps2x.fxc b/sp/src/materialsystem/stdshaders/teeth_bump_ps2x.fxc new file mode 100644 index 00000000..72e43a10 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/teeth_bump_ps2x.fxc @@ -0,0 +1,101 @@ +//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "shader_constant_register_map.h" + +const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); +PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total + +sampler BaseTextureSampler : register( s0 ); +sampler BumpTextureSampler : register( s1 ); +sampler NormalizeSampler : register( s2 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float4 worldVertToEyeVector_Darkening : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + // second row : TEXCOORD3; + // third row : TEXCOORD4; + float4 worldPos_projPosZ : TEXCOORD5; + float2 lightAtten01 : TEXCOORD6; + float2 lightAtten23 : TEXCOORD7; +}; + + + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + +#define worldVertToEyeVector i.worldVertToEyeVector_Darkening.xyz +#define fDarkening i.worldVertToEyeVector_Darkening.w + +#endif + + + +float4 main( PS_INPUT i ) : COLOR +{ + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + int nNumLights = NUM_LIGHTS; + + float4 vLightAtten = float4( i.lightAtten01, i.lightAtten23 ); + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + + float3 worldSpaceNormal, tangentSpaceNormal = float3(0, 0, 1); + float fSpecExp = g_EyePos_SpecExponent.w; + + float4 normalTexel = tex2D( BumpTextureSampler, i.baseTexCoord ); + tangentSpaceNormal = 2.0f * normalTexel.xyz - 1.0f; + worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) ); + + // If the exponent passed in as a constant is zero, use the value from the map as the exponent + if ( fSpecExp == 0 ) + fSpecExp = 1.0f * ( 1.0f - normalTexel.w ) + 150.0f * normalTexel.w; + + // Summation of diffuse illumination from all local lights + float3 diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, + bAmbientLight, vLightAtten, + cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, true, + false, 0, false, NormalizeSampler ); + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + + float3 vDummy, specularLighting; + + // Summation of specular from all local lights + PixelShaderDoSpecularLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, fSpecExp, normalize(worldVertToEyeVector), + vLightAtten, nNumLights, cLightInfo, + false, 1.0f, false, NormalizeSampler, 1.0f, false, 1.0f, + + // Outputs + specularLighting, vDummy ); + + // Specular plus diffuse, all darkened as a function of mouth openness + float3 result = (specularLighting * baseSample.a + baseSample.rgb * diffuseLighting) * fDarkening; + +#else + float3 result = baseSample.rgb * diffuseLighting * i.worldVertToEyeVector_Darkening.w; +#endif + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( float4(result, 1.0f), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/sp/src/materialsystem/stdshaders/teeth_bump_vs20.fxc b/sp/src/materialsystem/stdshaders/teeth_bump_vs20.fxc new file mode 100644 index 00000000..1dd834b5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/teeth_bump_vs20.fxc @@ -0,0 +1,152 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== + +// STATIC: "INTRO" "0..1" +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "vortwarp_vs20_helper.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_0 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_1 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float2 vTexCoord0 : TEXCOORD0; + float4 vUserData : TANGENT; // Sign for cross product in w + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 baseTexCoord : TEXCOORD0; + float4 worldVertToEyeVector_Darkening : TEXCOORD1; + float3x3 tangentSpaceTranspose : TEXCOORD2; + // second row : TEXCOORD3; + // third row : TEXCOORD4; + float4 worldPos_projPosZ : TEXCOORD5; + float2 lightAtten01 : TEXCOORD6; + float2 lightAtten23 : TEXCOORD7; +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), + vPosition.xyz, vNormal, vTangent.xyz ); +#endif + + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, worldPos, + worldNormal, worldTangentS, worldTangentT ); + +#if INTRO + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, worldTangentS, worldTangentT ); +#endif + + // Always normalize since flex path is controlled by runtime + // constant not a shader combo and will always generate the normalization + worldNormal = normalize( worldNormal ); + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, vProjPos, g_FogType ); +#endif + // Needed for specular + o.worldVertToEyeVector_Darkening.xyz = cEyePos - worldPos; + + // Special darkening of lights for mouth open/close + o.worldVertToEyeVector_Darkening.w = cTeethLighting.w * saturate( dot( worldNormal, cTeethLighting.xyz ) );; + + // Scalar light attenuation (mouth darkening applied in pixel shader) +#if defined( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) + o.lightAtten01.xy = float2(0,0); + o.lightAtten23.xy = float2(0,0); + #if ( NUM_LIGHTS > 0 ) + o.lightAtten01.x = GetVertexAttenForLight( worldPos, 0, false ); + #endif + #if ( NUM_LIGHTS > 1 ) + o.lightAtten01.y = GetVertexAttenForLight( worldPos, 1, false ); + #endif + #if ( NUM_LIGHTS > 2 ) + o.lightAtten23.x = GetVertexAttenForLight( worldPos, 2, false ); + #endif + #if ( NUM_LIGHTS > 3 ) + o.lightAtten23.y = GetVertexAttenForLight( worldPos, 3, false ); + #endif +#else + o.lightAtten01.x = GetVertexAttenForLight( worldPos, 0, true ); + o.lightAtten01.y = GetVertexAttenForLight( worldPos, 1, true ); + o.lightAtten23.x = GetVertexAttenForLight( worldPos, 2, true ); + o.lightAtten23.y = GetVertexAttenForLight( worldPos, 3, true ); +#endif + + o.baseTexCoord = v.vTexCoord0; + + // Tangent space transform + o.tangentSpaceTranspose[0] = float3( worldTangentS.x, worldTangentT.x, worldNormal.x ); + o.tangentSpaceTranspose[1] = float3( worldTangentS.y, worldTangentT.y, worldNormal.y ); + o.tangentSpaceTranspose[2] = float3( worldTangentS.z, worldTangentT.z, worldNormal.z ); + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/teeth_dx6.cpp b/sp/src/materialsystem/stdshaders/teeth_dx6.cpp new file mode 100644 index 00000000..8c097f6a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/teeth_dx6.cpp @@ -0,0 +1,69 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "BaseVSShader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX6 ) + +BEGIN_VS_SHADER( Teeth_DX6, + "Help for Teeth_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" ) + SHADER_PARAM( FORWARD, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Forward direction vector for teeth lighting" ) + 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 ); + } + + void DrawUsingSoftwareLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + 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(); + } + + SHADER_DRAW + { + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + bool hasFlashlight = UsingFlashlight( params ); + + if( hasFlashlight ) + { + DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + } + else + { + DrawUsingSoftwareLighting( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/teeth_dx8.cpp b/sp/src/materialsystem/stdshaders/teeth_dx8.cpp new file mode 100644 index 00000000..d91626d8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/teeth_dx8.cpp @@ -0,0 +1,116 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "BaseVSShader.h" + +#include "teeth.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Teeth, Teeth_DX8 ) + +BEGIN_VS_SHADER( Teeth_DX8, "Help for Teeth_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ILLUMFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "Amount to darken or brighten the teeth" ) + SHADER_PARAM( FORWARD, SHADER_PARAM_TYPE_VEC3, "[1 0 0]", "Forward direction vector for teeth lighting" ) + SHADER_PARAM( INTRO, SHADER_PARAM_TYPE_BOOL, "0", "is teeth in the ep1 intro" ) + SHADER_PARAM( ENTITYORIGIN, SHADER_PARAM_TYPE_VEC3,"0.0","center if the model in world space" ) + SHADER_PARAM( WARPPARAM, SHADER_PARAM_TYPE_FLOAT,"0.0","animation param between 0 and 1" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[INTRO]->IsDefined() ) + { + params[INTRO]->SetIntValue( 0 ); + } + } + + SHADER_FALLBACK + { + if ( IsPC() && ( g_pHardwareConfig->GetDXSupportLevel() < 80 || g_pConfig->bSoftwareLighting ) ) + { + return "Teeth_dx6"; + } + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + LoadTexture( BASETEXTURE ); + } + + void DrawUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_NORMAL, 1, 0, 0 ); + teeth_Static_Index vshIndex; + vshIndex.SetHALF_LAMBERT( IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + vshIndex.SetINTRO( params[INTRO]->GetIntValue() != 0 ); + pShaderShadow->SetVertexShader( "Teeth", vshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( "VertexLitTexture_Overbright2" ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetAmbientCubeDynamicStateVertexShader(); + + Vector4D lighting; + params[FORWARD]->GetVecValue( lighting.Base(), 3 ); + lighting[3] = params[ILLUMFACTOR]->GetFloatValue(); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() ); + + teeth_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetLIGHT_COMBO( pShaderAPI->GetCurrentLightCombo() ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if( params[INTRO]->GetIntValue() ) + { + float curTime = params[WARPPARAM]->GetFloatValue(); + float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; + Assert( params[ENTITYORIGIN]->IsDefined() ); + params[ENTITYORIGIN]->GetVecValue( timeVec, 3 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, timeVec, 1 ); + } + } + Draw(); + } + + SHADER_DRAW + { + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + bool hasFlashlight = UsingFlashlight( params ); + if( hasFlashlight ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, false, -1, -1, -1, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, false, false, 0, -1, -1, + // Optional parameters, specific to teeth: + true, FORWARD, ILLUMFACTOR ); + } + else + { + DrawUsingVertexShader( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc b/sp/src/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc new file mode 100644 index 00000000..7ef61872 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc @@ -0,0 +1,66 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +#include "common_flashlight_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); +sampler SpotSampler : register( s1 ); +sampler FlashlightDepthSampler : register( s2 ); +sampler RandomRotationSampler : register( s3 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float3 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT ); +const float3 g_FlashlightPos : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST ); +const float4 g_FlashlightAtten : register( PSREG_FLASHLIGHT_ATTENUATION ); +const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE ); +const float4 g_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; // Base texture coordinates + float4 spotTexCoord : TEXCOORD1; // Spotlight texture coordinates + float3 vertAtten : TEXCOORD2; // Distance/spot attenuation + float4 projPos : TEXCOORD3; // Projective space position + float3 worldPos : TEXCOORD4; // Necessary for pixel fog +}; + +float4 main( PS_INPUT i ) : COLOR +{ +#if defined( SHADER_MODEL_PS_2_0 ) + float3 result = tex2Dproj( SpotSampler, i.spotTexCoord.xyzw ); +#else + float3 vProjCoords = i.spotTexCoord.xyz / i.spotTexCoord.w; + float3 result = tex2D( SpotSampler, vProjCoords ); +#endif + + result *= cFlashlightColor.rgb; + +#if FLASHLIGHTSHADOWS && ( defined( SHADER_MODEL_PS_2_B ) || defined( SHADER_MODEL_PS_3_0 ) ) + result *= DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, i.projPos.xy / i.projPos.z, FLASHLIGHTDEPTHFILTERMODE, g_ShadowTweaks, true ); +#endif + result *= 0.35f; // Without this, unshadowed teeth always seem to glow + + result *= i.vertAtten; // Distance atten, NdotL and forward vector + + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + result *= baseSample.rgb; // Multiply by base map and diffuse + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos.z, i.projPos.z ); + return FinalOutput( float4( result, baseSample.a ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR ); +} + diff --git a/sp/src/materialsystem/stdshaders/teeth_flashlight_vs20.fxc b/sp/src/materialsystem/stdshaders/teeth_flashlight_vs20.fxc new file mode 100644 index 00000000..8c5ce4c5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/teeth_flashlight_vs20.fxc @@ -0,0 +1,149 @@ +//======= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "INTRO" "0..1" + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] + +#include "vortwarp_vs20_helper.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cFlashlightPosition : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cSpotlightProj1 : register( SHADER_SPECIFIC_CONST_1 ); +const float4 cSpotlightProj2 : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cSpotlightProj3 : register( SHADER_SPECIFIC_CONST_3 ); +const float4 cSpotlightProj4 : register( SHADER_SPECIFIC_CONST_4 ); +const float4 cFlashlighAtten : register( SHADER_SPECIFIC_CONST_5 ); // const, linear, quadratic & farZ + +const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_8 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_9 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float2 vTexCoord0 : TEXCOORD0; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 baseTexCoord : TEXCOORD0; // Base texture coordinates + float4 spotTexCoord : TEXCOORD1; // Spotlight texture coordinates + float3 vertAtten : TEXCOORD2; // Distance/spot attenuation + float4 vProjPos : TEXCOORD3; // Projective space position + float3 worldPos : TEXCOORD4; // Necessary for pixel fog +}; + + +float RemapValClamped_01( float val, float A, float B ) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + return cVal; +} + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + DecompressVertex_Normal( v.vNormal, vNormal ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); +#endif + + // Normalize the flexed normal + vNormal.xyz = normalize( vNormal.xyz ); + + // Transform the position + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, vPosition, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + +#if INTRO + float3 dummy = float3( 0.0f, 0.0f, 0.0f ); + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, dummy, dummy ); +#endif + + // Transform into projection space + o.projPos = mul( float4( worldPos, 1 ), cViewProj ); + o.worldPos = worldPos.xyz; + o.vProjPos = o.projPos; +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, o.projPos, g_FogType ); +#endif + // Spotlight texture coordinates + o.spotTexCoord.x = dot( cSpotlightProj1, float4(worldPos, 1) ); + o.spotTexCoord.y = dot( cSpotlightProj2, float4(worldPos, 1) ); + o.spotTexCoord.z = dot( cSpotlightProj3, float4(worldPos, 1) ); + o.spotTexCoord.w = dot( cSpotlightProj4, float4(worldPos, 1) ); + + // Compute vector to light + float3 vWorldPosToLightVector = cFlashlightPosition.xyz - worldPos; + + float3 vDistAtten = float3(1, 1, 1); + vDistAtten.z = dot( vWorldPosToLightVector, vWorldPosToLightVector ); + vDistAtten.y = rsqrt( vDistAtten.z ); + + float flDist = vDistAtten.z * vDistAtten.y; // Distance to light + vDistAtten.z = 1.0f / vDistAtten.z; // 1 / distsquared + + float fFarZ = cFlashlighAtten.w; + + float NdotL = saturate( dot( worldNormal, normalize( vWorldPosToLightVector ) ) ); + + float endFalloffFactor = RemapValClamped_01( flDist, fFarZ, 0.6 * fFarZ ); + o.vertAtten.xyz = endFalloffFactor * dot( vDistAtten, cFlashlighAtten.xyz ); + + // Final attenuation from flashlight only... + float linearAtten = NdotL * dot( vDistAtten, cFlashlighAtten.xyz ) * endFalloffFactor; + + // Forward vector + float3 vForward = cTeethLighting.xyz; + float fIllumFactor = cTeethLighting.w; + + // Modulate flashlight by mouth darkening + o.vertAtten = linearAtten * fIllumFactor * saturate( dot( worldNormal, vForward ) ); + + o.baseTexCoord = v.vTexCoord0; + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/teeth_ps2x.fxc b/sp/src/materialsystem/stdshaders/teeth_ps2x.fxc new file mode 100644 index 00000000..4893f9aa --- /dev/null +++ b/sp/src/materialsystem/stdshaders/teeth_ps2x.fxc @@ -0,0 +1,48 @@ +//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps30] + + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "common_ps_fxc.h" +#include "shader_constant_register_map.h" + +sampler BaseTextureSampler : register( s0 ); + +const float4 g_FogParams : register( PSREG_FOG_PARAMS ); +const float4 g_EyePos_SpecExponent : register( PSREG_EYEPOS_SPEC_EXPONENT ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + float3 vertAtten : TEXCOORD1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord ); + + float4 result; + result.xyz = baseSample.xyz * i.vertAtten; + result.a = baseSample.a; + + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + return FinalOutput( result, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} diff --git a/sp/src/materialsystem/stdshaders/teeth_vs20.fxc b/sp/src/materialsystem/stdshaders/teeth_vs20.fxc new file mode 100644 index 00000000..9a9ab045 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/teeth_vs20.fxc @@ -0,0 +1,127 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== + +// STATIC: "INTRO" "0..1" +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "vortwarp_vs20_helper.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cTeethLighting : register( SHADER_SPECIFIC_CONST_0 ); +#if INTRO +const float4 const4 : register( SHADER_SPECIFIC_CONST_1 ); +#define g_Time const4.w +#define modelOrigin const4.xyz +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_6 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_7 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float2 vTexCoord0 : TEXCOORD0; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + float2 baseTexCoord : TEXCOORD0; + float3 vertAtten : TEXCOORD1; + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + + float4 vPosition = v.vPos; + float3 vNormal; + DecompressVertex_Normal( v.vNormal, vNormal ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, v.vVertexID, float3( 0, 0, 0 ), vPosition.xyz, vNormal ); +#endif + + // Normalize the flexed normal + vNormal.xyz = normalize( vNormal.xyz ); + + // Transform the position + float3 worldPos, worldNormal; + SkinPositionAndNormal( g_bSkinning, vPosition, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal ); + +#if INTRO + float3 dummy = float3( 0.0f, 0.0f, 0.0f ); + WorldSpaceVertexProcess( g_Time, modelOrigin, worldPos, worldNormal, dummy, dummy ); +#endif + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); +#if !defined( _X360 ) + // Set fixed-function fog factor + o.fog = CalcFog( worldPos, vProjPos, g_FogType ); +#endif + + // Compute lighting +#if ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) + float3 linearColor = DoLighting( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, false ); +#else + float3 linearColor = DoLightingUnrolled( worldPos, worldNormal, float3(0.0f, 0.0f, 0.0f), bStaticLight, bDynamicLight, false, NUM_LIGHTS ); +#endif + + // Forward vector + float3 vForward = cTeethLighting.xyz; + float fIllumFactor = cTeethLighting.w; + + // Darken by forward dot normal and illumination factor + linearColor *= fIllumFactor * saturate( dot( worldNormal, vForward ) ); + + o.vertAtten = linearColor; + o.baseTexCoord = v.vTexCoord0; + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh b/sp/src/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh new file mode 100644 index 00000000..8f9139df --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh @@ -0,0 +1,24 @@ +ps.1.1 +def c0,0,0,0,.1 +def c1,0,0,0,.1 +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +; tc3 - detail texcoords +; +; c3 = outline color +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t3 ; detail mask + +mul r1,t0,t3 ; multiply + +mov r0.rgb, c3 ; color = outline color +;add r0.a, r1.a, c0.a +;cnd r0.rgb, r0.a, r0, r1 ; if ( alpha+c0 > 0.5 ) color = outline, else color = base +sub r0.a, r1.a, c1.a +cnd r0.rgb, r0.a, r1, r0 ; if ( alpha -c1 > 0.5) color=base diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_dx6.cpp b/sp/src/materialsystem/stdshaders/unlitgeneric_dx6.cpp new file mode 100644 index 00000000..fc8bdf47 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_dx6.cpp @@ -0,0 +1,310 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( UnlitGeneric, UnlitGeneric_DX6 ) +DEFINE_FALLBACK_SHADER( MonitorScreen, UnlitGeneric_DX6 ) +DEFINE_FALLBACK_SHADER( ParticleSphere, UnlitGeneric_DX6 ) +DEFINE_FALLBACK_SHADER( Predator, Predator_DX60 ) +DEFINE_FALLBACK_SHADER( Predator_DX60, UnlitGeneric_DX6 ) +DEFINE_FALLBACK_SHADER( WindowImposter, WindowImposter_DX60 ) +DEFINE_FALLBACK_SHADER( WindowImposter_DX60, UnlitGeneric_DX6 ) + +BEGIN_SHADER( UnlitGeneric_DX6, + "Help for UnlitGeneric_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + // No texture means no env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + // the second texture (if there is one) + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + LoadCubeMap( ENVMAP ); + else + LoadTexture( ENVMAP ); + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE); + + if (params[ENVMAPMASK]->IsDefined()) + { + LoadTexture( ENVMAPMASK ); + } + } + } + + int GetDrawFlagsPass1(IMaterialVar** params, bool doDetail) + { + int flags = SHADER_DRAW_POSITION; + if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR)) + flags |= SHADER_DRAW_COLOR; + if (params[BASETEXTURE]->IsTexture()) + flags |= SHADER_DRAW_TEXCOORD0; + if (doDetail) + flags |= SHADER_DRAW_TEXCOORD1; + return flags; + } + + void SetDetailShadowState(IShaderShadow* pShaderShadow) + { + // Specifically choose overbright2, will cause mod2x here + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 2.0f ); + } + + void SetDetailDymamicState(IShaderShadow* pShaderShadow) + { + BindTexture( SHADER_SAMPLER1, DETAIL, FRAME ); + SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, BASETEXTURETRANSFORM, DETAILSCALE ); + } + + void DrawAdditiveNonTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) + { + SHADOW_STATE + { + SetModulationShadowState(); + SetAdditiveBlendingShadowState( ); + if (doDetail) + SetDetailShadowState(pShaderShadow); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); + FogToBlack(); + } + DYNAMIC_STATE + { + SetModulationDynamicState(); + if (doDetail) + SetDetailDymamicState(pShaderShadow); + } + Draw( ); + } + + void DrawAdditiveTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + SetModulationShadowState(); + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + if (doDetail) + SetDetailShadowState(pShaderShadow); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); + FogToBlack(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + if (doDetail) + SetDetailDymamicState(pShaderShadow); + SetModulationDynamicState(); + } + Draw( ); + } + + void DrawNonTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) + { + SHADOW_STATE + { + SetModulationShadowState(); + SetNormalBlendingShadowState( ); + if (doDetail) + SetDetailShadowState(pShaderShadow); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); + FogToFogColor(); + } + DYNAMIC_STATE + { + SetModulationDynamicState(); + if (doDetail) + SetDetailDymamicState(pShaderShadow); + } + Draw( ); + } + + void DrawTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + SetModulationShadowState(); + SetNormalBlendingShadowState( BASETEXTURE, true ); + if (doDetail) + SetDetailShadowState(pShaderShadow); + pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + if (doDetail) + SetDetailDymamicState(pShaderShadow); + SetModulationDynamicState(); + } + Draw( ); + } + + SHADER_DRAW + { + bool isTextureDefined = params[BASETEXTURE]->IsTexture(); + bool hasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR); + bool doFirstPass = isTextureDefined || hasVertexColor || (!params[ENVMAP]->IsTexture()); + + if (doFirstPass) + { + SHADOW_STATE + { + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + if( params[ALPHATESTREFERENCE]->IsDefined() && params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); + } + } + + if (IS_FLAG_SET(MATERIAL_VAR_ADDITIVE)) + { + if (!isTextureDefined) + { + bool hasDetailTexture = params[DETAIL]->IsTexture(); + DrawAdditiveNonTextured( params, pShaderAPI, pShaderShadow, hasDetailTexture ); + } + else + { + // We can't do detail in a single pass if we're also + // colormodulating and have vertex color + bool hasDetailTexture = params[DETAIL]->IsTexture(); + bool isModulating = IsColorModulating() || IsAlphaModulating(); + bool onePassDetail = hasDetailTexture && (!hasVertexColor || !isModulating); + DrawAdditiveTextured( params, pShaderAPI, pShaderShadow, onePassDetail ); + if (hasDetailTexture && !onePassDetail) + { + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + } + } + else + { + if (!isTextureDefined) + { + bool hasDetailTexture = params[DETAIL]->IsTexture(); + DrawNonTextured( params, pShaderAPI, pShaderShadow, hasDetailTexture ); + } + else + { + // We can't do detail in a single pass if we're also + // colormodulating and have vertex color + bool hasDetailTexture = params[DETAIL]->IsTexture(); + bool isModulating = IsColorModulating() || IsAlphaModulating(); + bool onePassDetail = hasDetailTexture && (!hasVertexColor || !isModulating); + DrawTextured( params, pShaderAPI, pShaderShadow, onePassDetail ); + if (hasDetailTexture && !onePassDetail) + { + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + } + } + } + + SHADOW_STATE + { + // Disable mod2x used by detail + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); + } + + // Second pass... + if (params[ENVMAP]->IsTexture() && + (!doFirstPass || IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) ) + { + if (doFirstPass || IS_FLAG_SET(MATERIAL_VAR_ADDITIVE)) + { + FixedFunctionAdditiveMaskedEnvmapPass( ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + else + { + FixedFunctionMaskedEnvmapPass( ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_dx8.cpp b/sp/src/materialsystem/stdshaders/unlitgeneric_dx8.cpp new file mode 100644 index 00000000..19d0e169 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_dx8.cpp @@ -0,0 +1,72 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( UnlitGeneric, UnlitGeneric_DX8 ) + +BEGIN_VS_SHADER( UnlitGeneric_DX8, + "Help for UnlitGeneric_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) + SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") + SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) + SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") + SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") + SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") + SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && !g_pHardwareConfig->SupportsVertexAndPixelShaders()) + { + return "UnlitGeneric_DX6"; + } + return 0; + } + + SHADER_INIT_PARAMS() + { + InitParamsUnlitGeneric_DX8( + BASETEXTURE, DETAILSCALE, ENVMAPOPTIONAL, + ENVMAP, ENVMAPTINT, ENVMAPMASKSCALE, + DETAILBLENDMODE ); + } + + SHADER_INIT + { + InitUnlitGeneric_DX8( BASETEXTURE, DETAIL, ENVMAP, ENVMAPMASK ); + } + + SHADER_DRAW + { + VertexShaderUnlitGenericPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, + DETAIL, DETAILSCALE, true, ENVMAP, ENVMAPFRAME, ENVMAPMASK, + ENVMAPMASKFRAME, ENVMAPMASKSCALE, ENVMAPTINT, ALPHATESTREFERENCE, + DETAILBLENDMODE, + OUTLINE, OUTLINECOLOR, OUTLINESTART0, OUTLINEEND1, SEPARATEDETAILUVS ); + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_dx9.cpp b/sp/src/materialsystem/stdshaders/unlitgeneric_dx9.cpp new file mode 100644 index 00000000..b57474a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_dx9.cpp @@ -0,0 +1,200 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx9_helper.h" + +extern ConVar r_flashlight_version2; + +BEGIN_VS_SHADER( UnlitGeneric, "Help for UnlitGeneric" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "envmap frame number" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" ) + SHADER_PARAM( VERTEXALPHATEST, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( HDRCOLORSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "hdr color scale" ) + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) + SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) + SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) + SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "2D map for warping specular" ) + SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) + SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) + SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) + SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$detail texcoord transform" ) + + SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) + + SHADER_PARAM( DISTANCEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use distance-coded alpha generated from hi-res texture by vtex.") + SHADER_PARAM( DISTANCEALPHAFROMDETAIL, SHADER_PARAM_TYPE_BOOL, "0", "Take the distance-coded alpha mask from the detail texture.") + + SHADER_PARAM( SOFTEDGES, SHADER_PARAM_TYPE_BOOL, "0", "Enable soft edges to distance coded textures.") + SHADER_PARAM( SCALEEDGESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft edges based upon resolution. 1024x768 = nominal.") + SHADER_PARAM( EDGESOFTNESSSTART, SHADER_PARAM_TYPE_FLOAT, "0.6", "Start value for soft edges for distancealpha."); + SHADER_PARAM( EDGESOFTNESSEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "End value for soft edges for distancealpha."); + + SHADER_PARAM( GLOW, SHADER_PARAM_TYPE_BOOL, "0", "Enable glow/shadow for distance coded textures.") + SHADER_PARAM( GLOWCOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outter glow for distance coded line art." ) + SHADER_PARAM( GLOWALPHA, SHADER_PARAM_TYPE_FLOAT, "1", "Base glow alpha amount for glows/shadows with distance alpha." ) + SHADER_PARAM( GLOWSTART, SHADER_PARAM_TYPE_FLOAT, "0.7", "start value for glow/shadow") + SHADER_PARAM( GLOWEND, SHADER_PARAM_TYPE_FLOAT, "0.5", "end value for glow/shadow") + SHADER_PARAM( GLOWX, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset x for glow mask.") + SHADER_PARAM( GLOWY, SHADER_PARAM_TYPE_FLOAT, "0", "texture offset y for glow mask.") + + SHADER_PARAM( OUTLINE, SHADER_PARAM_TYPE_BOOL, "0", "Enable outline for distance coded textures.") + SHADER_PARAM( OUTLINECOLOR, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "color of outline for distance coded images." ) + SHADER_PARAM( OUTLINEALPHA, SHADER_PARAM_TYPE_FLOAT, "0.0", "alpha value for outline") + SHADER_PARAM( OUTLINESTART0, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer start value for outline") + SHADER_PARAM( OUTLINESTART1, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner start value for outline") + SHADER_PARAM( OUTLINEEND0, SHADER_PARAM_TYPE_FLOAT, "0.0", "inner end value for outline") + SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline") + SHADER_PARAM( SCALEOUTLINESOFTNESSBASEDONSCREENRES, SHADER_PARAM_TYPE_BOOL, "0", "Scale the size of the soft part of the outline based upon resolution. 1024x768 = nominal.") + + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) + + SHADER_PARAM( GAMMACOLORREAD, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of color texture read." ) + SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) + + SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries" ) + SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) + SHADER_PARAM( RECEIVEFLASHLIGHT, SHADER_PARAM_TYPE_INTEGER, "0", "Forces this material to receive flashlights." ) + + END_SHADER_PARAMS + + void SetupVars( VertexLitGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = -1; + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTextureTransform = DETAILTEXTURETRANSFORM; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = -1; + info.m_nBumpFrame = -1; + info.m_nBumpTransform = -1; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nVertexAlphaTest = VERTEXALPHATEST; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nHDRColorScale = HDRCOLORSCALE; + info.m_nPhongExponent = -1; + info.m_nPhongExponentTexture = -1; + info.m_nDiffuseWarpTexture = -1; + info.m_nPhongWarpTexture = -1; + info.m_nPhongBoost = -1; + info.m_nPhongFresnelRanges = -1; + info.m_nPhong = -1; + info.m_nPhongTint = -1; + info.m_nPhongAlbedoTint = -1; + info.m_nSelfIllumEnvMapMask_Alpha = -1; + info.m_nAmbientOnly = -1; + info.m_nBaseMapAlphaPhongMask = -1; + info.m_nEnvmapFresnel = -1; + info.m_nSelfIllumMask = -1; + + info.m_nDistanceAlpha = DISTANCEALPHA; + info.m_nDistanceAlphaFromDetail = DISTANCEALPHAFROMDETAIL; + info.m_nSoftEdges = SOFTEDGES; + info.m_nEdgeSoftnessStart = EDGESOFTNESSSTART; + info.m_nEdgeSoftnessEnd = EDGESOFTNESSEND; + info.m_nScaleEdgeSoftnessBasedOnScreenRes = SCALEEDGESOFTNESSBASEDONSCREENRES; + + info.m_nGlow = GLOW; + info.m_nGlowColor = GLOWCOLOR; + info.m_nGlowAlpha = GLOWALPHA; + info.m_nGlowStart = GLOWSTART; + info.m_nGlowEnd = GLOWEND; + info.m_nGlowX = GLOWX; + info.m_nGlowY = GLOWY; + + info.m_nOutline = OUTLINE; + info.m_nOutlineColor = OUTLINECOLOR; + info.m_nOutlineAlpha = OUTLINEALPHA; + info.m_nOutlineStart0 = OUTLINESTART0; + info.m_nOutlineStart1 = OUTLINESTART1; + info.m_nOutlineEnd0 = OUTLINEEND0; + info.m_nOutlineEnd1 = OUTLINEEND1; + info.m_nScaleOutlineSoftnessBasedOnScreenRes = SCALEOUTLINESOFTNESSBASEDONSCREENRES; + + info.m_nSeparateDetailUVs = SEPARATEDETAILUVS; + + info.m_nLinearWrite = LINEARWRITE; + info.m_nGammaColorRead = GAMMACOLORREAD; + + info.m_nDepthBlend = DEPTHBLEND; + info.m_nDepthBlendScale = DEPTHBLENDSCALE; + info.m_nReceiveFlashlight = RECEIVEFLASHLIGHT; + } + + SHADER_INIT_PARAMS() + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitParamsVertexLitGeneric_DX9( this, params, pMaterialName, false, vars ); + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "UnlitGeneric_DX8"; + } + return 0; + } + + SHADER_INIT + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitVertexLitGeneric_DX9( this, params, false, vars ); + } + + SHADER_DRAW + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + + bool bNewFlashlightPath = IsX360() || ( r_flashlight_version2.GetInt() != 0 ); + if ( ( pShaderShadow == NULL ) && ( pShaderAPI != NULL ) && !bNewFlashlightPath && pShaderAPI->InFlashlightMode() ) // Not snapshotting && flashlight pass + { + Draw( false ); + } + else + { + DrawVertexLitGeneric_DX9( this, params, pShaderAPI, pShaderShadow, false, vars, vertexCompression, pContextDataPtr ); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_inc.vsh b/sp/src/materialsystem/stdshaders/unlitgeneric_inc.vsh new file mode 100644 index 00000000..ac2abb7e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_inc.vsh @@ -0,0 +1,142 @@ +#include "macros.vsh" + +;------------------------------------------------------------------------------ +; $SHADER_SPECIFIC_CONST_0-$SHADER_SPECIFIC_CONST_1 = Base texture transform +; $SHADER_SPECIFIC_CONST_2-$SHADER_SPECIFIC_CONST_3 = Mask texture transform +; $SHADER_SPECIFIC_CONST_4-$SHADER_SPECIFIC_CONST_5 = Detail texture transform +;------------------------------------------------------------------------------ + +sub UnlitGeneric +{ + local( $detail ) = shift; + local( $envmap ) = shift; + local( $envmapcameraspace ) = shift; + local( $envmapsphere ) = shift; + local( $vertexcolor ) = shift; + local( $separatedetailuvs ) = shift; + + local( $worldPos, $worldNormal, $projPos, $reflectionVector ); + + ;------------------------------------------------------------------------------ + ; Vertex blending + ;------------------------------------------------------------------------------ + &AllocateRegister( \$worldPos ); + if( $envmap ) + { + &AllocateRegister( \$worldNormal ); + &SkinPositionAndNormal( $worldPos, $worldNormal ); + } + else + { + &SkinPosition( $worldPos ); + } + + ;------------------------------------------------------------------------------ + ; Transform the position from world to proj space + ;------------------------------------------------------------------------------ + + &AllocateRegister( \$projPos ); + + dp4 $projPos.x, $worldPos, $cViewProj0 + dp4 $projPos.y, $worldPos, $cViewProj1 + dp4 $projPos.z, $worldPos, $cViewProj2 + dp4 $projPos.w, $worldPos, $cViewProj3 + mov oPos, $projPos + + ;------------------------------------------------------------------------------ + ; Fog + ;------------------------------------------------------------------------------ + &CalcFog( $worldPos, $projPos ); + &FreeRegister( \$projPos ); + + if( !$envmap ) + { + &FreeRegister( \$worldPos ); + } + + ;------------------------------------------------------------------------------ + ; Texture coordinates (use world-space normal for envmap, tex transform for mask) + ;------------------------------------------------------------------------------ + dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 + dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + if ( $g_x360 ) + { + ; must write xyzw to match read in pixelshader + mov oT0.zw, $cZero + } + + if( $envmap ) + { + if( $envmapcameraspace ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + + ; transform reflection vector into view space + dp3 oT1.x, $reflectionVector, $cViewModel0 + dp3 oT1.y, $reflectionVector, $cViewModel1 + dp3 oT1.z, $reflectionVector, $cViewModel2 + if ( $g_x360 ) + { + ; must write xyzw to match read in pixelshader + mov oT1.w, $cZero + } + + &FreeRegister( \$reflectionVector ); + } + elsif( $envmapsphere ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + &ComputeSphereMapTexCoords( $reflectionVector, "oT1" ); + + &FreeRegister( \$reflectionVector ); + } + else + { + &ComputeReflectionVector( $worldPos, $worldNormal, "oT1" ); + } + + ; envmap mask + dp4 oT2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + dp4 oT2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + if ( $g_x360 ) + { + ; must write xyzw to match read in pixelshader + mov oT2.zw, $cZero + } + + &FreeRegister( \$worldPos ); + &FreeRegister( \$worldNormal ); + } + + if( $detail ) + { + if ( $separatedetailuvs ) + { + mov oT3, $vTexCoord1 + } + else + { + dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 + dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + } + + if ( $g_x360 ) + { + ; must write xyzw to match read in pixelshader + mov oT3.zw, $cZero + } + } + + if( $vertexcolor ) + { + ; Modulation color + mul oD0, $vColor, $cModulationColor + } + else + { + ; Modulation color + mov oD0, $cModulationColor + } +} diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc b/sp/src/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc new file mode 100644 index 00000000..dcbd43a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc @@ -0,0 +1,47 @@ +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + + float4 vDiffuse : COLOR0; + + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); + + o.vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + + o.fogFactorW = CalcFog( worldPos, o.vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + o.vDiffuse = 1.0f; + + return o; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc b/sp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc new file mode 100644 index 00000000..e3970e87 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc @@ -0,0 +1,9 @@ +struct PS_INPUT +{ + float4 vColor0 : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return i.vColor0; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc b/sp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc new file mode 100644 index 00000000..e4fffb83 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc @@ -0,0 +1,14 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#include "common_ps_fxc.h" + +struct PS_INPUT +{ + float4 vColor0 : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return FinalOutput( i.vColor0, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_ps11.fxc b/sp/src/materialsystem/stdshaders/unlitgeneric_ps11.fxc new file mode 100644 index 00000000..071d666c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_ps11.fxc @@ -0,0 +1,12 @@ +sampler TextureSampler : register( s0 ); + +struct PS_INPUT +{ + float4 vColor0 : COLOR0; + float2 vTexCoord0 : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return i.vColor0 * tex2D( TextureSampler, i.vTexCoord0 ); +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_ps2x.fxc b/sp/src/materialsystem/stdshaders/unlitgeneric_ps2x.fxc new file mode 100644 index 00000000..1620638f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_ps2x.fxc @@ -0,0 +1,19 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +#include "common_ps_fxc.h" + +sampler TextureSampler : register( s0 ); + +struct PS_INPUT +{ + float4 vColor0 : COLOR0; + float2 vTexCoord0 : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float4 result = i.vColor0 * tex2D( TextureSampler, i.vTexCoord0 ); + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_vs11.vsh b/sp/src/materialsystem/stdshaders/unlitgeneric_vs11.vsh new file mode 100644 index 00000000..b165fa7a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_vs11.vsh @@ -0,0 +1,23 @@ +vs.1.1 + +# STATIC: "DETAIL" "0..1" +# STATIC: "ENVMAP" "0..1" +# STATIC: "ENVMAPCAMERASPACE" "0..0" +# STATIC: "ENVMAPSPHERE" "0..1" +# STATIC: "VERTEXCOLOR" "0..1" +# STATIC: "SEPARATEDETAILUVS" "0..1" +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" + +# can't have envmapshere or envmapcameraspace without envmap +# SKIP: !$ENVMAP && ( $ENVMAPSPHERE || $ENVMAPCAMERASPACE ) + +# can't have both envmapsphere and envmapcameraspace +# SKIP: $ENVMAPSPHERE && $ENVMAPCAMERASPACE + +# SKIP: !$DETAIL && $SEPARATEDETAILUVS + + +#include "UnlitGeneric_inc.vsh" + +&UnlitGeneric( $DETAIL, $ENVMAP, $ENVMAPCAMERASPACE, $ENVMAPSPHERE, $VERTEXCOLOR, $SEPARATEDETAILUVS ); diff --git a/sp/src/materialsystem/stdshaders/unlitgeneric_vs20.fxc b/sp/src/materialsystem/stdshaders/unlitgeneric_vs20.fxc new file mode 100644 index 00000000..37249305 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/unlitgeneric_vs20.fxc @@ -0,0 +1,91 @@ +// STATIC: "VERTEXCOLOR" "0..1" +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +#include "common_vs_fxc.h" + +static const int g_FogType = DOWATERFOG; +static const bool g_bSkinning = SKINNING ? true : false; + +const float4 cBaseTextureTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +const float4 cMaskTextureTransform[2] : register( SHADER_SPECIFIC_CONST_2 ); +const float4 cDetailTextureTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); +const float4 g_vVertexColor : register( SHADER_SPECIFIC_CONST_6 ); + +struct VS_INPUT +{ + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + +#if VERTEXCOLOR + float4 vColor : COLOR0; +#endif + + float4 vTexCoord0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + float2 vTexCoord3 : TEXCOORD3; + + float4 vColor : COLOR0; + float4 fogFactorW : COLOR1; + +#if !defined( _X360 ) + float fog : FOG; +#endif + + float4 worldPos_projPosZ : TEXCOORD7; // Necessary for pixel fog +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float3 worldPos; + float3 worldNormal; + + //------------------------------------------------------------------------------ + // Vertex blending + //------------------------------------------------------------------------------ + SkinPosition( g_bSkinning, v.vPos, v.vBoneWeights, v.vBoneIndices, worldPos ); + + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.vProjPos = vProjPos; + vProjPos = dot( float4( worldPos, 1 ), cViewProjZ ); + o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z ); + + //------------------------------------------------------------------------------ + // Fog + //------------------------------------------------------------------------------ + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + //------------------------------------------------------------------------------ + // Texture coord transforms + //------------------------------------------------------------------------------ + o.vTexCoord0 = mul( v.vTexCoord0, (float2x4)cBaseTextureTransform ); + o.vTexCoord3 = mul( v.vTexCoord0, (float2x4)cDetailTextureTransform ); + + o.vColor = cModulationColor; + +#if VERTEXCOLOR + // 0 or 1 for g_vVertexColor.x, eliminating a bool + o.vColor = lerp( o.vColor, o.vColor * v.vColor, g_vVertexColor.x ); +#endif + + return o; +} + + + diff --git a/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc b/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc new file mode 100644 index 00000000..7768f477 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc @@ -0,0 +1,350 @@ +//======= Copyright © 1996-2008, Valve Corporation, All rights reserved. ====== + +// STATIC: "CUBEMAP" "0..1" +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "LIGHTWARPTEXTURE" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "SELFILLUMFRESNEL" "0..1" +// STATIC: "NORMALMAPALPHAENVMAPMASK" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..6" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps30] +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] [PC] + +// We don't use light combos when doing the flashlight +// SKIP: ( $FLASHLIGHT != 0 ) && ( $NUM_LIGHTS > 0 ) [PC] + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// SKIP: (! $DETAILTEXTURE) && ( $DETAIL_BLEND_MODE != 0 ) + +// Don't do diffuse warp on flashlight +// SKIP: ( $FLASHLIGHT == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) [PC] + +// Only warp diffuse if we have it at all +// SKIP: ( $DIFFUSELIGHTING == 0 ) && ( $LIGHTWARPTEXTURE == 1 ) + +// Skip this since it blows ps20 instruction limits +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $LIGHTWARPTEXTURE == 1 ) + +// Only need self illum fresnel when self illum enabled +// SKIP: ( $SELFILLUM == 0 ) && ( $SELFILLUMFRESNEL == 1 ) +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUMFRESNEL == 1 ) [PC] +// SKIP: ( $FLASHLIGHT == 1 ) && ( $SELFILLUM == 1 ) [PC] +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $DETAILTEXTURE == 1 ) +// SKIP: ( $SELFILLUMFRESNEL == 1 ) && ( $NORMALMAPALPHAENVMAPMASK == 1 ) + +// BlendTintByBaseAlpha is incompatible with other interpretations of alpha +// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM) + +// Only _XBOX allows flashlight and cubemap in the current implementation +// SKIP: $FLASHLIGHT && $CUBEMAP [PC] + +// Meaningless combinations +// SKIP: $NORMALMAPALPHAENVMAPMASK && !$CUBEMAP + +#include "common_flashlight_fxc.h" +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); +const float4 g_DiffuseModulation : register( c1 ); +const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); +const float3 g_EnvmapSaturation : register( c3 ); +const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); +#define g_SelfIllumTint ( g_SelfIllumTint_and_BlendFactor.rgb) +#define g_DetailBlendFactor (g_SelfIllumTint_and_BlendFactor.w) + +const float3 cAmbientCube[6] : register( c5 ); + +// 11, 12 not used? +#if ( SELFILLUMFRESNEL == 1 ) + const float4 g_SelfIllumScaleBiasExpBrightness : register( c11 ); +#endif + +const float4 g_ShaderControls : register( c12 ); +#define g_fPixelFogType g_ShaderControls.x +#define g_fWriteDepthToAlpha g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z + + +// 2 registers each - 6 registers total +PixelShaderLightInfo cLightInfo[3] : register( c13 ); // through c18 + +const float3 g_EyePos : register( c20 ); +const float4 g_FogParams : register( c21 ); + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const float3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + +sampler BaseTextureSampler : register( s0 ); +sampler EnvmapSampler : register( s1 ); +sampler DetailSampler : register( s2 ); +sampler BumpmapSampler : register( s3 ); +sampler EnvmapMaskSampler : register( s4 ); +sampler NormalizeSampler : register( s5 ); +sampler RandRotSampler : register( s6 ); // RandomRotation sampler +sampler FlashlightSampler : register( s7 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler +sampler DiffuseWarpSampler : register( s9 ); // Lighting warp sampler (1D texture for diffuse lighting modification) + +struct PS_INPUT +{ + float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; + float3 lightAtten : TEXCOORD1; + float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3 vWorldNormal : TEXCOORD3; // World-space normal + float4 vWorldTangent : TEXCOORD4; +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float4 vProjPos : TEXCOORD5; +#else + float3 vWorldBinormal : TEXCOORD5; +#endif + float4 worldPos_projPosZ : TEXCOORD6; + float3 detailTexCoord_atten3 : TEXCOORD7; + float4 fogFactorW : COLOR1; + +#if defined( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; +#endif +#endif +}; + +// Calculate both types of Fog and lerp to get result +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float fRangeFog = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); + float fHeightFog = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); + return lerp( fRangeFog, fHeightFog, fPixelFogType ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + pixelFogFactor = saturate( pixelFogFactor ); + float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + return lerp( fRangeResult, fHeightResult, fPixelFogType ); +} + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + +float4 main( PS_INPUT i ) : COLOR +{ + bool bCubemap = CUBEMAP ? true : false; + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bDoDiffuseWarp = LIGHTWARPTEXTURE ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bSelfIllumFresnel = SELFILLUMFRESNEL ? true : false; + bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false; + bool bHalfLambert = HALFLAMBERT ? true : false; + bool bFlashlight = (FLASHLIGHT!=0) ? true : false; + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + int nNumLights = NUM_LIGHTS; + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float3 vWorldBinormal = cross( i.vWorldNormal.xyz, i.vWorldTangent.xyz ) * i.vWorldTangent.w; +#else + float3 vWorldBinormal = i.vWorldBinormal; +#endif + + // Unpack four light attenuations + float4 vLightAtten = float4( i.lightAtten, i.detailTexCoord_atten3.z ); + + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); + +#if DETAILTEXTURE + float4 detailColor = tex2D( DetailSampler, i.detailTexCoord_atten3.xy ); + baseColor = TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + + float specularFactor = 1.0f; + float4 normalTexel = tex2D( BumpmapSampler, i.baseTexCoord2_tangentSpaceVertToEyeVectorXY.xy ); + float3 tangentSpaceNormal = normalTexel * 2.0f - 1.0f; + + if ( bNormalMapAlphaEnvmapMask ) + specularFactor = normalTexel.a; + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + + float3 worldSpaceNormal = float3( 0.0f, 0.0f, 1.0f ); + if ( bDiffuseLighting || bFlashlight || bCubemap || bSelfIllumFresnel ) + { + worldSpaceNormal = Vec3TangentToWorld( tangentSpaceNormal, i.vWorldNormal, i.vWorldTangent, vWorldBinormal ); +#if ( defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) + worldSpaceNormal = normalize( worldSpaceNormal ); +#else + worldSpaceNormal = NormalizeWithCubemap( NormalizeSampler, worldSpaceNormal ); +#endif + } + + if ( bDiffuseLighting ) + { + diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, vLightAtten, + cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, + false, 1.0f, bDoDiffuseWarp, DiffuseWarpSampler ); + } + + float3 albedo = baseColor; + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + float alpha = g_DiffuseModulation.a; + if ( !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha *= baseColor.a; + } + + +#if FLASHLIGHT + if( bFlashlight ) + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; + float2 vProjPos = float2(0, 0); +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = FLASHLIGHTSHADOWS; + vProjPos = i.vProjPos.xy / i.vProjPos.w; // Screen-space position for shadow map noise +#endif + +#if defined ( _X360 ) + float4 flashlightSpacePosition = i.flashlightSpacePos; +#else + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, nShadowSampleLevel, bDoShadows, false, vProjPos, false, g_EnvmapContrast_ShadowTweaks ); + +#if defined ( _X360 ) + diffuseLighting += flashlightColor; +#else + diffuseLighting = flashlightColor; +#endif + + } +#endif + + + float3 diffuseComponent = albedo * diffuseLighting; + + +#if !FLASHLIGHT || defined ( _X360 ) + if ( bSelfIllum ) + { + #if ( SELFILLUMFRESNEL == 1 ) // To free up the constant register...see top of file + // This will apply a fresnel term based on the vertex normal (not the per-pixel normal!) to help fake and internal glow look + #if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))) + float3 vVertexNormal = normalize( i.vWorldNormal.xyz ); + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, normalize( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + + float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); + #else + float3 vVertexNormal = i.vWorldNormal.xyz; + float flSelfIllumFresnel = ( pow( saturate( dot( vVertexNormal.xyz, ( i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ) ) ), g_SelfIllumScaleBiasExpBrightness.z ) * g_SelfIllumScaleBiasExpBrightness.x ) + g_SelfIllumScaleBiasExpBrightness.y; + + float3 selfIllumComponent = g_SelfIllumTint * albedo * g_SelfIllumScaleBiasExpBrightness.w; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a * saturate( flSelfIllumFresnel ) ); + #endif + #else + float3 selfIllumComponent = g_SelfIllumTint * albedo; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + #endif + } +#endif + + float3 specularLighting = float3( 0.0f, 0.0f, 0.0f ); +#if !FLASHLIGHT || defined ( _X360 ) + if( bCubemap ) + { + float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz ); + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; + float3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); + float3 greyScale = dot( specularLighting, float3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); + } +#endif + + float3 result = diffuseComponent + specularLighting; + +#if defined(SHADER_MODEL_PS_2_0) + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); +#else + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); +#endif + +#if defined( SHADER_MODEL_PS_2_0 ) + #if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; + #endif +#else // 2b or higher + alpha = lerp( alpha, fogFactor, g_fPixelFogType * g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog +#endif + +#if defined( SHADER_MODEL_PS_2_0 ) + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.worldPos_projPosZ.w ); +#else + return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.worldPos_projPosZ.w ); +#endif + +} + diff --git a/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc b/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc new file mode 100644 index 00000000..06afd956 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc @@ -0,0 +1,198 @@ +//======= Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ====== +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "USE_WITH_2B" "0..1" +// STATIC: "DECAL" "0..1" [vs30] +// STATIC: "FLASHLIGHT" "0..1" [XBOX] +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] + +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); // 0 & 1 +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); // 4 & 5 +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); + +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + + +//----------------------------------------------------------------------------- +// Input vertex format +//----------------------------------------------------------------------------- +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + float3 vTangentS : TANGENT; + float3 vTangentT : BINORMAL; + float4 vUserData : TANGENT; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + + +//----------------------------------------------------------------------------- +// Output vertex format +//----------------------------------------------------------------------------- +struct VS_OUTPUT +{ + // Stuff that isn't seen by the pixel shader + float4 projPos : POSITION; +#if !defined( _X360 ) + float fog : FOG; +#endif + // Stuff that is seen by the pixel shader + + float4 baseTexCoord2_tangentSpaceVertToEyeVectorXY : TEXCOORD0; + float3 lightAtten : TEXCOORD1; + float4 worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ : TEXCOORD2; + float3 vWorldNormal : TEXCOORD3; // World-space normal + float4 vWorldTangent : TEXCOORD4; +#if USE_WITH_2B + float4 vProjPos : TEXCOORD5; +#else + float3 vWorldBinormal : TEXCOORD5; +#endif + float4 worldPos_projPosZ : TEXCOORD6; + float3 detailTexCoord_atten3 : TEXCOORD7; + float4 fogFactorW : COLOR1; + +#if defined( _X360 ) && FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD8; +#endif +}; + + +//----------------------------------------------------------------------------- +// Main shader entry point +//----------------------------------------------------------------------------- +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + float4 vPosition = v.vPos; + float3 vNormal; + float4 vTangent; + DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vNormal, vTangent ); + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal, vTangent.xyz ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal, vTangent.xyz ); +#endif + + // Perform skinning + float3 worldNormal, worldPos, worldTangentS, worldTangentT; + SkinPositionNormalAndTangentSpace( g_bSkinning, vPosition, vNormal, vTangent, + v.vBoneWeights, v.vBoneIndices, worldPos, + worldNormal, worldTangentS, worldTangentT ); + + // Always normalize since flex path is controlled by runtime + // constant not a shader combo and will always generate the normalization + worldNormal = normalize( worldNormal ); + worldTangentS = normalize( worldTangentS ); + worldTangentT = normalize( worldTangentT ); + +#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + o.vWorldNormal.xyz = worldNormal.xyz; + o.vWorldTangent = float4( worldTangentS.xyz, vTangent.w ); // Propagate binormal sign in world tangent.w + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + +#if USE_WITH_2B + o.vProjPos = vProjPos; +#else + o.vWorldBinormal.xyz = worldTangentT.xyz; +#endif + + o.fogFactorW = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW; +#endif + + // Needed for water fog alpha and diffuse lighting + // FIXME: we shouldn't have to compute this all the time. + o.worldPos_projPosZ = float4( worldPos, vProjPos.z ); + + // Needed for cubemapping + parallax mapping + // FIXME: We shouldn't have to compute this all the time. + //o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); + o.worldVertToEyeVectorXYZ_tangentSpaceVertToEyeVectorZ.xyz = normalize( cEyePos.xyz - worldPos.xyz ); + +#if defined( SHADER_MODEL_VS_2_0 ) && ( !USE_STATIC_CONTROL_FLOW ) + o.lightAtten.xyz = float3(0,0,0); + o.detailTexCoord_atten3.z = 0.0f; + #if ( NUM_LIGHTS > 0 ) + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false ); + #endif + #if ( NUM_LIGHTS > 1 ) + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false ); + #endif + #if ( NUM_LIGHTS > 2 ) + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false ); + #endif + #if ( NUM_LIGHTS > 3 ) + o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, false ); + #endif +#else + // Scalar light attenuation + o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, true ); + o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, true ); + o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, true ); + o.detailTexCoord_atten3.z = GetVertexAttenForLight( worldPos, 3, true ); +#endif + + // Base texture coordinate transform + o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord2_tangentSpaceVertToEyeVectorXY.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); + + // Detail texture coordinate transform + o.detailTexCoord_atten3.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); + o.detailTexCoord_atten3.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); + +#if defined( _X360 ) && FLASHLIGHT + o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc b/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc new file mode 100644 index 00000000..1d1a47d0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc @@ -0,0 +1,484 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// +// +//=============================================================================// +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "ENVMAPMASK" "0..1" +// STATIC: "BASEALPHAENVMAPMASK" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SELFILLUM_ENVMAPMASK_ALPHA" "0..1" +// STATIC: "DETAIL_BLEND_MODE" "0..9" +// STATIC: "SEAMLESS_BASE" "0..1" +// STATIC: "SEAMLESS_DETAIL" "0..1" +// STATIC: "DISTANCEALPHA" "0..1" +// STATIC: "DISTANCEALPHAFROMDETAIL" "0..1" +// STATIC: "SOFT_MASK" "0..1" +// STATIC: "OUTLINE" "0..1" +// STATIC: "OUTER_GLOW" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps30] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] +// STATIC: "DEPTHBLEND" "0..1" [ps20b] [ps30] +// STATIC: "BLENDTINTBYBASEALPHA" "0..1" +// STATIC: "SRGB_INPUT_ADAPTER" "0..1" [ps20b] +// STATIC: "CUBEMAP_SPHERE_LEGACY" "0..1" + +// DYNAMIC: "PIXELFOGTYPE" "0..1" [ps20] +// DYNAMIC: "LIGHTING_PREVIEW" "0..2" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps30] + +// detail blend mode 6 = ps20b only +// SKIP: $DETAIL_BLEND_MODE == 6 [ps20] + +// SKIP: ($DETAILTEXTURE == 0 ) && ( $DETAIL_BLEND_MODE != 0 ) +// SKIP: ($DETAILTEXTURE == 0 ) && ( $SEAMLESS_DETAIL ) +// SKIP: ($ENVMAPMASK || $SELFILLUM_ENVMAPMASK_ALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK +// SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM +// SKIP: $SELFILLUM && $SELFILLUM_ENVMAPMASK_ALPHA +// SKIP: $SELFILLUM_ENVMAPMASK_ALPHA && (! $ENVMAPMASK) +// SKIP: $ENVMAPMASK && ($FLASHLIGHT || $FLASHLIGHTSHADOWS) [PC] +// SKIP: $BASEALPHAENVMAPMASK && ($SEAMLESS_BASE || $SEAMLESS_DETAIL) +// SKIP: ($DISTANCEALPHA == 0) && ($DISTANCEALPHAFROMDETAIL || $SOFT_MASK || $OUTLINE || $OUTER_GLOW) +// SKIP: ($DETAILTEXTURE == 0) && ($DISTANCEALPHAFROMDETAIL) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps30] + +// Flashlight shadow filter mode is irrelevant if there is no flashlight +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b] +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps30] + +// DISTANCEALPHA-related skips +// SKIP: ($DISTANCEALPHA) && ($ENVMAPMASK || $BASEALPHAENVMAPMASK || $SELFILLUM || $SELFILLUM_ENVMAPMASK_ALPHA ) +// SKIP: ($DISTANCEALPHA) && ($SEAMLESS_BASE || $SEAMLESS_DETAIL || $CUBEMAP || $LIGHTING_PREVIEW ) +// SKIP: ($DISTANCEALPHA) && ($WRITEWATERFOGTODESTALPHA || $PIXELFOGTYPE || $FLASHLIGHT || $FLASHLIGHTSHADOWS || $SRGB_INPUT_ADAPTER ) + +// SKIP: $SEAMLESS_BASE && $SRGB_INPUT_ADAPTER +// SKIP: $SEAMLESS_BASE && ($BLENDTINTBYBASEALPHA ) + +// BlendTintByBaseAlpha is incompatible with other interpretations of alpha +// SKIP: ($BLENDTINTBYBASEALPHA) && ($SELFILLUM || (($DISTANCEALPHA) && ($DISTANCEALPHAFROMDETAIL == 0)) || $BASEALPHAENVMAPMASK) + +// Only _XBOX allows flashlight and cubemap in the current implementation +// SKIP: $FLASHLIGHT && $CUBEMAP [PC] + +// SKIP: $CUBEMAP_SPHERE_LEGACY && ($CUBEMAP == 0) + +#include "common_flashlight_fxc.h" +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_EnvmapTint_TintReplaceFactor : register( c0 ); +const float4 g_DiffuseModulation : register( c1 ); +const float4 g_EnvmapContrast_ShadowTweaks : register( c2 ); +const float4 g_EnvmapSaturation_SelfIllumMask : register( c3 ); +const float4 g_SelfIllumTint_and_BlendFactor : register( c4 ); + +const float4 g_ShaderControls : register( c12 ); +const float4 g_DepthFeatheringConstants : register( c13 ); + +const float4 g_EyePos : register( c20 ); +const float4 g_FogParams : register( c21 ); + +#define g_SelfIllumTint g_SelfIllumTint_and_BlendFactor.xyz +#define g_DetailBlendFactor g_SelfIllumTint_and_BlendFactor.w +#define g_EnvmapSaturation g_EnvmapSaturation_SelfIllumMask.xyz +#define g_SelfIllumMaskControl g_EnvmapSaturation_SelfIllumMask.w + +const float4 g_FlashlightAttenuationFactors : register( c22 ); +const HALF3 g_FlashlightPos : register( c23 ); +const float4x4 g_FlashlightWorldToTexture : register( c24 ); // through c27 + + +sampler BaseTextureSampler : register( s0 ); +sampler EnvmapSampler : register( s1 ); +sampler DetailSampler : register( s2 ); +sampler EnvmapMaskSampler : register( s4 ); +sampler RandRotSampler : register( s6 ); // RandomRotation sampler +sampler FlashlightSampler : register( s7 ); +sampler ShadowDepthSampler : register( s8 ); // Flashlight shadow depth map sampler +sampler DepthSampler : register( s10 ); //depth buffer sampler for depth blending +sampler SelfIllumMaskSampler : register( s11 ); // selfillummask + +struct PS_INPUT +{ +#if SEAMLESS_BASE + HALF3 baseTexCoord : TEXCOORD0; // Base texture coordinate +#else + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate +#endif +#if SEAMLESS_DETAIL + HALF3 detailTexCoord : TEXCOORD1; // Seamless texture coordinate +#else + HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate +#endif + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + float3 worldVertToEyeVector : TEXCOORD3; // Necessary for reflection + float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight + +#if defined ( _X360 ) +#if FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD5; +#endif +#endif + + float4 projPos : TEXCOORD6; + float4 worldPos_projPosZ : TEXCOORD7; + float4 fogFactorW : COLOR1; +#if SEAMLESS_BASE || SEAMLESS_DETAIL + float3 SeamlessWeights : COLOR0; // x y z projection weights +#endif +}; + +const float4 g_GlowParameters : register( c5 ); +const float4 g_GlowColor : register( c6 ); +#define GLOW_UV_OFFSET g_GlowParameters.xy +#define OUTER_GLOW_MIN_DVALUE g_GlowParameters.z +#define OUTER_GLOW_MAX_DVALUE g_GlowParameters.w +#define OUTER_GLOW_COLOR g_GlowColor + +#define g_fPixelFogType g_ShaderControls.x +#define g_fWriteDepthToAlpha g_ShaderControls.y +#define g_fWriteWaterFogToDestAlpha g_ShaderControls.z +#define g_fVertexAlpha g_ShaderControls.w + + +const float4 g_DistanceAlphaParams : register( c7 ); +#define SOFT_MASK_MAX g_DistanceAlphaParams.x +#define SOFT_MASK_MIN g_DistanceAlphaParams.y + +const float4 g_OutlineColor : register( c8 ); +#define OUTLINE_COLOR g_OutlineColor + +const float4 g_OutlineParams : register( c9 ); +// these are ordered this way for optimal ps20 swizzling +#define OUTLINE_MIN_VALUE0 g_OutlineParams.x +#define OUTLINE_MAX_VALUE1 g_OutlineParams.y +#define OUTLINE_MAX_VALUE0 g_OutlineParams.z +#define OUTLINE_MIN_VALUE1 g_OutlineParams.w + +#if DETAILTEXTURE +const float3 g_DetailTint : register( c10 ); +#endif + + +// Calculate unified fog +float CalcPixelFogFactorConst( float fPixelFogType, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +{ + float flDepthBelowWater = fPixelFogType*fogParams.y - flWorldPosZ; // above water = negative, below water = positive + float flDepthBelowEye = fPixelFogType*flEyePosZ - flWorldPosZ; // above eye = negative, below eye = positive + // if fPixelFogType == 0, then flDepthBelowWater == flDepthBelowEye and frac will be 1 + float frac = (flDepthBelowEye == 0) ? 1 : saturate(flDepthBelowWater/flDepthBelowEye); + return saturate( min(fogParams.z, flProjPosZ * fogParams.w * frac - fogParams.x) ); +} + +// Blend both types of Fog and lerp to get result +float3 BlendPixelFogConst( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, float fPixelFogType ) +{ + //float3 fRangeResult = lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog + //float3 fHeightResult = lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + //return lerp( fRangeResult, fHeightResult, fPixelFogType ); + pixelFogFactor = lerp( pixelFogFactor*pixelFogFactor, pixelFogFactor, fPixelFogType ); + return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor ); +} + + +float4 FinalOutputConst( const float4 vShaderColor, float pixelFogFactor, float fPixelFogType, const int iTONEMAP_SCALE_TYPE, float fWriteDepthToDestAlpha, const float flProjZ ) +{ + float4 result = vShaderColor; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb *= LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb *= GAMMA_LIGHT_SCALE; + } + + result.a = lerp( result.a, DepthToDestAlpha( flProjZ ), fWriteDepthToDestAlpha ); + + result.rgb = BlendPixelFogConst( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, fPixelFogType ); + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion + + return result; +} + + +#if LIGHTING_PREVIEW == 2 +LPREVIEW_PS_OUT main( PS_INPUT i ) : COLOR +#else +float4 main( PS_INPUT i ) : COLOR +#endif +{ + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bCubemap = CUBEMAP ? true : false; + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bHasNormal = bCubemap || bDiffuseLighting; + bool bEnvmapMask = ENVMAPMASK ? true : false; + bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bVertexColor = VERTEXCOLOR ? true : false; + bool bFlashlight = FLASHLIGHT ? true : false; + bool bBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA ? true : false; + + HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); +#if SEAMLESS_BASE + baseColor = + i.SeamlessWeights.x * tex2D( BaseTextureSampler, i.baseTexCoord.yz )+ + i.SeamlessWeights.y * tex2D( BaseTextureSampler, i.baseTexCoord.zx )+ + i.SeamlessWeights.z * tex2D( BaseTextureSampler, i.baseTexCoord.xy ); +#else + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord.xy ); + +#if SRGB_INPUT_ADAPTER + baseColor.rgb = GammaToLinear( baseColor.rgb ); +#endif + +#endif // !SEAMLESS_BASE + + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 0) + float distAlphaMask = baseColor.a; +#endif + + +#if DETAILTEXTURE +#if SEAMLESS_DETAIL + float4 detailColor = + i.SeamlessWeights.x * tex2D( DetailSampler, i.detailTexCoord.yz )+ + i.SeamlessWeights.y * tex2D( DetailSampler, i.detailTexCoord.zx )+ + i.SeamlessWeights.z * tex2D( DetailSampler, i.detailTexCoord.xy ); +#else + float4 detailColor = tex2D( DetailSampler, i.detailTexCoord.xy ); +#endif + detailColor.rgb *= g_DetailTint; + +#if DISTANCEALPHA && (DISTANCEALPHAFROMDETAIL == 1) + float distAlphaMask = detailColor.a; + detailColor.a = 1.0; // make tcombine treat as 1.0 +#endif + baseColor = + TextureCombine( baseColor, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + +#if DISTANCEALPHA + // now, do all distance alpha effects + //if ( OUTLINE && ( distAlphaMask >= OUTLINE_MIN_VALUE0 ) && ( distAlphaMask <= OUTLINE_MAX_VALUE1 ) ) + //{ + // float oFactor=1.0; + // if ( distAlphaMask <= OUTLINE_MIN_VALUE1 ) + // { + // oFactor=smoothstep( OUTLINE_MIN_VALUE0, OUTLINE_MIN_VALUE1, distAlphaMask ); + // } + // else + // { + // oFactor=smoothstep( OUTLINE_MAX_VALUE1, OUTLINE_MAX_VALUE0, distAlphaMask ); + // } + // baseColor = lerp( baseColor, OUTLINE_COLOR, oFactor ); + //} + if ( OUTLINE ) + { + float4 oFactors = smoothstep(g_OutlineParams.xyzw, g_OutlineParams.wzyx, distAlphaMask ); + baseColor = lerp( baseColor, g_OutlineColor, oFactors.x * oFactors.y ); + } + + float mskUsed; + if ( SOFT_MASK ) + { + mskUsed = smoothstep( SOFT_MASK_MIN, SOFT_MASK_MAX, distAlphaMask ); + baseColor.a *= mskUsed; + } + else + { + mskUsed = distAlphaMask >= 0.5; + if (DETAILTEXTURE ) + baseColor.a *= mskUsed; + else + baseColor.a = mskUsed; + } + + + if ( OUTER_GLOW ) + { +#if DISTANCEALPHAFROMDETAIL + float4 glowTexel = tex2D( DetailSampler, i.detailTexCoord.xy+GLOW_UV_OFFSET ); +#else + float4 glowTexel = tex2D( BaseTextureSampler, i.baseTexCoord.xy+GLOW_UV_OFFSET ); +#endif + float4 glowc = OUTER_GLOW_COLOR*smoothstep( OUTER_GLOW_MIN_DVALUE, OUTER_GLOW_MAX_DVALUE, glowTexel.a ); + baseColor = lerp( glowc, baseColor, mskUsed ); + } + +#endif // DISTANCEALPHA + + float3 specularFactor = 1.0f; + float4 envmapMaskTexel; + if( bEnvmapMask ) + { + envmapMaskTexel = tex2D( EnvmapMaskSampler, i.baseTexCoord.xy ); + specularFactor *= envmapMaskTexel.xyz; + } + + if( bBaseAlphaEnvmapMask ) + { + specularFactor *= 1.0 - baseColor.a; // this blows! + } + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + if( bDiffuseLighting || bVertexColor && !( bVertexColor && bDiffuseLighting ) ) + { + diffuseLighting = i.color.rgb; + } + + float3 albedo = baseColor; + if (bBlendTintByBaseAlpha) + { + float3 tintedColor = albedo * g_DiffuseModulation.rgb; + tintedColor = lerp(tintedColor, g_DiffuseModulation.rgb, g_EnvmapTint_TintReplaceFactor.w); + albedo = lerp(albedo, tintedColor, baseColor.a); + } + else + { + albedo = albedo * g_DiffuseModulation.rgb; + } + + float alpha = g_DiffuseModulation.a; + if ( !bBaseAlphaEnvmapMask && !bSelfIllum && !bBlendTintByBaseAlpha ) + { + alpha *= baseColor.a; + } + + + if( bFlashlight ) + { + int nShadowSampleLevel = 0; + bool bDoShadows = false; +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = true; +#endif + +#if defined ( _X360 ) + float4 flashlightSpacePosition = i.flashlightSpacePos; +#else + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + // We want the N.L to happen on the flashlight pass, but can't afford it on ps20 + bool bUseWorldNormal = true; +#if ( defined( SHADER_MODEL_PS_2_0 ) && ( DETAILTEXTURE ) ) + bUseWorldNormal = false; +#endif + float3 flashlightColor = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + i.worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, + RandRotSampler, nShadowSampleLevel, bDoShadows, false, i.projPos.xy / i.projPos.w, false, g_EnvmapContrast_ShadowTweaks, bUseWorldNormal ); + +#if defined ( _X360 ) + diffuseLighting += flashlightColor; +#else + diffuseLighting = flashlightColor; +#endif + } + + if( bVertexColor && bDiffuseLighting ) + { + albedo *= i.color.rgb; + } + + alpha = lerp( alpha, alpha * i.color.a, g_fVertexAlpha ); + + float3 diffuseComponent = albedo * diffuseLighting; + +#if DETAILTEXTURE + diffuseComponent = + TextureCombinePostLighting( diffuseComponent, detailColor, DETAIL_BLEND_MODE, g_DetailBlendFactor ); +#endif + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); + +#if !FLASHLIGHT || defined ( _X360 ) + #if SELFILLUM_ENVMAPMASK_ALPHA + // range of alpha: + // 0 - 0.125 = lerp(diffuse,selfillum,alpha*8) + // 0.125-1.0 = selfillum*(1+alpha-0.125)*8 (over bright glows) + HALF3 selfIllumComponent = g_SelfIllumTint * albedo; + half Adj_Alpha=8*envmapMaskTexel.a; + diffuseComponent=( max( 0, 1-Adj_Alpha ) * diffuseComponent) + Adj_Alpha * selfIllumComponent; + #else + if ( bSelfIllum ) + { + float3 vSelfIllumMask = tex2D( SelfIllumMaskSampler, i.baseTexCoord.xy ); + vSelfIllumMask = lerp( baseColor.aaa, vSelfIllumMask, g_SelfIllumMaskControl ); + diffuseComponent = lerp( diffuseComponent, g_SelfIllumTint * albedo, vSelfIllumMask ); + } + #endif + + if( bCubemap ) + { +#if CUBEMAP_SPHERE_LEGACY + HALF3 reflectVect = normalize(CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz )); + + specularLighting = 0.5 * tex2D( EnvmapSampler, float2(reflectVect.x, reflectVect.y) ) * g_DiffuseModulation.rgb * diffuseLighting; +#else + HALF3 reflectVect = CalcReflectionVectorUnnormalized( i.worldSpaceNormal, i.worldVertToEyeVector.xyz ); + + specularLighting = ENV_MAP_SCALE * texCUBE( EnvmapSampler, reflectVect ); + specularLighting *= specularFactor; + specularLighting *= g_EnvmapTint_TintReplaceFactor.rgb; + HALF3 specularLightingSquared = specularLighting * specularLighting; + specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast_ShadowTweaks ); + HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) ); + specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation ); +#endif + } +#endif + + HALF3 result = diffuseComponent + specularLighting; + +#if LIGHTING_PREVIEW +# if LIGHTING_PREVIEW == 1 + float dotprod=0.7+0.25*dot(i.worldSpaceNormal,normalize(float3(1,2,-.5))); + return FinalOutput( float4( dotprod*albedo.xyz, alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); +# else + LPREVIEW_PS_OUT ret; + ret.flags=float4(1,1,1,1); + ret.color=float4( albedo.xyz, alpha ); + ret.normal=float4(i.worldSpaceNormal,alpha); + ret.position=float4(i.worldPos_projPosZ.xyz, alpha); + return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +# endif +#else + +# if (DEPTHBLEND == 1) + { + float2 vScreenPos; + vScreenPos.x = i.projPos.x; + vScreenPos.y = -i.projPos.y; + vScreenPos = (vScreenPos + i.projPos.w) * 0.5f; + alpha *= DepthFeathering( DepthSampler, vScreenPos / i.projPos.w, i.projPos.w - i.projPos.z, i.projPos.w, g_DepthFeatheringConstants ); + } +# endif + +#if defined( SHADER_MODEL_PS_2_0 ) + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); + #if (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); + #endif + return FinalOutput( float4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, i.projPos.z ); +#else // 2b or higher + float fogFactor = CalcPixelFogFactorConst( g_fPixelFogType, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.projPos.z ); + alpha = lerp( alpha, fogFactor, g_fWriteWaterFogToDestAlpha ); // Use the fog factor if it's height fog + return FinalOutputConst( float4( result.rgb, alpha ), fogFactor, g_fPixelFogType, TONEMAP_SCALE_LINEAR, g_fWriteDepthToAlpha, i.projPos.z ); +#endif + +#endif +} + diff --git a/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc b/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc new file mode 100644 index 00000000..9db6f864 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc @@ -0,0 +1,249 @@ +//======= Copyright © 1996-2007, Valve Corporation, All rights reserved. ====== + +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "CUBEMAP" "0..1" +// STATIC: "HALFLAMBERT" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SEAMLESS_BASE" "0..1" +// STATIC: "SEAMLESS_DETAIL" "0..1" +// STATIC: "SEPARATE_DETAIL_UVS" "0..1" +// STATIC: "DECAL" "0..1" [vs30] +// STATIC: "USE_STATIC_CONTROL_FLOW" "0..1" [vs20] +// STATIC: "DONT_GAMMA_CONVERT_VERTEX_COLOR" "0..1" +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "DYNAMIC_LIGHT" "0..1" +// DYNAMIC: "STATIC_LIGHT" "0..1" +// DYNAMIC: "DOWATERFOG" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// DYNAMIC: "LIGHTING_PREVIEW" "0..1" [PC] +// DYNAMIC: "LIGHTING_PREVIEW" "0..0" [XBOX] +// DYNAMIC: "MORPHING" "0..1" [vs30] +// DYNAMIC: "NUM_LIGHTS" "0..2" [vs20] + +// If using static control flow on Direct3D, we should use the NUM_LIGHTS=0 combo +// SKIP: $USE_STATIC_CONTROL_FLOW && ( $NUM_LIGHTS > 0 ) [vs20] +// SKIP: ($SEPARATE_DETAIL_UVS) && ($SEAMLESS_DETAIL) +// SKIP: ($DONT_GAMMA_CONVERT_VERTEX_COLOR && ( ! $VERTEXCOLOR ) ) +#include "common_vs_fxc.h" + +static const bool g_bSkinning = SKINNING ? true : false; +static const int g_FogType = DOWATERFOG; +static const bool g_bVertexColor = VERTEXCOLOR ? true : false; +static const bool g_bCubemap = CUBEMAP ? true : false; +static const bool g_bFlashlight = FLASHLIGHT ? true : false; +static const bool g_bHalfLambert = HALFLAMBERT ? true : false; +#if (defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL) +static const bool g_bDecalOffset = true; +#else +static const bool g_bDecalOffset = false; +#endif + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 ); +#if SEAMLESS_DETAIL || SEAMLESS_BASE +const float cSeamlessScale : register( SHADER_SPECIFIC_CONST_2); +#define SEAMLESS_SCALE cSeamlessScale.x +#endif + +const float4 cDetailTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_4 ); + +#if defined ( _X360 ) +const float4x4 g_FlashlightWorldToTexture : register( SHADER_SPECIFIC_CONST_6 ); // 6, 7, 8, 9 +#endif + +#ifdef SHADER_MODEL_VS_3_0 +// NOTE: cMorphTargetTextureDim.xy = target dimensions, +// cMorphTargetTextureDim.z = 4tuples/morph +const float3 cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); +#endif + +struct VS_INPUT +{ + // This is all of the stuff that we ever use. + float4 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vColor : COLOR0; + float3 vSpecular : COLOR1; + // make these float2's and stick the [n n 0 1] in the dot math. + float4 vTexCoord0 : TEXCOORD0; + float4 vTexCoord1 : TEXCOORD1; + float4 vTexCoord2 : TEXCOORD2; + float4 vTexCoord3 : TEXCOORD3; + + // Position and normal/tangent deltas + float3 vPosFlex : POSITION1; + float3 vNormalFlex : NORMAL1; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + + +struct VS_OUTPUT +{ + float4 projPos : POSITION; // Projection-space position +#if !defined( _X360 ) + float fog : FOG; +#endif + +#if SEAMLESS_BASE + HALF3 SeamlessTexCoord : TEXCOORD0; // Base texture x/y/z (indexed by swizzle) +#else + HALF2 baseTexCoord : TEXCOORD0; // Base texture coordinate +#endif +#if SEAMLESS_DETAIL + HALF3 SeamlessDetailTexCoord : TEXCOORD1; // Detail texture coordinate +#else + HALF2 detailTexCoord : TEXCOORD1; // Detail texture coordinate +#endif + float4 color : TEXCOORD2; // Vertex color (from lighting or unlit) + +#if CUBEMAP || _X360 + float3 worldVertToEyeVector : TEXCOORD3; // Necessary for cubemaps +#endif + + float3 worldSpaceNormal : TEXCOORD4; // Necessary for cubemaps and flashlight + +#if defined ( _X360 ) && FLASHLIGHT + float4 flashlightSpacePos : TEXCOORD5; +#endif + + float4 vProjPos : TEXCOORD6; + float4 worldPos_ProjPosZ : TEXCOORD7; + float4 fogFactorW : COLOR1; +#if SEAMLESS_DETAIL || SEAMLESS_BASE + float3 SeamlessWeights : COLOR0; // x y z projection weights +#endif + +}; + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o = ( VS_OUTPUT )0; + + bool bDynamicLight = DYNAMIC_LIGHT ? true : false; + bool bStaticLight = STATIC_LIGHT ? true : false; + bool bDoLighting = !g_bVertexColor && (bDynamicLight || bStaticLight); + + float4 vPosition = v.vPos; + float3 vNormal = 0; + if ( bDoLighting || FLASHLIGHT || SEAMLESS_BASE || SEAMLESS_DETAIL || LIGHTING_PREVIEW || g_bDecalOffset || CUBEMAP ) + { + // The vertex only contains valid normals if they are actually needed (fetching them when absent makes D3D complain) + DecompressVertex_Normal( v.vNormal, vNormal ); + } + +#if SEAMLESS_BASE || SEAMLESS_DETAIL + // compute blend weights in rgb + float3 NNormal=normalize( vNormal ); + o.SeamlessWeights.xyz = NNormal * NNormal; // sums to 1. +#endif + +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( v.vPosFlex, v.vNormalFlex, vPosition.xyz, vNormal ); +#else + ApplyMorph( morphSampler, cMorphTargetTextureDim, cMorphSubrect, + v.vVertexID, v.vTexCoord2, vPosition.xyz, vNormal ); +#endif + + // Perform skinning + float3 worldNormal, worldPos; + SkinPositionAndNormal( + g_bSkinning, + vPosition, vNormal, + v.vBoneWeights, v.vBoneIndices, + worldPos, worldNormal ); + + if ( !g_bVertexColor ) + { + worldNormal = normalize( worldNormal ); + } + +#if defined( SHADER_MODEL_VS_3_0 ) && MORPHING && DECAL + // Avoid z precision errors + worldPos += worldNormal * 0.05f * v.vTexCoord2.z; +#endif + + o.worldSpaceNormal = worldNormal; + + // Transform into projection space + float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj ); + o.projPos = vProjPos; + vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ ); + + o.vProjPos = vProjPos; + o.fogFactorW.w = CalcFog( worldPos, vProjPos, g_FogType ); +#if !defined( _X360 ) + o.fog = o.fogFactorW.w; +#endif + o.worldPos_ProjPosZ.xyz = worldPos.xyz; + o.worldPos_ProjPosZ.w = vProjPos.z; + + // Needed for cubemaps +#if CUBEMAP + o.worldVertToEyeVector.xyz = VSHADER_VECT_SCALE * (cEyePos - worldPos); +#endif + +#if !defined (_X360) && FLASHLIGHT + o.color = float4( 0.0f, 0.0f, 0.0f, 0.0f ); +#else + if ( g_bVertexColor ) + { + // Assume that this is unlitgeneric if you are using vertex color. + o.color.rgb = ( DONT_GAMMA_CONVERT_VERTEX_COLOR ) ? v.vColor.rgb : GammaToLinear( v.vColor.rgb ); + o.color.a = v.vColor.a; + } + else + { + #if ( ( USE_STATIC_CONTROL_FLOW ) || defined ( SHADER_MODEL_VS_3_0 ) ) + { + o.color.xyz = DoLighting( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert ); + } + #else + { + o.color.xyz = DoLightingUnrolled( worldPos, worldNormal, v.vSpecular, bStaticLight, bDynamicLight, g_bHalfLambert, NUM_LIGHTS ); + } + #endif + } +#endif + + +#if SEAMLESS_BASE + o.SeamlessTexCoord.xyz = SEAMLESS_SCALE * v.vPos.xyz; +#else + // Base texture coordinates + o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] ); + o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] ); +#endif + +#if SEAMLESS_DETAIL + // FIXME: detail texcoord as a 2d xform doesn't make much sense here, so I just do enough so + // that scale works. More smartness could allow 3d xform. + o.SeamlessDetailTexCoord.xyz = (SEAMLESS_SCALE*cDetailTexCoordTransform[0].x) * v.vPos.xyz; +#else + // Detail texture coordinates + // FIXME: This shouldn't have to be computed all the time. + o.detailTexCoord.x = dot( v.vTexCoord0, cDetailTexCoordTransform[0] ); + o.detailTexCoord.y = dot( v.vTexCoord0, cDetailTexCoordTransform[1] ); +#endif + +#if SEPARATE_DETAIL_UVS + o.detailTexCoord.xy = v.vTexCoord1.xy; +#endif + +#if LIGHTING_PREVIEW + float dot=0.5+0.5*worldNormal*float3(0.7071,0.7071,0); + o.color.xyz=float3(dot,dot,dot); +#endif + +#if defined ( _X360 ) && FLASHLIGHT + o.flashlightSpacePos = mul( float4( worldPos, 1.0f ), g_FlashlightWorldToTexture ); +#endif + + return o; +} + + diff --git a/sp/src/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc b/sp/src/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc new file mode 100644 index 00000000..52812637 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc @@ -0,0 +1,68 @@ +//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ====== + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "DIFFUSELIGHTING" "0..1" +// STATIC: "HALFLAMBERT" "0..1" + +// DYNAMIC: "AMBIENT_LIGHT" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..2" [ps20] +// DYNAMIC: "NUM_LIGHTS" "0..4" [ps20b] + +#define HDRTYPE HDR_TYPE_NONE +#include "common_vertexlitgeneric_dx9.h" + +const float4 g_OverbrightFactor : register( c4 ); +const float3 cAmbientCube[6] : register( c6 ); + +PixelShaderLightInfo cLightInfo[3] : register(c13); + +sampler BumpmapSampler : register( s0 ); +sampler NormalizeSampler : register( s1 ); + +struct PS_INPUT +{ + float2 baseTexCoord : TEXCOORD0; + // detail textures and bumpmaps are mutually exclusive so that we have enough texcoords. + float2 detailOrBumpTexCoord : TEXCOORD1; + // bump mapping and a separate envmap mask texture are mutually exclusive. + float2 envmapMaskTexCoord : TEXCOORD2; + float3 worldVertToEyeVector : TEXCOORD3; + float3x3 tangentSpaceTranspose : TEXCOORD4; + float4 worldPos_projPosZ : TEXCOORD5; + float2 lightAtten01 : TEXCOORD6; + float2 lightAtten23 : TEXCOORD7; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + bool bDiffuseLighting = DIFFUSELIGHTING ? true : false; + bool bHalfLambert = HALFLAMBERT ? true : false; + bool bAmbientLight = AMBIENT_LIGHT ? true : false; + int nNumLights = NUM_LIGHTS; + + float4 vLightAtten = float4( i.lightAtten01, i.lightAtten23 ); + + float3 tangentSpaceNormal = float3( 0.0f, 0.0f, 1.0f ); + float4 normalTexel = 1.0f; + float4 baseColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + + normalTexel = tex2D( BumpmapSampler, i.detailOrBumpTexCoord ); + tangentSpaceNormal = 2.0f * normalTexel - 1.0f; + + float3 diffuseLighting = float3( 1.0f, 1.0f, 1.0f ); + if( bDiffuseLighting ) + { + float3 worldSpaceNormal = mul( i.tangentSpaceTranspose, tangentSpaceNormal ); + float3 staticLightingColor = float3( 0.0f, 0.0f, 0.0f ); + diffuseLighting = PixelShaderDoLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, + float3( 0.0f, 0.0f, 0.0f ), false, bAmbientLight, + vLightAtten, cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert, + false, 0, false, NormalizeSampler ); + // multiply by .5 since we want a 50% (in gamma space) reflective surface) + diffuseLighting *= pow( 0.5f, 2.2f ); + } + + return FinalOutput( float4( diffuseLighting, 1.0f ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE ); +} + diff --git a/sp/src/materialsystem/stdshaders/vertexlit_notexture.psh b/sp/src/materialsystem/stdshaders/vertexlit_notexture.psh new file mode 100644 index 00000000..8b550bde --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlit_notexture.psh @@ -0,0 +1,13 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +mov r0, v0 +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh new file mode 100644 index 00000000..5faa681d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask (in alpha channel) + +mul r0, t0, c3 ; base times modulation +mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) +mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh new file mode 100644 index 00000000..ab653f19 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask (in alpha channel) +tex t3 ; detail texture + +mul r0, t0, c3 ; base times modulation +mul_x2 r0.rgb, r0, t3 ; detail texture +mul r1, t1, 1-t2.a ; Envmap * mask (in alpha channel) +mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh new file mode 100644 index 00000000..ac030f0a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t3 ; detail texture + +mul r0, t0, c3 ; base times modulation +mul_x2 r0.rgb, r0, t3 ; detail texture +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh new file mode 100644 index 00000000..51873a08 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh @@ -0,0 +1,21 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask +tex t3 ; detail texture + +mul r0, t0, c3 ; Base times modulation +mul_x2 r0.rgb, r0, t3 ; detail texture +mul r1, t1, t2 ; Envmap * mask +mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh new file mode 100644 index 00000000..44dee8d4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh @@ -0,0 +1,28 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 +tex t1 +tex t3 + +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh new file mode 100644 index 00000000..4be599ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh @@ -0,0 +1,29 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 ; base +tex t1 ; env map +tex t2 ; mask +tex t3 ; Detail + +mul r0.rgb, t0, c3 + ; base times modulation +mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha + +mul_x2 r0.rgb, r0, t3 ; detail texture + +mul r1, t2, t1 ; envmapmask * envmap +mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp new file mode 100644 index 00000000..8ecd111f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp @@ -0,0 +1,421 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( VertexLitGeneric, VertexLitGeneric_DX6 ) + +BEGIN_SHADER( VertexLitGeneric_DX6, + "Help for VertexLitGeneric_DX6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + // No envmap uses mode 0, it's one less pass + // Also, if multipass = 0, then go to mode 0 also + if ( ( !params[ENVMAP]->IsDefined() ) || + ( !IS_FLAG_SET(MATERIAL_VAR_MULTIPASS) ) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ENVMAPMODE ); + } + + // Vertex color requires mode 1 + if ( IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPMODE ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if ( IS_FLAG_SET(MATERIAL_VAR_DECAL) ) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + SET_FLAGS2( MATERIAL_VAR2_NEEDS_SOFTWARE_LIGHTING ); + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + LoadCubeMap( ENVMAP ); + else + LoadTexture( ENVMAP ); + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + LoadTexture( ENVMAPMASK ); + } + } + + int GetDrawFlagsPass1(IMaterialVar** params) + { + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_COLOR; + if (params[BASETEXTURE]->IsTexture()) + flags |= SHADER_DRAW_TEXCOORD0; + return flags; + } + + void DrawVertexLightingOnly( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); + + SetModulationShadowState(); + SetDefaultBlendingShadowState( ); + pShaderShadow->DrawFlags( GetDrawFlagsPass1( params ) ); + DefaultFog(); + } + DYNAMIC_STATE + { + SetModulationDynamicState(); + } + Draw(); + } + + void MultiplyByVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + // FIXME: How to deal with texture alpha?? + + pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); + pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, false ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, false ); + + // NOTE: We're not doing lightmapping here, but we want to use the + // same blend mode as we used for lightmapping + pShaderShadow->EnableBlending( true ); + SingleTextureLightmapBlendMode(); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 1 ); + + // This here will perform color = vertex light * (cc alpha) + 1 * (1 - cc alpha) + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_CONSTANTALPHA, + SHADER_TEXARG_VERTEXCOLOR, SHADER_TEXARG_CONSTANTCOLOR ); + + // Alpha isn't used, it doesn't matter what we set it to. + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_NONE, SHADER_TEXARG_NONE ); + + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_COLOR ); + FogToOOOverbright(); + } + DYNAMIC_STATE + { + // Put the alpha in the color channel to modulate the color down.... + float alpha = GetAlpha(); + pShaderAPI->Color4f( OO_OVERBRIGHT, OO_OVERBRIGHT, OO_OVERBRIGHT, alpha ); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableCustomPixelPipe( false ); + } + } + + + //----------------------------------------------------------------------------- + // Used by mode 1 + //----------------------------------------------------------------------------- + + void DrawBaseTimesVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // Base times vertex lighting, no vertex color + SHADOW_STATE + { + // alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + // base + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, OVERBRIGHT ); + + // Independenly configure alpha and color + + // Color = Color mod * Vertex Light * Tex (x2) + // Alpha = Constant Alpha * Tex Alpha (no tex alpha if self illum == 1) + // Can't have color modulation here + pShaderShadow->EnableConstantColor( IsColorModulating() ); + + // Independenly configure alpha and color + pShaderShadow->EnableAlphaPipe( true ); + pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); + pShaderShadow->EnableVertexAlpha( IS_FLAG_SET(MATERIAL_VAR_VERTEXALPHA) ); + + if (!IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && !IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE0, true ); + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + pShaderShadow->DrawFlags( GetDrawFlagsPass1( params ) ); + DefaultFog(); + } + DYNAMIC_STATE + { + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetModulationDynamicState(); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableAlphaPipe( false ); + } + } + + //----------------------------------------------------------------------------- + // Envmap times vertex lighting, no vertex color + //----------------------------------------------------------------------------- + + void DrawEnvmapTimesVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + int materialVarFlags = params[FLAGS]->GetIntValue(); + + // alpha test + pShaderShadow->EnableAlphaTest( false ); + + int flags = SetShadowEnvMappingState( ENVMAPMASK ) | SHADER_DRAW_COLOR; + bool hasEnvMapMask = params[ENVMAPMASK]->IsTexture(); + + pShaderShadow->OverbrightValue( hasEnvMapMask ? + SHADER_TEXTURE_STAGE1 : SHADER_TEXTURE_STAGE0, OVERBRIGHT ); + + // Independenly configure alpha and color + + // Color = Env map * Vertex Light * Envmapmask (x2) + // Alpha = Constant Alpha * Vertex light alpha * Env Map mask Alpha + pShaderShadow->EnableConstantColor( IsColorModulating() ); + + pShaderShadow->EnableAlphaPipe( true ); + pShaderShadow->EnableConstantAlpha( IsAlphaModulating() ); + pShaderShadow->EnableVertexAlpha( (materialVarFlags & MATERIAL_VAR_VERTEXALPHA) != 0 ); + if (hasEnvMapMask) + pShaderShadow->EnableTextureAlpha( SHADER_TEXTURE_STAGE1, true ); + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + } + DYNAMIC_STATE + { + SetDynamicEnvMappingState( ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); + } + Draw(); + + SHADOW_STATE + { + pShaderShadow->EnableCustomPixelPipe( false ); + pShaderShadow->EnableAlphaPipe( false ); + } + } + + void DrawMode1( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + bool texDefined = params[BASETEXTURE]->IsTexture(); + bool envDefined = params[ENVMAP]->IsTexture(); +// bool maskDefined = params[ENVMAPMASK]->IsTexture(); + + // Pass 1 : Base + env + + // FIXME: Could make it 1 pass for base + env, if it wasn't + // for the envmap tint. So this is 3 passes for now.... + + // If it's base + mask * env, gotta do that in 2 passes + // Gotta do funky stuff to fade out self-illuminated stuff + bool hasEnvMapTint = !IsWhite(ENVMAPTINT); + + // Special case, can do in one pass + if (!hasEnvMapTint && !texDefined && !IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR) && + !IsColorModulating() ) + { + DrawEnvmapTimesVertexLighting( params, pShaderAPI, pShaderShadow ); + return; + } + + if (texDefined) + { + FixedFunctionBaseTimesDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + else + { + FixedFunctionMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + + // We can get here if multipass isn't set if we specify a vertex color + if ( IS_FLAG_SET(MATERIAL_VAR_MULTIPASS) ) + { + if ( texDefined && envDefined ) + { + FixedFunctionAdditiveMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + } + + // Pass 2 : * vertex lighting + MultiplyByVertexLighting( params, pShaderAPI, pShaderShadow ); + + // FIXME: We could add it to the lightmap + // Draw the selfillum pass (blows away envmap at self-illum points) + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) + { + FixedFunctionSelfIlluminationPass( + SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); + } + } + + void DrawMode0( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + // Pass 1 : Base * lightmap or just lightmap + if ( params[BASETEXTURE]->IsTexture() ) + { + DrawBaseTimesVertexLighting( params, pShaderAPI, pShaderShadow ); + + // Detail map + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + + // Draw the selfillum pass + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) + { + FixedFunctionSelfIlluminationPass( + SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); + } + } + else + { + DrawVertexLightingOnly( params, pShaderAPI, pShaderShadow ); + + // Detail map + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + + // Pass 2 : Masked environment map + if ( params[ENVMAP]->IsTexture() && + (IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) ) + { + FixedFunctionAdditiveMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + } + + SHADER_DRAW + { + bool useMode1 = IS_FLAG_SET(MATERIAL_VAR_ENVMAPMODE); + if (!useMode1) + { + // Base * Vertex Lighting + env + DrawMode0( params, pShaderAPI, pShaderShadow ); + } + else + { + // ( Base + env ) * Vertex Lighting + DrawMode1( params, pShaderAPI, pShaderShadow ); + } + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp new file mode 100644 index 00000000..7a114a56 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp @@ -0,0 +1,413 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( VertexLitGeneric, VertexLitGeneric_DX7 ) +DEFINE_FALLBACK_SHADER( Skin_DX9, VertexLitGeneric_DX7 ) + +BEGIN_SHADER( VertexLitGeneric_DX7, + "Help for VertexLitGeneric_DX7" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + SET_FLAGS2( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS ); + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + } + + SHADER_FALLBACK + { + if (g_pHardwareConfig->GetDXSupportLevel() < 70) + return "VertexLitGeneric_DX6"; + + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + LoadCubeMap( ENVMAP ); + else + LoadTexture( ENVMAP ); + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + LoadTexture( ENVMAPMASK ); + } + } + + void DrawBaseTimesVertexColor( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + // alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + pShaderShadow->EnableCustomPixelPipe( true ); + + pShaderShadow->CustomTextureStages( 1 ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_VERTEXCOLOR ); + + // Get alpha from the texture so that alpha blend and alpha test work properly. + bool bTextureIsTranslucent = TextureIsTranslucent( BASETEXTURE, true ); + if ( bTextureIsTranslucent ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_NONE ); + } + else + { + if ( IsAlphaModulating() ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_ONE, SHADER_TEXARG_NONE ); + } + } + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_NORMAL | SHADER_DRAW_TEXCOORD0; + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + + if ( IsAlphaModulating() || IsColorModulating() ) + { + pShaderShadow->CustomTextureStages( 2 ); + + if ( IsColorModulating() ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + } + + // Get alpha from the texture so that alpha blend and alpha test work properly. + if ( IsAlphaModulating() && bTextureIsTranslucent ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + } + } + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + DYNAMIC_STATE + { + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetModulationDynamicState(); + } + Draw(); + } + + void DrawVertexColorNoBase( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + pShaderShadow->EnableCustomPixelPipe( true ); + + pShaderShadow->CustomTextureStages( 1 ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_ONE, SHADER_TEXARG_VERTEXCOLOR ); + + int flags = SHADER_DRAW_POSITION; + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + } + DYNAMIC_STATE + { +// SetModulationDynamicState(); + } + Draw(); + } + + void DrawBaseTimesBakedVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + // alpha test + pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) ); + + // base + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + int flags = SHADER_DRAW_POSITION; + if (params[BASETEXTURE]->IsTexture()) + { + flags |= SHADER_DRAW_TEXCOORD1; + } + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 1 ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_SPECULARCOLOR, SHADER_TEXARG_TEXTURE ); + + // Get alpha from the texture so that alpha blend and alpha test work properly. + bool bTextureIsTranslucent = TextureIsTranslucent( BASETEXTURE, true ); + if ( bTextureIsTranslucent ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_NONE ); + } + else + { + if ( IsAlphaModulating() ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_ONE, SHADER_TEXARG_NONE ); + } + } + + if ( IsAlphaModulating() || IsColorModulating() ) + { + pShaderShadow->CustomTextureStages( 2 ); + + if ( IsColorModulating()) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + } + + // Get alpha from the texture so that alpha blend and alpha test work properly. + if ( IsAlphaModulating() && bTextureIsTranslucent ) + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR ); + } + else + { + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); + } + } + + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + DYNAMIC_STATE + { + SetFixedFunctionTextureTransform( MATERIAL_TEXTURE1, BASETEXTURETRANSFORM ); + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetModulationDynamicState(); + } + Draw(); + } + + void DrawBakedVertexLightingNoBase( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow ) + { + SHADOW_STATE + { + int flags = SHADER_DRAW_POSITION; + pShaderShadow->DrawFlags( flags ); + DefaultFog(); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 1 ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_SPECULARCOLOR, SHADER_TEXARG_NONE ); + + // Alpha isn't used, it doesn't matter what we set it to. + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_NONE, SHADER_TEXARG_NONE ); + } + DYNAMIC_STATE + { + } + Draw(); + } + + SHADER_DRAW + { + bool bBakedLighting = IS_FLAG2_SET( MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING ); + bool hasFlashlight = UsingFlashlight( params ); + + if( hasFlashlight ) + { + DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + return; + } + // Pass 1 : Base * lightmap or just lightmap + if ( params[BASETEXTURE]->IsTexture() ) + { + // Draw base times lighting. + // Lighting is either sent down per vertex from the app, or it's in the second + // stream as color values. + if( bBakedLighting ) + { + DrawBaseTimesBakedVertexLighting( params, pShaderAPI, pShaderShadow ); + } + else + { + DrawBaseTimesVertexColor( params, pShaderAPI, pShaderShadow ); + } + + // Detail map + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + + // Draw the selfillum pass + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) ) + { + FixedFunctionSelfIlluminationPass( + SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT ); + } + } + else + { + if( bBakedLighting ) + { + DrawBakedVertexLightingNoBase( params, pShaderAPI, pShaderShadow ); + } + else + { + DrawVertexColorNoBase( params, pShaderAPI, pShaderShadow ); + } + + FixedFunctionMultiplyByDetailPass( + BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE ); + } + + + // Pass 2 : Masked environment map + if ( params[ENVMAP]->IsTexture() && (IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) ) + { + FixedFunctionAdditiveMaskedEnvmapPass( + ENVMAP, ENVMAPMASK, BASETEXTURE, + ENVMAPFRAME, ENVMAPMASKFRAME, FRAME, + BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT ); + } + + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp new file mode 100644 index 00000000..31addf42 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp @@ -0,0 +1,807 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "vertexlitgeneric_vs11.inc" +#include "vertexlitgeneric_selfillumonly.inc" +#include "emissive_scroll_blended_pass_helper.h" +#include "flesh_interior_blended_pass_helper.h" +#include "cloak_blended_pass_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( VertexLitGeneric, VertexLitGeneric_DX8 ) +DEFINE_FALLBACK_SHADER( Skin_DX9, VertexLitGeneric_DX8 ) + +BEGIN_VS_SHADER( VertexLitGeneric_DX8, + "Help for VertexLitGeneric" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" ) + SHADER_PARAM( FORCEBUMP, SHADER_PARAM_TYPE_BOOL, "0", "0 == Do bumpmapping if the card says it can handle it. 1 == Always do bumpmapping." ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + + // Emissive Scroll Pass + SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) + SHADER_PARAM( EMISSIVEBLENDBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) + SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) + SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + // Color Replacement Pass + SHADER_PARAM( BLENDTINTBYBASEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use the base alpha to blend in the $color modulation") + SHADER_PARAM( BLENDTINTCOLOROVERBASE, SHADER_PARAM_TYPE_FLOAT, "0", "blend between tint acting as a multiplication versus a replace" ) + + END_SHADER_PARAMS + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + + // Delete these lines if not bump mapping! + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + // Emissive Scroll Pass + void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) + { + info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; + info.m_nBaseTexture = EMISSIVEBLENDBASETEXTURE; + info.m_nFlowTexture = -1; // Not used in DX8 + info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; + info.m_nEmissiveTint = EMISSIVEBLENDTINT; + info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; + info.m_nTime = TIME; + } + + // Flesh Interior Pass + void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) + { + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + + info.m_nTime = TIME; + } + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + // We don't want no stinking bump mapping on models in dx8. + // Wait a minute! We want specular bump. .need to make that work by itself. +// params[BUMPMAP]->SetUndefined(); +// if( IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ) ) +// { +// CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); +// params[ENVMAP]->SetUndefined(); +// } + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if( !params[ENVMAPMASKSCALE]->IsDefined() ) + params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPMASKFRAME]->IsDefined() ) + params[ENVMAPMASKFRAME]->SetIntValue( 0 ); + + if( !params[ENVMAPTINT]->IsDefined() ) + params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + + if( !params[DETAILSCALE]->IsDefined() ) + params[DETAILSCALE]->SetFloatValue( 4.0f ); + + if( !params[DETAILBLENDFACTOR]->IsDefined() ) + params[DETAILBLENDFACTOR]->SetFloatValue( 1.0f ); + + if( !params[DETAILBLENDMODE]->IsDefined() ) + params[DETAILBLENDMODE]->SetFloatValue( 0 ); + + if( !params[ENVMAPCONTRAST]->IsDefined() ) + params[ENVMAPCONTRAST]->SetFloatValue( 0.0f ); + + if( !params[ENVMAPSATURATION]->IsDefined() ) + params[ENVMAPSATURATION]->SetFloatValue( 1.0f ); + + if( !params[ENVMAPFRAME]->IsDefined() ) + params[ENVMAPFRAME]->SetIntValue( 0 ); + + if( !params[BUMPFRAME]->IsDefined() ) + params[BUMPFRAME]->SetIntValue( 0 ); + + if( !params[ALPHATESTREFERENCE]->IsDefined() ) + params[ALPHATESTREFERENCE]->SetFloatValue( 0.0f ); + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + + // Get rid of the envmap if it's optional for this dx level. + if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If mat_specular 0, then get rid of envmap + if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() ) + { + params[ENVMAP]->SetUndefined(); + } + + // If a bumpmap is defined but an envmap isn't, then ignore the bumpmap. + // It was meant to be used with diffuse + if ( !params[ENVMAP]->IsDefined() ) + { + params[BUMPMAP]->SetUndefined(); + } + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + + // Emissive Scroll Pass + if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) + { + params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); + } + else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); + } + + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } + + // Color Replacement Pass + if ( !params[BLENDTINTBYBASEALPHA]->IsDefined() ) + { + params[BLENDTINTBYBASEALPHA]->SetIntValue(0); + } + + if ( !params[BLENDTINTCOLOROVERBASE]->IsDefined() ) + { + params[BLENDTINTCOLOROVERBASE]->SetFloatValue(0); + } + } + + SHADER_FALLBACK + { + if ( IsPC() ) + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 70) + return "VertexLitGeneric_DX6"; + + if ( g_pHardwareConfig->GetDXSupportLevel() < 80) + return "VertexLitGeneric_DX7"; + + if ( g_pHardwareConfig->PreferReducedFillrate() ) + return "VertexLitGeneric_NoBump_DX8"; + } + return 0; + } + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + if (g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined()) + { + LoadBumpMap( BUMPMAP ); + } + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if (params[ENVMAP]->IsDefined()) + { + if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + LoadCubeMap( ENVMAP ); + } + else + { + LoadTexture( ENVMAP ); + } + + if( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + + if (params[ENVMAPMASK]->IsDefined()) + { + LoadTexture( ENVMAPMASK ); + } + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitEmissiveScrollBlendedPass( this, params, info ); + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } + } + + inline const char *GetUnbumpedPixelShaderName( IMaterialVar** params, bool bSkipEnvmap ) + { + static char const* s_pPixelShaders[] = + { + "VertexLitGeneric_EnvmapV2", + "VertexLitGeneric_SelfIlluminatedEnvmapV2", + + "VertexLitGeneric_BaseAlphaMaskedEnvmapV2", + "VertexLitGeneric_SelfIlluminatedEnvmapV2", + + // Env map mask + "VertexLitGeneric_MaskedEnvmapV2", + "VertexLitGeneric_SelfIlluminatedMaskedEnvmapV2", + + "VertexLitGeneric_MaskedEnvmapV2", + "VertexLitGeneric_SelfIlluminatedMaskedEnvmapV2", + + // Detail + "VertexLitGeneric_DetailEnvmapV2", + "VertexLitGeneric_DetailSelfIlluminatedEnvmapV2", + + "VertexLitGeneric_DetailBaseAlphaMaskedEnvmapV2", + "VertexLitGeneric_DetailSelfIlluminatedEnvmapV2", + + // Env map mask + "VertexLitGeneric_DetailMaskedEnvmapV2", + "VertexLitGeneric_DetailSelfIlluminatedMaskedEnvmapV2", + + "VertexLitGeneric_DetailMaskedEnvmapV2", + "VertexLitGeneric_DetailSelfIlluminatedMaskedEnvmapV2", + }; + + if ( !params[BASETEXTURE]->IsTexture() ) + { + if (params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + if (!params[ENVMAPMASK]->IsTexture()) + { + return "VertexLitGeneric_EnvmapNoTexture"; + } + else + { + return "VertexLitGeneric_MaskedEnvmapNoTexture"; + } + } + else + { + if ( params[DETAIL]->IsTexture() ) + { + return "VertexLitGeneric_DetailNoTexture"; + } + else + { + return "VertexLitGeneric_NoTexture"; + } + } + } + else + { + if ( params[BLENDTINTBYBASEALPHA]->GetIntValue() ) + { + return "VertexLitGeneric_BlendTint"; + } + else if ( params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + int pshIndex = 0; + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + pshIndex |= 0x1; + if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK)) + pshIndex |= 0x2; + if (params[ENVMAPMASK]->IsTexture()) + pshIndex |= 0x4; + if (params[DETAIL]->IsTexture()) + pshIndex |= 0x8; + return s_pPixelShaders[pshIndex]; + } + else + { + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM)) + { + if ( params[DETAIL]->IsTexture() ) + return "VertexLitGeneric_DetailSelfIlluminated"; + else + return "VertexLitGeneric_SelfIlluminated"; + } + else if ( params[DETAIL]->IsTexture() ) + { + switch( params[DETAILBLENDMODE]->GetIntValue() ) + { + case 0: + return "VertexLitGeneric_Detail"; + + case 1: // additive modes + return "VertexLitGeneric_Detail_Additive"; + + case 5: + case 6: + return "VertexLitGeneric_Detail_Additive_selfillum"; + break; + + default: + return "VertexLitGeneric_Detail_LerpBase"; + } + } + else + { + return "VertexLitGeneric"; + } + } + } + } + + void DrawUnbumpedUsingVertexShader( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bSkipEnvmap ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); + + if ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); + } + + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + + // FIXME: We could enable this, but we'd never get it working on dx7 or lower + // FIXME: This isn't going to work until we make more vertex shaders that + // pass the vertex color and alpha values through. +#if 0 + if ( IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) || IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ) ) + fmt |= VERTEX_COLOR; +#endif + + if (params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + // envmap on stage 1 + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + // envmapmask on stage 2 + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK ) ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + } + + if (params[BASETEXTURE]->IsTexture()) + { + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + else + { + SetDefaultBlendingShadowState( ENVMAPMASK, false ); + } + + if ( params[DETAIL]->IsTexture()) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + // Set up the vertex shader index. + vertexlitgeneric_vs11_Static_Index vshIndex; + vshIndex.SetHALF_LAMBERT( IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); + //vshIndex.SetDETAIL( params[DETAIL]->IsTexture() ); + if( params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + vshIndex.SetENVMAP( true ); + vshIndex.SetENVMAPCAMERASPACE( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) ); + if( IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE) ) + { + vshIndex.SetENVMAPSPHERE( false ); + } + else + { + vshIndex.SetENVMAPSPHERE( IS_FLAG_SET( MATERIAL_VAR_ENVMAPSPHERE ) ); + } + } + else + { + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + } + pShaderShadow->SetVertexShader( "vertexlitgeneric_vs11", vshIndex.GetIndex() ); + + const char *pshName = GetUnbumpedPixelShaderName( params, bSkipEnvmap ); + pShaderShadow->SetPixelShader( pshName ); + DefaultFog(); + pShaderShadow->EnableAlphaWrites( true ); + } + DYNAMIC_STATE + { + if (params[BASETEXTURE]->IsTexture()) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + +// if (params[ENVMAP]->IsTexture()) + if (params[ENVMAP]->IsTexture() && !bSkipEnvmap ) + { + BindTexture( SHADER_SAMPLER1, ENVMAP, ENVMAPFRAME ); + + if (params[ENVMAPMASK]->IsTexture() || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + if (params[ENVMAPMASK]->IsTexture() ) + BindTexture( SHADER_SAMPLER2, ENVMAPMASK, ENVMAPMASKFRAME ); + else + BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); + + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, ENVMAPMASKSCALE ); + } + + if (IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) || + IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE)) + { + LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL ); + } + SetEnvMapTintPixelShaderDynamicState( 2, ENVMAPTINT, -1 ); + } + + if ( params[DETAIL]->IsTexture()) + { + BindTexture( SHADER_SAMPLER3, DETAIL, DETAILFRAME ); + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); + } + + SetAmbientCubeDynamicStateVertexShader(); + SetModulationPixelShaderDynamicState( 3 ); + EnablePixelShaderOverbright( 0, true, true ); + SetPixelShaderConstant( 1, SELFILLUMTINT ); + + if ( params[DETAIL]->IsTexture() && ( ! IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) ) ) + { + float c1[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + c1[0] = c1[1] = c1[2] = c1[3] = params[DETAILBLENDFACTOR]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 1, c1, 1 ); + } + + if ( params[BLENDTINTBYBASEALPHA]->GetIntValue() ) + { + float c1[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + c1[0] = c1[1] = c1[2] = c1[3] = params[BLENDTINTCOLOROVERBASE]->GetFloatValue(); + pShaderAPI->SetPixelShaderConstant( 1, c1 ); + } + + vertexlitgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 ); + vshIndex.SetLIGHT_COMBO( pShaderAPI->GetCurrentLightCombo() ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + if( pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_WRITE_DEPTH_TO_DESTALPHA ) ) + { + pShaderAPI->SetPixelShaderIndex( 0 ); + } + else + { + // write 255 to alpha if we aren't told to write depth to dest alpha (We don't ever actually write depth to dest alpha in dx8) + pShaderAPI->SetPixelShaderIndex( 1 ); + float c4[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + pShaderAPI->SetPixelShaderConstant( 4, c4, 1 ); + } + } + Draw(); + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( false/*disabled! no effect*/ && params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + // There is some strangeness in DX8 when trying to skip the main pass, so leave this alone for now + //bDrawStandardPass = false; + } + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + // FLASHLIGHTFIXME: need to make these the same. + bool hasFlashlight = UsingFlashlight( params ); + bool bBump = g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsTexture(); + + if( hasFlashlight ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, bBump, BUMPMAP, BUMPFRAME, BUMPTRANSFORM, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, false, false, 0, -1, -1 ); + } + else if( bBump ) + { + bool bSkipEnvmap = true; + DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bSkipEnvmap ); + + // specular pass + bool bBlendSpecular = true; + if( params[ENVMAP]->IsTexture() ) + { + DrawModelBumpedSpecularLighting( BUMPMAP, BUMPFRAME, ENVMAP, ENVMAPFRAME, + ENVMAPTINT, ALPHA, ENVMAPCONTRAST, ENVMAPSATURATION, BUMPTRANSFORM, bBlendSpecular ); + } + } + else + { + bool bSkipEnvmap = false; + DrawUnbumpedUsingVertexShader( params, pShaderAPI, pShaderShadow, bSkipEnvmap ); + } + } + else + { + // Skip this pass! + Draw( false ); + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER + + +//----------------------------------------------------------------------------- +// Version that doesn't do bumpmapping +//----------------------------------------------------------------------------- +BEGIN_INHERITED_SHADER( VertexLitGeneric_NoBump_DX8, VertexLitGeneric_DX8, + "Help for VertexLitGeneric_NoBump_DX8" ) + + SHADER_FALLBACK + { + if (g_pConfig->bSoftwareLighting) + return "VertexLitGeneric_DX6"; + + if (!g_pHardwareConfig->SupportsVertexAndPixelShaders()) + return "VertexLitGeneric_DX7"; + + return 0; + } + + virtual bool ShouldUseBumpmapping( IMaterialVar **params ) + { + if ( !g_pConfig->UseBumpmapping() ) + return false; + + if ( !params[BUMPMAP]->IsDefined() ) + return false; + + return ( params[FORCEBUMP]->GetIntValue() != 0 ); + } + +END_INHERITED_SHADER + diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp new file mode 100644 index 00000000..47105813 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp @@ -0,0 +1,520 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=====================================================================================// + +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx9_helper.h" +#include "emissive_scroll_blended_pass_helper.h" +#include "cloak_blended_pass_helper.h" +#include "flesh_interior_blended_pass_helper.h" +#include "weapon_sheen_pass_helper.h" + + +BEGIN_VS_SHADER( VertexLitGeneric, "Help for VertexLitGeneric" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( COMPRESS, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "compression wrinklemap" ) + SHADER_PARAM( STRETCH, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "expansion wrinklemap" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "envmap frame number" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPCOMPRESS, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "compression bump map" ) + SHADER_PARAM( BUMPSTRETCH, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "expansion bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( SELFILLUM_ENVMAPMASK_ALPHA, SHADER_PARAM_TYPE_FLOAT,"0.0","defines that self illum value comes from env map mask alpha" ) + SHADER_PARAM( SELFILLUMFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "Self illum fresnel" ) + SHADER_PARAM( SELFILLUMFRESNELMINMAXEXP, SHADER_PARAM_TYPE_VEC4, "0", "Self illum fresnel min, max, exp" ) + SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( FLASHLIGHTNOLAMBERT, SHADER_PARAM_TYPE_BOOL, "0", "Flashlight pass sets N.L=1.0" ) + + // Debugging term for visualizing ambient data on its own + SHADER_PARAM( AMBIENTONLY, SHADER_PARAM_TYPE_INTEGER, "0", "Control drawing of non-ambient light ()" ) + + SHADER_PARAM( PHONGEXPONENT, SHADER_PARAM_TYPE_FLOAT, "5.0", "Phong exponent for local specular lights" ) + SHADER_PARAM( PHONGTINT, SHADER_PARAM_TYPE_VEC3, "5.0", "Phong tint for local specular lights" ) + SHADER_PARAM( PHONGALBEDOTINT, SHADER_PARAM_TYPE_BOOL, "1.0", "Apply tint by albedo (controlled by spec exponent texture" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "1D ramp texture for tinting scalar diffuse term" ) + SHADER_PARAM( PHONGWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "warp the specular term" ) + SHADER_PARAM( PHONGFRESNELRANGES, SHADER_PARAM_TYPE_VEC3, "[0 0.5 1]", "Parameters for remapping fresnel output" ) + SHADER_PARAM( PHONGBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Phong overbrightening factor (specular mask channel should be authored to account for this)" ) + SHADER_PARAM( PHONGEXPONENTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "Phong Exponent map" ) + SHADER_PARAM( PHONG, SHADER_PARAM_TYPE_BOOL, "0", "enables phong lighting" ) + SHADER_PARAM( BASEMAPALPHAPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "indicates that there is no normal map and that the phong mask is in base alpha" ) + SHADER_PARAM( INVERTPHONGMASK, SHADER_PARAM_TYPE_INTEGER, "0", "invert the phong mask (0=full phong, 1=no phong)" ) + SHADER_PARAM( ENVMAPFRESNEL, SHADER_PARAM_TYPE_FLOAT, "0", "Degree to which Fresnel should be applied to env map" ) + SHADER_PARAM( SELFILLUMMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "If we bind a texture here, it overrides base alpha (if any) for self illum" ) + + // detail (multi-) texturing + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + SHADER_PARAM( DETAILTEXTURETRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$detail texcoord transform" ) + + // Rim lighting terms + SHADER_PARAM( RIMLIGHT, SHADER_PARAM_TYPE_BOOL, "0", "enables rim lighting" ) + SHADER_PARAM( RIMLIGHTEXPONENT, SHADER_PARAM_TYPE_FLOAT, "4.0", "Exponent for rim lights" ) + SHADER_PARAM( RIMLIGHTBOOST, SHADER_PARAM_TYPE_FLOAT, "1.0", "Boost for rim lights" ) + SHADER_PARAM( RIMMASK, SHADER_PARAM_TYPE_BOOL, "0", "Indicates whether or not to use alpha channel of exponent texture to mask the rim term" ) + + // Seamless mapping scale + SHADER_PARAM( SEAMLESS_BASE, SHADER_PARAM_TYPE_BOOL, "0", "whether to apply seamless mapping to the base texture. requires a smooth model." ) + SHADER_PARAM( SEAMLESS_DETAIL, SHADER_PARAM_TYPE_BOOL, "0", "where to apply seamless mapping to the detail texture." ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "the scale for the seamless mapping. # of repetions of texture per inch." ) + + // Emissive Scroll Pass + SHADER_PARAM( EMISSIVEBLENDENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable emissive blend pass" ) + SHADER_PARAM( EMISSIVEBLENDBASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDSCROLLVECTOR, SHADER_PARAM_TYPE_VEC2, "[0.11 0.124]", "Emissive scroll vec" ) + SHADER_PARAM( EMISSIVEBLENDSTRENGTH, SHADER_PARAM_TYPE_FLOAT, "1.0", "Emissive blend strength" ) + SHADER_PARAM( EMISSIVEBLENDTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "self-illumination map" ) + SHADER_PARAM( EMISSIVEBLENDTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( EMISSIVEBLENDFLOWTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "flow map" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) + + // Cloak Pass + SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" ) + SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" ) + SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + + // Weapon Sheen Pass + SHADER_PARAM( SHEENPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables weapon sheen render in a second pass" ) + SHADER_PARAM( SHEENMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "sheenmap" ) + SHADER_PARAM( SHEENMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "sheenmap mask" ) + SHADER_PARAM( SHEENMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( SHEENMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "sheenmap tint" ) + SHADER_PARAM( SHEENMAPMASKSCALEX, SHADER_PARAM_TYPE_FLOAT, "1", "X Scale the size of the map mask to the size of the target" ) + SHADER_PARAM( SHEENMAPMASKSCALEY, SHADER_PARAM_TYPE_FLOAT, "1", "Y Scale the size of the map mask to the size of the target" ) + SHADER_PARAM( SHEENMAPMASKOFFSETX, SHADER_PARAM_TYPE_FLOAT, "0", "X Offset of the mask relative to model space coords of target" ) + SHADER_PARAM( SHEENMAPMASKOFFSETY, SHADER_PARAM_TYPE_FLOAT, "0", "Y Offset of the mask relative to model space coords of target" ) + SHADER_PARAM( SHEENMAPMASKDIRECTION, SHADER_PARAM_TYPE_INTEGER, "0", "The direction the sheen should move (length direction of weapon) XYZ, 0,1,2" ) + SHADER_PARAM( SHEENINDEX, SHADER_PARAM_TYPE_INTEGER, "0", "Index of the Effect Type (Color Additive, Override etc...)" ) + + // Flesh Interior Pass + SHADER_PARAM( FLESHINTERIORENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enable Flesh interior blend pass" ) + SHADER_PARAM( FLESHINTERIORTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh color texture" ) + SHADER_PARAM( FLESHINTERIORNOISETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh noise texture" ) + SHADER_PARAM( FLESHBORDERTEXTURE1D, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh border 1D texture" ) + SHADER_PARAM( FLESHNORMALTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh normal texture" ) + SHADER_PARAM( FLESHSUBSURFACETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh subsurface texture" ) + SHADER_PARAM( FLESHCUBETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Flesh cubemap texture" ) + SHADER_PARAM( FLESHBORDERNOISESCALE, SHADER_PARAM_TYPE_FLOAT, "1.5", "Flesh Noise UV scalar for border" ) + SHADER_PARAM( FLESHDEBUGFORCEFLESHON, SHADER_PARAM_TYPE_BOOL, "0", "Flesh Debug full flesh" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS1, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS2, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS3, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHEFFECTCENTERRADIUS4, SHADER_PARAM_TYPE_VEC4, "[0 0 0 0.001]", "Flesh effect center and radius" ) + SHADER_PARAM( FLESHSUBSURFACETINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Subsurface Color" ) + SHADER_PARAM( FLESHBORDERWIDTH, SHADER_PARAM_TYPE_FLOAT, "0.3", "Flesh border" ) + SHADER_PARAM( FLESHBORDERSOFTNESS, SHADER_PARAM_TYPE_FLOAT, "0.42", "Flesh border softness (> 0.0 && <= 0.5)" ) + SHADER_PARAM( FLESHBORDERTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Flesh border Color" ) + SHADER_PARAM( FLESHGLOBALOPACITY, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh global opacity" ) + SHADER_PARAM( FLESHGLOSSBRIGHTNESS, SHADER_PARAM_TYPE_FLOAT, "0.66", "Flesh gloss brightness" ) + SHADER_PARAM( FLESHSCROLLSPEED, SHADER_PARAM_TYPE_FLOAT, "1.0", "Flesh scroll speed" ) + + SHADER_PARAM( SEPARATEDETAILUVS, SHADER_PARAM_TYPE_BOOL, "0", "Use texcoord1 for detail texture" ) + SHADER_PARAM( LINEARWRITE, SHADER_PARAM_TYPE_INTEGER, "0", "Disables SRGB conversion of shader results." ) + SHADER_PARAM( DEPTHBLEND, SHADER_PARAM_TYPE_INTEGER, "0", "fade at intersection boundaries. Only supported without bumpmaps" ) + SHADER_PARAM( DEPTHBLENDSCALE, SHADER_PARAM_TYPE_FLOAT, "50.0", "Amplify or reduce DEPTHBLEND fading. Lower values make harder edges." ) + + SHADER_PARAM( BLENDTINTBYBASEALPHA, SHADER_PARAM_TYPE_BOOL, "0", "Use the base alpha to blend in the $color modulation") + SHADER_PARAM( BLENDTINTCOLOROVERBASE, SHADER_PARAM_TYPE_FLOAT, "0", "blend between tint acting as a multiplication versus a replace" ) + END_SHADER_PARAMS + + void SetupVars( VertexLitGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nWrinkle = COMPRESS; + info.m_nStretch = STRETCH; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nNormalWrinkle = BUMPCOMPRESS; + info.m_nNormalStretch = BUMPSTRETCH; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nAlphaTestReference = ALPHATESTREFERENCE; + info.m_nFlashlightNoLambert = FLASHLIGHTNOLAMBERT; + + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nSelfIllumEnvMapMask_Alpha = SELFILLUM_ENVMAPMASK_ALPHA; + info.m_nSelfIllumFresnel = SELFILLUMFRESNEL; + info.m_nSelfIllumFresnelMinMaxExp = SELFILLUMFRESNELMINMAXEXP; + + info.m_nAmbientOnly = AMBIENTONLY; + info.m_nPhongExponent = PHONGEXPONENT; + info.m_nPhongExponentTexture = PHONGEXPONENTTEXTURE; + info.m_nPhongTint = PHONGTINT; + info.m_nPhongAlbedoTint = PHONGALBEDOTINT; + info.m_nDiffuseWarpTexture = LIGHTWARPTEXTURE; + info.m_nPhongWarpTexture = PHONGWARPTEXTURE; + info.m_nPhongBoost = PHONGBOOST; + info.m_nPhongFresnelRanges = PHONGFRESNELRANGES; + info.m_nPhong = PHONG; + info.m_nBaseMapAlphaPhongMask = BASEMAPALPHAPHONGMASK; + info.m_nEnvmapFresnel = ENVMAPFRESNEL; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTextureTransform = DETAILTEXTURETRANSFORM; + + // Rim lighting parameters + info.m_nRimLight = RIMLIGHT; + info.m_nRimLightPower = RIMLIGHTEXPONENT; + info.m_nRimLightBoost = RIMLIGHTBOOST; + info.m_nRimMask = RIMMASK; + + // seamless + info.m_nSeamlessScale = SEAMLESS_SCALE; + info.m_nSeamlessDetail = SEAMLESS_DETAIL; + info.m_nSeamlessBase = SEAMLESS_BASE; + + info.m_nSeparateDetailUVs = SEPARATEDETAILUVS; + + info.m_nLinearWrite = LINEARWRITE; + info.m_nDetailTint = DETAILTINT; + info.m_nInvertPhongMask = INVERTPHONGMASK; + + info.m_nDepthBlend = DEPTHBLEND; + info.m_nDepthBlendScale = DEPTHBLENDSCALE; + + info.m_nSelfIllumMask = SELFILLUMMASK; + info.m_nBlendTintByBaseAlpha = BLENDTINTBYBASEALPHA; + info.m_nTintReplacesBaseColor = BLENDTINTCOLOROVERBASE; + } + + // Cloak Pass + void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info ) + { + info.m_nCloakFactor = CLOAKFACTOR; + info.m_nCloakColorTint = CLOAKCOLORTINT; + info.m_nRefractAmount = REFRACTAMOUNT; + + // Delete these lines if not bump mapping! + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + } + + // Weapon Sheen Pass + void SetupVarsWeaponSheenPass( WeaponSheenPassVars_t &info ) + { + info.m_nSheenMap = SHEENMAP; + info.m_nSheenMapMask = SHEENMAPMASK; + info.m_nSheenMapMaskFrame = SHEENMAPMASKFRAME; + info.m_nSheenMapTint = SHEENMAPTINT; + info.m_nSheenMapMaskScaleX = SHEENMAPMASKSCALEX; + info.m_nSheenMapMaskScaleY = SHEENMAPMASKSCALEY; + info.m_nSheenMapMaskOffsetX = SHEENMAPMASKOFFSETX; + info.m_nSheenMapMaskOffsetY = SHEENMAPMASKOFFSETY; + info.m_nSheenMapMaskDirection = SHEENMAPMASKDIRECTION; + info.m_nSheenIndex = SHEENINDEX; + + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + } + + bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time + return true; + else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag2 in case the base material still needs it + } + if ( params[SHEENPASSENABLED]->GetIntValue() ) // If material supports weapon sheen + return true; + + // Check flag2 if not drawing cloak pass + return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE ); + } + + bool IsTranslucent( IMaterialVar **params ) const + { + if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking + { + if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check + return true; + // else, not cloaking this frame, so check flag in case the base material still needs it + } + + // Check flag if not drawing cloak pass + return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ); + } + + // Emissive Scroll Pass + void SetupVarsEmissiveScrollBlendedPass( EmissiveScrollBlendedPassVars_t &info ) + { + info.m_nBlendStrength = EMISSIVEBLENDSTRENGTH; + info.m_nBaseTexture = EMISSIVEBLENDBASETEXTURE; + info.m_nFlowTexture = EMISSIVEBLENDFLOWTEXTURE; + info.m_nEmissiveTexture = EMISSIVEBLENDTEXTURE; + info.m_nEmissiveTint = EMISSIVEBLENDTINT; + info.m_nEmissiveScrollVector = EMISSIVEBLENDSCROLLVECTOR; + info.m_nTime = TIME; + } + + // Flesh Interior Pass + void SetupVarsFleshInteriorBlendedPass( FleshInteriorBlendedPassVars_t &info ) + { + info.m_nFleshTexture = FLESHINTERIORTEXTURE; + info.m_nFleshNoiseTexture = FLESHINTERIORNOISETEXTURE; + info.m_nFleshBorderTexture1D = FLESHBORDERTEXTURE1D; + info.m_nFleshNormalTexture = FLESHNORMALTEXTURE; + info.m_nFleshSubsurfaceTexture = FLESHSUBSURFACETEXTURE; + info.m_nFleshCubeTexture = FLESHCUBETEXTURE; + + info.m_nflBorderNoiseScale = FLESHBORDERNOISESCALE; + info.m_nflDebugForceFleshOn = FLESHDEBUGFORCEFLESHON; + info.m_nvEffectCenterRadius1 = FLESHEFFECTCENTERRADIUS1; + info.m_nvEffectCenterRadius2 = FLESHEFFECTCENTERRADIUS2; + info.m_nvEffectCenterRadius3 = FLESHEFFECTCENTERRADIUS3; + info.m_nvEffectCenterRadius4 = FLESHEFFECTCENTERRADIUS4; + + info.m_ncSubsurfaceTint = FLESHSUBSURFACETINT; + info.m_nflBorderWidth = FLESHBORDERWIDTH; + info.m_nflBorderSoftness = FLESHBORDERSOFTNESS; + info.m_ncBorderTint = FLESHBORDERTINT; + info.m_nflGlobalOpacity = FLESHGLOBALOPACITY; + info.m_nflGlossBrightness = FLESHGLOSSBRIGHTNESS; + info.m_nflScrollSpeed = FLESHSCROLLSPEED; + + info.m_nTime = TIME; + } + + SHADER_INIT_PARAMS() + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitParamsVertexLitGeneric_DX9( this, params, pMaterialName, true, vars ); + + // Cloak Pass + if ( !params[CLOAKPASSENABLED]->IsDefined() ) + { + params[CLOAKPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitParamsCloakBlendedPass( this, params, pMaterialName, info ); + } + + // Sheen Pass + if ( !params[SHEENPASSENABLED]->IsDefined() ) + { + params[SHEENPASSENABLED]->SetIntValue( 0 ); + } + else if ( params[SHEENPASSENABLED]->GetIntValue() ) + { + WeaponSheenPassVars_t info; + SetupVarsWeaponSheenPass( info ); + InitParamsWeaponSheenPass( this, params, pMaterialName, info ); + } + + // Emissive Scroll Pass + if ( !params[EMISSIVEBLENDENABLED]->IsDefined() ) + { + params[EMISSIVEBLENDENABLED]->SetIntValue( 0 ); + } + else if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitParamsEmissiveScrollBlendedPass( this, params, pMaterialName, info ); + } + + // Flesh Interior Pass + if ( !params[FLESHINTERIORENABLED]->IsDefined() ) + { + params[FLESHINTERIORENABLED]->SetIntValue( 0 ); + } + else if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitParamsFleshInteriorBlendedPass( this, params, pMaterialName, info ); + } + } + + SHADER_FALLBACK + { + if (g_pHardwareConfig->GetDXSupportLevel() < 70) + return "VertexLitGeneric_DX6"; + + if (g_pHardwareConfig->GetDXSupportLevel() < 80) + return "VertexLitGeneric_DX7"; + + if (g_pHardwareConfig->GetDXSupportLevel() < 90) + return "VertexLitGeneric_DX8"; + + return 0; + } + + SHADER_INIT + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + InitVertexLitGeneric_DX9( this, params, true, vars ); + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + InitCloakBlendedPass( this, params, info ); + } + + // TODO : Only do this if we're in range of the camera + // Weapon Sheen + if ( params[SHEENPASSENABLED]->GetIntValue() ) + { + WeaponSheenPassVars_t info; + SetupVarsWeaponSheenPass( info ); + InitWeaponSheenPass( this, params, info ); + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + InitEmissiveScrollBlendedPass( this, params, info ); + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + InitFleshInteriorBlendedPass( this, params, info ); + } + } + + SHADER_DRAW + { + // Skip the standard rendering if cloak pass is fully opaque + bool bDrawStandardPass = true; + if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + if ( CloakBlendedPassIsFullyOpaque( params, info ) ) + { + bDrawStandardPass = false; + } + } + + // Standard rendering pass + if ( bDrawStandardPass ) + { + VertexLitGeneric_DX9_Vars_t vars; + SetupVars( vars ); + DrawVertexLitGeneric_DX9( this, params, pShaderAPI, pShaderShadow, true, vars, vertexCompression, pContextDataPtr ); + } + else + { + // Skip this pass! + Draw( false ); + } + + // Weapon sheen pass + // only if doing standard as well (don't do it if cloaked) + if ( params[SHEENPASSENABLED]->GetIntValue() ) + { + WeaponSheenPassVars_t info; + SetupVarsWeaponSheenPass( info ); + if ( ( pShaderShadow != NULL ) || ( bDrawStandardPass && ShouldDrawMaterialSheen( params, info ) ) ) + { + DrawWeaponSheenPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else + { + // Skip this pass! + Draw( false ); + } + } + + // Cloak Pass + if ( params[CLOAKPASSENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) ) + { + CloakBlendedPassVars_t info; + SetupVarsCloakBlendedPass( info ); + DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Emissive Scroll Pass + if ( params[EMISSIVEBLENDENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( params[EMISSIVEBLENDSTRENGTH]->GetFloatValue() > 0.0f ) ) + { + EmissiveScrollBlendedPassVars_t info; + SetupVarsEmissiveScrollBlendedPass( info ); + DrawEmissiveScrollBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + + // Flesh Interior Pass + if ( params[FLESHINTERIORENABLED]->GetIntValue() ) + { + // If ( snapshotting ) or ( we need to draw this frame ) + if ( ( pShaderShadow != NULL ) || ( true ) ) + { + FleshInteriorBlendedPassVars_t info; + SetupVarsFleshInteriorBlendedPass( info ); + DrawFleshInteriorBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } + else // We're not snapshotting and we don't need to draw this frame + { + // Skip this pass! + Draw( false ); + } + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h new file mode 100644 index 00000000..3736bfe8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h @@ -0,0 +1,71 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VERTEXLITGENERIC_DX95_HELPER_H +#define VERTEXLITGENERIC_DX95_HELPER_H + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct VertexLitGeneric_DX95_Vars_t +{ + VertexLitGeneric_DX95_Vars_t() { memset( this, 0xFF, sizeof(VertexLitGeneric_DX95_Vars_t) ); } + + int m_nBaseTexture; + int m_nBaseTextureFrame; + int m_nBaseTexture2; + int m_nBaseTextureFrame2; + int m_nBaseTexture3; + int m_nBaseTextureFrame3; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nSelfIllumTint; + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nBumpFrame; + int m_nBumpmap2; + int m_nBumpFrame2; + int m_nBumpMask; + int m_nBumpmap3; + int m_nBumpFrame3; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nAlphaTestReference; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + int m_nSelfIllumEnvMapMask_Alpha; + +}; + +void InitParamsVertexLitGeneric_DX95( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX95_Vars_t &info ); +void InitVertexLitGeneric_DX95( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX95_Vars_t &info ); +void DrawVertexLitGeneric_DX95( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bVertexLitGeneric, VertexLitGeneric_DX95_Vars_t &info ); + + +#endif // VERTEXLITGENERIC_DX95_HELPER_H diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp new file mode 100644 index 00000000..b1f49eab --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp @@ -0,0 +1,1434 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "BaseVSShader.h" +#include "vertexlitgeneric_dx9_helper.h" +#include "skin_dx9_helper.h" + +#include "VertexLit_and_unlit_Generic_vs20.inc" +#include "VertexLit_and_unlit_Generic_bump_vs20.inc" + +#include "vertexlit_and_unlit_generic_ps20.inc" +#include "vertexlit_and_unlit_generic_ps20b.inc" +#include "vertexlit_and_unlit_generic_bump_ps20.inc" +#include "vertexlit_and_unlit_generic_bump_ps20b.inc" + +#ifndef _X360 +#include "vertexlit_and_unlit_generic_vs30.inc" +#include "vertexlit_and_unlit_generic_ps30.inc" +#include "vertexlit_and_unlit_generic_bump_vs30.inc" +#include "vertexlit_and_unlit_generic_bump_ps30.inc" +#endif + +#include "commandbuilder.h" +#include "convar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT ); +static ConVar r_lightwarpidentity( "r_lightwarpidentity","0", FCVAR_CHEAT ); + + +static inline bool WantsSkinShader( IMaterialVar** params, const VertexLitGeneric_DX9_Vars_t &info ) +{ + if ( info.m_nPhong == -1) // Don't use skin without Phong + return false; + + if ( params[info.m_nPhong]->GetIntValue() == 0 ) // Don't use skin without Phong turned on + return false; + + if ( ( info.m_nDiffuseWarpTexture != -1 ) && params[info.m_nDiffuseWarpTexture]->IsTexture() ) // If there's Phong and diffuse warp do skin + return true; + + if ( ( info.m_nBaseMapAlphaPhongMask != -1 ) && params[info.m_nBaseMapAlphaPhongMask]->GetIntValue() != 1 ) + { + if ( info.m_nBumpmap == -1 ) // Don't use without a bump map + return false; + + if ( !params[info.m_nBumpmap]->IsTexture() ) // Don't use if the texture isn't specified + return false; + } + + return true; +} + +int g_nSnapShots; + +//----------------------------------------------------------------------------- +// Initialize shader parameters +//----------------------------------------------------------------------------- +void InitParamsVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ) +{ + InitIntParam( info.m_nPhong, params, 0 ); + + InitFloatParam( info.m_nAlphaTestReference, params, 0.0f ); + InitIntParam( info.m_nVertexAlphaTest, params, 0 ); + + InitIntParam( info.m_nFlashlightNoLambert, params, 0 ); + + if ( info.m_nDetailTint != -1 && !params[info.m_nDetailTint]->IsDefined() ) + { + params[info.m_nDetailTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if ( info.m_nEnvmapTint != -1 && !params[info.m_nEnvmapTint]->IsDefined() ) + { + params[info.m_nEnvmapTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + InitIntParam( info.m_nEnvmapFrame, params, 0 ); + InitIntParam( info.m_nBumpFrame, params, 0 ); + InitFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + InitIntParam( info.m_nReceiveFlashlight, params, 0 ); + + InitFloatParam( info.m_nDetailScale, params, 4.0f ); + + if ( (info.m_nBlendTintByBaseAlpha != -1) && (!params[info.m_nBlendTintByBaseAlpha]->IsDefined()) ) + { + params[info.m_nBlendTintByBaseAlpha]->SetIntValue( 0 ); + } + + InitFloatParam( info.m_nTintReplacesBaseColor, params, 0 ); + + if ( (info.m_nSelfIllumTint != -1) && (!params[info.m_nSelfIllumTint]->IsDefined()) ) + { + params[info.m_nSelfIllumTint]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + + if ( WantsSkinShader( params, info ) ) + { + if ( !g_pHardwareConfig->SupportsPixelShaders_2_b() || !g_pConfig->UsePhong() ) + { + params[info.m_nPhong]->SetIntValue( 0 ); + } + else + { + InitParamsSkin_DX9( pShader, params, pMaterialName, info ); + return; + } + } + + // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture + if ( info.m_nFlashlightTexture != -1 ) + { + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + } + + // Write over $basetexture with $info.m_nBumpmap if we are going to be using diffuse normal mapping. + if ( info.m_nAlbedo != -1 && g_pConfig->UseBumpmapping() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() && params[info.m_nAlbedo]->IsDefined() && + params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nBaseTexture]->SetStringValue( params[info.m_nAlbedo]->GetStringValue() ); + } + + // This shader can be used with hw skinning + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + + if ( bVertexLitGeneric ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); + } + else + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + InitIntParam( info.m_nEnvmapMaskFrame, params, 0 ); + InitFloatParam( info.m_nEnvmapContrast, params, 0.0 ); + InitFloatParam( info.m_nEnvmapSaturation, params, 1.0f ); + InitFloatParam( info.m_nSeamlessScale, params, 0.0 ); + + // handle line art parms + InitFloatParam( info.m_nEdgeSoftnessStart, params, 0.5 ); + InitFloatParam( info.m_nEdgeSoftnessEnd, params, 0.5 ); + InitFloatParam( info.m_nGlowAlpha, params, 1.0 ); + InitFloatParam( info.m_nOutlineAlpha, params, 1.0 ); + + // No texture means no self-illum or env mask in base alpha + if ( info.m_nBaseTexture != -1 && !params[info.m_nBaseTexture]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + if( ( (info.m_nBumpmap != -1) && g_pConfig->UseBumpmapping() && params[info.m_nBumpmap]->IsDefined() ) + // we don't need a tangent space if we have envmap without bumpmap + // || ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) + ) + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) // diffuse warp goes down bump path... + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + else // no tangent space needed + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + } + + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + if ( hasNormalMapAlphaEnvmapMask ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ) && info.m_nBumpmap != -1 && + params[info.m_nBumpmap]->IsDefined() && !hasNormalMapAlphaEnvmapMask ) + { + Warning( "material %s has a normal map and $basealphaenvmapmask. Must use $normalmapalphaenvmapmask to get specular.\n\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + + if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() && info.m_nBumpmap != -1 && params[info.m_nBumpmap]->IsDefined() ) + { + params[info.m_nEnvmapMask]->SetUndefined(); + if ( !hasNormalMapAlphaEnvmapMask ) + { + Warning( "material %s has a normal map and an envmapmask. Must use $normalmapalphaenvmapmask.\n\n", pMaterialName ); + params[info.m_nEnvmap]->SetUndefined(); + } + } + + // If mat_specular 0, then get rid of envmap + if ( !g_pConfig->UseSpecular() && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() && params[info.m_nBaseTexture]->IsDefined() ) + { + params[info.m_nEnvmap]->SetUndefined(); + } + + InitFloatParam( info.m_nHDRColorScale, params, 1.0f ); + + InitIntParam( info.m_nLinearWrite, params, 0 ); + InitIntParam( info.m_nGammaColorRead, params, 0 ); + + InitIntParam( info.m_nDepthBlend, params, 0 ); + InitFloatParam( info.m_nDepthBlendScale, params, 50.0f ); +} + + +//----------------------------------------------------------------------------- +// Initialize shader +//----------------------------------------------------------------------------- + +void InitVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ) +{ + // both detailed and bumped = needs skin shader (for now) + bool bNeedsSkinBecauseOfDetail = false; + + //bool bHasBump = ( info.m_nBumpmap != -1 ) && params[info.m_nBumpmap]->IsTexture(); + //if ( bHasBump ) + //{ + // if ( ( info.m_nDetail != -1 ) && params[info.m_nDetail]->IsDefined() ) + // bNeedsSkinBecauseOfDetail = true; + //} + + if ( bNeedsSkinBecauseOfDetail || + ( info.m_nPhong != -1 && + params[info.m_nPhong]->GetIntValue() && + g_pHardwareConfig->SupportsPixelShaders_2_b() ) ) + { + InitSkin_DX9( pShader, params, info ); + return; + } + + if ( info.m_nFlashlightTexture != -1 ) + { + pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB ); + } + + bool bIsBaseTextureTranslucent = false; + if ( info.m_nBaseTexture != -1 && params[info.m_nBaseTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture, ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ? 0 : TEXTUREFLAGS_SRGB ); + + if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() ) + { + bIsBaseTextureTranslucent = true; + } + } + + bool bHasSelfIllumMask = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && (info.m_nSelfIllumMask != -1) && params[info.m_nSelfIllumMask]->IsDefined(); + + // No alpha channel in any of the textures? No self illum or envmapmask + if ( !bIsBaseTextureTranslucent ) + { + bool bHasSelfIllumFresnel = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + // Can still be self illum with no base alpha if using one of these alternate modes + if ( !bHasSelfIllumFresnel && !bHasSelfIllumMask ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + } + + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + if ( info.m_nDetail != -1 && params[info.m_nDetail]->IsDefined() ) + { + int nDetailBlendMode = ( info.m_nDetailTextureCombineMode == -1 ) ? 0 : params[info.m_nDetailTextureCombineMode]->GetIntValue(); + if ( nDetailBlendMode == 0 ) //Mod2X + pShader->LoadTexture( info.m_nDetail ); + else + pShader->LoadTexture( info.m_nDetail, TEXTUREFLAGS_SRGB ); + } + + if ( g_pConfig->UseBumpmapping() ) + { + if ( (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsDefined() ) + { + pShader->LoadBumpMap( info.m_nBumpmap ); + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + } + else if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL ); + } + } + + // Don't alpha test if the alpha channel is used for other purposes + if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + if ( info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsDefined() ) + { + if ( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + pShader->LoadCubeMap( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + else + { + pShader->LoadTexture( info.m_nEnvmap, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ? TEXTUREFLAGS_SRGB : 0 ); + } + + if ( !g_pHardwareConfig->SupportsCubeMaps() ) + { + SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE ); + } + } + if ( info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsDefined() ) + { + pShader->LoadTexture( info.m_nEnvmapMask ); + } + + if ( (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsDefined() ) + { + pShader->LoadTexture( info.m_nDiffuseWarpTexture ); + } + + if ( bHasSelfIllumMask ) + { + pShader->LoadTexture( info.m_nSelfIllumMask ); + } +} + +class CVertexLitGeneric_DX9_Context : public CBasePerMaterialContextData +{ +public: + CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut; + +}; + + +//----------------------------------------------------------------------------- +// Draws the shader +//----------------------------------------------------------------------------- +static void DrawVertexLitGeneric_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, + bool bVertexLitGeneric, bool bHasFlashlight, + VertexLitGeneric_DX9_Vars_t &info, + VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr ) + +{ + CVertexLitGeneric_DX9_Context *pContextData = reinterpret_cast< CVertexLitGeneric_DX9_Context *> ( *pContextDataPtr ); + +/*^*/ // printf("\t\t>DrawVertexLitGeneric_DX9_Internal\n"); + + bool bHasBump = IsTextureSet( info.m_nBumpmap, params ); +#if !defined( _X360 ) + bool bIsDecal = IS_FLAG_SET( MATERIAL_VAR_DECAL ); +#endif + + bool hasDiffuseLighting = bVertexLitGeneric; +/*^*/ // printf("\t\t[%d] bVertexLitGeneric\n",(int)bVertexLitGeneric); + + if ( IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) ) + { + bHasFlashlight = false; + } + + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + bool bHasDiffuseWarp = (!bHasFlashlight || IsX360() ) && hasDiffuseLighting && (info.m_nDiffuseWarpTexture != -1) && params[info.m_nDiffuseWarpTexture]->IsTexture(); + + + //bool bNoCull = IS_FLAG_SET( MATERIAL_VAR_NOCULL ); + bool bFlashlightNoLambert = false; + if ( ( info.m_nFlashlightNoLambert != -1 ) && params[info.m_nFlashlightNoLambert]->GetIntValue() ) + { + bFlashlightNoLambert = true; + } + + bool bAmbientOnly = IsBoolSet( info.m_nAmbientOnly, params ); + + float fBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); + bool bHasDetailTexture = IsTextureSet( info.m_nDetail, params ); + int nDetailBlendMode = bHasDetailTexture ? GetIntParam( info.m_nDetailTextureCombineMode, params ) : 0; + int nDetailTranslucencyTexture = -1; + + if ( bHasDetailTexture ) + { + if ( ( nDetailBlendMode == 6 ) && ( ! (g_pHardwareConfig->SupportsPixelShaders_2_b() ) ) ) + { + nDetailBlendMode = 5; // skip fancy threshold blending if ps2.0 + } + if ( ( nDetailBlendMode == 3 ) || ( nDetailBlendMode == 8 ) || ( nDetailBlendMode == 9 ) ) + nDetailTranslucencyTexture = info.m_nDetail; + } + + bool bBlendTintByBaseAlpha = IsBoolSet( info.m_nBlendTintByBaseAlpha, params ); + float fTintReplaceFactor = GetFloatParam( info.m_nTintReplacesBaseColor, params, 0.0 ); + + BlendType_t nBlendType; + bool bHasBaseTexture = IsTextureSet( info.m_nBaseTexture, params ); + if ( bHasBaseTexture ) + { + // if base alpha is used for tinting, ignore the base texture for computing translucency + nBlendType = pShader->EvaluateBlendRequirements( bBlendTintByBaseAlpha ? -1 : info.m_nBaseTexture, true, nDetailTranslucencyTexture ); + } + else + { + nBlendType = pShader->EvaluateBlendRequirements( info.m_nEnvmapMask, false ); + } + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested && (!bHasFlashlight || IsX360() ); //dest alpha is free for special use + + bool bHasEnvmap = (!bHasFlashlight || IsX360() ) && info.m_nEnvmap != -1 && params[info.m_nEnvmap]->IsTexture(); + + + bool bHasVertexColor = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + bool bHasVertexAlpha = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); +/*^*/ // printf("\t\t[%d] bHasVertexColor\n",(int)bHasVertexColor); +/*^*/ // printf("\t\t[%d] bHasVertexAlpha\n",(int)bHasVertexAlpha); + + if ( pShader->IsSnapshotting() || (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) + { +/*^*/ // printf("\t\t[1] snapshotting=%d pContextData=%08x pContextData->m_bMaterialVarsChanged=%d \n",(int)pShader->IsSnapshotting(), (int)pContextData, pContextData ? (int)pContextData->m_bMaterialVarsChanged : -1 ); + bool bSeamlessBase = IsBoolSet( info.m_nSeamlessBase, params ); + bool bSeamlessDetail = IsBoolSet( info.m_nSeamlessDetail, params ); + bool bDistanceAlpha = IsBoolSet( info.m_nDistanceAlpha, params ); + bool bHasSelfIllum = (!bHasFlashlight || IsX360() ) && IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + bool bHasEnvmapMask = (!bHasFlashlight || IsX360() ) && info.m_nEnvmapMask != -1 && params[info.m_nEnvmapMask]->IsTexture(); + bool bHasSelfIllumFresnel = ( !IsTextureSet( info.m_nDetail, params ) ) && ( bHasSelfIllum ) && ( info.m_nSelfIllumFresnel != -1 ) && ( params[info.m_nSelfIllumFresnel]->GetIntValue() != 0 ); + + bool bHasSelfIllumMask = bHasSelfIllum && IsTextureSet( info.m_nSelfIllumMask, params ); + bool hasSelfIllumInEnvMapMask = + ( info.m_nSelfIllumEnvMapMask_Alpha != -1 ) && + ( params[info.m_nSelfIllumEnvMapMask_Alpha]->GetFloatValue() != 0.0 ) ; + + if ( pShader->IsSnapshotting() ) + { +/*^*/ // printf("\t\t[2] snapshotting...\n"); + + bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + + + if ( info.m_nVertexAlphaTest != -1 && params[info.m_nVertexAlphaTest]->GetIntValue() > 0 ) + { + bHasVertexAlpha = true; + } + + // look at color and alphamod stuff. + // Unlit generic never uses the flashlight + if ( bHasSelfIllumFresnel ) + { + CLEAR_FLAGS( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); + hasNormalMapAlphaEnvmapMask = false; + } + + bool bHasEnvmap = (!bHasFlashlight || IsX360() ) && ( info.m_nEnvmap != -1 ) && params[info.m_nEnvmap]->IsTexture(); + bool bHasLegacyEnvSphereMap = bHasEnvmap && IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE); + bool bHasNormal = bVertexLitGeneric || bHasEnvmap || bHasFlashlight || bSeamlessBase || bSeamlessDetail; + if ( IsPC() ) + { + // On PC, LIGHTING_PREVIEW requires normals (they won't use much memory - unlitgeneric isn't used on many models) + bHasNormal = true; + } + + bool bHalfLambert = IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ); + // Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + + if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) + { + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); + } + + int nShadowFilterMode = 0; + if ( bHasFlashlight ) + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + + if ( !IsX360() ) + { + if (params[info.m_nBaseTexture]->IsTexture()) + { + pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); + } + else + { + pShader->SetAdditiveBlendingShadowState( info.m_nEnvmapMask, false ); + } + + if ( bIsAlphaTested ) + { + // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to + // be the same on both the regular pass and the flashlight pass. + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); + } + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->EnableBlending( true ); + pShaderShadow->EnableDepthWrites( false ); + } + else + { + pShader->SetBlendingShadowState( nBlendType ); + } + } + else + { + pShader->SetBlendingShadowState( nBlendType ); + } + + unsigned int flags = VERTEX_POSITION; + if ( bHasNormal ) + { + flags |= VERTEX_NORMAL; + } +/*^*/ // printf("\t\t[%1d] VERTEX_NORMAL\n",(flags&VERTEX_NORMAL)!=0); + + int userDataSize = 0; + bool bSRGBInputAdapter = false; + + // basetexture + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + if ( bHasBaseTexture ) + { + if ( ( info.m_nGammaColorRead != -1 ) && ( params[info.m_nGammaColorRead]->GetIntValue() == 1 ) ) + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); + else + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + // If we're on OSX GL on a crappy OS which can't do sRGB from render targets, check to see if we're reading from one... + if ( IsOSX() && !g_pHardwareConfig->CanDoSRGBReadFromRTs() ) + { + ITexture *pBaseTexture = params[info.m_nBaseTexture]->GetTextureValue(); + if ( pBaseTexture && pBaseTexture->IsRenderTarget() ) + { + bSRGBInputAdapter = true; + } + } + } + + if ( bHasEnvmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + } + } + if ( bHasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Depth texture + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER8 ); + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Noise map + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Flashlight cookie + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, true ); + userDataSize = 4; // tangent S + } + + if ( bHasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + if ( nDetailBlendMode != 0 ) //Not Mod2X + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + } + + if ( bHasBump || bHasDiffuseWarp ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + userDataSize = 4; // tangent S + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + } + if ( bHasEnvmapMask ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + + if ( bHasVertexColor || bHasVertexAlpha ) + { + flags |= VERTEX_COLOR; + } +/*^*/ // printf("\t\t[%1d] VERTEX_COLOR\n",(flags&VERTEX_COLOR)!=0); +/*^*/ // printf("\t\t[%1d] VERTEX_COLOR_STREAM_1\n",(flags&VERTEX_COLOR_STREAM_1)!=0); + + + if( bHasDiffuseWarp && (!bHasFlashlight || IsX360() ) && !bHasSelfIllumFresnel ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); // Diffuse warp texture + } + + if ( (info.m_nDepthBlend != -1) && (params[info.m_nDepthBlend]->GetIntValue()) ) + { + if( bHasBump ) + Warning( "DEPTHBLEND not supported by bump mapped variations of vertexlitgeneric to avoid shader bloat. Either remove the bump map or convince a graphics programmer that it's worth it.\n" ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); + } + + if( bHasSelfIllum ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER11, true ); // self illum mask + } + + bool bSRGBWrite = true; + if( (info.m_nLinearWrite != -1) && (params[info.m_nLinearWrite]->GetIntValue() == 1) ) + { + bSRGBWrite = false; + } + + pShaderShadow->EnableSRGBWrite( bSRGBWrite ); + + // texcoord0 : base texcoord + int pTexCoordDim[3] = { 2, 2, 3 }; + int nTexCoordCount = 1; + + if ( IsBoolSet( info.m_nSeparateDetailUVs, params ) ) + { + ++nTexCoordCount; + } + else + { + pTexCoordDim[1] = 0; + } + +#ifndef _X360 + // Special morphed decal information + if ( bIsDecal && g_pHardwareConfig->HasFastVertexTextures() ) + { + nTexCoordCount = 3; + } +#endif + + // This shader supports compressed vertices, so OR in that flag: + flags |= VERTEX_FORMAT_COMPRESSED; +/*^*/ // printf("\t\t[%1d] VERTEX_FORMAT_COMPRESSED\n",(flags&VERTEX_FORMAT_COMPRESSED)!=0); + +/*^*/ // printf("\t\t -> CShaderShadowDX8::VertexShaderVertexFormat( flags=%08x, texcount=%d )\n",flags,nTexCoordCount); + + + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize ); + + if ( bHasBump || bHasDiffuseWarp ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, g_pHardwareConfig->SupportsPixelShaders_2_b() ); +#ifdef _X360 + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); +#endif + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way + { + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b ); + } + else // ps_2_0 + { + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_VERTEX_SHADER_COMBO( USE_WITH_2B, true ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bHasDiffuseWarp && !bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUMFRESNEL, bHasSelfIllumFresnel ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask && bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 ); + } +#endif + } + else // !(bHasBump || bHasDiffuseWarp) + { + bool bDistanceAlphaFromDetail = false; + bool bSoftMask = false; + bool bGlow = false; + bool bOutline = false; + + static ConVarRef mat_reduceparticles( "mat_reduceparticles" ); + bool bDoDepthBlend = IsBoolSet( info.m_nDepthBlend, params ) && !mat_reduceparticles.GetBool(); + + if ( bDistanceAlpha ) + { + bDistanceAlphaFromDetail = IsBoolSet( info.m_nDistanceAlphaFromDetail, params ); + bSoftMask = IsBoolSet( info.m_nSoftEdges, params ); + bGlow = IsBoolSet( info.m_nGlow, params ); + bOutline = IsBoolSet( info.m_nOutline, params ); + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) ); + SET_STATIC_VERTEX_SHADER_COMBO( USE_STATIC_CONTROL_FLOW, bUseStaticControlFlow ); + SET_STATIC_VERTEX_SHADER_COMBO( DONT_GAMMA_CONVERT_VERTEX_COLOR, (! bSRGBWrite ) && bHasVertexColor ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send Gl this way + { + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDoDepthBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( SRGB_INPUT_ADAPTER, bSRGBInputAdapter ? 1 : 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b ); + } + else // ps_2_0 + { + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); + } + } +#ifndef _X360 + else + { + // The vertex shader uses the vertex id stream + SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); + + DECLARE_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor || bHasVertexAlpha ); + SET_STATIC_VERTEX_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert ); + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_VERTEX_SHADER_COMBO( SEPARATE_DETAIL_UVS, IsBoolSet( info.m_nSeparateDetailUVs, params ) ); + SET_STATIC_VERTEX_SHADER_COMBO( DECAL, bIsDecal ); + SET_STATIC_VERTEX_SHADER_COMBO( DONT_GAMMA_CONVERT_VERTEX_COLOR, bSRGBWrite ? 0 : 1 ); + SET_STATIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM_ENVMAPMASK_ALPHA, ( hasSelfIllumInEnvMapMask && ( bHasEnvmapMask ) ) ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap ); + SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP_SPHERE_LEGACY, bHasLegacyEnvSphereMap ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, hasDiffuseLighting ); + SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, bHasEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, bHasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_BASE, bSeamlessBase ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS_DETAIL, bSeamlessDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHA, bDistanceAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( DISTANCEALPHAFROMDETAIL, bDistanceAlphaFromDetail ); + SET_STATIC_PIXEL_SHADER_COMBO( SOFT_MASK, bSoftMask ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bOutline ); + SET_STATIC_PIXEL_SHADER_COMBO( OUTER_GLOW, bGlow ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER_COMBO( DEPTHBLEND, bDoDepthBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( BLENDTINTBYBASEALPHA, bBlendTintByBaseAlpha ); + SET_STATIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 ); + } +#endif + } + + if ( bHasFlashlight && !IsX360() ) + { + pShader->FogToBlack(); + } + else + { + pShader->DefaultFog(); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff and the loadout and character select screens. + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + } + + if ( pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) ) + { +/*^*/ // printf("\t\t[3] pShaderAPI && ( (! pContextData ) || ( pContextData->m_bMaterialVarsChanged ) ) TRUE \n"); + if ( ! pContextData ) // make sure allocated + { + ++g_nSnapShots; + pContextData = new CVertexLitGeneric_DX9_Context; + *pContextDataPtr = pContextData; + } + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_SemiStaticCmdsOut.SetPixelShaderFogParams( 21 ); + if ( bHasBaseTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); + } + else + { + if( bHasEnvmap ) + { + // if we only have an envmap (no basetexture), then we want the albedo to be black. + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + } + if ( bHasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nDetail, info.m_nDetailFrame ); + } + if ( bHasSelfIllum ) + { + if ( bHasSelfIllumMask ) // Separate texture for self illum? + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER11, info.m_nSelfIllumMask, -1 ); // Bind it + } + else // else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER11, TEXTURE_BLACK ); // Bind dummy + } + } + + if ( (info.m_nDepthBlend != -1) && (params[info.m_nDepthBlend]->GetIntValue()) ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER10, TEXTURE_FRAME_BUFFER_FULL_DEPTH ); + } + if ( bSeamlessDetail || bSeamlessBase ) + { + float flSeamlessData[4]={ params[info.m_nSeamlessScale]->GetFloatValue(), + 0,0,0}; + pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, flSeamlessData ); + } + + if ( info.m_nBaseTextureTransform != -1 ) + { + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); + } + + + if ( bHasDetailTexture ) + { + if ( IS_PARAM_DEFINED( info.m_nDetailTextureTransform ) ) + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nDetailTextureTransform, info.m_nDetailScale ); + else + pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBaseTextureTransform, info.m_nDetailScale ); + //Assert( !bHasBump ); + if ( info.m_nDetailTint != -1 ) + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstantGammaToLinear( 10, info.m_nDetailTint ); + else + { + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 10, 1, 1, 1, 1 ); + } + } + if ( bDistanceAlpha ) + { + float flSoftStart = GetFloatParam( info.m_nEdgeSoftnessStart, params ); + float flSoftEnd = GetFloatParam( info.m_nEdgeSoftnessEnd, params ); + // set all line art shader parms + bool bScaleEdges = IsBoolSet( info.m_nScaleEdgeSoftnessBasedOnScreenRes, params ); + bool bScaleOutline = IsBoolSet( info.m_nScaleOutlineSoftnessBasedOnScreenRes, params ); + + float flResScale = 1.0; + + float flOutlineStart0 = GetFloatParam( info.m_nOutlineStart0, params ); + float flOutlineStart1 = GetFloatParam( info.m_nOutlineStart1, params ); + float flOutlineEnd0 = GetFloatParam( info.m_nOutlineEnd0, params ); + float flOutlineEnd1 = GetFloatParam( info.m_nOutlineEnd1, params ); + + if ( bScaleEdges || bScaleOutline ) + { + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + flResScale=max( 0.5, max( 1024.0/nWidth, 768/nHeight ) ); + + if ( bScaleEdges ) + { + float flMid = 0.5 * ( flSoftStart + flSoftEnd ); + flSoftStart = clamp( flMid + flResScale * ( flSoftStart - flMid ), 0.05, 0.99 ); + flSoftEnd = clamp( flMid + flResScale * ( flSoftEnd - flMid ), 0.05, 0.99 ); + } + + + if ( bScaleOutline ) + { + // shrink the soft part of the outline, enlarging hard part + float flMidS = 0.5 * ( flOutlineStart1 + flOutlineStart0 ); + flOutlineStart1 = clamp( flMidS + flResScale * ( flOutlineStart1 - flMidS ), 0.05, 0.99 ); + float flMidE = 0.5 * ( flOutlineEnd1 + flOutlineEnd0 ); + flOutlineEnd1 = clamp( flMidE + flResScale * ( flOutlineEnd1 - flMidE ), 0.05, 0.99 ); + } + + } + + float flConsts[]={ + // c5 - glow values + GetFloatParam( info.m_nGlowX, params ), + GetFloatParam( info.m_nGlowY, params ), + GetFloatParam( info.m_nGlowStart, params ), + GetFloatParam( info.m_nGlowEnd, params ), + // c6 - glow color + 0,0,0, // will be filled in + GetFloatParam( info.m_nGlowAlpha, params ), + // c7 - mask range parms + flSoftStart, + flSoftEnd, + 0,0, + // c8 - outline color + 0,0,0, + GetFloatParam( info.m_nOutlineAlpha, params ), + // c9 - outline parms. ordered for optimal ps20 .wzyx swizzling + flOutlineStart0, + flOutlineEnd1, + flOutlineEnd0, + flOutlineStart1, + }; + + if ( info.m_nGlowColor != -1 ) + { + params[info.m_nGlowColor]->GetVecValue( flConsts+4, 3 ); + } + if ( info.m_nOutlineColor != -1 ) + { + params[info.m_nOutlineColor]->GetVecValue( flConsts+12, 3 ); + } + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 5, flConsts, 5 ); + + } + if ( !g_pConfig->m_bFastNoBump ) + { + if ( bHasBump ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); + } + else if ( bHasDiffuseWarp ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + } + else + { + if ( bHasBump ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); + } + } + // Setting w to 1 means use separate selfillummask + float vEnvMapSaturation_SelfIllumMask[4] = {1.0f, 1.0f, 1.0f, 0.0f}; + if ( info.m_nEnvmapSaturation != -1 ) + params[info.m_nEnvmapSaturation]->GetVecValue( vEnvMapSaturation_SelfIllumMask, 3 ); + + vEnvMapSaturation_SelfIllumMask[3] = bHasSelfIllumMask ? 1.0f : 0.0f; + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 3, vEnvMapSaturation_SelfIllumMask, 1 ); + if ( bHasEnvmap ) + { + pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicStateGammaToLinear( 0, info.m_nEnvmapTint, fTintReplaceFactor ); + } + else + { + pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicStateGammaToLinear( 0, -1, fTintReplaceFactor); + } + + if ( bHasEnvmapMask ) + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); + } + + if ( bHasSelfIllumFresnel && (!bHasFlashlight || IsX360() ) ) + { + float vConstScaleBiasExp[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; + float flMin = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[0] : 0.0f; + float flMax = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[1] : 1.0f; + float flExp = IS_PARAM_DEFINED( info.m_nSelfIllumFresnelMinMaxExp ) ? params[info.m_nSelfIllumFresnelMinMaxExp]->GetVecValue()[2] : 1.0f; + + vConstScaleBiasExp[1] = ( flMax != 0.0f ) ? ( flMin / flMax ) : 0.0f; // Bias + vConstScaleBiasExp[0] = 1.0f - vConstScaleBiasExp[1]; // Scale + vConstScaleBiasExp[2] = flExp; // Exp + vConstScaleBiasExp[3] = flMax; // Brightness + + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 11, vConstScaleBiasExp ); + } + + if( bHasDiffuseWarp && (!bHasFlashlight || IsX360() ) && !bHasSelfIllumFresnel ) + { + if ( r_lightwarpidentity.GetBool() ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_IDENTITY_LIGHTWARP ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER9, info.m_nDiffuseWarpTexture, -1 ); + } + } + + if ( bHasFlashlight ) + { + // Tweaks associated with a given flashlight + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + float tweaks[4]; + tweaks[0] = flashlightState.m_flShadowFilterSize / flashlightState.m_flShadowMapResolution; + tweaks[1] = ShadowAttenFromState( flashlightState ); + pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); + pShaderAPI->SetPixelShaderConstant( 2, tweaks, 1 ); + + // Dimensions of screen, used for screen-space noise map sampling + float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; + int nWidth, nHeight; + pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); + vScreenScale[0] = (float) nWidth / 32.0f; + vScreenScale[1] = (float) nHeight / 32.0f; + pShaderAPI->SetPixelShaderConstant( 31, vScreenScale, 1 ); + } + + if ( ( !bHasFlashlight || IsX360() ) && ( info.m_nEnvmapContrast != -1 ) ) + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 2, info.m_nEnvmapContrast ); + + // mat_fullbright 2 handling + bool bLightingOnly = bVertexLitGeneric && mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + if( bLightingOnly ) + { + if ( bHasBaseTexture ) + { + if( ( bHasSelfIllum && !hasSelfIllumInEnvMapMask ) ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); + } + else + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); + } + } + if ( bHasDetailTexture ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER2, TEXTURE_GREY ); + } + } + + if ( bHasBump || bHasDiffuseWarp ) + { + pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + pContextData->m_SemiStaticCmdsOut.SetPixelShaderStateAmbientLightCube( 5 ); + pContextData->m_SemiStaticCmdsOut.CommitPixelShaderLighting( 13 ); + } + pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant_W( 4, info.m_nSelfIllumTint, fBlendFactor ); + pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); + pContextData->m_SemiStaticCmdsOut.End(); + } + } + if ( pShaderAPI ) + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + if ( bHasEnvmap ) + { + DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER1, info.m_nEnvmap, info.m_nEnvmapFrame ); + } + + bool bFlashlightShadows = false; + if ( bHasFlashlight ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows ) + { + pShader->BindTexture( SHADER_SAMPLER8, pFlashlightDepthTexture, 0 ); + DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER6, TEXTURE_SHADOW_NOISE_2D ); + } + + SetFlashLightColorFromState( state, pShaderAPI, 28, bFlashlightNoLambert ); + + Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); + pShader->BindTexture( SHADER_SAMPLER7, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); + } + + + // Set up light combo state + LightState_t lightState = {0, false, false}; + if ( bVertexLitGeneric && (!bHasFlashlight || IsX360() ) ) + { + pShaderAPI->GetDX9LightState( &lightState ); + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; + int numBones = pShaderAPI->GetCurrentNumBones(); + + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + if ( bHasBump || bHasDiffuseWarp ) + { +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_vs20 ); + + // Bind ps_2_b shader so we can get shadow mapping... + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way + { + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps20 ); + } + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_bump_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_bump_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_bump_ps30 ); + + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } +#endif + } + else // !( bHasBump || bHasDiffuseWarp ) + { + if ( bAmbientOnly ) // Override selected light combo to be ambient only + { + lightState.m_bAmbientLight = true; + lightState.m_bStaticLight = false; + lightState.m_nNumLights = 0; + } + +#ifndef _X360 + if ( !g_pHardwareConfig->HasFastVertexTextures() ) +#endif + { + bool bUseStaticControlFlow = g_pHardwareConfig->SupportsStaticControlFlow(); + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( + LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, bUseStaticControlFlow ? 0 : lightState.m_nNumLights ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_vs20 ); + + // Bind ps_2_b shader so we can get shadow mapping + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() || g_pHardwareConfig->ShouldAlwaysUseShaderModel2bShaders() ) // Always send GL this way + { + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20b ); + +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( + LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( + LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps20 ); + } + } +#ifndef _X360 + else + { + pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( vertexlit_and_unlit_generic_vs30 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( STATIC_LIGHT, lightState.m_bStaticLight ? 1 : 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vertexlit_and_unlit_generic_ps30 ); +// SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, + pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) ); + SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, vertexlit_and_unlit_generic_ps30 ); + + bool bUnusedTexCoords[3] = { false, false, !pShaderAPI->IsHWMorphingEnabled() || !bIsDecal }; + pShaderAPI->MarkUnusedVertexFields( 0, 3, bUnusedTexCoords ); + } +#endif + } + + if ( ( info.m_nHDRColorScale != -1 ) && pShader->IsHDREnabled() ) + { + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( 1, params[info.m_nHDRColorScale]->GetFloatValue() ); + } + else + { + pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); + } + + float eyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + DynamicCmdsOut.SetPixelShaderConstant( 20, eyePos ); + + // Non-bump case does its own depth feathering work + if ( !bHasBump && !bHasDiffuseWarp ) + { + DynamicCmdsOut.SetDepthFeatheringPixelShaderConstant( 13, GetFloatParam( info.m_nDepthBlendScale, params, 50.0f ) ); + } + + float fPixelFogType = pShaderAPI->GetPixelFogCombo() == 1 ? 1 : 0; + float fWriteDepthToAlpha = bWriteDepthToAlpha && IsPC() ? 1 : 0; + float fWriteWaterFogToDestAlpha = (pShaderAPI->GetPixelFogCombo() == 1 && bWriteWaterFogToAlpha) ? 1 : 0; + float fVertexAlpha = bHasVertexAlpha ? 1 : 0; + + // Controls for lerp-style paths through shader code (bump and non-bump have use different register) + float vShaderControls[4] = { fPixelFogType, fWriteDepthToAlpha, fWriteWaterFogToDestAlpha, fVertexAlpha }; + DynamicCmdsOut.SetPixelShaderConstant( 12, vShaderControls, 1 ); + + // flashlightfixme: put this in common code. + if ( bHasFlashlight ) + { + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + SetFlashLightColorFromState( flashlightState, pShaderAPI, 28, bFlashlightNoLambert ); + + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture.Base(), 4 ); + + pShader->BindTexture( SHADER_SAMPLER7, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); + + float atten_pos[8]; + atten_pos[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors + atten_pos[1] = flashlightState.m_fLinearAtten; + atten_pos[2] = flashlightState.m_fQuadraticAtten; + atten_pos[3] = flashlightState.m_FarZ; + atten_pos[4] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin + atten_pos[5] = flashlightState.m_vecLightOrigin[1]; + atten_pos[6] = flashlightState.m_vecLightOrigin[2]; + atten_pos[7] = 1.0f; + DynamicCmdsOut.SetPixelShaderConstant( 22, atten_pos, 2 ); + + DynamicCmdsOut.SetPixelShaderConstant( 24, worldToTexture.Base(), 4 ); + } + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + pShader->Draw(); + +/*^*/ // printf("\t\tSupportsPixelShaders_2_b() && g_pConfig->UseBumpmapping() && g_pConfig->UsePhong() ) + { + DrawSkin_DX9( pShader, params, pShaderAPI, pShaderShadow, info, vertexCompression, pContextDataPtr ); + return; + } + + bool bReceiveFlashlight = bVertexLitGeneric; + bool bNewFlashlight = IsX360(); + if ( bNewFlashlight ) + { + bReceiveFlashlight = bReceiveFlashlight || ( GetIntParam( info.m_nReceiveFlashlight, params ) != 0 ); + } + bool bHasFlashlight = bReceiveFlashlight && pShader->UsingFlashlight( params ); + + DrawVertexLitGeneric_DX9_Internal( pShader, params, pShaderAPI, + pShaderShadow, bVertexLitGeneric, bHasFlashlight, info, vertexCompression, pContextDataPtr ); +} diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h new file mode 100644 index 00000000..0b5b02e4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h @@ -0,0 +1,144 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VERTEXLITGENERIC_DX9_HELPER_H +#define VERTEXLITGENERIC_DX9_HELPER_H + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct VertexLitGeneric_DX9_Vars_t +{ + VertexLitGeneric_DX9_Vars_t() { memset( this, 0xFF, sizeof(*this) ); } + + int m_nBaseTexture; + int m_nWrinkle; + int m_nStretch; + int m_nBaseTextureFrame; + int m_nBaseTextureTransform; + int m_nAlbedo; + int m_nDetail; + int m_nDetailFrame; + int m_nDetailScale; + int m_nEnvmap; + int m_nEnvmapFrame; + int m_nEnvmapMask; + int m_nEnvmapMaskFrame; + int m_nEnvmapMaskTransform; + int m_nEnvmapTint; + int m_nBumpmap; + int m_nNormalWrinkle; + int m_nNormalStretch; + int m_nBumpFrame; + int m_nBumpTransform; + int m_nEnvmapContrast; + int m_nEnvmapSaturation; + int m_nAlphaTestReference; + int m_nVertexAlphaTest; + int m_nFlashlightNoLambert; + int m_nFlashlightTexture; + int m_nFlashlightTextureFrame; + + int m_nSelfIllumTint; + int m_nSelfIllumFresnel; + int m_nSelfIllumFresnelMinMaxExp; + + int m_nPhongExponent; + int m_nPhongTint; + int m_nPhongAlbedoTint; + int m_nPhongExponentTexture; + int m_nDiffuseWarpTexture; + int m_nPhongWarpTexture; + int m_nPhongBoost; + int m_nPhongFresnelRanges; + int m_nSelfIllumEnvMapMask_Alpha; + int m_nAmbientOnly; + int m_nHDRColorScale; + int m_nPhong; + int m_nBaseMapAlphaPhongMask; + int m_nEnvmapFresnel; + + int m_nDetailTextureCombineMode; + int m_nDetailTextureBlendFactor; + + // Rim lighting parameters + int m_nRimLight; + int m_nRimLightPower; + int m_nRimLightBoost; + int m_nRimMask; + + int m_nSeamlessScale; + int m_nSeamlessBase; + int m_nSeamlessDetail; + + // distance coded line art parameters + int m_nDistanceAlpha; + int m_nDistanceAlphaFromDetail; + + int m_nSoftEdges; + int m_nEdgeSoftnessStart; + int m_nEdgeSoftnessEnd; + int m_nScaleEdgeSoftnessBasedOnScreenRes; + + int m_nGlow; + int m_nGlowColor; + int m_nGlowAlpha; + int m_nGlowStart; + int m_nGlowEnd; + int m_nGlowX; + int m_nGlowY; + int m_nOutline; + int m_nOutlineColor; + int m_nOutlineAlpha; + int m_nOutlineStart0; + int m_nOutlineStart1; + int m_nOutlineEnd0; + int m_nOutlineEnd1; + int m_nScaleOutlineSoftnessBasedOnScreenRes; + + int m_nSeparateDetailUVs; + int m_nDetailTextureTransform; + + int m_nLinearWrite; + int m_nGammaColorRead; + + int m_nDetailTint; + int m_nInvertPhongMask; + + int m_nDepthBlend; + int m_nDepthBlendScale; + + int m_nSelfIllumMask; + int m_nReceiveFlashlight; + + int m_nBlendTintByBaseAlpha; + + int m_nTintReplacesBaseColor; + +}; + +void InitParamsVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ); +void InitVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info ); +void DrawVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, + bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, + CBasePerMaterialContextData **pContextDataPtr + ); + + +#endif // VERTEXLITGENERIC_DX9_HELPER_H diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_envmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_envmap.psh new file mode 100644 index 00000000..e539da67 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_envmap.psh @@ -0,0 +1,17 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map + +mul r0, t0, c3 ; base times modulation +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh new file mode 100644 index 00000000..a5810b5e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh @@ -0,0 +1,137 @@ +vs.1.1 + +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "SKINNING" "0..1" +# STATIC: "TEETH" "0..1" + +#include "macros.vsh" + +local( $worldPos, $worldNormal, $projPos ); + +alloc $worldPos +alloc $worldNormal +alloc $projPos + +if( 0 ) +{ + ; NOTE: Don't do this optimization anymore since it would mean a gazillion combos + ; Special case for static prop lighting. We can go directly from + ; world to proj space for position, with the exception of z, which + ; is needed for fogging *if* height fog is enabled. + + ; NOTE: We don't use this path if $envmap is defined since we need + ; worldpos for envmapping. + dp4 $projPos.x, $vPos, $cModelViewProj0 + dp4 $projPos.y, $vPos, $cModelViewProj1 + dp4 $projPos.z, $vPos, $cModelViewProj2 + dp4 $projPos.w, $vPos, $cModelViewProj3 + ; normal + dp3 $worldNormal.x, $vNormal, $cModel0 + dp3 $worldNormal.y, $vNormal, $cModel1 + dp3 $worldNormal.z, $vNormal, $cModel2 + + ; Need this for height fog if it's enabled and for height clipping + dp4 $worldPos.z, $vPos, $cModel2 +} +else +{ + &SkinPositionAndNormal( $worldPos, $worldNormal ); + + if( $SKINNING == 1 ) + { + &Normalize( $worldNormal ); + } + + ;------------------------------------------------------------------------------ + ; Transform the position from world to view space + ;------------------------------------------------------------------------------ + dp4 $projPos.x, $worldPos, $cViewProj0 + dp4 $projPos.y, $worldPos, $cViewProj1 + dp4 $projPos.z, $worldPos, $cViewProj2 + dp4 $projPos.w, $worldPos, $cViewProj3 +} + +mov oPos, $projPos + +;------------------------------------------------------------------------------ +; Fog +;------------------------------------------------------------------------------ +&CalcFog( $worldPos, $projPos ); + +; base tex coords +dp4 oT1.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_6 +dp4 oT1.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_7 + +; normal map coords +;dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_8 +;dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_9 + +; spotlight texcoords +dp4 oT0.x, $worldPos, $SHADER_SPECIFIC_CONST_1 +dp4 oT0.y, $worldPos, $SHADER_SPECIFIC_CONST_2 +dp4 oT0.z, $worldPos, $SHADER_SPECIFIC_CONST_3 +dp4 oT0.w, $worldPos, $SHADER_SPECIFIC_CONST_4 + +local( $worldPosToLightVector, $distFactors ); + +alloc $worldPosToLightVector + +sub $worldPosToLightVector, $SHADER_SPECIFIC_CONST_0, $worldPos +mov oT2, $worldPosToLightVector + +local( $distatten ); +alloc $distatten +; $distatten = [ 1, 1/dist, 1/distsquared ] + +; dist squared +dp3 $distatten.z, $worldPosToLightVector, $worldPosToLightVector + +; oodist +rsq $distatten.y, $distatten.z + +mov $distatten.x, $cOne + +local( $dist ); +alloc $dist +mul $dist.x, $distatten.z, $distatten.y + +rcp $distatten.z, $distatten.z ; 1/distsquared + +local( $endFalloffFactor ); +alloc $endFalloffFactor + +; ( dist - farZ ) +sub $endFalloffFactor.x, $dist.x, $SHADER_SPECIFIC_CONST_5.w +; 1 / ( (0.6f * farZ) - farZ) +mul $endFalloffFactor, $endFalloffFactor.x, $SHADER_SPECIFIC_CONST_0.w +max $endFalloffFactor, $endFalloffFactor, $cZero +min $endFalloffFactor, $endFalloffFactor, $cOne + +local( $vertAtten ); +alloc $vertAtten +dp3 $vertAtten, $distatten, $SHADER_SPECIFIC_CONST_5 +mul $vertAtten, $vertAtten, $endFalloffFactor + +if( $TEETH ) +{ + alloc $mouthAtten + dp3 $mouthAtten, $worldNormal.xyz, $SHADER_SPECIFIC_CONST_10.xyz + max $mouthAtten, $cZero, $mouthAtten + mul $mouthAtten, $mouthAtten, $SHADER_SPECIFIC_CONST_10.w + mul $vertAtten, $vertAtten, $mouthAtten + free $mouthAtten +} + +mov oD0, $vertAtten + +mov oT3.xyz, $worldNormal.xyz + + +free $dist +free $endFalloffFactor +free $worldPos +free $worldNormal +free $projPos +free $worldPosToLightVector +free $distatten +free $vertAtten diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_inc.vsh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_inc.vsh new file mode 100644 index 00000000..da6b6bf9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_inc.vsh @@ -0,0 +1,145 @@ +#include "macros.vsh" + +sub VertexLitGeneric +{ + local( $detail ) = shift; + local( $envmap ) = shift; + local( $envmapcameraspace ) = shift; + local( $envmapsphere ) = shift; + local( $decal ) = shift; + + local( $worldPos, $worldNormal, $projPos ); + local( $reflectionVector ); + + ;------------------------------------------------------------------------------ + ; Vertex blending + ;------------------------------------------------------------------------------ + &AllocateRegister( \$worldPos ); + &AllocateRegister( \$worldNormal ); + &AllocateRegister( \$projPos ); +; if( $g_staticLightType eq "static" && $g_ambientLightType eq "none" && +; $g_localLightType1 eq "none" && $g_localLightType2 eq "none" && !$envmap ) + if( 0 ) + { + ; NOTE: Don't do this optimization anymore since it would mean a gazillion combos + ; of the flashlight shaders + ; Special case for static prop lighting. We can go directly from + ; world to proj space for position, with the exception of z, which + ; is needed for fogging *if* height fog is enabled. + + ; NOTE: We don't use this path if $envmap is defined since we need + ; worldpos for envmapping. + dp4 $projPos.x, $vPos, $cModelViewProj0 + dp4 $projPos.y, $vPos, $cModelViewProj1 + dp4 $projPos.z, $vPos, $cModelViewProj2 + dp4 $projPos.w, $vPos, $cModelViewProj3 + ; normal + dp3 $worldNormal.x, $vNormal, $cModel0 + dp3 $worldNormal.y, $vNormal, $cModel1 + dp3 $worldNormal.z, $vNormal, $cModel2 + + ; Need this for height fog if it's enabled and for height clipping + dp4 $worldPos.z, $vPos, $cModel2 + } + else + { + &SkinPositionAndNormal( $worldPos, $worldNormal ); + + if( $SKINNING == 1 ) + { + &Normalize( $worldNormal ); + } + + ;------------------------------------------------------------------------------ + ; Transform the position from world to view space + ;------------------------------------------------------------------------------ + dp4 $projPos.x, $worldPos, $cViewProj0 + dp4 $projPos.y, $worldPos, $cViewProj1 + dp4 $projPos.z, $worldPos, $cViewProj2 + dp4 $projPos.w, $worldPos, $cViewProj3 + } + + mov oPos, $projPos + + ;------------------------------------------------------------------------------ + ; Fog + ;------------------------------------------------------------------------------ + &CalcFog( $worldPos, $projPos ); + &FreeRegister( \$projPos ); + + ;------------------------------------------------------------------------------ + ; Lighting + ;------------------------------------------------------------------------------ + &DoLighting( $worldPos, $worldNormal ); + + if( !$envmap ) + { + &FreeRegister( \$worldNormal ); + } + + ;------------------------------------------------------------------------------ + ; Texture coordinates + ;------------------------------------------------------------------------------ + + dp4 oT0.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_0 + dp4 oT0.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_1 + + if( $envmap ) + { + if( $envmapcameraspace ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + + ; transform reflection vector into view space + dp3 oT1.x, $reflectionVector, $cViewModel0 + dp3 oT1.y, $reflectionVector, $cViewModel1 + dp3 oT1.z, $reflectionVector, $cViewModel2 + + &FreeRegister( \$reflectionVector ); + } + elsif( $envmapsphere ) + { + &AllocateRegister( \$reflectionVector ); + &ComputeReflectionVector( $worldPos, $worldNormal, $reflectionVector ); + &ComputeSphereMapTexCoords( $reflectionVector, "oT1" ); + + &FreeRegister( \$reflectionVector ); + } + else + { + &ComputeReflectionVector( $worldPos, $worldNormal, "oT1" ); + } + + ; envmap mask + dp4 oT2.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_2 + dp4 oT2.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_3 + + &FreeRegister( \$worldNormal ); + } + else + { + if ( $decal ) + { + &AllocateRegister( \$temp ); + mov $temp, $vTexCoord0 + sub oT1.xyz, $temp.xyz, $vTexCoord1.xyz + sub oT2.xyz, $vTexCoord2.xyz, $temp.xyz + &FreeRegister( \$temp ); + } + else + { + ; YUCK! This is to make texcoords continuous for mat_softwaretl + mov oT1, $cZero + mov oT2, $cZero + } + } + + if( $detail ) + { + dp4 oT3.x, $vTexCoord0, $SHADER_SPECIFIC_CONST_4 + dp4 oT3.y, $vTexCoord0, $SHADER_SPECIFIC_CONST_5 + } + &FreeRegister( \$worldPos ); +} + diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh new file mode 100644 index 00000000..dd19efce --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh @@ -0,0 +1,5 @@ +ps.1.1 + +mov r0, v0 + + diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc b/sp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc new file mode 100644 index 00000000..70ad7094 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc @@ -0,0 +1,9 @@ +struct PS_INPUT +{ + float3 vColor0 : COLOR0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + return float4( i.vColor0, 1.0 ); +} diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh new file mode 100644 index 00000000..c10600e3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh @@ -0,0 +1,19 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +tex t0 ; base color +tex t1 ; cube map +tex t2 ; envmap mask + +mul r0, t0, c3 ; Base times modulation +mul r1, t1, t2 ; Envmap * mask +mad r0.rgb, r1, c2, r0 ; Base * mod + envmap * mask * tint +mul r0.rgb, v0, r0 ; apply vertex lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh new file mode 100644 index 00000000..321e797b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh @@ -0,0 +1,25 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 +tex t1 + +mul r0.rgb, t0, c3 + ; base times modulation +mov r0.a, c3.a ; use modulation alpha (don't use texture alpha) + +mad r0.rgb, t1, c2, r0 ; + envmap * envmaptint (color only) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting + diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh new file mode 100644 index 00000000..e7c52910 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh @@ -0,0 +1,26 @@ +ps.1.1 + +;------------------------------------------------------------------------------ +; Draw a texture . . woo hoo! +; t0 - texture +; +; The texture coordinates need to be defined as follows: +; tc0 - texcoords +;------------------------------------------------------------------------------ + +; Get the color from the texture +tex t0 ; base +tex t1 ; env map +tex t2 ; mask + +mul r0.rgb, t0, c3 + ; base times modulation +mul r0.a, c3.a, t2.a ; alpha = mod alpha * mask alpha + +mul r1, t2, t1 ; envmapmask * envmap +mad r0.rgb, r1, c2, r0 ; + envmapmask * envmap * envmaptint (color only) + +mul r0.rgb, v0, r0 ; Apply lighting +mul_x2 r0.rgb, c0, r0 ; * 2 * (overbrightFactor/2) + +mul r1, t0, c1 ; Self illum * tint +lrp r0.rgb, t0.a, r1, r0 ; Blend between self-illum + base * lighting diff --git a/sp/src/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh b/sp/src/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh new file mode 100644 index 00000000..c0ab2765 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh @@ -0,0 +1,22 @@ +vs.1.1 + +# STATIC: "HALF_LAMBERT" "0..1" +# STATIC: "ENVMAP" "0..1" +# STATIC: "ENVMAPCAMERASPACE" "0..0" +# STATIC: "ENVMAPSPHERE" "0..1" +# DYNAMIC: "DOWATERFOG" "0..1" +# DYNAMIC: "LIGHT_COMBO" "0..21" +# DYNAMIC: "SKINNING" "0..1" + +# can't have envmapshere or envmapcameraspace without envmap +# SKIP: !$ENVMAP && ( $ENVMAPSPHERE || $ENVMAPCAMERASPACE ) + +# can't have both envmapsphere and envmapcameraspace +# SKIP: $ENVMAPSPHERE && $ENVMAPCAMERASPACE + +# decal is by itself +# SKIP: $DECAL && ( $DETAIL || $ENVMAP || $ENVMAPCAMERASPACE || $ENVMAPSPHERE ) + +#include "VertexLitGeneric_inc.vsh" + +&VertexLitGeneric( 1, $ENVMAP, $ENVMAPCAMERASPACE, $ENVMAPSPHERE, 0 ); diff --git a/sp/src/materialsystem/stdshaders/volume_clouds.cpp b/sp/src/materialsystem/stdshaders/volume_clouds.cpp new file mode 100644 index 00000000..1421dbb4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/volume_clouds.cpp @@ -0,0 +1,59 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "volume_clouds_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( VolumeClouds, VolumeClouds_dx9 ) +BEGIN_VS_SHADER( VolumeClouds_dx9, "VolumeClouds" ) + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" ) + SHADER_PARAM( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "Texture 1" ) + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "", "Texture 2" ) + SHADER_PARAM( BASETEXTURE3, SHADER_PARAM_TYPE_TEXTURE, "", "Texture 3" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "0.0", "Needs CurrentTime Proxy" ) + END_SHADER_PARAMS + + void SetupVarsVolumeClouds( VolumeCloudsVars_t &info ) + { + info.m_nRefractAmount = REFRACTAMOUNT; + info.m_nTexture1 = BASETEXTURE; + info.m_nTexture2 = BASETEXTURE2; + info.m_nTexture3 = BASETEXTURE3; + info.m_nTime = TIME; + } + + SHADER_INIT_PARAMS() + { + VolumeCloudsVars_t info; + SetupVarsVolumeClouds( info ); + InitParamsVolumeClouds( this, params, pMaterialName, info ); + } + + SHADER_FALLBACK + { + if ( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + // Fallback to unlit generic + return "UnlitGeneric_DX8"; + } + + return 0; + } + + SHADER_INIT + { + VolumeCloudsVars_t info; + SetupVarsVolumeClouds( info ); + InitVolumeClouds( this, params, info ); + } + + SHADER_DRAW + { + VolumeCloudsVars_t info; + SetupVarsVolumeClouds( info ); + DrawVolumeClouds( this, params, pShaderAPI, pShaderShadow, info, vertexCompression ); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/volume_clouds_helper.cpp b/sp/src/materialsystem/stdshaders/volume_clouds_helper.cpp new file mode 100644 index 00000000..cd2e889e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/volume_clouds_helper.cpp @@ -0,0 +1,138 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "volume_clouds_helper.h" +#include "convar.h" + +// Auto generated inc files +#include "volume_clouds_vs20.inc" +#include "volume_clouds_ps20.inc" +#include "volume_clouds_ps20b.inc" + + +void InitParamsVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VolumeCloudsVars_t &info ) +{ + // Set material flags + SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING ); + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + SET_FLAGS( MATERIAL_VAR_TRANSLUCENT ); + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nTime, 0.0f ); + + // Set material parameter default values + SET_PARAM_FLOAT_IF_NOT_DEFINED( info.m_nRefractAmount, kDefaultRefractAmount ); +} + +void InitVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, VolumeCloudsVars_t &info ) +{ + // Load textures + if ( (info.m_nTexture1 != -1) && params[info.m_nTexture1]->IsDefined() ) + { + pShader->LoadTexture( info.m_nTexture1, TEXTUREFLAGS_SRGB ); + } + + if ( (info.m_nTexture2 != -1) && params[info.m_nTexture2]->IsDefined() ) + { + pShader->LoadTexture( info.m_nTexture2, TEXTUREFLAGS_SRGB ); + } + + if ( (info.m_nTexture3 != -1) && params[info.m_nTexture3]->IsDefined() ) + { + pShader->LoadTexture( info.m_nTexture3, TEXTUREFLAGS_SRGB ); + } +} + +void DrawVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, VolumeCloudsVars_t &info, VertexCompressionType_t vertexCompression ) +{ + SHADOW_STATE + { + // Set stream format (note that this shader supports compression) + unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; + int nTexCoordCount = 1; + int userDataSize = 0; + pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); + + // Vertex Shader + DECLARE_STATIC_VERTEX_SHADER( volume_clouds_vs20 ); + SET_STATIC_VERTEX_SHADER( volume_clouds_vs20 ); + + // Pixel Shader + if( g_pHardwareConfig->SupportsPixelShaders_2_b() && !IsOpenGL() ) // Always send POSIX down the 20 path (rg - why?) + { + DECLARE_STATIC_PIXEL_SHADER( volume_clouds_ps20b ); + SET_STATIC_PIXEL_SHADER( volume_clouds_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( volume_clouds_ps20 ); + SET_STATIC_PIXEL_SHADER( volume_clouds_ps20 ); + } + + // Textures + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + pShaderShadow->EnableSRGBWrite( true ); + + // Blending + pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->EnableAlphaWrites( false ); + + // !!! We need to turn this back on because EnableAlphaBlending() above disables it! + //pShaderShadow->EnableDepthWrites( true ); + } + DYNAMIC_STATE + { + // Set Vertex Shader Combos + DECLARE_DYNAMIC_VERTEX_SHADER( volume_clouds_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); + SET_DYNAMIC_VERTEX_SHADER( volume_clouds_vs20 ); + + // Set Vertex Shader Constants + + // Time + float vPackedVsConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + float flTime = IS_PARAM_DEFINED( info.m_nTime ) && params[info.m_nTime]->GetFloatValue() > 0.0f ? params[info.m_nTime]->GetFloatValue() : pShaderAPI->CurrentTime(); + float flRotateSpeed = 0.065f; + vPackedVsConst1[0] = flTime * flRotateSpeed * 1.0f; + vPackedVsConst1[1] = flTime * flRotateSpeed * 2.0f; + vPackedVsConst1[2] = flTime * flRotateSpeed * 4.0f; + vPackedVsConst1[0] -= (float)( (int)( vPackedVsConst1[0] / ( 2.0f * 3.14159f ) ) ) * 2.0f * 3.14159f; + vPackedVsConst1[1] -= (float)( (int)( vPackedVsConst1[1] / ( 2.0f * 3.14159f ) ) ) * 2.0f * 3.14159f; + vPackedVsConst1[2] -= (float)( (int)( vPackedVsConst1[2] / ( 2.0f * 3.14159f ) ) ) * 2.0f * 3.14159f; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, vPackedVsConst1, 1 ); + + // Set Pixel Shader Combos + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() && !IsOpenGL() ) // Always send POSIX down the 20 path (rg - why?) + { + DECLARE_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( volume_clouds_ps20 ); + } + + // Bind textures + pShader->BindTexture( SHADER_SAMPLER0, info.m_nTexture1 ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nTexture2 ); + pShader->BindTexture( SHADER_SAMPLER2, info.m_nTexture3 ); + + // Set Pixel Shader Constants + float vEyePos[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); + pShaderAPI->SetPixelShaderConstant( 5, vEyePos, 1 ); + + float vPackedConst6[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + vPackedConst6[0] = IS_PARAM_DEFINED( info.m_nRefractAmount ) ? params[info.m_nRefractAmount]->GetFloatValue() : kDefaultRefractAmount; + vPackedConst6[1] = vPackedVsConst1[0]; // Time % 1000 + pShaderAPI->SetPixelShaderConstant( 6, vPackedConst6, 1 ); + } + pShader->Draw(); +} diff --git a/sp/src/materialsystem/stdshaders/volume_clouds_helper.h b/sp/src/materialsystem/stdshaders/volume_clouds_helper.h new file mode 100644 index 00000000..abbb63b7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/volume_clouds_helper.h @@ -0,0 +1,41 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// + +#ifndef VOLUME_CLOUDS_HELPER_H +#define VOLUME_CLOUDS_HELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct VolumeCloudsVars_t +{ + VolumeCloudsVars_t() { memset( this, 0xFF, sizeof( VolumeCloudsVars_t ) ); } + + int m_nRefractAmount; + int m_nTexture1; + int m_nTexture2; + int m_nTexture3; + int m_nTime; +}; + +// Default values (Arrays should only be vec[4]) +static const float kDefaultRefractAmount = 0.1f; + +void InitParamsVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, VolumeCloudsVars_t &info ); +void InitVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, VolumeCloudsVars_t &info ); +void DrawVolumeClouds( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, VolumeCloudsVars_t &info, VertexCompressionType_t vertexCompression ); + +#endif // VolumeClouds_HELPER_H diff --git a/sp/src/materialsystem/stdshaders/volume_clouds_ps2x.fxc b/sp/src/materialsystem/stdshaders/volume_clouds_ps2x.fxc new file mode 100644 index 00000000..7435f305 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/volume_clouds_ps2x.fxc @@ -0,0 +1,66 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// + +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] + +// Includes ======================================================================================= +#include "common_vertexlitgeneric_dx9.h" + +// Texture Samplers =============================================================================== +sampler g_tInnerSampler : register( s0 ); +sampler g_tMiddleSampler : register( s1 ); +sampler g_tOuterSampler : register( s2 ); + +// Shaders Constants and Globals ================================================================== +//const float4 g_vPackedConst6 : register( c6 ); +//#define g_flTime g_vPackedConst6.w + +// Interpolated values ============================================================================ +struct PS_INPUT +{ + float4 v2DTangentViewVector01 : TEXCOORD0; + float4 vUv01 : TEXCOORD1; + float4 v2DTangentViewVector2_vUv2 : TEXCOORD2; +}; + +// Main =========================================================================================== +float4 main( PS_INPUT i ) : COLOR +{ + float4 vFinalColor = float4( 0.0f, 0.0f, 0.0f, 1.0f ); + +#if defined(SHADER_MODEL_PS_2_0) + float flNumLayers = 2.0f; +#else + float flNumLayers = 10.0f; +#endif + + //float flColorDim = 1.0f; + for ( float j=flNumLayers-1.0f; j>=0.0f; j-=1.0f ) // From hightest to lowest layer + { + float4 vInnerTexel = tex2D( g_tInnerSampler, saturate( i.vUv01.xy + i.v2DTangentViewVector01.xy * 0.005 * j ) ); + float4 vMiddleTexel = tex2D( g_tMiddleSampler, saturate( i.vUv01.wz + i.v2DTangentViewVector01.wz * 0.005 * j ) ); + float4 vOuterTexel = tex2D( g_tOuterSampler, saturate( i.v2DTangentViewVector2_vUv2.wz + i.v2DTangentViewVector2_vUv2.xy * 0.005 * j ) ); + + float4 vThisTexel; + vThisTexel.rgb = ( vInnerTexel.rgb * vInnerTexel.a ) + ( vMiddleTexel.rgb * vMiddleTexel.a ) + ( vOuterTexel.rgb * vOuterTexel.a ); + vThisTexel.a = 1.0f - ( ( 1.0f - vOuterTexel.a ) * ( 1.0f - vMiddleTexel.a ) * ( 1.0f - vInnerTexel.a ) ); + + //vThisTexel.rgb *= flColorDim; + //flColorDim *= 0.95f; + + // 5.0 and 0.8625 are magic numbers that look good with the current textures + float flBlendValue = saturate( pow( vThisTexel.a, lerp( 5.0f, 0.8625f, saturate( j/(flNumLayers-1.0f) ) ) ) ); + + vFinalColor.rgb = vThisTexel.rgb + ( vFinalColor.rgb * ( 1.0f - flBlendValue ) ); + vFinalColor.a *= 1.0f - flBlendValue; // Dest alpha scalar + } + + //===============// + // Combine terms // + //===============// + float4 result; + result.rgb = vFinalColor.rgb; + result.a = 1.0f - vFinalColor.a; + + return FinalOutput( result, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR ); //go back to final output when it'll fit. +} diff --git a/sp/src/materialsystem/stdshaders/volume_clouds_vs20.fxc b/sp/src/materialsystem/stdshaders/volume_clouds_vs20.fxc new file mode 100644 index 00000000..ccab2574 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/volume_clouds_vs20.fxc @@ -0,0 +1,103 @@ +//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============// + +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +// Includes +#include "common_vs_fxc.h" + +// Globals +static const bool g_bSkinning = SKINNING ? true : false; + +const float3 g_vTime : register( SHADER_SPECIFIC_CONST_0 ); +#define g_flTime1x g_vTime.x +#define g_flTime2x g_vTime.y +#define g_flTime4x g_vTime.z + +const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_1 ); + +// Structs +struct VS_INPUT +{ + float4 vPos : POSITION; // Position + float4 vNormal : NORMAL; // Normal + float4 vBoneWeights : BLENDWEIGHT; // Skin weights + float4 vBoneIndices : BLENDINDICES; // Skin indices + float4 vTexCoord0 : TEXCOORD0; // Base texture coordinates + float4 vUserData : TANGENT; +}; + +struct VS_OUTPUT +{ + float4 vProjPosition : POSITION; // Projection-space position + float4 v2DTangentViewVector01 : TEXCOORD0; + float4 vUv01 : TEXCOORD1; + float4 v2DTangentViewVector2_vUv2 : TEXCOORD2; +}; + +// Main +VS_OUTPUT main( const VS_INPUT i ) +{ + VS_OUTPUT o; + + // Decompress compressed normal and tangent + float4 vObjPosition = i.vPos.xyzw; + float3 vObjNormal; + float4 vObjTangent; + DecompressVertex_NormalTangent( i.vNormal, i.vUserData, vObjNormal, vObjTangent ); + + // Transform the position + float3 vWorldPosition = { 0.0f, 0.0f, 0.0f }; + float3 vWorldNormal = { 0.0f, 0.0f, 0.0f }; + float3 vWorldTangent = { 0.0f, 0.0f, 0.0f }; + float3 vWorldBinormal = { 0.0f, 0.0f, 0.0f }; + SkinPositionNormalAndTangentSpace( g_bSkinning, vObjPosition, vObjNormal.xyz, vObjTangent.xyzw, i.vBoneWeights, i.vBoneIndices, vWorldPosition, vWorldNormal, vWorldTangent, vWorldBinormal ); + vWorldNormal.xyz = normalize( vWorldNormal.xyz ); + vWorldTangent.xyz = normalize( vWorldTangent.xyz ); + vWorldBinormal.xyz = normalize( vWorldBinormal.xyz ); + + // Transform into projection space + float4 vProjPosition = mul( float4( vWorldPosition, 1.0f ), cViewProj ); + o.vProjPosition = vProjPosition; + + // View vector + float3 vWorldViewVector = normalize( vWorldPosition.xyz - cEyePos.xyz ); + float3 vTangentViewVector = Vec3WorldToTangentNormalized( vWorldViewVector.xyz, vWorldNormal.xyz, vWorldTangent.xyz, vWorldBinormal.xyz ); + + // Texture coordinates + float4 mRotate; + float2 vBaseUv = i.vTexCoord0.xy; + + // Inner layer + mRotate.x = cos( g_flTime4x ); + mRotate.y = -sin( g_flTime4x ); + mRotate.z = -mRotate.y; + mRotate.w = mRotate.x; + o.vUv01.xy = ( vBaseUv.xy - 0.5f ) * 1.0f; + o.vUv01.xy = float2( dot( o.vUv01.xy, mRotate.xy ), dot( o.vUv01.xy, mRotate.zw ) ); + o.vUv01.xy += 0.5f; + o.v2DTangentViewVector01.xy = float2( dot( vTangentViewVector.xy, mRotate.xy ), dot( vTangentViewVector.xy, mRotate.zw ) ); + + // Middle layer + mRotate.x = cos( g_flTime2x ); + mRotate.y = -sin( g_flTime2x ); + mRotate.z = -mRotate.y; + mRotate.w = mRotate.x; + o.vUv01.wz = ( vBaseUv.xy - 0.5f ) * 1.0f; + o.vUv01.wz = float2( dot( o.vUv01.wz, mRotate.xy ), dot( o.vUv01.wz, mRotate.zw ) ); + o.vUv01.wz += 0.5f; + o.v2DTangentViewVector01.wz = float2( dot( vTangentViewVector.xy, mRotate.xy ), dot( vTangentViewVector.xy, mRotate.zw ) ); + + // Outer layer + mRotate.x = cos( g_flTime1x ); + mRotate.y = -sin( g_flTime1x ); + mRotate.z = -mRotate.y; + mRotate.w = mRotate.x; + float2 vUv2 = ( vBaseUv.xy - 0.5f ) * 1.0f; + vUv2.xy = float2( dot( vUv2.xy, mRotate.xy ), dot( vUv2.xy, mRotate.zw ) ); + vUv2.xy += 0.5f; + o.v2DTangentViewVector2_vUv2.wz = vUv2.xy; + o.v2DTangentViewVector2_vUv2.xy = float2( dot( vTangentViewVector.xy, mRotate.xy ), dot( vTangentViewVector.xy, mRotate.zw ) ); + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/vr_distort_hud.cpp b/sp/src/materialsystem/stdshaders/vr_distort_hud.cpp new file mode 100644 index 00000000..b78a3e51 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vr_distort_hud.cpp @@ -0,0 +1,224 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "BaseVSShader.h" +#include "commandbuilder.h" + +#include "vr_distort_hud_ps20.inc" +#include "vr_distort_hud_ps20b.inc" +#include "vr_distort_hud_vs20.inc" +#include "vr_distort_hud_ps30.inc" +#include "vr_distort_hud_vs30.inc" + +#include "../materialsystem_global.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +class CVRDistortTexture_DX9_Context : public CBasePerMaterialContextData +{ +public: + uint8 *m_pStaticCmds; + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; + + void ResetStaticCmds( void ) + { + if ( m_pStaticCmds ) + { + delete[] m_pStaticCmds; + m_pStaticCmds = NULL; + } + } + + CVRDistortTexture_DX9_Context( void ) + { + m_pStaticCmds = NULL; + } + + ~CVRDistortTexture_DX9_Context( void ) + { + ResetStaticCmds(); + } + +}; + + +BEGIN_VS_SHADER( vr_distort_hud, "Help for hud warp" ) + BEGIN_SHADER_PARAMS + + SHADER_PARAM( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_gui", "" ) + SHADER_PARAM( DISTORTMAP, SHADER_PARAM_TYPE_TEXTURE, "vr_distort_map_left", "" ) + SHADER_PARAM( DISTORTBOUNDS, SHADER_PARAM_TYPE_VEC4, "[ 0 0 1 1 ]", "" ) + SHADER_PARAM( HUDTRANSLUCENT, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( HUDUNDISTORT, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( DISTORTMAP, TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NODEBUGOVERRIDE | TEXTUREFLAGS_SINGLECOPY | + TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT ); + } + + SHADER_DRAW + { + CVRDistortTexture_DX9_Context *pContextData = reinterpret_cast< CVRDistortTexture_DX9_Context *> ( *pContextDataPtr ); + bool bNeedRegenStaticCmds = ( !pContextData ) || pShaderShadow; + + if ( !pContextData ) // make sure allocated + { + pContextData = new CVRDistortTexture_DX9_Context; + *pContextDataPtr = pContextData; + } + + if ( pShaderShadow || bNeedRegenStaticCmds ) + { + pContextData->ResetStaticCmds(); + CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; + + staticCmdsBuf.BindTexture( this, SHADER_SAMPLER0, BASETEXTURE, -1 ); + staticCmdsBuf.BindTexture( this, SHADER_SAMPLER1, DISTORTMAP, -1 ); + + staticCmdsBuf.End(); + + // now, copy buf + pContextData->m_pStaticCmds = new uint8[ staticCmdsBuf.Size() ]; + memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); + } + + if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) + { + // need to regenerate the semistatic cmds + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_bMaterialVarsChanged = false; + + pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); + pContextData->m_SemiStaticCmdsOut.End(); + } + + SHADOW_STATE + { + SetInitialShadowState( ); + + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableDepthTest( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->EnableSRGBWrite( true ); + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); + + if ( IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT ) ) + { + pShaderShadow->EnableAlphaTest( true ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + else + { + pShaderShadow->EnableAlphaTest( false ); + pShaderShadow->EnableBlending( false ); + pShaderShadow->BlendFunc( SHADER_BLEND_ONE, SHADER_BLEND_ZERO ); + } + + DefaultFog(); + + int nFormat = 0; + nFormat |= VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( nFormat, 2, 0, 0 ); + + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_STATIC_VERTEX_SHADER( vr_distort_hud_vs20 ); + SET_STATIC_VERTEX_SHADER( vr_distort_hud_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( vr_distort_hud_ps20b ); + SET_STATIC_PIXEL_SHADER( vr_distort_hud_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( vr_distort_hud_ps20 ); + SET_STATIC_PIXEL_SHADER( vr_distort_hud_ps20 ); + } + } + else + { + DECLARE_STATIC_VERTEX_SHADER( vr_distort_hud_vs30 ); + SET_STATIC_VERTEX_SHADER( vr_distort_hud_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vr_distort_hud_ps30 ); + SET_STATIC_PIXEL_SHADER( vr_distort_hud_ps30 ); + } + } + + DYNAMIC_STATE + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + pShaderAPI->SetDefaultState(); + + SetPixelShaderConstant( 0, DISTORTBOUNDS ); + SetPixelShaderConstant( 1, HUDTRANSLUCENT ); + + int hudUndistortEnabled = ( params[ HUDUNDISTORT ]->GetIntValue() == 0 ) ? 0 : 1; + + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_HUDUNDISTORT, hudUndistortEnabled ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_HUDUNDISTORT, hudUndistortEnabled ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps20 ); + } + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( vr_distort_hud_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_HUDUNDISTORT, hudUndistortEnabled ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_hud_ps30 ); + } + + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + + Draw(); + + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc b/sp/src/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc new file mode 100644 index 00000000..331c1897 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc @@ -0,0 +1,78 @@ +// DYNAMIC: "CMBO_HUDUNDISTORT" "0..1" + +#include "shader_constant_register_map.h" +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler DistortMapTextureSampler : register( s1 ); + +const float4 DistortBounds : register( c0 ); +const int bHudTranslucent : register( c1 ); + +struct PS_INPUT +{ + float2 vBaseTexCoord : TEXCOORD0; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + float2 vOriginal = i.vBaseTexCoord.xy; + + + // The full uv 0->1 range of the base texture here is shifted/scaled so that it maps + // to the region that would be minUV->maxUV of the base texture in the regular undistort + // code. This lets us overlay a higher-resolution inset rectangle directly onto the + // render target with undistort, which results in a much higher-quality HUD. + + float2 minUV = DistortBounds.xy; + float2 maxUV = DistortBounds.zw; + float2 scaleUV = 1.0 / ( maxUV - minUV ); + + + float2 vGreen; + float4 vFinal; + + #if ( CMBO_HUDUNDISTORT ) + { + float4 vRead = tex2D( DistortMapTextureSampler, vOriginal ); + + float2 vRed = vRead.xy; + float2 vBlue = vRead.zw; + + vGreen = ( vRed + vBlue ) / 2.0; + + vRed = ( vRed - minUV ) * scaleUV; + vGreen = ( vGreen - minUV ) * scaleUV; + vBlue = ( vBlue - minUV ) * scaleUV; + + vFinal.r = tex2D( BaseTextureSampler, vRed ).r; + vFinal.ga = tex2D( BaseTextureSampler, vGreen ).ga; + vFinal.b = tex2D( BaseTextureSampler, vBlue ).b; + } + #else + { + vGreen = ( vOriginal - minUV ) * scaleUV; + vFinal = tex2D( BaseTextureSampler, vGreen ); + } + #endif + + + // When the HUD isn't supposed to be rendered as translucent, some of its elements do occasionally have non-unit alpha. + // We always have blending and alphatest enabled here, so if the hud itself is not supposed to be translucent we need + // to fix up the alphas. + vFinal.a = lerp( 1, vFinal.a, bHudTranslucent ); + + + // Smooth off the edges of the quad. This also gives (0,0,0,0) in the outer areas, for alpha test and for blackout. + + const float edgeRampFrac = 0.005; + float2 uvEdgeRamp = smoothstep( float2(-edgeRampFrac,-edgeRampFrac), float2(edgeRampFrac,edgeRampFrac), vGreen ) * + ( 1 - smoothstep( float2(1-edgeRampFrac,1-edgeRampFrac), float2(1+edgeRampFrac,1+edgeRampFrac), vGreen ) ); + + float edgeRamp = uvEdgeRamp.x * uvEdgeRamp.y; + + vFinal *= edgeRamp; + + + return vFinal; +} diff --git a/sp/src/materialsystem/stdshaders/vr_distort_hud_vs20.fxc b/sp/src/materialsystem/stdshaders/vr_distort_hud_vs20.fxc new file mode 100644 index 00000000..b82bfa13 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vr_distort_hud_vs20.fxc @@ -0,0 +1,26 @@ +#include "common_vs_fxc.h" + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + o.vProjPos = v.vPos; + o.vBaseTexCoord = v.vBaseTexCoord; + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/vr_distort_texture.cpp b/sp/src/materialsystem/stdshaders/vr_distort_texture.cpp new file mode 100644 index 00000000..1e87d72a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vr_distort_texture.cpp @@ -0,0 +1,213 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "BaseVSShader.h" +#include "commandbuilder.h" + +#include "vr_distort_texture_ps20.inc" +#include "vr_distort_texture_ps20b.inc" +#include "vr_distort_texture_vs20.inc" +#include "vr_distort_texture_ps30.inc" +#include "vr_distort_texture_vs30.inc" + +#include "../materialsystem_global.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + + + + + + +class CVRDistortTexture_DX9_Context : public CBasePerMaterialContextData +{ +public: + uint8 *m_pStaticCmds; + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > m_SemiStaticCmdsOut; + + void ResetStaticCmds( void ) + { + if ( m_pStaticCmds ) + { + delete[] m_pStaticCmds; + m_pStaticCmds = NULL; + } + } + + CVRDistortTexture_DX9_Context( void ) + { + m_pStaticCmds = NULL; + } + + ~CVRDistortTexture_DX9_Context( void ) + { + ResetStaticCmds(); + } + +}; + + +static const float kAllZeros[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + +BEGIN_VS_SHADER( vr_distort_texture, "Help for warp" ) + BEGIN_SHADER_PARAMS + + SHADER_PARAM( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( DISTORTMAP, SHADER_PARAM_TYPE_TEXTURE, "vr_distort_map", "" ) + SHADER_PARAM( USERENDERTARGET, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + LoadTexture( DISTORTMAP, TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NODEBUGOVERRIDE | + TEXTUREFLAGS_SINGLECOPY | TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT ); + } + + SHADER_DRAW + { + CVRDistortTexture_DX9_Context *pContextData = reinterpret_cast< CVRDistortTexture_DX9_Context *> ( *pContextDataPtr ); + bool bNeedRegenStaticCmds = ( !pContextData ) || pShaderShadow; + + if ( !pContextData ) // make sure allocated + { + pContextData = new CVRDistortTexture_DX9_Context; + *pContextDataPtr = pContextData; + } + + if ( pShaderShadow || bNeedRegenStaticCmds ) + { + pContextData->ResetStaticCmds(); + CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; + + staticCmdsBuf.BindTexture( this, SHADER_SAMPLER0, BASETEXTURE, -1 ); + staticCmdsBuf.BindTexture( this, SHADER_SAMPLER1, DISTORTMAP, -1 ); + + staticCmdsBuf.End(); + + // now, copy buf + pContextData->m_pStaticCmds = new uint8[ staticCmdsBuf.Size() ]; + memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); + } + + if ( pShaderAPI && pContextData->m_bMaterialVarsChanged ) + { + // need to regenerate the semistatic cmds + pContextData->m_SemiStaticCmdsOut.Reset(); + pContextData->m_bMaterialVarsChanged = false; + + pContextData->m_SemiStaticCmdsOut.SetAmbientCubeDynamicStateVertexShader(); + pContextData->m_SemiStaticCmdsOut.End(); + } + + SHADOW_STATE + { + SetInitialShadowState( ); + + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableDepthTest( false ); + + pShaderShadow->EnableBlending( false ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + pShaderShadow->EnableSRGBWrite( true ); + pShaderShadow->EnableAlphaWrites( false ); + pShaderShadow->EnableAlphaTest( false ); + + DefaultFog(); + + int nFormat = 0; + nFormat |= VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( nFormat, 2, 0, 0 ); + + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_STATIC_VERTEX_SHADER( vr_distort_texture_vs20 ); + SET_STATIC_VERTEX_SHADER( vr_distort_texture_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( vr_distort_texture_ps20b ); + SET_STATIC_PIXEL_SHADER( vr_distort_texture_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( vr_distort_texture_ps20 ); + SET_STATIC_PIXEL_SHADER( vr_distort_texture_ps20 ); + } + } + else + { + DECLARE_STATIC_VERTEX_SHADER( vr_distort_texture_vs30 ); + SET_STATIC_VERTEX_SHADER( vr_distort_texture_vs30 ); + + DECLARE_STATIC_PIXEL_SHADER( vr_distort_texture_ps30 ); + SET_STATIC_PIXEL_SHADER( vr_distort_texture_ps30 ); + } + } + + DYNAMIC_STATE + { + CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; + DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); + DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); + + pShaderAPI->SetDefaultState(); + + int useRenderTarget = ( params[ USERENDERTARGET ]->GetIntValue() == 0 ) ? 0 : 1; + + if ( !g_pHardwareConfig->SupportsShaderModel_3_0() ) + { + DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_USERENDERTARGET, useRenderTarget ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_USERENDERTARGET, useRenderTarget ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps20 ); + } + } + else + { + DECLARE_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs30 ); + SET_DYNAMIC_VERTEX_SHADER( vr_distort_texture_vs30 ); + + DECLARE_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps30 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( CMBO_USERENDERTARGET, useRenderTarget ); + SET_DYNAMIC_PIXEL_SHADER( vr_distort_texture_ps30 ); + } + + DynamicCmdsOut.End(); + pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); + } + Draw(); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc b/sp/src/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc new file mode 100644 index 00000000..23ff3f5f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc @@ -0,0 +1,49 @@ +// DYNAMIC: "CMBO_USERENDERTARGET" "0..1" + +#include "shader_constant_register_map.h" +#include "common_ps_fxc.h" + +sampler BaseTextureSampler : register( s0 ); +sampler DistortMapTextureSampler : register( s1 ); + + +struct PS_INPUT +{ + float2 vBaseTexCoord : TEXCOORD0; +}; + + +float4 main( PS_INPUT i ) : COLOR +{ + float2 vOriginal = i.vBaseTexCoord.xy; + + float4 vRead = tex2D( DistortMapTextureSampler, vOriginal ); + + float2 vGreen; + vGreen.r = ( vRead.x + vRead.z ) / 2.0; + vGreen.g = ( vRead.y + vRead.w ) / 2.0; + + float4 vFinal; + vFinal.r = tex2D( BaseTextureSampler, vRead.xy ).r; + vFinal.ga = tex2D( BaseTextureSampler, vGreen ).ga; + vFinal.b = tex2D( BaseTextureSampler, vRead.zw ).b; + + float fBoundsCheck; + #if ( CMBO_USERENDERTARGET ) + { + fBoundsCheck = saturate( dot( (vGreen.xy < float2(0.01,0.01)), float2(1,1)) + dot( (vGreen.xy > float2(0.99,0.99)), float2(1,1)) ); + } + #else + { + fBoundsCheck = saturate( dot( (vGreen.xy < float2(0.005,0.005)), float2(1,1)) + dot( (vGreen.xy > float2(0.995,0.995)), float2(1,1)) + + (vGreen.x > 0.495 && vGreen.x < 0.505 ) ); + } + #endif + + vFinal.xyz = lerp( vFinal.xyz, float3(0,0,0), fBoundsCheck ); + + return vFinal; +} + + + diff --git a/sp/src/materialsystem/stdshaders/vr_distort_texture_vs20.fxc b/sp/src/materialsystem/stdshaders/vr_distort_texture_vs20.fxc new file mode 100644 index 00000000..b82bfa13 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vr_distort_texture_vs20.fxc @@ -0,0 +1,26 @@ +#include "common_vs_fxc.h" + + +struct VS_INPUT +{ + float4 vPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vBaseTexCoord : TEXCOORD0; +}; + + +VS_OUTPUT main( const VS_INPUT v ) +{ + VS_OUTPUT o; + + o.vProjPos = v.vPos; + o.vBaseTexCoord = v.vBaseTexCoord; + + return o; +} diff --git a/sp/src/materialsystem/stdshaders/water.cpp b/sp/src/materialsystem/stdshaders/water.cpp new file mode 100644 index 00000000..92a26375 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/water.cpp @@ -0,0 +1,614 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" +#include "common_hlsl_cpp_consts.h" // hack hack hack! +#include "convar.h" + +#include "WaterCheap_vs20.inc" +#include "WaterCheap_ps20.inc" +#include "WaterCheap_ps20b.inc" +#include "Water_vs20.inc" +#include "Water_ps20.inc" +#include "water_ps20b.inc" + +#ifndef _X360 +static ConVar r_waterforceexpensive( "r_waterforceexpensive", "0", FCVAR_ARCHIVE ); +#endif + +DEFINE_FALLBACK_SHADER( Water, Water_DX9_HDR ) + +BEGIN_VS_SHADER( Water_DX90, + "Help for Water" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterRefraction", "" ) + SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0.8", "" ) + SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "dev/water_normal", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." ) + SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" ) + SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( FOGSTART, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( FOGEND, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( ABOVEWATER, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( NOLOWENDLIGHTMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( SCROLL1, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( SCROLL2, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( BLURREFRACT, SHADER_PARAM_TYPE_BOOL, "0", "Cause the refraction to be blurry on ps2b hardware" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + if( !params[ABOVEWATER]->IsDefined() ) + { + Warning( "***need to set $abovewater for material %s\n", pMaterialName ); + params[ABOVEWATER]->SetIntValue( 1 ); + } + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() ) + { + params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f ); + } + if( !params[CHEAPWATERENDDISTANCE]->IsDefined() ) + { + params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f ); + } + if( !params[SCALE]->IsDefined() ) + { + params[SCALE]->SetVecValue( 1.0f, 1.0f ); + } + if( !params[SCROLL1]->IsDefined() ) + { + params[SCROLL1]->SetVecValue( 0.0f, 0.0f, 0.0f ); + } + if( !params[SCROLL2]->IsDefined() ) + { + params[SCROLL2]->SetVecValue( 0.0f, 0.0f, 0.0f ); + } + if( !params[FOGCOLOR]->IsDefined() ) + { + params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f ); + Warning( "material %s needs to have a $fogcolor.\n", pMaterialName ); + } + if( !params[REFLECTENTITIES]->IsDefined() ) + { + params[REFLECTENTITIES]->SetIntValue( 0 ); + } + if( !params[REFLECTBLENDFACTOR]->IsDefined() ) + { + params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f ); + } + + // By default, we're force expensive on dx9. NO WE DON'T!!!! + if( !params[FORCEEXPENSIVE]->IsDefined() ) + { +#ifdef _X360 + params[FORCEEXPENSIVE]->SetIntValue( 0 ); +#else + params[FORCEEXPENSIVE]->SetIntValue( 1 ); +#endif + } + if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + + // Fallbacks for water need lightmaps usually + if ( !params[NOLOWENDLIGHTMAP]->GetIntValue() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[NORMALMAP]->IsDefined() ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + return "Water_DX81"; + } + return 0; + } + + SHADER_INIT + { + Assert( params[WATERDEPTH]->IsDefined() ); + + if( params[REFRACTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTEXTURE, TEXTUREFLAGS_SRGB ); + } + if( params[REFLECTTEXTURE]->IsDefined() ) + { + LoadTexture( REFLECTTEXTURE, TEXTUREFLAGS_SRGB ); + } + if ( params[ENVMAP]->IsDefined() ) + { + LoadCubeMap( ENVMAP, TEXTUREFLAGS_SRGB ); + } + if ( params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + if( params[BASETEXTURE]->IsDefined() ) + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + } + } + + inline void GetVecParam( int constantVar, float *val ) + { + if( constantVar == -1 ) + return; + + IMaterialVar* pVar = s_ppParams[constantVar]; + Assert( pVar ); + + if (pVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) + pVar->GetVecValue( val, 4 ); + else + val[0] = val[1] = val[2] = val[3] = pVar->GetFloatValue(); + } + + inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + if( bRefraction ) + { + // refract sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + if( bReflection ) + { + // reflect sampler + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); + if( params[BASETEXTURE]->IsTexture() ) + { + // BASETEXTURE + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); + // LIGHTMAP + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); + } + } + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 1; + if( params[BASETEXTURE]->IsTexture() ) + { + numTexCoords = 3; + } + pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 ); + + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( params[NORMALMAP]->IsTexture() && g_pHardwareConfig->SupportsNormalMapCompression() ) + { + ITexture *pNormalMap = params[NORMALMAP]->GetTextureValue(); + if ( pNormalMap ) + { + // Clamp this to 0 or 1 since that's how we've authored the water shader (i.e. no separate alpha map/channel) + nNormalDecodeMode = pNormalMap->GetNormalDecodeMode() == NORMAL_DECODE_NONE ? NORMAL_DECODE_NONE : NORMAL_DECODE_ATI2N; + } + } + + DECLARE_STATIC_VERTEX_SHADER( water_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_VERTEX_SHADER( water_vs20 ); + + // "REFLECT" "0..1" + // "REFRACT" "0..1" + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( water_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_PIXEL_SHADER_COMBO( BLURRY_REFRACT, params[BLURREFRACT]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( water_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( water_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( ABOVEWATER, params[ABOVEWATER]->GetIntValue() ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( water_ps20 ); + } + + FogToFogColor(); + + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + + pShaderShadow->EnableAlphaWrites( true ); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + if( bRefraction ) + { + // HDRFIXME: add comment about binding.. Specify the number of MRTs in the enable + BindTexture( SHADER_SAMPLER0, REFRACTTEXTURE, -1 ); + } + if( bReflection ) + { + BindTexture( SHADER_SAMPLER2, REFLECTTEXTURE, -1 ); + } + BindTexture( SHADER_SAMPLER4, NORMALMAP, BUMPFRAME ); + if( params[BASETEXTURE]->IsTexture() ) + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + // Refraction tint + if( bRefraction ) + { + SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT ); + } + // Reflection tint + if( bReflection ) + { + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + // Need to multiply by 4 in linear space since we premultiplied into + // the render target by .25 to get overbright data in the reflection render target. + float gammaReflectTint[3]; + params[REFLECTTINT]->GetVecValue( gammaReflectTint, 3 ); + float linearReflectTint[4]; + linearReflectTint[0] = GammaToLinear( gammaReflectTint[0] ) * 4.0f; + linearReflectTint[1] = GammaToLinear( gammaReflectTint[1] ) * 4.0f; + linearReflectTint[2] = GammaToLinear( gammaReflectTint[2] ) * 4.0f; + linearReflectTint[3] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 4, linearReflectTint, 1 ); + } + else + { + SetPixelShaderConstantGammaToLinear( 4, REFLECTTINT ); + } + } + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + float curtime=pShaderAPI->CurrentTime(); + float vc0[4]; + float v0[4]; + params[SCROLL1]->GetVecValue(v0,4); + vc0[0]=curtime*v0[0]; + vc0[1]=curtime*v0[1]; + params[SCROLL2]->GetVecValue(v0,4); + vc0[2]=curtime*v0[0]; + vc0[3]=curtime*v0[1]; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 ); + + float c0[4] = { 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); + + float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; + pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); + + // fresnel constants + float c3[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 3, c3, 1 ); + + float c5[4] = { params[REFLECTAMOUNT]->GetFloatValue(), params[REFLECTAMOUNT]->GetFloatValue(), + params[REFRACTAMOUNT]->GetFloatValue(), params[REFRACTAMOUNT]->GetFloatValue() }; + pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); + + SetPixelShaderConstantGammaToLinear( 6, FOGCOLOR ); + + float c7[4] = + { + params[FOGSTART]->GetFloatValue(), + params[FOGEND]->GetFloatValue() - params[FOGSTART]->GetFloatValue(), + 1.0f, + 0.0f + }; + if (g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) + { + // water overbright factor + c7[2] = 4.0; + } + pShaderAPI->SetPixelShaderConstant( 7, c7, 1 ); + + pShaderAPI->SetPixelShaderFogParams( 8 ); + + DECLARE_DYNAMIC_VERTEX_SHADER( water_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( water_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, pShaderAPI->ShouldWriteDepthToDestAlpha() ); + SET_DYNAMIC_PIXEL_SHADER( water_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( water_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( water_ps20 ); + } + } + Draw(); + } + + inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bBlend, bool bRefraction ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + + // In edit mode, use nocull + if ( UsingEditor( params ) ) + { + s_pShaderShadow->EnableCulling( false ); + } + + if( bBlend ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + // envmap + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + // normal map + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( bRefraction && bBlend ) + { + // refraction map (used for alpha) + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + NormalDecodeMode_t nNormalDecodeMode = NORMAL_DECODE_NONE; + if ( params[NORMALMAP]->IsTexture() && g_pHardwareConfig->SupportsNormalMapCompression() ) + { + ITexture *pNormalMap = params[NORMALMAP]->GetTextureValue(); + if ( pNormalMap ) + { + // Clamp this to 0 or 1 since that's how we've authored the water shader (i.e. no separate alpha map/channel) + nNormalDecodeMode = pNormalMap->GetNormalDecodeMode() == NORMAL_DECODE_NONE ? NORMAL_DECODE_NONE : NORMAL_DECODE_ATI2N; + } + } + + DECLARE_STATIC_VERTEX_SHADER( watercheap_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( BLEND, bBlend && bRefraction ); + SET_STATIC_VERTEX_SHADER( watercheap_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( watercheap_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( watercheap_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( FRESNEL, params[NOFRESNEL]->GetIntValue() == 0 ); + SET_STATIC_PIXEL_SHADER_COMBO( BLEND, bBlend ); + SET_STATIC_PIXEL_SHADER_COMBO( REFRACTALPHA, bRefraction ); + SET_STATIC_PIXEL_SHADER_COMBO( HDRTYPE, g_pHardwareConfig->GetHDRType() ); + Vector4D Scroll1; + params[SCROLL1]->GetVecValue( Scroll1.Base(), 4 ); + SET_STATIC_PIXEL_SHADER_COMBO( MULTITEXTURE,fabs(Scroll1.x) > 0.0); + SET_STATIC_PIXEL_SHADER_COMBO( NORMAL_DECODE_MODE, (int) nNormalDecodeMode ); + SET_STATIC_PIXEL_SHADER( watercheap_ps20 ); + } + + // HDRFIXME: test cheap water! + if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) + { + // we are writing linear values from this shader. + pShaderShadow->EnableSRGBWrite( true ); + } + + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + BindTexture( SHADER_SAMPLER0, ENVMAP, ENVMAPFRAME ); + BindTexture( SHADER_SAMPLER1, NORMALMAP, BUMPFRAME ); + if( bRefraction && bBlend ) + { + BindTexture( SHADER_SAMPLER2, REFRACTTEXTURE, -1 ); + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + SetPixelShaderConstant( 0, FOGCOLOR ); + + float cheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue(); + float cheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); + float cheapWaterParams[4] = + { + cheapWaterStartDistance * VSHADER_VECT_SCALE, + cheapWaterEndDistance * VSHADER_VECT_SCALE, + PSHADER_VECT_SCALE / ( cheapWaterEndDistance - cheapWaterStartDistance ), + cheapWaterStartDistance / ( cheapWaterEndDistance - cheapWaterStartDistance ), + }; + pShaderAPI->SetPixelShaderConstant( 1, cheapWaterParams ); + + if( g_pConfig->bShowSpecular ) + { + SetPixelShaderConstant( 2, REFLECTTINT, REFLECTBLENDFACTOR ); + } + else + { + float zero[4] = { 0.0f, 0.0f, 0.0f, params[REFLECTBLENDFACTOR]->GetFloatValue() }; + pShaderAPI->SetPixelShaderConstant( 2, zero ); + } + + pShaderAPI->SetPixelShaderFogParams( 3 ); + + if( params[SCROLL1]->IsDefined()) + { + float curtime=pShaderAPI->CurrentTime(); + float vc0[4]; + float v0[4]; + params[SCROLL1]->GetVecValue(v0,4); + vc0[0]=curtime*v0[0]; + vc0[1]=curtime*v0[1]; + params[SCROLL2]->GetVecValue(v0,4); + vc0[2]=curtime*v0[0]; + vc0[3]=curtime*v0[1]; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vc0, 1 ); + } + + DECLARE_DYNAMIC_VERTEX_SHADER( watercheap_vs20 ); + SET_DYNAMIC_VERTEX_SHADER( watercheap_vs20 ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20b ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( watercheap_ps20 ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( HDRENABLED, IsHDREnabled() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( watercheap_ps20 ); + } + } + Draw(); + } + + SHADER_DRAW + { + // TODO: fit the cheap water stuff into the water shader so that we don't have to do + // 2 passes. +#ifdef _X360 + bool bForceExpensive = false; +#else + bool bForceExpensive = r_waterforceexpensive.GetBool(); +#endif + bool bForceCheap = (params[FORCECHEAP]->GetIntValue() != 0) || UsingEditor( params ); + if ( bForceCheap ) + { + bForceExpensive = false; + } + else + { + bForceExpensive = bForceExpensive || (params[FORCEEXPENSIVE]->GetIntValue() != 0); + } + Assert( !( bForceCheap && bForceExpensive ) ); + + bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); +#ifdef _X360 + bool bReflection = params[REFLECTTEXTURE]->IsTexture(); +#else + bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); +#endif + bool bDrewSomething = false; + if ( !bForceCheap && ( bReflection || bRefraction ) ) + { + bDrewSomething = true; + DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction ); + } + + // Use $decal to see if we are a decal or not. . if we are, then don't bother + // drawing the cheap version for now since we don't have access to env_cubemap +#ifdef _X360 + if( params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) && !bForceExpensive ) +#else + if( !bReflection && params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) +#endif + { + bDrewSomething = true; + DrawCheapWater( params, pShaderShadow, pShaderAPI, !bForceCheap, bRefraction ); + } + + if( !bDrewSomething ) + { + // We are likely here because of the tools. . . draw something so that + // we won't go into wireframe-land. + Draw(); + } + } +END_SHADER + +//----------------------------------------------------------------------------- +// This allows us to use a block labelled 'Water_DX9_HDR' in the water materials +//----------------------------------------------------------------------------- +BEGIN_INHERITED_SHADER( Water_DX9_HDR, Water_DX90, + "Help for Water_DX9_HDR" ) + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + return "WATER_DX90"; + } + return 0; + } +END_INHERITED_SHADER + diff --git a/sp/src/materialsystem/stdshaders/water_dudv.cpp b/sp/src/materialsystem/stdshaders/water_dudv.cpp new file mode 100644 index 00000000..cf29c183 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/water_dudv.cpp @@ -0,0 +1,95 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + + +#include "BaseVSShader.h" + +#include "waterdudv_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Water_DuDv, "Help for Water_DuDv" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "", "dudv bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + } + + SHADER_FALLBACK + { + return 0; + } + + SHADER_INIT + { + if ( params[BUMPMAP]->IsDefined() ) + { + LoadTexture( BUMPMAP ); + } + if( !params[REFRACTTINT]->IsDefined() ) + { + params[REFRACTTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + } + + SHADER_DRAW + { + SHADOW_STATE + { + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableColorWrites( true ); + pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, true ); + int fmt = VERTEX_POSITION | VERTEX_NORMAL; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0, 0 ); + + pShaderShadow->SetVertexShader( "WaterDuDv_vs11", 0 ); + pShaderShadow->SetPixelShader( "WaterDuDv_ps11", 0 ); + DisableFog(); + } + DYNAMIC_STATE + { + waterdudv_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + vshIndex.SetDOFOG( pShaderAPI->GetSceneFogMode() != MATERIAL_FOG_NONE ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + Vector4D vec; + const float *pTint = params[REFRACTTINT]->GetVecValue(); + float flAverage = ( pTint[0] + pTint[1] + pTint[2] ) / 3.0f; + vec.Init( flAverage, flAverage, flAverage, 1.0f ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vec.Base() ); + + // Amount to refract + SetPixelShaderConstant( 0, REFRACTAMOUNT ); + + // Used to renormalize + vec.Init( 1.0f, 1.0f, 1.0f, 1.0f ); + pShaderAPI->SetPixelShaderConstant( 1, vec.Base() ); + + // Used to deal with the red channel + vec.Init( 0.0f, 1.0f, 1.0f, 1.0f ); + pShaderAPI->SetPixelShaderConstant( 2, vec.Base() ); + + vec.Init( 1.0f, 0.0f, 0.0f, 0.0f ); + pShaderAPI->SetPixelShaderConstant( 3, vec.Base() ); + + BindTexture( SHADER_TEXTURE_STAGE0, BUMPMAP, BUMPFRAME ); + } + Draw(); + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/water_dx60.cpp b/sp/src/materialsystem/stdshaders/water_dx60.cpp new file mode 100644 index 00000000..b6c952b3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/water_dx60.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// NOTE: Water DX60 is located in LightmappedGeneric_DX6 so it can inherit +DEFINE_FALLBACK_SHADER( Water, Water_DX60 ) + diff --git a/sp/src/materialsystem/stdshaders/water_dx80.cpp b/sp/src/materialsystem/stdshaders/water_dx80.cpp new file mode 100644 index 00000000..2f31bb5b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/water_dx80.cpp @@ -0,0 +1,419 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" + +#include "water_vs11.inc" +#include "watercheappervertexfresnel_vs11.inc" +#include "watercheap_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_VS_SHADER( Water_DX80, + "Help for Water_DX80" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "", "dudv bump map" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." ) + SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() ) + { + params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f ); + } + if( !params[CHEAPWATERENDDISTANCE]->IsDefined() ) + { + params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f ); + } + if( !params[SCALE]->IsDefined() ) + { + params[SCALE]->SetVecValue( 1.0f, 1.0f ); + } + if( !params[FOGCOLOR]->IsDefined() ) + { + params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f ); + Warning( "material %s needs to have a $fogcolor.\n", pMaterialName ); + } + if( !params[REFLECTENTITIES]->IsDefined() ) + { + params[REFLECTENTITIES]->SetIntValue( 0 ); + } + if( !params[FORCEEXPENSIVE]->IsDefined() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + if( !params[REFLECTBLENDFACTOR]->IsDefined() ) + { + params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f ); + } + if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + } + + SHADER_FALLBACK + { + if ( IsPC() && ( g_pHardwareConfig->GetDXSupportLevel() < 80 || !g_pHardwareConfig->HasProjectedBumpEnv() ) ) + { + return "Water_DX60"; + } + return 0; + } + + SHADER_INIT + { + Assert( params[WATERDEPTH]->IsDefined() ); + if( params[REFRACTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTEXTURE ); + } + if( params[REFLECTTEXTURE]->IsDefined() ) + { + LoadTexture( REFLECTTEXTURE ); + } + if (params[BUMPMAP]->IsDefined() ) + { + LoadTexture( BUMPMAP ); + } + if (params[ENVMAP]->IsDefined() ) + { + LoadCubeMap( ENVMAP ); + } + if (params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + } + + inline void SetCheapWaterFactors( IMaterialVar **params, IShaderDynamicAPI* pShaderAPI, int nConstantReg ) + { + float flCheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue(); + float flCheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); + float flCheapWaterConstants[4] = + { + flCheapWaterStartDistance, + 1.0f / ( flCheapWaterEndDistance - flCheapWaterStartDistance ), + 0.0f, + 0.0f + }; + pShaderAPI->SetVertexShaderConstant( nConstantReg, flCheapWaterConstants ); + } + + inline void DrawReflection( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bBlendReflection ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + if( bBlendReflection ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + + water_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Water_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WaterReflect_ps11", 0 ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); + + float fReflectionAmount = params[REFLECTAMOUNT]->GetFloatValue(); + pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fReflectionAmount, 0.0f, 0.0f, fReflectionAmount ); + + BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER1, REFLECTTEXTURE, -1 ); + BindTexture( SHADER_SAMPLER2, NORMALMAP, BUMPFRAME ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); + pShaderAPI->SetVertexShaderIndex( 0 ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + // used to invert y + float c[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); + + SetPixelShaderConstant( 0, REFLECTTINT ); + + water_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + inline void DrawRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + water_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Water_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WaterRefract_ps11", 0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); + float fRefractionAmount = params[REFRACTAMOUNT]->GetFloatValue(); + pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fRefractionAmount, 0.0f, 0.0f, fRefractionAmount ); + BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER1, REFRACTTEXTURE ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + + // used to invert y + float c[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); + + SetPixelShaderConstant( 0, REFRACTTINT ); + + water_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + inline void DrawRefractionForFresnel( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI ) + { + SHADOW_STATE + { + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + water_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Water_vs11", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WaterRefractFresnel_ps11", 0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders. + pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE1, 0, true ); + float fRefractionAmount = params[REFRACTAMOUNT]->GetFloatValue(); + pShaderAPI->SetBumpEnvMatrix( SHADER_TEXTURE_STAGE1, fRefractionAmount, 0.0f, 0.0f, fRefractionAmount ); + BindTexture( SHADER_SAMPLER0, BUMPMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER1, REFRACTTEXTURE ); + BindTexture( SHADER_SAMPLER2, NORMALMAP, BUMPFRAME ); + s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + SetCheapWaterFactors( params, pShaderAPI, VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 ); + + // used to invert y + float c[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, c, 1 ); + + SetPixelShaderConstant( 0, REFRACTTINT ); + + water_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bBlend, bool bBlendFresnel, bool bNoPerVertexFresnel ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + + // In edit mode, use nocull + if ( UsingEditor( params ) ) + { + s_pShaderShadow->EnableCulling( false ); + } + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if( bBlend ) + { + if ( bBlendFresnel ) + { + EnableAlphaBlending( SHADER_BLEND_DST_ALPHA, SHADER_BLEND_ONE_MINUS_DST_ALPHA ); + } + else + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + } + + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | + VERTEX_TANGENT_T, 1, 0, 0 ); + + if( bNoPerVertexFresnel ) + { + watercheap_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WaterCheap_vs11", vshIndex.GetIndex() ); + } + else + { + watercheappervertexfresnel_vs11_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WaterCheapPerVertexFresnel_vs11", vshIndex.GetIndex() ); + } + + static const char *s_pPixelShaderName[] = + { + "WaterCheapOpaque_ps11", + "WaterCheap_ps11", + "WaterCheapNoFresnelOpaque_ps11", + "WaterCheapNoFresnel_ps11", + }; + + int nPshIndex = 0; + if ( bBlend ) nPshIndex |= 0x1; + if ( bNoPerVertexFresnel ) nPshIndex |= 0x2; + pShaderShadow->SetPixelShader( s_pPixelShaderName[nPshIndex] ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + BindTexture( SHADER_SAMPLER0, NORMALMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER3, ENVMAP, ENVMAPFRAME ); + + if( bBlend && !bBlendFresnel ) + { + SetCheapWaterFactors( params, pShaderAPI, VERTEX_SHADER_SHADER_SPECIFIC_CONST_2 ); + } + else + { + float flCheapWaterConstants[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, flCheapWaterConstants ); + } + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BUMPTRANSFORM ); + + SetPixelShaderConstant( 0, FOGCOLOR ); + SetPixelShaderConstant( 1, REFLECTTINT, REFLECTBLENDFACTOR ); + + if( bNoPerVertexFresnel ) + { + watercheap_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + else + { + watercheappervertexfresnel_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + } + Draw(); + } + + SHADER_DRAW + { + // NOTE: Here's what all this means. + // 1) ForceCheap means use env_cubemap only + // 2) ForceExpensive means do real reflection instead of env_cubemap. + // By default, it will do refraction and use env_cubemap for the reflection. + // If dest alpha is available, it will also use dest alpha for a fresnel term. + // otherwise there will be no fresnel term as it looks bizzare. + + bool bBlendReflection = false; + bool bForceCheap = params[FORCECHEAP]->GetIntValue() != 0 || UsingEditor( params ); + bool bForceExpensive = !bForceCheap && (params[FORCEEXPENSIVE]->GetIntValue() != 0); + bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); + bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); + bool bReflectionUseFresnel = false; + + // Can't do fresnel when forcing cheap or if there's no refraction + if( !bForceCheap ) + { + if( bRefraction ) + { + // NOTE: Expensive reflection does the fresnel correctly per-pixel + if ( g_pHardwareConfig->HasDestAlphaBuffer() && !bReflection && !params[NOFRESNEL]->GetIntValue() ) + { + DrawRefractionForFresnel( params, pShaderShadow, pShaderAPI ); + bReflectionUseFresnel = true; + } + else + { + DrawRefraction( params, pShaderShadow, pShaderAPI ); + } + bBlendReflection = true; + } + if( bReflection ) + { + DrawReflection( params, pShaderShadow, pShaderAPI, bBlendReflection ); + } + } + + // Use $decal to see if we are a decal or not. . if we are, then don't bother + // drawing the cheap version for now since we don't have access to env_cubemap + if( !bReflection && params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) ) + { + bool bNoPerVertexFresnel = ( params[NOFRESNEL]->GetIntValue() || bReflectionUseFresnel || bForceCheap || !bRefraction ); + DrawCheapWater( params, pShaderShadow, pShaderAPI, bBlendReflection, bReflectionUseFresnel, bNoPerVertexFresnel ); + } + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/water_dx81.cpp b/sp/src/materialsystem/stdshaders/water_dx81.cpp new file mode 100644 index 00000000..764ffe9e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/water_dx81.cpp @@ -0,0 +1,311 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "mathlib/vmatrix.h" + +#include "water_ps14.inc" +#include "watercheap_vs14.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( Water, Water_DX81 ) + +BEGIN_VS_SHADER( Water_DX81, + "Help for Water_DX81" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( REFRACTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "" ) + SHADER_PARAM( REFLECTTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "_rt_WaterReflection", "" ) + SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFRACTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "refraction tint" ) + SHADER_PARAM( REFLECTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "0", "" ) + SHADER_PARAM( REFLECTTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "reflection tint" ) + SHADER_PARAM( NORMALMAP, SHADER_PARAM_TYPE_TEXTURE, "", "normal map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( SCALE, SHADER_PARAM_TYPE_VEC2, "[1 1]", "" ) + SHADER_PARAM( TIME, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( WATERDEPTH, SHADER_PARAM_TYPE_FLOAT, "", "" ) + SHADER_PARAM( CHEAPWATERSTARTDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should start transitioning to a cheaper water shader." ) + SHADER_PARAM( CHEAPWATERENDDISTANCE, SHADER_PARAM_TYPE_FLOAT, "", "This is the distance from the eye in inches that the shader should finish transitioning to a cheaper water shader." ) + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "env_cubemap", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( FOGCOLOR, SHADER_PARAM_TYPE_COLOR, "", "" ) + SHADER_PARAM( FORCECHEAP, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( FORCEEXPENSIVE, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTENTITIES, SHADER_PARAM_TYPE_BOOL, "", "" ) + SHADER_PARAM( REFLECTBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1.0", "" ) + SHADER_PARAM( NOFRESNEL, SHADER_PARAM_TYPE_BOOL, "0", "" ) + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + if( !params[CHEAPWATERSTARTDISTANCE]->IsDefined() ) + { + params[CHEAPWATERSTARTDISTANCE]->SetFloatValue( 500.0f ); + } + if( !params[CHEAPWATERENDDISTANCE]->IsDefined() ) + { + params[CHEAPWATERENDDISTANCE]->SetFloatValue( 1000.0f ); + } + if( !params[SCALE]->IsDefined() ) + { + params[SCALE]->SetVecValue( 1.0f, 1.0f ); + } + if( !params[FOGCOLOR]->IsDefined() ) + { + params[FOGCOLOR]->SetVecValue( 1.0f, 0.0f, 0.0f ); + Warning( "material %s needs to have a $fogcolor.\n", pMaterialName ); + } + if( !params[REFLECTENTITIES]->IsDefined() ) + { + params[REFLECTENTITIES]->SetIntValue( 0 ); + } + if( !params[FORCEEXPENSIVE]->IsDefined() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + if( params[FORCEEXPENSIVE]->GetIntValue() && params[FORCECHEAP]->GetIntValue() ) + { + params[FORCEEXPENSIVE]->SetIntValue( 0 ); + } + if( !params[REFLECTBLENDFACTOR]->IsDefined() ) + { + params[REFLECTBLENDFACTOR]->SetFloatValue( 1.0f ); + } + if( !params[FORCEEXPENSIVE]->GetIntValue() && !params[ENVMAP]->IsDefined() ) + { + params[ENVMAP]->SetStringValue( "engine/defaultcubemap" ); + } + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 81 ) + { + return "Water_DX80"; + } + return 0; + } + + SHADER_INIT + { + Assert( params[WATERDEPTH]->IsDefined() ); + if( params[REFRACTTEXTURE]->IsDefined() ) + { + LoadTexture( REFRACTTEXTURE ); + } + if( params[REFLECTTEXTURE]->IsDefined() ) + { + LoadTexture( REFLECTTEXTURE ); + } + if (params[ENVMAP]->IsDefined() ) + { + LoadTexture( ENVMAP ); + } + if (params[NORMALMAP]->IsDefined() ) + { + LoadBumpMap( NORMALMAP ); + } + } + + inline int GetReflectionRefractionPixelShaderIndex( bool bReflection, bool bRefraction ) + { + // "REFLECT" "0..1" + // "REFRACT" "0..1" + int pshIndex = ( bReflection ? 1 : 0 ) | ( bRefraction ? 2 : 0 ); + return pshIndex; + } + + inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if( bRefraction ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + if( bReflection ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; + pShaderShadow->VertexShaderVertexFormat( fmt, 1, 0, 0 ); + + water_ps14_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "Water_ps14", vshIndex.GetIndex() ); + + int pshIndex = GetReflectionRefractionPixelShaderIndex( bReflection, bRefraction ); + pShaderShadow->SetPixelShader ( "Water_ps14", pshIndex ); + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_NORMALIZATION_CUBEMAP ); + if( bRefraction ) + { + BindTexture( SHADER_SAMPLER2, REFRACTTEXTURE, -1 ); + } + BindTexture( SHADER_SAMPLER3, NORMALMAP, BUMPFRAME ); + if( bReflection ) + { + BindTexture( SHADER_SAMPLER4, REFLECTTEXTURE, -1 ); + } + + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, REFLECTAMOUNT ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); + SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, REFRACTAMOUNT ); + + float c0[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); + + SetPixelShaderConstant( 1, REFRACTTINT ); + SetPixelShaderConstant( 4, REFLECTTINT ); + + float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; + pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); + + // ERASE ME! + float c3[4] = { 5.0f, 0.0f, 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 3, c3, 1 ); + + // reflection/refraction scale + float reflectionRefractionScale[4] = { params[REFLECTAMOUNT]->GetFloatValue(), + params[REFRACTAMOUNT]->GetFloatValue(), 0.0f, 0.0f }; + pShaderAPI->SetPixelShaderConstant( 5, reflectionRefractionScale, 1 ); + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, reflectionRefractionScale, 1 ); + + water_ps14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + enum DrawCheapType_t + { + DRAW_CHEAP_OPAQUE = 0, + DRAW_CHEAP_FRESNEL_OPAQUE, + DRAW_CHEAP_LOD_ONLY, + DRAW_CHEAP_FRESNEL_AND_LOD, + }; + + inline void DrawCheapWater( IMaterialVar **params, IShaderShadow* pShaderShadow, + IShaderDynamicAPI* pShaderAPI, DrawCheapType_t type ) + { + SHADOW_STATE + { + SetInitialShadowState( ); + + // In edit mode, use nocull + if ( UsingEditor( params ) ) + { + s_pShaderShadow->EnableCulling( false ); + } + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + if ( (type != DRAW_CHEAP_OPAQUE) && (type != DRAW_CHEAP_FRESNEL_OPAQUE) ) + { + EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + } + pShaderShadow->VertexShaderVertexFormat( + VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | + VERTEX_TANGENT_T, 1, 0, 0 ); + + watercheap_vs14_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WaterCheap_vs14", vshIndex.GetIndex() ); + + static const char *s_pPixelShader[] = + { + "WaterCheapOpaque_ps14", + "WaterCheapFresnelOpaque_ps14", + "WaterCheap_ps14", + "WaterCheapFresnel_ps14", + }; + + pShaderShadow->SetPixelShader( s_pPixelShader[type] ); + FogToFogColor(); + } + DYNAMIC_STATE + { + pShaderAPI->SetDefaultState(); + BindTexture( SHADER_SAMPLER0, NORMALMAP, BUMPFRAME ); + BindTexture( SHADER_SAMPLER3, ENVMAP, ENVMAPFRAME ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALIZATION_CUBEMAP ); + + float pCheapWaterConstants[4] = { 0, 0, 0, 0 }; + if ( (type != DRAW_CHEAP_OPAQUE) && (type != DRAW_CHEAP_FRESNEL_OPAQUE) ) + { + float flCheapWaterStartDistance = params[CHEAPWATERSTARTDISTANCE]->GetFloatValue(); + float flCheapWaterEndDistance = params[CHEAPWATERENDDISTANCE]->GetFloatValue(); + pCheapWaterConstants[0] = flCheapWaterStartDistance; + pCheapWaterConstants[1] = 1.0f / ( flCheapWaterEndDistance - flCheapWaterStartDistance ); + } + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, pCheapWaterConstants ); + + SetPixelShaderConstant( 0, FOGCOLOR ); + SetPixelShaderConstant( 1, REFLECTTINT, REFLECTBLENDFACTOR ); + + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BUMPTRANSFORM ); + + watercheap_vs14_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + Draw(); + } + + SHADER_DRAW + { + // NOTE: Here's what all this means. + // 1) ForceCheap means use env_cubemap only + // 2) ForceExpensive means do real reflection instead of env_cubemap. + // By default, it will do refraction and use env_cubemap for the reflection. + + // Also, it will fade to cheap water at a particular distance, + // based on CheapWaterStartDistance and CheapWaterEndDistance + // * In the ForceCheap case, no fading is required + // * In the default case, it will fade based on these parameters in a single pass + // * In the expensive case, it will have to perform the fade in a separate pass. + + bool bForceCheap = params[FORCECHEAP]->GetIntValue() != 0 || UsingEditor( params ); + bool bForceExpensive = params[FORCEEXPENSIVE]->GetIntValue() != 0; + bool bRefraction = params[REFRACTTEXTURE]->IsTexture(); + bool bReflection = bForceExpensive && params[REFLECTTEXTURE]->IsTexture(); + DrawCheapType_t type = params[NOFRESNEL]->GetIntValue() ? DRAW_CHEAP_OPAQUE : DRAW_CHEAP_FRESNEL_OPAQUE; + if( !bForceCheap && (bRefraction || bReflection) ) + { + DrawReflectionRefraction( params, pShaderShadow, pShaderAPI, bReflection, bRefraction ); + if ( !bReflection ) + { + type = params[NOFRESNEL]->GetIntValue() ? DRAW_CHEAP_LOD_ONLY : DRAW_CHEAP_FRESNEL_AND_LOD; + } + else + { + type = DRAW_CHEAP_LOD_ONLY; + } + } + + // Use $decal to see if we are a decal or not. . if we are, then don't bother + // drawing the cheap version for now since we don't have access to env_cubemap + if( params[ENVMAP]->IsTexture() && !IS_FLAG_SET( MATERIAL_VAR_DECAL ) && !bReflection ) + { + DrawCheapWater( params, pShaderShadow, pShaderAPI, type ); + } + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/water_ps2x.fxc b/sp/src/materialsystem/stdshaders/water_ps2x.fxc new file mode 100644 index 00000000..a80a8a15 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/water_ps2x.fxc @@ -0,0 +1,110 @@ +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b] [= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "BASETEXTURE" "0..1" +// STATIC: "MULTITEXTURE" "0..1" +// STATIC: "REFLECT" "0..1" +// STATIC: "REFRACT" "0..1" +// STATIC: "ABOVEWATER" "0..1" +// STATIC: "BLURRY_REFRACT" "0..1" [ps20b] + +// When we turn NORMAL_DECODE_MODE on, this shader only needs 0..1, not 0..2 +// STATIC: "NORMAL_DECODE_MODE" "0..0" [XBOX] +// STATIC: "NORMAL_DECODE_MODE" "0..0" [PC] + +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] + +// SKIP: $MULTITEXTURE && $BASETEXTURE + +#if defined(SHADER_MODEL_PS_2_0) +# define BLURRY_REFRACT 0 +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + +#include "water_ps2x_helper.h" + + +sampler RefractSampler : register( s0 ); +#if BASETEXTURE +sampler BaseTextureSampler : register( s1 ); +#endif +sampler ReflectSampler : register( s2 ); +#if BASETEXTURE +sampler LightmapSampler : register( s3 ); +#endif +sampler NormalSampler : register( s4 ); + +const HALF4 vRefractTint : register( c1 ); +const HALF4 vReflectTint : register( c4 ); +const float4 g_ReflectRefractScale : register( c5 ); // xy - reflect scale, zw - refract scale +const HALF4 g_WaterFogColor : register( c6 ); +const HALF4 g_WaterFogParams : register( c7 ); + +const float4 g_PixelFogParams : register( c8 ); + + +#define g_WaterFogStart g_WaterFogParams.x +#define g_WaterFogEndMinusStart g_WaterFogParams.y +#define g_Reflect_OverBright g_WaterFogParams.z + +struct PS_INPUT +{ + float2 vBumpTexCoord : TEXCOORD0; + half3 vTangentEyeVect : TEXCOORD1; + float4 vReflectXY_vRefractYX : TEXCOORD2; + float W : TEXCOORD3; + float4 vProjPos : TEXCOORD4; + float screenCoord : TEXCOORD5; +#if MULTITEXTURE + float4 vExtraBumpTexCoord : TEXCOORD6; +#endif +#if BASETEXTURE +// CENTROID: TEXCOORD6 + HALF4 lightmapTexCoord1And2 : TEXCOORD6; +// CENTROID: TEXCOORD7 + HALF4 lightmapTexCoord3 : TEXCOORD7; +#endif + + float4 fogFactorW : COLOR1; +}; + +float4 main( PS_INPUT i ) : COLOR +{ + DrawWater_params_t params; + + params.vBumpTexCoord = i.vBumpTexCoord; +#if MULTITEXTURE + params.vExtraBumpTexCoord = i.vExtraBumpTexCoord; +#endif + params.vReflectXY_vRefractYX = i.vReflectXY_vRefractYX; + params.w = i.W; + params.vReflectRefractScale = g_ReflectRefractScale; + params.fReflectOverbright = g_Reflect_OverBright; + params.vReflectTint = vReflectTint; + params.vRefractTint = vRefractTint; + params.vTangentEyeVect = i.vTangentEyeVect; + params.waterFogColor = g_WaterFogColor; +#if BASETEXTURE + params.lightmapTexCoord1And2 = i.lightmapTexCoord1And2; + params.lightmapTexCoord3 = i.lightmapTexCoord3; +#endif + params.vProjPos = i.vProjPos; + params.pixelFogParams = g_PixelFogParams; + params.fWaterFogStart = g_WaterFogStart; + params.fWaterFogEndMinusStart = g_WaterFogEndMinusStart; + + float4 result; + float fogFactor; + DrawWater( params, + // yay. . can't put sampler in a struct. +#if BASETEXTURE + BaseTextureSampler, + LightmapSampler, +#endif + NormalSampler, RefractSampler, ReflectSampler, + result, fogFactor ); + + return FinalOutput( float4( result.rgb, 1.0f ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE, (WRITE_DEPTH_TO_DESTALPHA != 0), i.vProjPos.z ); +} + diff --git a/sp/src/materialsystem/stdshaders/water_ps2x_helper.h b/sp/src/materialsystem/stdshaders/water_ps2x_helper.h new file mode 100644 index 00000000..b15b9986 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/water_ps2x_helper.h @@ -0,0 +1,239 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#include "common_ps_fxc.h" + +struct DrawWater_params_t +{ + float2 vBumpTexCoord; +#if MULTITEXTURE + float4 vExtraBumpTexCoord; +#endif + float4 vReflectXY_vRefractYX; + float w; + float4 vReflectRefractScale; + float fReflectOverbright; + float4 vReflectTint; + float4 vRefractTint; + half3 vTangentEyeVect; + float4 waterFogColor; +#if BASETEXTURE + HALF4 lightmapTexCoord1And2; + HALF4 lightmapTexCoord3; +#endif + float4 vProjPos; + float4 pixelFogParams; + float fWaterFogStart; + float fWaterFogEndMinusStart; +}; + +void DrawWater( in DrawWater_params_t i, +#if BASETEXTURE + in sampler BaseTextureSampler, + in sampler LightmapSampler, +#endif + in sampler NormalSampler, + in sampler RefractSampler, + in sampler ReflectSampler, + out float4 result, out float fogFactor ) +{ + bool bReflect = REFLECT ? true : false; + bool bRefract = REFRACT ? true : false; + +#if MULTITEXTURE + float4 vNormal = tex2D( NormalSampler, i.vBumpTexCoord ); + float4 vNormal1 = tex2D( NormalSampler, i.vExtraBumpTexCoord.xy ); + float4 vNormal2 = tex2D( NormalSampler, i.vExtraBumpTexCoord.zw ); + vNormal = 0.33 * ( vNormal + vNormal1 + vNormal2 ); + +#if ( NORMAL_DECODE_MODE == NORM_DECODE_ATI2N ) + vNormal.xy = vNormal.xy * 2.0f - 1.0f; + vNormal.z = sqrt( 1.0f - dot(vNormal.xy, vNormal.xy) ); + vNormal.a = 1.0f; +#else + vNormal.xyz = 2.0 * vNormal.xyz - 1.0; +#endif + +#else + float4 vNormal = DecompressNormal( NormalSampler, i.vBumpTexCoord, NORMAL_DECODE_MODE ); +#endif + + // Perform division by W only once + float ooW = 1.0f / i.w; + + float2 unwarpedRefractTexCoord = i.vReflectXY_vRefractYX.wz * ooW; + +#if ABOVEWATER + float waterFogDepthValue = tex2D( RefractSampler, unwarpedRefractTexCoord ).a; +#else + // We don't actually have valid depth values in alpha when we are underwater looking out, so + // just set to farthest value. + float waterFogDepthValue = 1.0f; +#endif + float4 reflectRefractScale = i.vReflectRefractScale; +#if !BASETEXTURE +#if ( BLURRY_REFRACT == 0 ) + reflectRefractScale *= waterFogDepthValue; +#endif +#endif + + // Compute coordinates for sampling Reflection + float2 vReflectTexCoord; + float2 vRefractTexCoord; + + // vectorize the dependent UV calculations (reflect = .xy, refract = .wz) + float4 vN; + vN.xy = vNormal.xy; + vN.w = vNormal.x; + vN.z = vNormal.y; + float4 vDependentTexCoords = vN * vNormal.a * reflectRefractScale; + + vDependentTexCoords += ( i.vReflectXY_vRefractYX * ooW ); + vReflectTexCoord = vDependentTexCoords.xy; + vRefractTexCoord = vDependentTexCoords.wz; + + HALF4 vReflectColor = tex2D( ReflectSampler, vReflectTexCoord ); +#if BLURRY_REFRACT + // Sample reflection and refraction + float2 ddx1=float2(0.005,0); + float2 ddy1=float2(0,0.005); + float4 vRefractColor=float4(0,0,0,0); + +#if 0 + float sumweights=0; + for(int ix=-2;ix<=2;ix++) + { + for(int iy=-2;iy<=2;iy++) + { + float weight=1; ///(1+abs(ix)+abs(iy)); + vRefractColor += weight*tex2D( RefractSampler, vRefractTexCoord+ix*ddx1+iy*ddy1); + sumweights+=weight; + } + } +#else + // NOTE: Generated by genwaterloop.pl in the stdshaders directory. + // Need to unroll for 360 to avoid shader compilation problems. + // Modified genwaterloop.pl and regenerate if you need different params + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -2 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + -1 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 0 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 1 * ddx1 + 2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -2 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + -1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 0 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 1 * ddy1 ); + vRefractColor += tex2D( RefractSampler, vRefractTexCoord + 2 * ddx1 + 2 * ddy1 ); + float sumweights = 25; + // NOTE: end of generated code. +#endif + + vRefractColor *= (1.0/sumweights); + vReflectColor *= i.fReflectOverbright; + vReflectColor *= i.vReflectTint; + vRefractColor *= i.vRefractTint; +# if ABOVEWATER + // Don't mess with this in the underwater case since we don't really have + // depth values there. + // get the blurred depth value to be used for fog. + waterFogDepthValue = vRefractColor.a; +# endif +#else + vReflectColor *= i.vReflectTint; + HALF4 vRefractColor = tex2D( RefractSampler, vRefractTexCoord ); + // get the depth value from the refracted sample to be used for fog. +# if ABOVEWATER + // Don't mess with this in the underwater case since we don't really have + // depth values there. + waterFogDepthValue = tex2D( RefractSampler, vRefractTexCoord ).a; +# endif +#endif + + half3 vEyeVect; + vEyeVect = normalize( i.vTangentEyeVect ); + + // Fresnel term + HALF fNdotV = saturate( dot( vEyeVect, vNormal ) ); + HALF fFresnel = pow( 1.0 - fNdotV, 5 ); + +#if !BASETEXTURE + // fFresnel == 1.0f means full reflection + fFresnel *= saturate( ( waterFogDepthValue - 0.05f ) * 20.0f ); +#endif + + + // blend between refraction and fog color. +#if ABOVEWATER + vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, saturate( waterFogDepthValue - 0.05f ) ); +#else + float waterFogFactor = saturate( ( i.vProjPos.z - i.fWaterFogStart ) / i.fWaterFogEndMinusStart ); + vRefractColor = lerp( vRefractColor, i.waterFogColor * LINEAR_LIGHT_SCALE, waterFogFactor ); +#endif + +#if BASETEXTURE + float4 baseSample = tex2D( BaseTextureSampler, i.vBumpTexCoord.xy ); + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + HALF3 lightmapColor1 = lightmapSample1.rgb; + HALF3 lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); + HALF3 lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); + + float3 dp; + dp.x = saturate( dot( vNormal, bumpBasis[0] ) ); + dp.y = saturate( dot( vNormal, bumpBasis[1] ) ); + dp.z = saturate( dot( vNormal, bumpBasis[2] ) ); + dp *= dp; + + float3 diffuseLighting = dp.x * lightmapColor1 + + dp.y * lightmapColor2 + + dp.z * lightmapColor3; + float sum = dot( dp, float3( 1.0f, 1.0f, 1.0f ) ); + diffuseLighting *= LIGHT_MAP_SCALE / sum; + HALF3 diffuseComponent = baseSample.rgb * diffuseLighting; +#endif + + if( bReflect && bRefract ) + { + result = lerp( vRefractColor, vReflectColor, fFresnel ); + } + else if( bReflect ) + { +#if BASETEXTURE + result = float4( diffuseComponent, 1.0f ) + vReflectColor * fFresnel * baseSample.a; +#else + result = vReflectColor; +#endif + } + else if( bRefract ) + { + result = vRefractColor; + } + else + { + result = float4( 0.0f, 0.0f, 0.0f, 0.0f ); + } + +#if (PIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE) + fogFactor = CalcRangeFog( i.vProjPos.z, i.pixelFogParams.x, i.pixelFogParams.z, i.pixelFogParams.w ); +#else + fogFactor = 0; +#endif +} diff --git a/sp/src/materialsystem/stdshaders/waterreflect_ps14.psh b/sp/src/materialsystem/stdshaders/waterreflect_ps14.psh new file mode 100644 index 00000000..7104e45c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/waterreflect_ps14.psh @@ -0,0 +1,8 @@ +ps.1.4 + +texld r0, t0_dw.xyw ; sample dudv map + +phase + +texld r0, t0 + diff --git a/sp/src/materialsystem/stdshaders/waterrefract_ps14.psh b/sp/src/materialsystem/stdshaders/waterrefract_ps14.psh new file mode 100644 index 00000000..5b5d1755 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/waterrefract_ps14.psh @@ -0,0 +1,23 @@ +ps.1.4 + +; non-fresnel version +; t0: +; texture: dudv map +; texcoords: coords for normal map +; t1: +; texcoords: uvw for first dp3 +; t2: +; texture: renderable texture that we are going to perturb +; texcoords: uvw for second dp3 +;tex t0 ; sample dudv map +;texm3x2pad t1, t0 ; +;texm3x2tex t2, t0 ; sample renderabletexture + +;mul r0, t2, c1 + + +texld r0, t0 ; sample dudv map + +phase + +texld r0, t2_dw.xyw diff --git a/sp/src/materialsystem/stdshaders/worldtwotextureblend.cpp b/sp/src/materialsystem/stdshaders/worldtwotextureblend.cpp new file mode 100644 index 00000000..542013e0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldtwotextureblend.cpp @@ -0,0 +1,500 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#include "BaseVSShader.h" + +#include "convar.h" + +#include "lightmappedgeneric_vs20.inc" +#include "WorldTwoTextureBlend_ps20.inc" +#include "WorldTwoTextureBlend_ps20b.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern ConVar r_flashlight_version2; + +// FIXME: Need to make a dx9 version so that "CENTROID" works. +BEGIN_VS_SHADER( WorldTwoTextureBlend, + "Help for WorldTwoTextureBlend" ) + +BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "iris texture", 0 ) + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend_detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale of the detail texture" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) +END_SHADER_PARAMS + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "WorldTwoTextureBlend_DX6"; + + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "WorldTwoTextureBlend_DX8"; + + return 0; + } + + SHADER_INIT_PARAMS() + { + + if( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->IsDefined() ) + { + params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->SetIntValue( 0 ); + } + + if ( g_pHardwareConfig->SupportsBorderColor() ) + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" ); + } + else + { + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + } + + // Write over $basetexture with $albedo if we are going to be using diffuse normal mapping. + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() && params[ALBEDO]->IsDefined() && + params[BASETEXTURE]->IsDefined() && + !( params[NODIFFUSEBUMPLIGHTING]->IsDefined() && params[NODIFFUSEBUMPLIGHTING]->GetIntValue() ) ) + { + params[BASETEXTURE]->SetStringValue( params[ALBEDO]->GetStringValue() ); + } + + if( !params[NODIFFUSEBUMPLIGHTING]->IsDefined() ) + { + params[NODIFFUSEBUMPLIGHTING]->SetIntValue( 0 ); + } + + if( !params[SELFILLUMTINT]->IsDefined() ) + { + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[DETAILSCALE]->IsDefined() ) + { + params[DETAILSCALE]->SetFloatValue( 4.0f ); + } + + if( !params[BUMPFRAME]->IsDefined() ) + { + params[BUMPFRAME]->SetIntValue( 0 ); + } + + if( !params[DETAILFRAME]->IsDefined() ) + { + params[DETAILFRAME]->SetIntValue( 0 ); + } + + // No texture means no self-illum or env mask in base alpha + if ( !params[BASETEXTURE]->IsDefined() ) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + + // If in decal mode, no debug override... + if (IS_FLAG_SET(MATERIAL_VAR_DECAL)) + { + SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() && (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0) ) + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ); + } + } + + SHADER_INIT + { + if( g_pConfig->UseBumpmapping() && params[BUMPMAP]->IsDefined() ) + { + LoadBumpMap( BUMPMAP ); + } + + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE, TEXTUREFLAGS_SRGB ); + + if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent()) + { + CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM ); + CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK ); + } + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + + LoadTexture( FLASHLIGHTTEXTURE, TEXTUREFLAGS_SRGB ); + + // Don't alpha test if the alpha channel is used for other purposes + if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) ) + { + CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST ); + } + + // We always need this because of the flashlight. + SET_FLAGS2( MATERIAL_VAR2_NEEDS_TANGENT_SPACES ); + } + + void DrawPass( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, + IShaderShadow* pShaderShadow, bool hasFlashlight, VertexCompressionType_t vertexCompression ) + { + bool hasBump = params[BUMPMAP]->IsTexture(); + bool hasDiffuseBumpmap = hasBump && (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0); + bool hasBaseTexture = params[BASETEXTURE]->IsTexture(); + bool hasDetailTexture = /*!hasBump && */params[DETAIL]->IsTexture(); + bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) != 0; + bool bHasDetailAlpha = params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->GetIntValue() != 0; + bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; + + BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); + bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use + + bool bSeamlessMapping = params[SEAMLESS_SCALE]->GetFloatValue() != 0.0; + + SHADOW_STATE + { + int nShadowFilterMode = 0; + + // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState + pShaderShadow->EnableAlphaTest( bIsAlphaTested ); + if( hasFlashlight ) + { + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats + } + + SetAdditiveBlendingShadowState( BASETEXTURE, true ); + pShaderShadow->EnableDepthWrites( false ); + + // Be sure not to write to dest alpha + pShaderShadow->EnableAlphaWrites( false ); + } + else + { + SetDefaultBlendingShadowState( BASETEXTURE, true ); + } + + unsigned int flags = VERTEX_POSITION; + if( hasBaseTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); + } + // if( hasLightmap ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ); + } + if( hasFlashlight ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); + pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 ); + flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL; + } + if( hasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); + } + if( hasBump ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); + } + if( hasVertexColor ) + { + flags |= VERTEX_COLOR; + } + + // Normalizing cube map + pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); + + // texcoord0 : base texcoord + // texcoord1 : lightmap texcoord + // texcoord2 : lightmap texcoord offset + int numTexCoords = 2; + if( hasBump ) + { + numTexCoords = 3; + } + + pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); + + // Pre-cache pixel shaders + bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); + + pShaderShadow->EnableSRGBWrite( true ); + + DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, false ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, false ); + SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, hasFlashlight ); + SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); + SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, false ); + SET_STATIC_VERTEX_SHADER_COMBO( RELIEF_MAPPING, 0 ); //( bumpmap_variant == 2 )?1:0); + SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); //( bumpmap_variant == 2 )?1:0); +#ifdef _X360 + SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); +#endif + SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); + SET_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); + SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); + SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); + SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); + SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); + SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); + SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); + SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); + SET_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); + } + + // HACK HACK HACK - enable alpha writes all the time so that we have them for + // underwater stuff. + // But only do it if we're not using the alpha already for translucency + pShaderShadow->EnableAlphaWrites( bFullyOpaque ); + + + if( hasFlashlight ) + { + FogToBlack(); + } + else + { + DefaultFog(); + } + } + DYNAMIC_STATE + { + if( hasBaseTexture ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); + } + + // if( hasLightmap ) + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + } + + bool bFlashlightShadows = false; + if( hasFlashlight ) + { + VMatrix worldToTexture; + ITexture *pFlashlightDepthTexture; + FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); + bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ); + + SetFlashLightColorFromState( state, pShaderAPI ); + + BindTexture( SHADER_SAMPLER2, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); + + if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() ) + { + BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture ); + } + } + if( hasDetailTexture ) + { + BindTexture( SHADER_SAMPLER3, DETAIL, DETAILFRAME ); + } + if( hasBump ) + { + if( !g_pConfig->m_bFastNoBump ) + { + BindTexture( SHADER_SAMPLER4, BUMPMAP, BUMPFRAME ); + } + else + { + pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALMAP_FLAT ); + } + } + pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); + + // If we don't have a texture transform, we don't have + // to set vertex shader constants or run vertex shader instructions + // for the texture transform. + bool bHasTextureTransform = + !( params[BASETEXTURETRANSFORM]->MatrixIsIdentity() && + params[BUMPTRANSFORM]->MatrixIsIdentity() ); + + bool bVertexShaderFastPath = !bHasTextureTransform; + if( params[DETAIL]->IsTexture() ) + { + bVertexShaderFastPath = false; + } + if( pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0 ) + { + bVertexShaderFastPath = false; + } + + float color[4] = { 1.0, 1.0, 1.0, 1.0 }; + ComputeModulationColor( color ); + if( !( bVertexShaderFastPath && color[0] == 1.0f && color[1] == 1.0f && color[2] == 1.0f && color[3] == 1.0f ) ) + { + bVertexShaderFastPath = false; + s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); + if (! bSeamlessMapping) + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + if( hasBump && !bHasDetailAlpha ) + { + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BUMPTRANSFORM ); + Assert( !hasDetailTexture ); + } + } + + MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); + DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); + SET_DYNAMIC_VERTEX_SHADER_COMBO( + LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0); + SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); + + bool bWriteDepthToAlpha; + bool bWriteWaterFogToAlpha; + if( bFullyOpaque ) + { + bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); + bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); + AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); + } + else + { + //can't write a special value to dest alpha if we're actually using as-intended alpha + bWriteDepthToAlpha = false; + bWriteWaterFogToAlpha = false; + } + + + if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); + SET_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); + + // Don't write fog to alpha if we're using translucency + SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z) && + (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested ); + SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); + SET_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); + } + + + // always set the transform for detail textures since I'm assuming that you'll + // always have a detailscale. + if( hasDetailTexture ) + { + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, DETAILSCALE ); + Assert( !( hasBump && !bHasDetailAlpha ) ); + } + + SetPixelShaderConstantGammaToLinear( 7, SELFILLUMTINT ); + + float eyePos[4]; + pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); + pShaderAPI->SetPixelShaderConstant( 10, eyePos, 1 ); + pShaderAPI->SetPixelShaderFogParams( 11 ); + + if ( bSeamlessMapping ) + { + float map_scale[4]={ params[SEAMLESS_SCALE]->GetFloatValue(),0,0,0}; + pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale ); + } + + + if( hasFlashlight ) + { + VMatrix worldToTexture; + const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); + + // Set the flashlight attenuation factors + float atten[4]; + atten[0] = flashlightState.m_fConstantAtten; + atten[1] = flashlightState.m_fLinearAtten; + atten[2] = flashlightState.m_fQuadraticAtten; + atten[3] = flashlightState.m_FarZ; + pShaderAPI->SetPixelShaderConstant( 20, atten, 1 ); + + // Set the flashlight origin + float pos[4]; + pos[0] = flashlightState.m_vecLightOrigin[0]; + pos[1] = flashlightState.m_vecLightOrigin[1]; + pos[2] = flashlightState.m_vecLightOrigin[2]; + pos[3] = 1.0f; + pShaderAPI->SetPixelShaderConstant( 15, pos, 1 ); + + pShaderAPI->SetPixelShaderConstant( 16, worldToTexture.Base(), 4 ); + } + } + Draw(); + } + + SHADER_DRAW + { + bool bHasFlashlight = UsingFlashlight( params ); + if ( bHasFlashlight && ( IsX360() || r_flashlight_version2.GetInt() ) ) + { + DrawPass( params, pShaderAPI, pShaderShadow, false, vertexCompression ); + SHADOW_STATE + { + SetInitialShadowState( ); + } + } + DrawPass( params, pShaderAPI, pShaderShadow, bHasFlashlight, vertexCompression ); + } + +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp b/sp/src/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp new file mode 100644 index 00000000..3ae6383a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp @@ -0,0 +1,258 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +DEFINE_FALLBACK_SHADER( WorldTwoTextureBlend, WorldTwoTextureBlend_DX6 ) + + +BEGIN_SHADER( WorldTwoTextureBlend_DX6, + "Help for WorldTwoTextureBlend" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "iris texture", 0 ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend_detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale of the detail texture" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + END_SHADER_PARAMS + + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + LoadTexture( BASETEXTURE ); + LoadTexture( DETAIL ); + } + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + if( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->IsDefined() ) + params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->SetIntValue( 0 ); + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + + SHADER_DRAW + { + float detailScale = params[DETAILSCALE]->GetFloatValue(); + + bool hasFlashlight = UsingFlashlight( params ); + + if( hasFlashlight ) + { + DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + return; + } + + // DX6 fallback mode. + if ( params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->GetIntValue() ) + { + DetailAlphaMaskPass1( pShaderShadow, pShaderAPI, params, detailScale ); + DetailAlphaMaskPass2( pShaderShadow, pShaderAPI, detailScale ); + } + else + { + // FIXME: add multitexture support! + NormalModePass1( pShaderShadow, pShaderAPI ); + NormalModePass2( pShaderShadow, pShaderAPI, params, detailScale ); + NormalModePass3( pShaderShadow, pShaderAPI, params, detailScale ); + } + } + + + // ------------------------------------------------------------------------------ // + // "Normal" mode - doesn't use the detail texture's alpha mask. + // ------------------------------------------------------------------------------ // + + void NormalModePass1( + IShaderShadow *pShaderShadow, + IShaderDynamicAPI *pShaderAPI ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + } + Draw(); + } + + void NormalModePass2( + IShaderShadow *pShaderShadow, + IShaderDynamicAPI *pShaderAPI, + IMaterialVar **params, + float detailScale ) + { + SHADOW_STATE + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableBlending( true ); + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + if ( detailScale != 1.0f ) + { + pShaderAPI->MatrixMode( MATERIAL_TEXTURE0 ); + pShaderAPI->LoadIdentity(); + pShaderAPI->ScaleXY( detailScale, detailScale ); + } + BindTexture( SHADER_SAMPLER0, DETAIL ); + } + Draw(); + } + + void NormalModePass3( + IShaderShadow *pShaderShadow, + IShaderDynamicAPI *pShaderAPI, + IMaterialVar **params, + float detailScale ) + { + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + SingleTextureLightmapBlendMode(); + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + FogToOOOverbright(); + } + DYNAMIC_STATE + { + if ( detailScale != 1.0f ) + pShaderAPI->LoadIdentity( ); + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + Draw(); + } + + + // ------------------------------------------------------------------------------ // + // "Detail alpha mask mode". + // ------------------------------------------------------------------------------ // + + void DetailAlphaMaskPass1( + IShaderShadow *pShaderShadow, + IShaderDynamicAPI *pShaderAPI, + IMaterialVar **params, + float detailScale ) + { + // The equation is [B*Da + (1-Da)] * [D * L] + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 2 ); + + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + // Stage 0 + // Color = B*2 + // Note the 2x here.. we do 4x total in this shader and + // the first 2x is here. The second is in SingleTextureLightmapBlendMode in the 2nd pass. + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + + // Stage 1 [where P = prev stage] + // Color = B*Da + (1-Da) + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATEINVCOLOR_ADDALPHA, + SHADER_TEXARG_INVTEXTUREALPHA, SHADER_TEXARG_PREVIOUSSTAGE ); + + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_TEXCOORD1 ); + FogToFogColor(); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + BindTexture( SHADER_SAMPLER1, DETAIL ); + + pShaderAPI->Color4f( 1, 1, 1, 1 ); + + if ( detailScale != 1.0f ) + { + pShaderAPI->MatrixMode( MATERIAL_TEXTURE1 ); + pShaderAPI->LoadIdentity(); + pShaderAPI->ScaleXY( detailScale, detailScale ); + } + + } + Draw(); + } + + void DetailAlphaMaskPass2( IShaderShadow *pShaderShadow, IShaderDynamicAPI *pShaderAPI, float detailScale ) + { + SHADOW_STATE + { + s_pShaderShadow->EnableCustomPixelPipe( true ); + s_pShaderShadow->CustomTextureStages( 2 ); + + s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, true); + + // Make sure the texgen transform is applied to the texture coordinates and not to an auto-generated reflection vector or whatever. + s_pShaderShadow->TexGen( SHADER_TEXTURE_STAGE0, SHADER_TEXGENPARAM_OBJECT_LINEAR ); + + // This turns on blending and does overbrighting if it's enabled. + SingleTextureLightmapBlendMode(); + + // Stage 0, color = D + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); + + // Stage 1, color = D*L + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE, + SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_TEXTURE ); + + // Use the lightmap coordinates in both stages. + pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 | SHADER_DRAW_LIGHTMAP_TEXCOORD1 ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER0, DETAIL); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + if ( detailScale != 1.0f ) + { + pShaderAPI->MatrixMode( MATERIAL_TEXTURE1 ); + pShaderAPI->LoadIdentity(); + + pShaderAPI->MatrixMode( MATERIAL_TEXTURE0 ); + pShaderAPI->LoadIdentity(); + pShaderAPI->ScaleXY( detailScale, detailScale ); + } + } + + Draw(); + } + +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp b/sp/src/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp new file mode 100644 index 00000000..a58d9dfb --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp @@ -0,0 +1,175 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "lightmappedgeneric_vs11.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +DEFINE_FALLBACK_SHADER( WorldTwoTextureBlend, WorldTwoTextureBlend_DX8 ) + +BEGIN_VS_SHADER( WorldTwoTextureBlend_DX8, + "Help for WorldTwoTextureBlend_DX8" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM_OVERRIDE( BASETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend", "iris texture", 0 ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/WorldTwoTextureBlend_detail", "detail texture" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "1.0", "scale of the detail texture" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + END_SHADER_PARAMS + + SHADER_FALLBACK + { + if ( IsPC() && g_pHardwareConfig->GetDXSupportLevel() < 80 ) + return "WorldTwoTextureBlend_DX6"; + + return 0; + } + SHADER_INIT + { + LoadTexture( FLASHLIGHTTEXTURE ); + if (params[BASETEXTURE]->IsDefined()) + { + LoadTexture( BASETEXTURE ); + } + + if (params[DETAIL]->IsDefined()) + { + LoadTexture( DETAIL ); + } + } + + SHADER_INIT_PARAMS() + { + // FLASHLIGHTFIXME + params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" ); + + if( !params[SELFILLUMTINT]->IsDefined() ) + { + params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f ); + } + + if( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->IsDefined() ) + { + params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->SetIntValue( 0 ); + } + + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + + const char *GetPixelShaderName( IMaterialVar** params, bool bHasBaseTexture, bool bHasDetailTexture ) + { + bool bSelfIllum = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM); + if ( !bHasBaseTexture ) + { + if ( !bHasDetailTexture ) + return "LightmappedGeneric_NoTexture"; + + return "LightmappedGeneric_DetailNoTexture"; + } + + if ( !bHasDetailTexture ) + { + if ( bSelfIllum ) + return "LightmappedGeneric_SelfIlluminated"; + + return "LightmappedGeneric"; + } + + if ( !params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->GetIntValue() ) + { + if ( bSelfIllum ) + return "WorldTwoTextureBlend_SelfIlluminated"; + + return "WorldTwoTextureBlend"; + } + + return "WorldTwoTextureBlend_DetailAlpha"; + } + + + SHADER_DRAW + { + bool hasFlashlight = UsingFlashlight( params ); + if( hasFlashlight ) + { + DrawFlashlight_dx80( params, pShaderAPI, pShaderShadow, false, -1, -1, -1, + FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME, true, false, 0, -1, -1 ); + return; + } + + bool bHasBaseTexture = params[BASETEXTURE]->IsTexture(); + bool bHasDetailTexture = params[DETAIL]->IsTexture(); + bool bHasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); + + SHADOW_STATE + { + if ( bHasBaseTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + } + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + if ( bHasDetailTexture ) + { + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + } + pShaderShadow->EnableBlending( false ); + + pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 2, 0, 0 ); + + // Let the shaders do the fun stuff. + lightmappedgeneric_vs11_Static_Index vshIndex; + vshIndex.SetDETAIL( bHasDetailTexture ); + vshIndex.SetENVMAP( false ); + vshIndex.SetENVMAPCAMERASPACE( false ); + vshIndex.SetENVMAPSPHERE( false ); + vshIndex.SetVERTEXCOLOR( bHasVertexColor ); + pShaderShadow->SetVertexShader( "LightmappedGeneric_vs11", vshIndex.GetIndex() ); + + const char *pPixelShaderName = GetPixelShaderName( params, bHasBaseTexture, bHasDetailTexture ); + pShaderShadow->SetPixelShader( pPixelShaderName ); + + FogToFogColor(); + } + DYNAMIC_STATE + { + if ( bHasBaseTexture ) + { + BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); + SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); + } + + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + if ( bHasDetailTexture ) + { + BindTexture( SHADER_SAMPLER2, DETAIL ); + SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, BASETEXTURETRANSFORM, DETAILSCALE ); + } + + SetModulationVertexShaderDynamicState(); + + // Dynamic vertex shader index. + lightmappedgeneric_vs11_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + EnablePixelShaderOverbright( 0, true, true ); + SetPixelShaderConstant( 1, SELFILLUMTINT ); + } + Draw(); + } + +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc b/sp/src/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc new file mode 100644 index 00000000..b81fa7bd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc @@ -0,0 +1,217 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC] +// STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX] +// STATIC: "DETAILTEXTURE" "0..1" +// STATIC: "BUMPMAP" "0..1" +// STATIC: "VERTEXCOLOR" "0..1" +// STATIC: "SELFILLUM" "0..1" +// STATIC: "DIFFUSEBUMPMAP" "0..1" +// STATIC: "DETAIL_ALPHA_MASK_BASE_TEXTURE" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// STATIC: "SEAMLESS" "0..1" +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b] [PC] +// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..0" [ps20b] [XBOX] + +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b] [PC] +// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..0" [ps20b] [XBOX] +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b] + +// SKIP: $DETAILTEXTURE && ( $BUMPMAP && !$DETAIL_ALPHA_MASK_BASE_TEXTURE ) +// SKIP: !$BUMPMAP && $DIFFUSEBUMPMAP +// SKIP: $VERTEXCOLOR && $BUMPMAP +// SKIP: FLASHLIGHT && $SELFILLUM +// SKIP: FLASHLIGHT && $DETAIL_ALPHA_MASK_BASE_TEXTURE +// SKIP: FLASHLIGHT && ($BUMPMAP || $DIFFUSEBUMPMAP) + +// We don't care about flashlight depth unless the flashlight is on +// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 ) [ps20b] + +#if defined( SHADER_MODEL_PS_2_0 ) +# define WRITE_DEPTH_TO_DESTALPHA 0 +#endif + + +#define HDRTYPE HDR_TYPE_NONE +#include "common_flashlight_fxc.h" +#include "common_ps_fxc.h" + +const HALF4 g_SelfIllumTint : register( c7 ); +static const HALF g_OverbrightFactor = 2.0f; + +const HALF3 g_EyePos : register( c10 ); +const HALF4 g_FogParams : register( c11 ); + +const HALF3 g_FlashlightPos : register( c15 ); +// flashlightfixme: Move this math into the vertex shader. +const float4x4 g_FlashlightWorldToTexture : register( c16 ); + +const float4 g_FlashlightAttenuationFactors : register( c20 ); + +sampler BaseTextureSampler : register( s0 ); +sampler LightmapSampler : register( s1 ); +sampler FlashlightSampler : register( s2 ); +sampler DetailSampler : register( s3 ); +sampler BumpmapSampler : register( s4 ); +sampler NormalizeSampler : register( s6 ); + +struct PS_INPUT +{ + HALF2 baseTexCoord : TEXCOORD0; + HALF4 detailOrBumpTexCoord : TEXCOORD1; + HALF4 lightmapTexCoord1And2 : TEXCOORD2; // CENTROID: TEXCOORD2 + HALF2 lightmapTexCoord3 : TEXCOORD3; // CENTROID: TEXCOORD3 + HALF4 worldPos_projPosZ : TEXCOORD4; + HALF3x3 tangentSpaceTranspose : TEXCOORD5; + // tangentSpaceTranspose : TEXCOORD6; + // tangentSpaceTranspose : TEXCOORD7; + HALF4 vertexColor : COLOR; +}; + + +float4 main( PS_INPUT i ) : COLOR +{ + bool bDetailTexture = DETAILTEXTURE ? true : false; + bool bBumpmap = BUMPMAP ? true : false; + bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false; + bool bVertexColor = VERTEXCOLOR ? true : false; + bool bSelfIllum = SELFILLUM ? true : false; + bool bDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE ? true : false; + bool bFlashlight = FLASHLIGHT ? true : false; + + HALF3 lightmapColor1 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor2 = HALF3( 1.0f, 1.0f, 1.0f ); + HALF3 lightmapColor3 = HALF3( 1.0f, 1.0f, 1.0f ); + if( bBumpmap && bDiffuseBumpmap ) + { + HALF2 bumpCoord1; + HALF2 bumpCoord2; + HALF2 bumpCoord3; + ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy, + bumpCoord1, bumpCoord2, bumpCoord3 ); + + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + lightmapColor1 = lightmapSample1.rgb; + lightmapColor2 = tex2D( LightmapSampler, bumpCoord2 ); + lightmapColor3 = tex2D( LightmapSampler, bumpCoord3 ); + } + else + { + if( !bFlashlight ) + { + HALF2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3.xy ); + HALF4 lightmapSample1 = tex2D( LightmapSampler, bumpCoord1 ); + lightmapColor1 = lightmapSample1.rgb; + } + } + + HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); + if( bDetailTexture ) + { + detailColor = tex2D( DetailSampler, i.detailOrBumpTexCoord.xy ); + } + + HALF4 baseColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f ); + baseColor = tex2D( BaseTextureSampler, i.baseTexCoord ); + if ( bDetailAlphaMaskBaseTexture ) + { + // This is what WorldTwoTextureBlend_DX6 does. + baseColor.rgb = saturate( saturate( baseColor * 2 ) * detailColor.a + (1 - detailColor.a) ); + baseColor.rgb *= detailColor; + } + else + { + baseColor.rgb = lerp( baseColor, detailColor, detailColor.a ); + } + + HALF3 normal = HALF3( 0.0f, 0.0f, 1.0f ); + if( bBumpmap ) + { + HALF3 normalTexel; + normalTexel = tex2D( BumpmapSampler, i.detailOrBumpTexCoord.xy ); + normal = 2.0 * normalTexel - 1.0; + } + + HALF3 albedo = HALF3( 1.0f, 1.0f, 1.0f ); + HALF alpha = 1.0f; + albedo *= baseColor; + if( !bSelfIllum ) + { + alpha *= baseColor.a; + } + + // The vertex color contains the modulation color + vertex color combined + albedo *= i.vertexColor; + alpha *= i.vertexColor.a; // not sure about this one + + HALF3 diffuseLighting; + if( bFlashlight ) + { + float3 worldSpaceNormal; + // Make the unbumped version not so fucking stupid and not need tangentSpaceTranspose you knob. + worldSpaceNormal = mul( normal, i.tangentSpaceTranspose ); + + int nShadowSampleLevel = 0; + bool bDoShadows = false; +// On ps_2_b, we can do shadow mapping +#if ( FLASHLIGHTSHADOWS && (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) ) ) + nShadowSampleLevel = FLASHLIGHTDEPTHFILTERMODE; + bDoShadows = true; +#endif + float4 flashlightSpacePosition = mul( float4( i.worldPos_projPosZ.xyz, 1.0f ), g_FlashlightWorldToTexture ); + + diffuseLighting = DoFlashlight( g_FlashlightPos, i.worldPos_projPosZ.xyz, flashlightSpacePosition, + worldSpaceNormal, g_FlashlightAttenuationFactors.xyz, + g_FlashlightAttenuationFactors.w, FlashlightSampler, FlashlightSampler, NormalizeSampler, + nShadowSampleLevel, bDoShadows, false, float2(0, 0), false ); + } + else + { + if( bBumpmap && bDiffuseBumpmap ) + { + float dot1 = saturate( dot( normal, bumpBasis[0] ) ); + float dot2 = saturate( dot( normal, bumpBasis[1] ) ); + float dot3 = saturate( dot( normal, bumpBasis[2] ) ); + + float sum = dot1 + dot2 + dot3; + diffuseLighting = dot1 * lightmapColor1 + + dot2 * lightmapColor2 + + dot3 * lightmapColor3; + diffuseLighting *= 1.0f / sum; + } + else + { + diffuseLighting = lightmapColor1; + } + + // Only scale here since the flashlight will already be scaled properly + diffuseLighting *= g_OverbrightFactor; + } + + HALF3 diffuseComponent = albedo * diffuseLighting; + + if( bSelfIllum ) + { + HALF3 selfIllumComponent = g_SelfIllumTint * albedo; + diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a ); + } + + HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f ); + HALF3 result = diffuseComponent + specularLighting; + + float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w ); + +#if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT) + alpha = fogFactor; +#endif + + return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w ); +} + diff --git a/sp/src/materialsystem/stdshaders/worldvertexalpha.cpp b/sp/src/materialsystem/stdshaders/worldvertexalpha.cpp new file mode 100644 index 00000000..85bad1c1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldvertexalpha.cpp @@ -0,0 +1,259 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "WorldVertexAlpha.inc" +#include "worldvertexalpha_ps20.inc" +#include "worldvertexalpha_ps20b.inc" + +BEGIN_VS_SHADER( WorldVertexAlpha, + "Help for WorldVertexAlpha" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + SET_FLAGS2( MATERIAL_VAR2_BLEND_WITH_LIGHTMAP_ALPHA ); + } + SHADER_INIT + { + // Load the base texture here! + LoadTexture( BASETEXTURE ); + } + + SHADER_FALLBACK + { +// if( g_pHardwareConfig->GetDXSupportLevel() < 90 || g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) + { + return "WorldVertexAlpha_DX8"; + } + return 0; + } + + SHADER_DRAW + { + if( g_pHardwareConfig->SupportsVertexAndPixelShaders() && !UsingEditor( params ) ) + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + { + // NOTE: This is the DX8, Non-Hammer version. + + SHADOW_STATE + { + // Base time lightmap (Need two texture stages) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + + worldvertexalpha_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WorldVertexAlpha" ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Bind the base texture (Stage0) and lightmap (Stage1) + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + EnablePixelShaderOverbright( 0, true, true ); + + worldvertexalpha_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + + Draw(); + } + else + { + // DX 9 version with HDR support + + // Pass 1 + SHADOW_STATE + { + SetInitialShadowState(); + + pShaderShadow->EnableAlphaWrites( true ); + + // Base time lightmap (Need two texture stages) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + pShaderShadow->EnableBlendingSeparateAlpha( true ); + pShaderShadow->BlendFuncSeparateAlpha( SHADER_BLEND_ZERO, SHADER_BLEND_SRC_ALPHA ); + + worldvertexalpha_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( PASS, 0 ); + SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( PASS, 0 ); + SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + } + + + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Bind the base texture (Stage0) and lightmap (Stage1) + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + worldvertexalpha_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + } + } + Draw(); + + // Pass 2 + SHADOW_STATE + { + SetInitialShadowState(); + + pShaderShadow->EnableAlphaWrites( true ); + pShaderShadow->EnableColorWrites( false ); + + // Base time lightmap (Need two texture stages) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + pShaderShadow->EnableBlendingSeparateAlpha( true ); + pShaderShadow->BlendFuncSeparateAlpha( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); + + worldvertexalpha_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + SET_STATIC_PIXEL_SHADER_COMBO( PASS, 1 ); + SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + } + else + { + DECLARE_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + SET_STATIC_PIXEL_SHADER_COMBO( PASS, 1 ); + SET_STATIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + } + + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Bind the base texture (Stage0) and lightmap (Stage1) + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + + worldvertexalpha_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + + if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20b ); + } + else + { + DECLARE_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + SET_DYNAMIC_PIXEL_SHADER( worldvertexalpha_ps20 ); + } + } + Draw(); + } + } + else + { + // NOTE: This is the DX7, Hammer version. + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); +// pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + + // Use vertex color for Hammer because it puts the blending alpha in the vertices. + unsigned int colorFlag = 0; + if( UsingEditor( params ) ) + { + colorFlag |= SHADER_DRAW_COLOR; + } + + pShaderShadow->DrawFlags( colorFlag | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | + SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + + Draw(); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/worldvertexalpha_dx8.cpp b/sp/src/materialsystem/stdshaders/worldvertexalpha_dx8.cpp new file mode 100644 index 00000000..0ea139ee --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldvertexalpha_dx8.cpp @@ -0,0 +1,113 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" + +#include "worldvertexalpha.inc" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( WorldVertexAlpha, WorldVertexAlpha_DX8 ) + +BEGIN_VS_SHADER( WorldVertexAlpha_DX8, + "Help for WorldVertexAlpha_DX8" ) + + BEGIN_SHADER_PARAMS + END_SHADER_PARAMS + + SHADER_INIT_PARAMS() + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + } + SHADER_INIT + { + // Load the base texture here! + LoadTexture( BASETEXTURE ); + } + + SHADER_DRAW + { + if( g_pHardwareConfig->SupportsVertexAndPixelShaders() && !UsingEditor( params ) ) + { + // NOTE: This is the DX8, Non-Hammer version. + + SHADOW_STATE + { + // Base time lightmap (Need two texture stages) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + + int fmt = VERTEX_POSITION; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + + worldvertexalpha_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexAlpha", vshIndex.GetIndex() ); + + pShaderShadow->SetPixelShader( "WorldVertexAlpha" ); + FogToFogColor(); + } + + DYNAMIC_STATE + { + // Bind the base texture (Stage0) and lightmap (Stage1) + BindTexture( SHADER_SAMPLER0, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); + EnablePixelShaderOverbright( 0, true, true ); + + worldvertexalpha_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + + Draw(); + } + else + { + // NOTE: This is the DX7, Hammer version. + // FIXME: Gary - you need to write a proper non-fixed function shader for this. + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); + + pShaderShadow->EnableBlending( true ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); +// pShaderShadow->BlendFunc( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_SRC_ALPHA ); + + // Use vertex color for Hammer because it puts the blending alpha in the vertices. + unsigned int colorFlag = 0; + if( UsingEditor( params ) ) + { + colorFlag |= SHADER_DRAW_COLOR; + } + + pShaderShadow->DrawFlags( colorFlag | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | + SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + } + DYNAMIC_STATE + { + BindTexture( SHADER_SAMPLER1, BASETEXTURE ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + + Draw(); + } + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/worldvertextransition.cpp b/sp/src/materialsystem/stdshaders/worldvertextransition.cpp new file mode 100644 index 00000000..e7d6a9ab --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldvertextransition.cpp @@ -0,0 +1,157 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#include "BaseVSShader.h" +#include "convar.h" + +#include "worldvertextransition_dx8_helper.h" +#include "lightmappedgeneric_dx9_helper.h" + +static LightmappedGeneric_DX9_Vars_t s_info; + + +DEFINE_FALLBACK_SHADER( WorldVertexTransition, WorldVertexTransition_DX9 ) + +BEGIN_VS_SHADER( WorldVertexTransition_DX9, "Help for WorldVertexTransition" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( ALBEDO, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture", "albedo (Base texture with no baked lighting)" ) + SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" ) + SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( DETAILFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $detail" ) + SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" ) + + // detail (multi-) texturing + SHADER_PARAM( DETAILBLENDMODE, SHADER_PARAM_TYPE_INTEGER, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ) + SHADER_PARAM( DETAILBLENDFACTOR, SHADER_PARAM_TYPE_FLOAT, "1", "blend amount for detail texture." ) + SHADER_PARAM( DETAILTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "detail texture tint" ) + + SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" ) + SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" ) + SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "", "" ) + SHADER_PARAM( ENVMAPMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$envmapmask texcoord transform" ) + SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" ) + SHADER_PARAM( BUMPMAP, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( ENVMAPCONTRAST, SHADER_PARAM_TYPE_FLOAT, "0.0", "contrast 0 == normal 1 == color*color" ) + SHADER_PARAM( ENVMAPSATURATION, SHADER_PARAM_TYPE_FLOAT, "1.0", "saturation 0 == greyscale 1 == normal" ) + SHADER_PARAM( FRESNELREFLECTION, SHADER_PARAM_TYPE_FLOAT, "1.0", "1.0 == mirror, 0.0 == water" ) + SHADER_PARAM( NODIFFUSEBUMPLIGHTING, SHADER_PARAM_TYPE_INTEGER, "0", "0 == Use diffuse bump lighting, 1 = No diffuse bump lighting" ) + SHADER_PARAM( BUMPMAP2, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader3_normal", "bump map" ) + SHADER_PARAM( BUMPFRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $bumpmap" ) + SHADER_PARAM( BUMPTRANSFORM2, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$bumpmap texcoord transform" ) + SHADER_PARAM( BUMPMASK, SHADER_PARAM_TYPE_TEXTURE, "models/shadertest/shader1_normal", "bump map" ) + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" ) + SHADER_PARAM( FRAME2, SHADER_PARAM_TYPE_INTEGER, "0", "frame number for $basetexture2" ) + SHADER_PARAM( BASETEXTURENOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( BASETEXTURE2NOENVMAP, SHADER_PARAM_TYPE_BOOL, "0", "" ) + SHADER_PARAM( DETAIL_ALPHA_MASK_BASE_TEXTURE, SHADER_PARAM_TYPE_BOOL, "0", + "If this is 1, then when detail alpha=0, no base texture is blended and when " + "detail alpha=1, you get detail*base*lightmap" ) + SHADER_PARAM( LIGHTWARPTEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "light munging lookup texture" ) + SHADER_PARAM( BLENDMODULATETEXTURE, SHADER_PARAM_TYPE_TEXTURE, "", "texture to use r/g channels for blend range for" ) + SHADER_PARAM( BLENDMASKTRANSFORM, SHADER_PARAM_TYPE_MATRIX, "center .5 .5 scale 1 1 rotate 0 translate 0 0", "$blendmodulatetexture texcoord transform" ) + SHADER_PARAM( MASKEDBLENDING, SHADER_PARAM_TYPE_INTEGER, "0", "blend using texture with no vertex alpha. For using texture blending on non-displacements" ) + SHADER_PARAM( SSBUMP, SHADER_PARAM_TYPE_INTEGER, "0", "whether or not to use alternate bumpmap format with height" ) + SHADER_PARAM( SEAMLESS_SCALE, SHADER_PARAM_TYPE_FLOAT, "0", "Scale factor for 'seamless' texture mapping. 0 means to use ordinary mapping" ) + END_SHADER_PARAMS + + void SetupVars( WorldVertexTransitionEditor_DX8_Vars_t& info ) + { + info.m_nBaseTextureVar = BASETEXTURE; + info.m_nBaseTextureFrameVar = FRAME; + info.m_nBaseTextureTransformVar = BASETEXTURETRANSFORM; + info.m_nBaseTexture2Var = BASETEXTURE2; + info.m_nBaseTexture2FrameVar = FRAME2; + info.m_nBaseTexture2TransformVar = BASETEXTURETRANSFORM; // FIXME!!!! + } + + void SetupVars( LightmappedGeneric_DX9_Vars_t& info ) + { + info.m_nBaseTexture = BASETEXTURE; + info.m_nBaseTextureFrame = FRAME; + info.m_nBaseTextureTransform = BASETEXTURETRANSFORM; + info.m_nAlbedo = ALBEDO; + info.m_nSelfIllumTint = SELFILLUMTINT; + + info.m_nDetail = DETAIL; + info.m_nDetailFrame = DETAILFRAME; + info.m_nDetailScale = DETAILSCALE; + info.m_nDetailTextureCombineMode = DETAILBLENDMODE; + info.m_nDetailTextureBlendFactor = DETAILBLENDFACTOR; + info.m_nDetailTint = DETAILTINT; + + info.m_nEnvmap = ENVMAP; + info.m_nEnvmapFrame = ENVMAPFRAME; + info.m_nEnvmapMask = ENVMAPMASK; + info.m_nEnvmapMaskFrame = ENVMAPMASKFRAME; + info.m_nEnvmapMaskTransform = ENVMAPMASKTRANSFORM; + info.m_nEnvmapTint = ENVMAPTINT; + info.m_nBumpmap = BUMPMAP; + info.m_nBumpFrame = BUMPFRAME; + info.m_nBumpTransform = BUMPTRANSFORM; + info.m_nEnvmapContrast = ENVMAPCONTRAST; + info.m_nEnvmapSaturation = ENVMAPSATURATION; + info.m_nFresnelReflection = FRESNELREFLECTION; + info.m_nNoDiffuseBumpLighting = NODIFFUSEBUMPLIGHTING; + info.m_nBumpmap2 = BUMPMAP2; + info.m_nBumpFrame2 = BUMPFRAME2; + info.m_nBaseTexture2 = BASETEXTURE2; + info.m_nBaseTexture2Frame = FRAME2; + info.m_nBumpTransform2 = BUMPTRANSFORM2; + info.m_nBumpMask = BUMPMASK; + info.m_nBaseTextureNoEnvmap = BASETEXTURENOENVMAP; + info.m_nBaseTexture2NoEnvmap = BASETEXTURE2NOENVMAP; + info.m_nDetailAlphaMaskBaseTexture = DETAIL_ALPHA_MASK_BASE_TEXTURE; + info.m_nFlashlightTexture = FLASHLIGHTTEXTURE; + info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME; + info.m_nLightWarpTexture = LIGHTWARPTEXTURE; + info.m_nBlendModulateTexture = BLENDMODULATETEXTURE; + info.m_nBlendMaskTransform = BLENDMASKTRANSFORM; + info.m_nMaskedBlending = MASKEDBLENDING; + info.m_nSelfShadowedBumpFlag = SSBUMP; + info.m_nSeamlessMappingScale = SEAMLESS_SCALE; + info.m_nAlphaTestReference = -1; + } + + SHADER_FALLBACK + { + if( g_pHardwareConfig->GetDXSupportLevel() < 90 ) + return "WorldVertexTransition_DX8"; + + return 0; + } + + SHADER_INIT_PARAMS() + { + SetupVars( s_info ); + InitParamsLightmappedGeneric_DX9( this, params, pMaterialName, s_info ); + } + + SHADER_INIT + { + SetupVars( s_info ); + InitLightmappedGeneric_DX9( this, params, s_info ); + } + + SHADER_DRAW + { + if ( UsingEditor( params ) ) + { + WorldVertexTransitionEditor_DX8_Vars_t info; + SetupVars( info ); + DrawWorldVertexTransitionEditor_DX8( this, params, pShaderAPI, pShaderShadow, info ); + return; + } + + DrawLightmappedGeneric_DX9( this, params, pShaderAPI, pShaderShadow, s_info, pContextDataPtr ); + } +END_SHADER + diff --git a/sp/src/materialsystem/stdshaders/worldvertextransition_dx6.cpp b/sp/src/materialsystem/stdshaders/worldvertextransition_dx6.cpp new file mode 100644 index 00000000..163291e3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldvertextransition_dx6.cpp @@ -0,0 +1,52 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "shaderlib/cshader.h" + +#include "worldvertextransition_dx6_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DEFINE_FALLBACK_SHADER( WorldVertexTransition, WorldVertexTransition_DX6 ) + +BEGIN_SHADER( WorldVertexTransition_DX6, + "Help for WorldVertexTransition_dx6" ) + + BEGIN_SHADER_PARAMS + SHADER_PARAM( BASETEXTURE2, SHADER_PARAM_TYPE_TEXTURE, "shadertest/BaseTexture2", "base texture2 help" ) + END_SHADER_PARAMS + + void SetupVars( WorldVertexTransition_DX6_Vars_t& info ) + { + info.m_nBaseTextureVar = BASETEXTURE; + info.m_nBaseTextureFrameVar = FRAME; + info.m_nBaseTexture2Var = BASETEXTURE2; + info.m_nFlashlightTextureVar = FLASHLIGHTTEXTURE; + } + + SHADER_INIT_PARAMS() + { + WorldVertexTransition_DX6_Vars_t info; + SetupVars( info ); + InitParamsWorldVertexTransition_DX6( params, info ); + } + + SHADER_INIT + { + WorldVertexTransition_DX6_Vars_t info; + SetupVars( info ); + InitWorldVertexTransition_DX6( this, params, info ); + } + + SHADER_DRAW + { + WorldVertexTransition_DX6_Vars_t info; + SetupVars( info ); + DrawWorldVertexTransition_DX6( this, params, pShaderAPI, pShaderShadow, info ); + } +END_SHADER diff --git a/sp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp b/sp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp new file mode 100644 index 00000000..7539ff29 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp @@ -0,0 +1,206 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "shaderlib/cshader.h" +#include "worldvertextransition_dx6_helper.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +void InitParamsWorldVertexTransition_DX6( IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + // FLASHLIGHTFIXME + params[info.m_nFlashlightTextureVar]->SetStringValue( "effects/flashlight001" ); +} + +void InitWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ) +{ + // FLASHLIGHTFIXME + if ( params[info.m_nFlashlightTextureVar]->IsDefined() ) + { + pShader->LoadTexture( info.m_nFlashlightTextureVar ); + } + + if ( params[info.m_nBaseTextureVar]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTextureVar ); + } + + if ( params[info.m_nBaseTexture2Var]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture2Var ); + } +} + +static void DrawFlashlightPass( CBaseShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, int nPass, WorldVertexTransition_DX6_Vars_t &info ) +{ + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT ); + pShaderShadow->EnableDepthWrites( false ); + pShaderShadow->EnableAlphaWrites( false ); + + pShaderShadow->SetDiffuseMaterialSource( SHADER_MATERIALSOURCE_COLOR1 ); + if( nPass == 0 ) + { + pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); + } + else + { + pShader->EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_SRC_ALPHA, SHADER_BLEND_ONE ); + } + + int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_COLOR | SHADER_DRAW_NORMAL; + pShaderShadow->DrawFlags( flags ); + pShader->FogToBlack(); + + pShaderShadow->EnableLighting( true ); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 2 ); + + // color stage 0 + // projected texture * vertex color (lighting) + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE, + SHADER_TEXARG_TEXTURE, + SHADER_TEXARG_VERTEXCOLOR ); + + // color stage 1 + // * base texture + 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 * vertex color + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, + SHADER_TEXOP_MODULATE, + SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_VERTEXCOLOR ); + + // 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 ); + } + DYNAMIC_STATE + { + pShader->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 ); + + pShader->BindTexture( SHADER_SAMPLER0, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME ); + if( nPass == 0 ) + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture2Var, -1 ); + } + else + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTextureVar, info.m_nBaseTextureFrameVar ); + } + } + pShader->Draw(); +} + + +void DrawWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransition_DX6_Vars_t &info ) +{ + bool bHasFlashlight = pShader->UsingFlashlight( params ); + if( bHasFlashlight ) + { + DrawFlashlightPass( pShader, params, pShaderAPI, pShaderShadow, 0, info ); + DrawFlashlightPass( pShader, params, pShaderAPI, pShaderShadow, 1, info ); + return; + } + + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, OVERBRIGHT ); + + pShaderShadow->DrawFlags( SHADER_DRAW_COLOR | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + pShader->FogToFogColor(); + } + DYNAMIC_STATE + { + //pShaderAPI->TexMinFilter( SHADER_TEXFILTERMODE_NEAREST ); + //pShaderAPI->TexMagFilter( SHADER_TEXFILTERMODE_NEAREST ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTextureVar ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + pShader->Draw(); + + SHADOW_STATE + { + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableBlending( true ); + + pShaderShadow->EnableCustomPixelPipe( true ); + pShaderShadow->CustomTextureStages( 2 ); + + // alpha and color stage 0 + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_ALPHA, + SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, + SHADER_TEXARG_TEXTURE ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_SELECTARG1, + SHADER_TEXARG_TEXTURE, + SHADER_TEXARG_TEXTURE ); + + // alpha and color stage 1 + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_ALPHA, + SHADER_TEXOP_MODULATE, + SHADER_TEXARG_TEXTURE, + SHADER_TEXARG_VERTEXCOLOR ); + + pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, + SHADER_TEXCHANNEL_COLOR, + SHADER_TEXOP_MODULATE2X, + SHADER_TEXARG_PREVIOUSSTAGE, + SHADER_TEXARG_TEXTURE ); + + // Looks backwards, but this is done so that lightmap alpha = 1 when only + // using 1 texture (needed for translucent displacements). + pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); + + pShaderShadow->DrawFlags( SHADER_DRAW_COLOR | SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1 | SHADER_DRAW_LIGHTMAP_TEXCOORD0 ); + pShader->FogToFogColor(); + } + DYNAMIC_STATE + { + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture2Var ); + pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_LIGHTMAP ); + } + pShader->Draw(); +} diff --git a/sp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.h b/sp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.h new file mode 100644 index 00000000..16e0bfd5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.h @@ -0,0 +1,39 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef WORLDVERTEXTRANSITION_DX6_HELPER_H +#define WORLDVERTEXTRANSITION_DX6_HELPER_H + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct WorldVertexTransition_DX6_Vars_t +{ + WorldVertexTransition_DX6_Vars_t() { memset( this, 0xFF, sizeof(WorldVertexTransition_DX6_Vars_t) ); } + + int m_nBaseTextureVar; + int m_nBaseTextureFrameVar; + int m_nBaseTexture2Var; + int m_nFlashlightTextureVar; +}; + +void InitParamsWorldVertexTransition_DX6( IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ); +void InitWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, WorldVertexTransition_DX6_Vars_t &info ); +void DrawWorldVertexTransition_DX6( CBaseShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransition_DX6_Vars_t &info ); + + +#endif // WORLDVERTEXTRANSITION_DX6_HELPER_H \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp b/sp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp new file mode 100644 index 00000000..6a49fd71 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp @@ -0,0 +1,81 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "worldvertextransition_dx8_helper.h" +#include "BaseVSShader.h" + +#include "WorldVertexTransition.inc" + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +void InitParamsWorldVertexTransitionEditor_DX8( IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ) +{ + SET_FLAGS2( MATERIAL_VAR2_LIGHTING_LIGHTMAP ); +} + +void InitWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ) +{ + if ( params[info.m_nBaseTextureVar]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTextureVar ); + } + + if ( params[info.m_nBaseTexture2Var]->IsDefined() ) + { + pShader->LoadTexture( info.m_nBaseTexture2Var ); + } +} + +void DrawWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransitionEditor_DX8_Vars_t &info ) +{ + SHADOW_STATE + { + // This is the dx8 worldcraft version (non-bumped always.. too bad) + pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); + pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); + + int fmt = VERTEX_POSITION | VERTEX_COLOR; + pShaderShadow->VertexShaderVertexFormat( fmt, 2, 0, 0 ); + + worldvertextransition_Static_Index vshIndex; + pShaderShadow->SetVertexShader( "WorldVertexTransition", vshIndex.GetIndex() ); + pShaderShadow->SetPixelShader( "WorldVertexTransition_Editor" ); + + pShader->FogToFogColor(); + } + DYNAMIC_STATE + { + pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTextureVar, info.m_nBaseTextureFrameVar ); + pShader->BindTexture( SHADER_SAMPLER1, info.m_nBaseTexture2Var, info.m_nBaseTexture2FrameVar ); + + // Texture 3 = lightmap + pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_LIGHTMAP ); + + pShader->EnablePixelShaderOverbright( 0, true, true ); + + // JasonM - Gnarly hack since we're calling this legacy shader from DX9 + int nTextureTransformConst = VERTEX_SHADER_SHADER_SPECIFIC_CONST_0; + int nTextureTransformConst2 = VERTEX_SHADER_SHADER_SPECIFIC_CONST_2; + if ( g_pHardwareConfig->GetDXSupportLevel() >= 90) + { + nTextureTransformConst -= 10; + nTextureTransformConst2 -= 10; + } + + pShader->SetVertexShaderTextureTransform( nTextureTransformConst, info.m_nBaseTextureTransformVar ); + pShader->SetVertexShaderTextureTransform( nTextureTransformConst2, info.m_nBaseTexture2TransformVar ); + + worldvertextransition_Dynamic_Index vshIndex; + vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); + pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() ); + } + pShader->Draw(); +} diff --git a/sp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.h b/sp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.h new file mode 100644 index 00000000..d17d532e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.h @@ -0,0 +1,44 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef WORLDVERTEXTRANSITION_DX8_HELPER_H +#define WORLDVERTEXTRANSITION_DX8_HELPER_H + +#include + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CBaseVSShader; +class IMaterialVar; +class IShaderDynamicAPI; +class IShaderShadow; + + +//----------------------------------------------------------------------------- +// Init params/ init/ draw methods +//----------------------------------------------------------------------------- +struct WorldVertexTransitionEditor_DX8_Vars_t +{ + WorldVertexTransitionEditor_DX8_Vars_t() { memset( this, 0xFF, sizeof(WorldVertexTransitionEditor_DX8_Vars_t) ); } + + int m_nBaseTextureVar; + int m_nBaseTextureFrameVar; + int m_nBaseTextureTransformVar; + int m_nBaseTexture2Var; + int m_nBaseTexture2FrameVar; + int m_nBaseTexture2TransformVar; +}; + +void InitParamsWorldVertexTransitionEditor_DX8( IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ); +void InitWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, WorldVertexTransitionEditor_DX8_Vars_t &info ); +void DrawWorldVertexTransitionEditor_DX8( CBaseVSShader *pShader, IMaterialVar** params, + IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, WorldVertexTransitionEditor_DX8_Vars_t &info ); + + +#endif // WORLDVERTEXTRANSITION_DX8_HELPER_H \ No newline at end of file