aboutsummaryrefslogtreecommitdiff
path: root/mp/src/materialsystem
diff options
context:
space:
mode:
Diffstat (limited to 'mp/src/materialsystem')
-rw-r--r--mp/src/materialsystem/stdshaders/BlurFilterX.cpp122
-rw-r--r--mp/src/materialsystem/stdshaders/BlurFilterX_dx80.cpp86
-rw-r--r--mp/src/materialsystem/stdshaders/BlurFilterY.cpp136
-rw-r--r--mp/src/materialsystem/stdshaders/BlurFilterY_dx80.cpp91
-rw-r--r--mp/src/materialsystem/stdshaders/BlurFilter_ps11.psh18
-rw-r--r--mp/src/materialsystem/stdshaders/BlurFilter_ps2x.fxc91
-rw-r--r--mp/src/materialsystem/stdshaders/BlurFilter_vs11.fxc34
-rw-r--r--mp/src/materialsystem/stdshaders/BlurFilter_vs20.fxc39
-rw-r--r--mp/src/materialsystem/stdshaders/Cable.psh27
-rw-r--r--mp/src/materialsystem/stdshaders/Cable.vsh117
-rw-r--r--mp/src/materialsystem/stdshaders/DebugDrawDepth_ps2x.fxc23
-rw-r--r--mp/src/materialsystem/stdshaders/DebugDrawDepth_vs20.fxc38
-rw-r--r--mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask.cpp94
-rw-r--r--mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_ps2x.fxc26
-rw-r--r--mp/src/materialsystem/stdshaders/DebugDrawEnvmapMask_vs20.fxc39
-rw-r--r--mp/src/materialsystem/stdshaders/DebugTextureView.cpp104
-rw-r--r--mp/src/materialsystem/stdshaders/DebugTextureView_ps2x.fxc81
-rw-r--r--mp/src/materialsystem/stdshaders/DebugTextureView_vs20.fxc23
-rw-r--r--mp/src/materialsystem/stdshaders/Eyes.psh16
-rw-r--r--mp/src/materialsystem/stdshaders/Eyes_Overbright2.psh18
-rw-r--r--mp/src/materialsystem/stdshaders/Eyes_vs20.fxc145
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_AddBaseAlphaMaskedEnvMap.psh17
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapMaskNoTexture.psh17
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_AddEnvMapNoTexture.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseAlphaMaskedEnvMapV2.psh22
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.psh14
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTexture.vsh38
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BaseTextureBlend.vsh43
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.psh66
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap.vsh96
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.psh72
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedEnvmap_ps14.vsh92
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.psh79
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap.vsh54
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.psh39
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_base_ps14.vsh55
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.psh47
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_BumpmappedLightmap_blend_ps14.vsh57
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.psh47
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_Decal.vsh56
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_Detail.psh18
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailNoTexture.psh16
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_DetailSelfIlluminated.psh23
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapNoTexture.psh21
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_EnvMapV2.psh20
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly.vsh45
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_LightingOnly_Overbright2.psh6
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapNoTexture.psh24
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_MaskedEnvMapV2.psh22
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLighting.psh20
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingNoTexture.psh20
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_MultiplyByLightingSelfIllum.psh23
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_NoTexture.psh14
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_SSBumpmappedLightmap.psh34
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminated.psh21
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedEnvMapV2.psh27
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_SelfIlluminatedMaskedEnvMapV2.psh28
-rw-r--r--mp/src/materialsystem/stdshaders/LightmappedGeneric_VertexColor.vsh15
-rw-r--r--mp/src/materialsystem/stdshaders/Refract_model_vs11.vsh105
-rw-r--r--mp/src/materialsystem/stdshaders/Refract_ps11.psh36
-rw-r--r--mp/src/materialsystem/stdshaders/Refract_vs20.fxc140
-rw-r--r--mp/src/materialsystem/stdshaders/Refract_world_vs11.vsh168
-rw-r--r--mp/src/materialsystem/stdshaders/ShadowModel.psh22
-rw-r--r--mp/src/materialsystem/stdshaders/ShadowModel.vsh85
-rw-r--r--mp/src/materialsystem/stdshaders/Teeth.vsh97
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric.psh13
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_BaseAlphaMaskedEnvMap.psh19
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_Detail.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_DetailBaseAlphaMaskedEnvMap.psh29
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMap.psh25
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMask.psh29
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapMaskNoTexture.psh21
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_DetailEnvMapNoTexture.psh19
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_DetailNoTexture.psh10
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMap.psh17
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMask.psh19
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapMaskNoTexture.psh17
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_EnvMapNoTexture.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_LightingOnly.vsh21
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_MaskBaseByDetailAlpha_ps11.fxc20
-rw-r--r--mp/src/materialsystem/stdshaders/UnlitGeneric_NoTexture.psh7
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric.psh13
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_BaseAlphaMaskedEnvMapV2.psh17
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_BlendTint.psh17
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail.psh16
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailBaseAlphaMaskedEnvMapV2.psh18
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailEnvMapV2.psh16
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailMaskedEnvMapV2.psh18
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailNoTexture.psh12
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminated.psh22
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedEnvMapV2.psh24
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_DetailSelfIlluminatedMaskedEnvMapV2.psh26
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_LerpBase.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_Detail_additive_selfillum.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapNoTexture.psh14
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvMapV2.psh14
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2.psh36
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha.psh42
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14.psh42
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmapV2_ps14.psh39
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting.vsh93
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.vsh90
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapNoTexture.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_MaskedEnvMapV2.psh16
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_NoTexture.psh9
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.psh5
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIllumOnly.vsh41
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminated.psh19
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedEnvMapV2.psh21
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitGeneric_SelfIlluminatedMaskedEnvMapV2.psh23
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitTexture.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/VertexLitTexture_Overbright2.psh16
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheapFresnelOpaque_ps14.psh40
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheapFresnel_ps14.psh39
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheapNoFresnelOpaque_ps11.psh19
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheapNoFresnel_ps11.psh18
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps11.psh26
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheapOpaque_ps14.psh31
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheapPerVertexFresnel_vs11.vsh100
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheap_ps11.psh26
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheap_ps14.psh30
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheap_ps2x.fxc152
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheap_vs11.vsh88
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheap_vs14.vsh96
-rw-r--r--mp/src/materialsystem/stdshaders/WaterCheap_vs20.fxc84
-rw-r--r--mp/src/materialsystem/stdshaders/WaterReflect_ps11.psh27
-rw-r--r--mp/src/materialsystem/stdshaders/WaterRefractFresnel_ps11.psh24
-rw-r--r--mp/src/materialsystem/stdshaders/WaterRefract_ps11.psh13
-rw-r--r--mp/src/materialsystem/stdshaders/Water_ps14.psh96
-rw-r--r--mp/src/materialsystem/stdshaders/Water_ps14.vsh95
-rw-r--r--mp/src/materialsystem/stdshaders/Water_vs11.vsh102
-rw-r--r--mp/src/materialsystem/stdshaders/Water_vs20.fxc117
-rw-r--r--mp/src/materialsystem/stdshaders/WorldTexture.psh14
-rw-r--r--mp/src/materialsystem/stdshaders/WorldTwoTextureBlend.psh21
-rw-r--r--mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_DetailAlpha.psh25
-rw-r--r--mp/src/materialsystem/stdshaders/WorldTwoTextureBlend_SelfIlluminated.psh27
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexAlpha.psh10
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexAlpha.vsh37
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexAlpha_ps2x.fxc43
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition.psh18
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition.vsh48
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition_BlendBase2.psh16
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition_Editor.psh10
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.psh23
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition_Seamless.vsh54
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition_dx8.cpp537
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition_ps14.psh32
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition_ps2x.fxc47
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition_vs14.vsh52
-rw-r--r--mp/src/materialsystem/stdshaders/WorldVertexTransition_vs20.fxc64
-rw-r--r--mp/src/materialsystem/stdshaders/cable_dx6.cpp62
-rw-r--r--mp/src/materialsystem/stdshaders/cable_dx8.cpp132
-rw-r--r--mp/src/materialsystem/stdshaders/cable_dx9.cpp141
-rw-r--r--mp/src/materialsystem/stdshaders/cable_ps2x.fxc54
-rw-r--r--mp/src/materialsystem/stdshaders/cable_vs20.fxc80
-rw-r--r--mp/src/materialsystem/stdshaders/cloud.cpp76
-rw-r--r--mp/src/materialsystem/stdshaders/cloud_dx8.cpp77
-rw-r--r--mp/src/materialsystem/stdshaders/cloud_dx9.cpp94
-rw-r--r--mp/src/materialsystem/stdshaders/cloud_ps11.psh6
-rw-r--r--mp/src/materialsystem/stdshaders/cloud_ps20.fxc26
-rw-r--r--mp/src/materialsystem/stdshaders/cloud_vs11.vsh26
-rw-r--r--mp/src/materialsystem/stdshaders/cloud_vs20.fxc37
-rw-r--r--mp/src/materialsystem/stdshaders/debugdepth.cpp113
-rw-r--r--mp/src/materialsystem/stdshaders/debugluxel.cpp140
-rw-r--r--mp/src/materialsystem/stdshaders/debugmodifyvertex.cpp93
-rw-r--r--mp/src/materialsystem/stdshaders/debugmorphaccumulator_dx9.cpp64
-rw-r--r--mp/src/materialsystem/stdshaders/debugmorphaccumulator_ps30.fxc16
-rw-r--r--mp/src/materialsystem/stdshaders/debugmorphaccumulator_vs30.fxc23
-rw-r--r--mp/src/materialsystem/stdshaders/debugmrttexture.cpp86
-rw-r--r--mp/src/materialsystem/stdshaders/debugmrttexture_ps2x.fxc26
-rw-r--r--mp/src/materialsystem/stdshaders/debugmrttexture_vs20.fxc29
-rw-r--r--mp/src/materialsystem/stdshaders/debugnormalmap.cpp148
-rw-r--r--mp/src/materialsystem/stdshaders/debugsoftwarevertexshader.cpp56
-rw-r--r--mp/src/materialsystem/stdshaders/debugtangentspace.cpp133
-rw-r--r--mp/src/materialsystem/stdshaders/debugtangentspace.vsh34
-rw-r--r--mp/src/materialsystem/stdshaders/debugtangentspace_vs11.fxc51
-rw-r--r--mp/src/materialsystem/stdshaders/debugtangentspace_vs20.fxc55
-rw-r--r--mp/src/materialsystem/stdshaders/depthtodestalpha_ps20b.fxc11
-rw-r--r--mp/src/materialsystem/stdshaders/depthtodestalpha_vs20.fxc23
-rw-r--r--mp/src/materialsystem/stdshaders/depthwrite.cpp207
-rw-r--r--mp/src/materialsystem/stdshaders/depthwrite_ps2x.fxc44
-rw-r--r--mp/src/materialsystem/stdshaders/depthwrite_vs20.fxc83
-rw-r--r--mp/src/materialsystem/stdshaders/detail.cpp37
-rw-r--r--mp/src/materialsystem/stdshaders/detail_ps11.psh12
-rw-r--r--mp/src/materialsystem/stdshaders/detail_vs11.vsh56
-rw-r--r--mp/src/materialsystem/stdshaders/eye_refract.cpp253
-rw-r--r--mp/src/materialsystem/stdshaders/eye_refract_helper.cpp461
-rw-r--r--mp/src/materialsystem/stdshaders/eye_refract_helper.h69
-rw-r--r--mp/src/materialsystem/stdshaders/eye_refract_ps2x.fxc494
-rw-r--r--mp/src/materialsystem/stdshaders/eye_refract_vs20.fxc217
-rw-r--r--mp/src/materialsystem/stdshaders/eyeball.cpp37
-rw-r--r--mp/src/materialsystem/stdshaders/eyeglint_dx9.cpp66
-rw-r--r--mp/src/materialsystem/stdshaders/eyeglint_ps2x.fxc32
-rw-r--r--mp/src/materialsystem/stdshaders/eyeglint_vs20.fxc38
-rw-r--r--mp/src/materialsystem/stdshaders/eyes.cpp186
-rw-r--r--mp/src/materialsystem/stdshaders/eyes.vsh80
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_dx6.cpp251
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.cpp550
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_dx8_dx9_helper.h54
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_dx9.cpp84
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_flashlight2_ps11.psh17
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_flashlight_inc.fxc92
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_flashlight_ps11.fxc9
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_flashlight_ps2x.fxc15
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_flashlight_vs11.vsh115
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_flashlight_vs20.fxc145
-rw-r--r--mp/src/materialsystem/stdshaders/eyes_ps2x.fxc68
-rw-r--r--mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_helper.cpp271
-rw-r--r--mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_ps11.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_dx8_vs11.vsh114
-rw-r--r--mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.cpp355
-rw-r--r--mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_helper.h68
-rw-r--r--mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_ps2x.fxc127
-rw-r--r--mp/src/materialsystem/stdshaders/flesh_interior_blended_pass_vs20.fxc155
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_basealphamaskedenvmap.psh22
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_basetextureblend.psh9
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_decal.cpp135
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_ps2x.fxc59
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_decal_vs20.fxc74
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_dx6.cpp288
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_dx8.cpp802
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9.cpp164
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.cpp1085
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_dx9_helper.h99
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_envmap.psh20
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs11.fxc122
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_flashlight_vs20.fxc184
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_inc.vsh110
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_overbright2_ps11.fxc12
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_lightingonly_vs11.fxc51
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_maskedenvmap.psh22
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasealphamaskedselfillum.psh24
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_multiplybylightingbasenotexture.psh20
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_ps11.fxc122
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2_3_x.h583
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_ps2x.fxc59
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedenvmap.psh27
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_selfilluminatedmaskedenvmap.psh27
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_vs11.vsh20
-rw-r--r--mp/src/materialsystem/stdshaders/lightmappedgeneric_vs20.fxc254
-rw-r--r--mp/src/materialsystem/stdshaders/refract.cpp111
-rw-r--r--mp/src/materialsystem/stdshaders/refract_dx60.cpp16
-rw-r--r--mp/src/materialsystem/stdshaders/refract_dx80.cpp317
-rw-r--r--mp/src/materialsystem/stdshaders/refract_dx9_helper.cpp342
-rw-r--r--mp/src/materialsystem/stdshaders/refract_dx9_helper.h62
-rw-r--r--mp/src/materialsystem/stdshaders/refract_ps2x.fxc250
-rw-r--r--mp/src/materialsystem/stdshaders/shadowmodel_dx8.cpp97
-rw-r--r--mp/src/materialsystem/stdshaders/shadowmodel_dx9.cpp154
-rw-r--r--mp/src/materialsystem/stdshaders/shadowmodel_ps20.fxc20
-rw-r--r--mp/src/materialsystem/stdshaders/shadowmodel_vs20.fxc81
-rw-r--r--mp/src/materialsystem/stdshaders/skin_dx9_helper.cpp977
-rw-r--r--mp/src/materialsystem/stdshaders/skin_dx9_helper.h35
-rw-r--r--mp/src/materialsystem/stdshaders/skin_ps20b.fxc371
-rw-r--r--mp/src/materialsystem/stdshaders/skin_vs20.fxc173
-rw-r--r--mp/src/materialsystem/stdshaders/sky_dx6.cpp15
-rw-r--r--mp/src/materialsystem/stdshaders/sky_dx9.cpp126
-rw-r--r--mp/src/materialsystem/stdshaders/sky_hdr_compressed_ps2x.fxc29
-rw-r--r--mp/src/materialsystem/stdshaders/sky_hdr_compressed_rgbs_ps2x.fxc81
-rw-r--r--mp/src/materialsystem/stdshaders/sky_hdr_dx9.cpp297
-rw-r--r--mp/src/materialsystem/stdshaders/sky_ps2x.fxc27
-rw-r--r--mp/src/materialsystem/stdshaders/sky_vs20.fxc64
-rw-r--r--mp/src/materialsystem/stdshaders/sprite.cpp379
-rw-r--r--mp/src/materialsystem/stdshaders/sprite_dx6.cpp289
-rw-r--r--mp/src/materialsystem/stdshaders/sprite_dx9.cpp490
-rw-r--r--mp/src/materialsystem/stdshaders/sprite_ps11.psh15
-rw-r--r--mp/src/materialsystem/stdshaders/sprite_ps2x.fxc61
-rw-r--r--mp/src/materialsystem/stdshaders/sprite_vs11.vsh9
-rw-r--r--mp/src/materialsystem/stdshaders/sprite_vs20.fxc65
-rw-r--r--mp/src/materialsystem/stdshaders/spritecard.cpp484
-rw-r--r--mp/src/materialsystem/stdshaders/spritecard_ps11.fxc72
-rw-r--r--mp/src/materialsystem/stdshaders/spritecard_ps2x.fxc194
-rw-r--r--mp/src/materialsystem/stdshaders/spritecard_vsxx.fxc347
-rw-r--r--mp/src/materialsystem/stdshaders/teeth.cpp578
-rw-r--r--mp/src/materialsystem/stdshaders/teeth_bump_ps2x.fxc101
-rw-r--r--mp/src/materialsystem/stdshaders/teeth_bump_vs20.fxc152
-rw-r--r--mp/src/materialsystem/stdshaders/teeth_dx6.cpp69
-rw-r--r--mp/src/materialsystem/stdshaders/teeth_dx8.cpp116
-rw-r--r--mp/src/materialsystem/stdshaders/teeth_flashlight_ps2x.fxc66
-rw-r--r--mp/src/materialsystem/stdshaders/teeth_flashlight_vs20.fxc149
-rw-r--r--mp/src/materialsystem/stdshaders/teeth_ps2x.fxc48
-rw-r--r--mp/src/materialsystem/stdshaders/teeth_vs20.fxc127
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_basetimesdetail.psh24
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_dx6.cpp310
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_dx8.cpp72
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_dx9.cpp200
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_inc.vsh142
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_lightingonly_vs11.fxc47
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps11.fxc9
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_notexture_ps2x.fxc14
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_ps11.fxc12
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_ps2x.fxc19
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_vs11.vsh23
-rw-r--r--mp/src/materialsystem/stdshaders/unlitgeneric_vs20.fxc91
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_ps2x.fxc350
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_bump_vs20.fxc198
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_ps2x.fxc484
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlit_and_unlit_generic_vs20.fxc249
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlit_lighting_only_ps2x.fxc68
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlit_notexture.psh13
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_basealphamaskedenvmap.psh19
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_detailbasealphamaskedenvmap.psh21
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_detailenvmap.psh19
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_detailmaskedenvmap.psh21
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedenvmap.psh28
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_detailselfilluminatedmaskedenvmap.psh29
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_dx6.cpp421
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_dx7.cpp413
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_dx8.cpp807
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9.cpp520
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_dx95_helper.h71
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp1434
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.h144
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_envmap.psh17
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_flashlight_vs11.vsh137
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_inc.vsh145
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2.psh5
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_lightingonly_overbright2_ps11.fxc9
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_maskedenvmap.psh19
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedenvmap.psh25
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_selfilluminatedmaskedenvmap.psh26
-rw-r--r--mp/src/materialsystem/stdshaders/vertexlitgeneric_vs11.vsh22
-rw-r--r--mp/src/materialsystem/stdshaders/volume_clouds.cpp59
-rw-r--r--mp/src/materialsystem/stdshaders/volume_clouds_helper.cpp138
-rw-r--r--mp/src/materialsystem/stdshaders/volume_clouds_helper.h41
-rw-r--r--mp/src/materialsystem/stdshaders/volume_clouds_ps2x.fxc66
-rw-r--r--mp/src/materialsystem/stdshaders/volume_clouds_vs20.fxc103
-rw-r--r--mp/src/materialsystem/stdshaders/vr_distort_hud.cpp224
-rw-r--r--mp/src/materialsystem/stdshaders/vr_distort_hud_ps2x.fxc78
-rw-r--r--mp/src/materialsystem/stdshaders/vr_distort_hud_vs20.fxc26
-rw-r--r--mp/src/materialsystem/stdshaders/vr_distort_texture.cpp213
-rw-r--r--mp/src/materialsystem/stdshaders/vr_distort_texture_ps2x.fxc49
-rw-r--r--mp/src/materialsystem/stdshaders/vr_distort_texture_vs20.fxc26
-rw-r--r--mp/src/materialsystem/stdshaders/water.cpp614
-rw-r--r--mp/src/materialsystem/stdshaders/water_dudv.cpp95
-rw-r--r--mp/src/materialsystem/stdshaders/water_dx60.cpp15
-rw-r--r--mp/src/materialsystem/stdshaders/water_dx80.cpp419
-rw-r--r--mp/src/materialsystem/stdshaders/water_dx81.cpp311
-rw-r--r--mp/src/materialsystem/stdshaders/water_ps2x.fxc110
-rw-r--r--mp/src/materialsystem/stdshaders/water_ps2x_helper.h239
-rw-r--r--mp/src/materialsystem/stdshaders/waterreflect_ps14.psh8
-rw-r--r--mp/src/materialsystem/stdshaders/waterrefract_ps14.psh23
-rw-r--r--mp/src/materialsystem/stdshaders/worldtwotextureblend.cpp500
-rw-r--r--mp/src/materialsystem/stdshaders/worldtwotextureblend_dx6.cpp258
-rw-r--r--mp/src/materialsystem/stdshaders/worldtwotextureblend_dx8.cpp175
-rw-r--r--mp/src/materialsystem/stdshaders/worldtwotextureblend_ps2x.fxc217
-rw-r--r--mp/src/materialsystem/stdshaders/worldvertexalpha.cpp259
-rw-r--r--mp/src/materialsystem/stdshaders/worldvertexalpha_dx8.cpp113
-rw-r--r--mp/src/materialsystem/stdshaders/worldvertextransition.cpp157
-rw-r--r--mp/src/materialsystem/stdshaders/worldvertextransition_dx6.cpp52
-rw-r--r--mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.cpp206
-rw-r--r--mp/src/materialsystem/stdshaders/worldvertextransition_dx6_helper.h39
-rw-r--r--mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.cpp81
-rw-r--r--mp/src/materialsystem/stdshaders/worldvertextransition_dx8_helper.h44
355 files changed, 37024 insertions, 0 deletions
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 <string.h>
+
+//-----------------------------------------------------------------------------
+// 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 <string.h>
+
+
+//-----------------------------------------------------------------------------
+// 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 <string.h>
+
+//-----------------------------------------------------------------------------
+// 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 <string.h>
+#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 <string.h>
+
+//-----------------------------------------------------------------------------
+// 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 <string.h>
+
+#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 <string.h>
+#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 <string.h>
+#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 <string.h>
+#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 <string.h>
+
+
+//-----------------------------------------------------------------------------
+// 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\t<DrawVertexLitGeneric_DX9_Internal\n");
+}
+
+
+void DrawVertexLitGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
+ IShaderShadow* pShaderShadow, bool bVertexLitGeneric, VertexLitGeneric_DX9_Vars_t &info, VertexCompressionType_t vertexCompression,
+ CBasePerMaterialContextData **pContextDataPtr )
+{
+ if ( WantsSkinShader( params, info ) && g_pHardwareConfig->SupportsPixelShaders_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 <string.h>
+
+
+//-----------------------------------------------------------------------------
+// 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 <string.h>
+
+//-----------------------------------------------------------------------------
+// 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 <string.h>
+
+
+//-----------------------------------------------------------------------------
+// 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