From 87020dcb978f905e70efef5b7dd903cb4476afc0 Mon Sep 17 00:00:00 2001 From: celisej567 Date: Thu, 15 Dec 2022 17:10:27 +0300 Subject: [PATCH] Added Third CSM Level -Added csm_third_intensity ConVar -Added enablethird Hammer option -Changed csm_current_distance ConVar -Added csm_third_fov ConVar -Added csm_nearz and csm_farz ConVars -Entity-helpers was renamed -Now r_farz will be 210000 all the time, so fog's one will not work --- client/c_env_cascade_light.cpp | 338 +++++++++++++++++++++++++++------ client/clientshadowmgr.cpp | 69 +++++-- fgd/csm.fgd | 9 + server/env_cascade_light.cpp | 241 ++++++++++++++++++++--- 4 files changed, 561 insertions(+), 96 deletions(-) diff --git a/client/c_env_cascade_light.cpp b/client/c_env_cascade_light.cpp index 20eee20..a43cc15 100644 --- a/client/c_env_cascade_light.cpp +++ b/client/c_env_cascade_light.cpp @@ -18,23 +18,16 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -//ConVar csm_slopescaledepthbias_shadowmap("csm_slopescaledepthbias_shadowmap", "0.00005"); -//ConVar csm_depthbias_shadowmap("csm_depthbias_shadowmap", "4"); - static ConVar scissor("r_flashlightscissor", "0"); -ConVar csm_enable("csm_enable", "1"); -//ConVarRef csm_second_intensity("csm_second_intensity"); -ConVar csm_intensity("csm_intensity", "1000"); -#ifdef MAPBASE -//static ConVar csm_ortho("csm_ortho","0", 0, "Turn light into ortho. Im lazy right now to make this works fine"); -//ConVar csm_ortho_nearz("csm_ortho_nearz", "512"); -//ConVar csm_ortho_left("csm_ortho_left", "-1000"); -//ConVar csm_ortho_top("csm_ortho_top", "-1000"); -//ConVar csm_ortho_bottom("csm_ortho_bottom", "1000"); -//ConVar csm_ortho_right("csm_ortho_right", "1000"); -//ConVar csm_test_color_interpolation("csm_test_color_interpolation","0"); //я не помню что она делает, но она определённо этого не делает -#endif +//intensity +ConVar csm_intensity("csm_intensity", "200"); +ConVar csm_second_intensity("csm_second_intensity", "200"); +ConVar csm_third_intensity("csm_third_intensity", "200"); + + +ConVar csm_filter("csm_filter", "1"); +ConVar csm_enable("csm_enable", "1"); //----------------------------------------------------------------------------- // Purpose: main point for change angle of the light @@ -70,10 +63,9 @@ void C_LightOrigin::Simulate() { Update(); BaseClass::Simulate(); + ConVarRef("r_farz").SetValue("210000"); } -ConVar bebra("csm_filter", "1"); //if you have r_flashlightdepthres 4096 then better to change this value to 0.5 - //----------------------------------------------------------------------------- // Purpose: main csm code @@ -188,7 +180,7 @@ void C_EnvCascadeLight::UpdateLight( bool bForceUpdate ) Vector vForward, vRight, vUp, vPos = GetAbsOrigin(); FlashlightState_t state; - state.m_flShadowFilterSize = bebra.GetFloat(); + state.m_flShadowFilterSize = csm_filter.GetFloat(); if (m_hTargetEntity != NULL) @@ -370,9 +362,6 @@ void C_EnvCascadeLight::UpdateLight( bool bForceUpdate ) g_pClientShadowMgr->UpdateProjectedTexture(m_LightHandle, true); - //mat_slopescaledepthbias_shadowmap.SetValue("4"); - //mat_depthbias_shadowmap.SetValue("0.00001"); - scissor.SetValue("0"); } @@ -458,7 +447,6 @@ END_RECV_TABLE() C_EnvCascadeLightSecond::C_EnvCascadeLightSecond(void) { - m_LightHandle = CLIENTSHADOW_INVALID_HANDLE; } @@ -498,7 +486,274 @@ void C_EnvCascadeLightSecond::UpdateLight(bool bForceUpdate) Vector vForward, vRight, vUp, vPos = GetAbsOrigin(); FlashlightState_t state; - state.m_flShadowFilterSize = bebra.GetFloat(); + state.m_flShadowFilterSize = csm_filter.GetFloat(); + + if (m_hTargetEntity != NULL) + { + if (m_bCameraSpace) + { + const QAngle& angles = GetLocalAngles(); + + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + if (pPlayer) + { + const QAngle playerAngles = pPlayer->GetAbsAngles(); + + Vector vPlayerForward, vPlayerRight, vPlayerUp; + AngleVectors(playerAngles, &vPlayerForward, &vPlayerRight, &vPlayerUp); + + matrix3x4_t mRotMatrix; + AngleMatrix(angles, mRotMatrix); + + VectorITransform(vPlayerForward, mRotMatrix, vForward); + VectorITransform(vPlayerRight, mRotMatrix, vRight); + VectorITransform(vPlayerUp, mRotMatrix, vUp); + + float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length(); + vPos = m_hTargetEntity->GetAbsOrigin() - vForward * dist; + + VectorNormalize(vForward); + VectorNormalize(vRight); + VectorNormalize(vUp); + } + } + else + { + vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin(); + VectorNormalize(vForward); + Assert(0); + } + } + else + { + AngleVectors(GetAbsAngles(), &vForward, &vRight, &vUp); + } + + Vector vLinearFloatLightColor(m_LightColor.r, m_LightColor.g, m_LightColor.b); + float flLinearFloatLightAlpha = m_LightColor.a; + +#ifdef MAPBASE + if (m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha) + { + if (m_flColorTransitionTime != 0.0f) + { + float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f; + + m_CurrentLinearFloatLightColor.x = Approach(vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed); + m_CurrentLinearFloatLightColor.y = Approach(vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed); + m_CurrentLinearFloatLightColor.z = Approach(vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed); + m_flCurrentLinearFloatLightAlpha = Approach(flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed); + //m_flCurrentBrightnessScale = Approach(m_flBrightnessScale, m_flCurrentBrightnessScale, flColorTransitionSpeed); + } + else + { + // Just do it instantly + m_CurrentLinearFloatLightColor.x = vLinearFloatLightColor.x; + m_CurrentLinearFloatLightColor.y = vLinearFloatLightColor.y; + m_CurrentLinearFloatLightColor.z = vLinearFloatLightColor.z; + m_flCurrentLinearFloatLightAlpha = flLinearFloatLightAlpha; + //m_flCurrentBrightnessScale = m_flBrightnessScale; + } + } +#else + if (m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha) + { + float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f; + + m_CurrentLinearFloatLightColor.x = Approach(vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed); + m_CurrentLinearFloatLightColor.y = Approach(vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed); + m_CurrentLinearFloatLightColor.z = Approach(vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed); + m_flCurrentLinearFloatLightAlpha = Approach(flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed); + } +#endif + + + state.m_fHorizontalFOVDegrees = m_flLightFOV; + state.m_fVerticalFOVDegrees = m_flLightFOV; + + state.m_vecLightOrigin = vPos; + BasisToQuaternion(vForward, vRight, vUp, state.m_quatOrientation); + + state.m_fQuadraticAtten = 0.0; + state.m_fLinearAtten = 100; + state.m_fConstantAtten = 0.0f; + //state.m_Color[0] = m_LinearFloatLightColor.x; + //state.m_Color[1] = m_LinearFloatLightColor.y; + //state.m_Color[2] = m_LinearFloatLightColor.z; + +#ifdef MAPBASE + float flAlpha = m_flCurrentLinearFloatLightAlpha * (1.0f / 255.0f); + state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * flAlpha) * csm_second_intensity.GetFloat(); + state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * flAlpha) * csm_second_intensity.GetFloat(); + state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * flAlpha) * csm_second_intensity.GetFloat(); +#else + state.m_Color[0] = m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * csm_second_intensity.GetFloat(); + state.m_Color[1] = m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * csm_second_intensity.GetFloat(); + state.m_Color[2] = m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * csm_second_intensity.GetFloat(); +#endif + + state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient; + state.m_NearZ = m_flNearZ; + state.m_FarZ = m_flFarZ; + state.m_flShadowSlopeScaleDepthBias = ConVarRef("mat_slopescaledepthbias_shadowmap").GetFloat();//csm_slopescaledepthbias_shadowmap.GetFloat(); + state.m_flShadowDepthBias = ConVarRef("mat_depthbias_shadowmap").GetFloat();//csm_depthbias_shadowmap.GetFloat(); + state.m_bEnableShadows = m_bEnableShadows; + state.m_pSpotlightTexture = materials->FindTexture(m_SpotlightTextureName, TEXTURE_GROUP_OTHER, false); + state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame; + + state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality + + + if (m_LightHandle == CLIENTSHADOW_INVALID_HANDLE) + { + m_LightHandle = g_pClientShadowMgr->CreateFlashlight(state); + } + else + { + if (m_hTargetEntity != NULL || bForceUpdate == true) + { + g_pClientShadowMgr->UpdateFlashlightState(m_LightHandle, state); + } + } + + if (m_bLightOnlyTarget) + { + g_pClientShadowMgr->SetFlashlightTarget(m_LightHandle, m_hTargetEntity); + } + else + { + g_pClientShadowMgr->SetFlashlightTarget(m_LightHandle, NULL); + } + + g_pClientShadowMgr->SetFlashlightLightWorld(m_LightHandle, m_bLightWorld); + + g_pClientShadowMgr->UpdateProjectedTexture(m_LightHandle, true); + + scissor.SetValue("0"); +} + + +void C_EnvCascadeLightSecond::Simulate(void) +{ + m_bState = csm_enable.GetBool(); + UpdateLight(true); + BaseClass::Simulate(); +} + +//----------------------------------------------------------------------------- +// Purpose: second csm +//----------------------------------------------------------------------------- + +class C_EnvCascadeLightThird : public C_BaseEntity +{ + DECLARE_CLASS(C_EnvCascadeLightThird, C_BaseEntity); +public: + DECLARE_CLIENTCLASS(); + + virtual void OnDataChanged(DataUpdateType_t updateType); + void ShutDownLightHandle(void); + + virtual void Simulate(); + + void UpdateLight(bool bForceUpdate); + void updatePos(); + + C_EnvCascadeLightThird(); + ~C_EnvCascadeLightThird(); + + +private: + + ClientShadowHandle_t m_LightHandle; + + color32 m_LightColor; + +#ifdef MAPBASE + float m_flBrightnessScale; + float m_flCurrentBrightnessScale; +#endif + Vector m_CurrentLinearFloatLightColor; + float m_flCurrentLinearFloatLightAlpha; + float m_flColorTransitionTime; + + EHANDLE m_hTargetEntity; + CBaseEntity* pEntity = NULL; + bool firstUpdate = true; + bool m_bState; + float m_flLightFOV; + bool m_bEnableShadows; + bool m_bLightOnlyTarget; + bool m_bLightWorld; + bool m_bCameraSpace; + Vector m_LinearFloatLightColor; + float m_flAmbient; + float m_flNearZ; + float m_flFarZ; + char m_SpotlightTextureName[MAX_PATH]; + int m_nSpotlightTextureFrame; + int m_nShadowQuality; +}; + +IMPLEMENT_CLIENTCLASS_DT(C_EnvCascadeLightThird, DT_EnvCascadeLightThird, CEnvCascadeLightThird) +RecvPropInt(RECVINFO(m_LightColor), 0, RecvProxy_IntToColor32), +RecvPropEHandle(RECVINFO(m_hTargetEntity)), +RecvPropBool(RECVINFO(m_bState)), +RecvPropFloat(RECVINFO(m_flLightFOV)), +RecvPropBool(RECVINFO(m_bEnableShadows)), +RecvPropBool(RECVINFO(m_bLightOnlyTarget)), +RecvPropBool(RECVINFO(m_bLightWorld)), +RecvPropBool(RECVINFO(m_bCameraSpace)), +RecvPropVector(RECVINFO(m_LinearFloatLightColor)), +RecvPropFloat(RECVINFO(m_flAmbient)), +RecvPropString(RECVINFO(m_SpotlightTextureName)), +RecvPropInt(RECVINFO(m_nSpotlightTextureFrame)), +RecvPropFloat(RECVINFO(m_flNearZ)), +RecvPropFloat(RECVINFO(m_flFarZ)), +RecvPropInt(RECVINFO(m_nShadowQuality)) +END_RECV_TABLE() + +C_EnvCascadeLightThird::C_EnvCascadeLightThird(void) +{ + m_LightHandle = CLIENTSHADOW_INVALID_HANDLE; +} + + +C_EnvCascadeLightThird::~C_EnvCascadeLightThird(void) +{ + ShutDownLightHandle(); +} + +void C_EnvCascadeLightThird::ShutDownLightHandle(void) +{ + if (m_LightHandle != CLIENTSHADOW_INVALID_HANDLE) + { + g_pClientShadowMgr->DestroyFlashlight(m_LightHandle); + m_LightHandle = CLIENTSHADOW_INVALID_HANDLE; + } +} + +void C_EnvCascadeLightThird::OnDataChanged(DataUpdateType_t updateType) +{ + UpdateLight(true); + BaseClass::OnDataChanged(updateType); +} + +void C_EnvCascadeLightThird::UpdateLight(bool bForceUpdate) +{ + + if (m_bState == false) + { + + if (m_LightHandle != CLIENTSHADOW_INVALID_HANDLE) + ShutDownLightHandle(); + + + return; + } + + Vector vForward, vRight, vUp, vPos = GetAbsOrigin(); + FlashlightState_t state; + state.m_flShadowFilterSize = csm_filter.GetFloat(); if (m_hTargetEntity != NULL) { @@ -596,18 +851,16 @@ void C_EnvCascadeLightSecond::UpdateLight(bool bForceUpdate) #ifdef MAPBASE float flAlpha = m_flCurrentLinearFloatLightAlpha * (1.0f / 255.0f); - state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * flAlpha) * ConVarRef("csm_second_intensity").GetFloat(); - state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * flAlpha) * ConVarRef("csm_second_intensity").GetFloat(); - state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * flAlpha) * ConVarRef("csm_second_intensity").GetFloat(); + state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * flAlpha) * csm_third_intensity.GetFloat(); + state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * flAlpha) * csm_third_intensity.GetFloat(); + state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * flAlpha) * csm_third_intensity.GetFloat(); #else - state.m_Color[0] = m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * ConVarRef("csm_second_intensity").GetFloat(); - state.m_Color[1] = m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * ConVarRef("csm_second_intensity").GetFloat(); - state.m_Color[2] = m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * ConVarRef("csm_second_intensity").GetFloat(); + state.m_Color[0] = m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * csm_third_intensity.GetFloat(); + state.m_Color[1] = m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * csm_third_intensity.GetFloat(); + state.m_Color[2] = m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * csm_third_intensity.GetFloat(); #endif state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient; - m_flNearZ = 5000; - m_flFarZ = 16000; state.m_NearZ = m_flNearZ; state.m_FarZ = m_flFarZ; state.m_flShadowSlopeScaleDepthBias = ConVarRef("mat_slopescaledepthbias_shadowmap").GetFloat();//csm_slopescaledepthbias_shadowmap.GetFloat(); @@ -617,25 +870,6 @@ void C_EnvCascadeLightSecond::UpdateLight(bool bForceUpdate) state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame; state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality - -#ifdef MAPBASE - /* - state.m_bOrtho = csm_ortho.GetBool(); - if(state.m_bOrtho) - { - float flOrthoSize = 1000.0f; - - state.m_fOrthoLeft = -flOrthoSize; - state.m_fOrthoTop = -flOrthoSize; - state.m_fOrthoRight = flOrthoSize; - state.m_fOrthoBottom = flOrthoSize; - - state.m_fLinearAtten = ConVarRef("csm_current_distance").GetInt() * 2; - state.m_FarZAtten = ConVarRef("csm_current_distance").GetInt() * 2; - } - */ -#endif - if (m_LightHandle == CLIENTSHADOW_INVALID_HANDLE) { @@ -673,13 +907,11 @@ void C_EnvCascadeLightSecond::UpdateLight(bool bForceUpdate) g_pClientShadowMgr->UpdateProjectedTexture(m_LightHandle, true); - m_flLightFOV = ConVarRef("csm_second_fov").GetFloat(); - scissor.SetValue("0"); } -void C_EnvCascadeLightSecond::Simulate(void) +void C_EnvCascadeLightThird::Simulate(void) { m_bState = csm_enable.GetBool(); UpdateLight(true); diff --git a/client/clientshadowmgr.cpp b/client/clientshadowmgr.cpp index 50bc6a1..d24a9e1 100644 --- a/client/clientshadowmgr.cpp +++ b/client/clientshadowmgr.cpp @@ -96,10 +96,6 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" - -const char* maxprojlights = CommandLine()->ParmValue("-ptmax", "10"); -ConVar pr_max("pr_max", maxprojlights, 0, "Changes maximum of enabled env_projectedtexture and everything related to it at one time."); - static ConVar r_flashlightdrawfrustum( "r_flashlightdrawfrustum", "0" ); static ConVar r_flashlightmodels( "r_flashlightmodels", "1" ); static ConVar r_shadowrendertotexture( "r_shadowrendertotexture", "0" ); @@ -111,14 +107,16 @@ static ConVar r_shadow_mincastintensity( "r_shadow_mincastintensity", "0.3", FCV #endif static ConVar r_flashlight_version2( "r_flashlight_version2", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ); -ConVar r_flashlightdepthtexture( "r_flashlightdepthtexture", "1" ); +ConVar r_flashlightdepthtexture( "r_flashlightdepthtexture", "0" ); #if defined( _X360 ) ConVar r_flashlightdepthres( "r_flashlightdepthres", "512" ); #else -const char* projlightres = CommandLine()->ParmValue("-ptr", "2048"); //Параметр запуска обазначающий разрешение env_projectedtexture - -ConVar r_flashlightdepthres("r_flashlightdepthres", projlightres, 0, "Changes resolution of env_projectedtexture and everything related to it."); +#ifdef MAPBASE +ConVar r_flashlightdepthres( "r_flashlightdepthres", "2048" ); +#else +ConVar r_flashlightdepthres( "r_flashlightdepthres", "1024" ); +#endif #endif #ifdef ASW_PROJECTED_TEXTURES @@ -127,6 +125,11 @@ ConVar r_threaded_client_shadow_manager( "r_threaded_client_shadow_manager", "1" ConVar r_threaded_client_shadow_manager( "r_threaded_client_shadow_manager", "0" ); #endif +#ifdef MAPBASE +ConVarRef mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap" ); +ConVarRef mat_depthbias_shadowmap( "mat_depthbias_shadowmap" ); +#endif + #ifdef _WIN32 #pragma warning( disable: 4701 ) #endif @@ -1396,7 +1399,14 @@ bool CClientShadowMgr::Init() SetShadowBlobbyCutoffArea( 0.005 ); - m_nMaxDepthTextureShadows = pr_max.GetInt(); +#ifndef MAPBASE + bool bTools = CommandLine()->CheckParm( "-tools" ) != NULL; + m_nMaxDepthTextureShadows = bTools ? 4 : 1; // Just one shadow depth texture in games, more in tools +#else + // 5 lets mappers use up to 4 shadow-casting projected textures, which is better than 3. + int iNumShadows = CommandLine()->ParmValue( "-numshadowtextures", 5 ); + m_nMaxDepthTextureShadows = iNumShadows; +#endif bool bLowEnd = ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 ); @@ -1419,6 +1429,15 @@ bool CClientShadowMgr::Init() materials->AddRestoreFunc( ShadowRestoreFunc ); +#ifdef MAPBASE + // These need to be referenced here since the cvars don't exist in the initial declaration + mat_slopescaledepthbias_shadowmap = ConVarRef( "mat_slopescaledepthbias_shadowmap" ); + mat_depthbias_shadowmap = ConVarRef( "mat_depthbias_shadowmap" ); + + mat_slopescaledepthbias_shadowmap.SetValue( "16" ); // Would do something like 2 here, but it causes citizens to look weird under flashlights + mat_depthbias_shadowmap.SetValue( "0.00005" ); +#endif + return true; } @@ -2319,25 +2338,20 @@ void CClientShadowMgr::BuildWorldToShadowMatrix( VMatrix& matWorldToShadow, cons matWorldToShadow[3][3] = 1.0f; } - void CClientShadowMgr::BuildPerspectiveWorldToFlashlightMatrix( VMatrix& matWorldToShadow, const FlashlightState_t &flashlightState ) { VPROF_BUDGET( "CClientShadowMgr::BuildPerspectiveWorldToFlashlightMatrix", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); // Buildworld to shadow matrix, then perspective projection and concatenate - VMatrix matWorldToShadowView, matPerspective, addW, scaleHalf; - - BuildWorldToShadowMatrix(matWorldToShadowView, flashlightState.m_vecLightOrigin, - flashlightState.m_quatOrientation); - - MatrixBuildPerspective(matPerspective, flashlightState.m_fHorizontalFOVDegrees, - flashlightState.m_fVerticalFOVDegrees, - flashlightState.m_NearZ, flashlightState.m_FarZ); - - - MatrixMultiply(matPerspective, matWorldToShadowView, matWorldToShadow); + VMatrix matWorldToShadowView, matPerspective; + BuildWorldToShadowMatrix( matWorldToShadowView, flashlightState.m_vecLightOrigin, + flashlightState.m_quatOrientation ); + MatrixBuildPerspective( matPerspective, flashlightState.m_fHorizontalFOVDegrees, + flashlightState.m_fVerticalFOVDegrees, + flashlightState.m_NearZ, flashlightState.m_FarZ ); + MatrixMultiply( matPerspective, matWorldToShadowView, matWorldToShadow ); } #ifdef ASW_PROJECTED_TEXTURES @@ -4470,13 +4484,18 @@ void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) } CViewSetup shadowView; +#ifndef MAPBASE shadowView.m_flAspectRatio = 1.0f; +#endif shadowView.x = shadowView.y = 0; shadowView.width = shadowDepthTexture->GetActualWidth(); shadowView.height = shadowDepthTexture->GetActualHeight(); #ifndef ASW_PROJECTED_TEXTURES shadowView.m_bOrtho = false; shadowView.m_bDoBloomAndToneMapping = false; +#ifdef MAPBASE + shadowView.m_flAspectRatio = (flashlightState.m_fHorizontalFOVDegrees / flashlightState.m_fVerticalFOVDegrees); +#endif // MAPBASE #endif // Copy flashlight parameters @@ -4484,6 +4503,10 @@ void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) if ( !flashlightState.m_bOrtho ) { shadowView.m_bOrtho = false; + +#ifdef MAPBASE + shadowView.m_flAspectRatio = (flashlightState.m_fHorizontalFOVDegrees / flashlightState.m_fVerticalFOVDegrees); +#endif // MAPBASE } else { @@ -4492,6 +4515,10 @@ void CClientShadowMgr::ComputeShadowDepthTextures( const CViewSetup &viewSetup ) shadowView.m_OrthoTop = flashlightState.m_fOrthoTop; shadowView.m_OrthoRight = flashlightState.m_fOrthoRight; shadowView.m_OrthoBottom = flashlightState.m_fOrthoBottom; + +#ifdef MAPBASE + shadowView.m_flAspectRatio = 1.0f; +#endif } shadowView.m_bDoBloomAndToneMapping = false; diff --git a/fgd/csm.fgd b/fgd/csm.fgd index bace0f8..88d7f85 100644 --- a/fgd/csm.fgd +++ b/fgd/csm.fgd @@ -17,6 +17,13 @@ 0 : "No" ] + enablethird(Choices) : "Enable Third level?" : 1 : "Enable Third CSM level? CSM will effect at more distance but its more expensive." = + [ + 1 : "Yes" + 0 : "No" + ] + + ambient(integer) :"Ambient" : 0 : "idk" input Enable(void) : "Turn on the texture" @@ -25,6 +32,8 @@ input Texture(string) : "Change texture" input LightColor(color255) : "Set the light color." input SetAngles(string) : "Set the sun direction." + input AddAngles(string) : "Add angle for the sun" + input ResetAngles(void) : "Reset angle of the sun" ] @PointClass base(Angles) iconsprite("editor/light_env.vmt") = light_environment : diff --git a/server/env_cascade_light.cpp b/server/env_cascade_light.cpp index 48fa804..786dbf3 100644 --- a/server/env_cascade_light.cpp +++ b/server/env_cascade_light.cpp @@ -16,15 +16,23 @@ #define ENV_CASCADE_STARTON (1<<0) +//distance static ConVar defdist("csm_default_distance", "1000", FCVAR_DEVELOPMENTONLY, "Default Z distance. Used for some fov calculations. Please dont change"); -static ConVar curdist("csm_current_distance","14000", 0, "Current Z distance. You can change it."); -static ConVar defFOV("csm_default_fov","15", FCVAR_DEVELOPMENTONLY, "Default FOV. Used for some fov calculations. Please dont change"); -static ConVar curFOV("csm_current_fov","15", 0, "Current FOV. You can change it"); -static ConVar csm_second_fov("csm_second_fov", "25", FCVAR_NONE ,"FOV of the second csm."); -ConVar csm_enable("csm_enable", "1"); -ConVar csm_second_intensity("csm_second_intensity", "1000"); +static ConVar curdist("csm_current_distance", "100000", 0, "Current Z distance. You can change it."); + +//fov things +static ConVar defFOV("csm_default_fov", "15", FCVAR_DEVELOPMENTONLY, "Default FOV. Used for some fov calculations. Please dont change"); +static ConVar curFOV("csm_current_fov", "15", 0, "Current FOV. You can change it"); +static ConVar csm_second_fov("csm_second_fov", "350", FCVAR_NONE, "FOV of the second csm."); +static ConVar csm_third_fov("csm_third_fov", "2800", FCVAR_NONE, "FOV of the second csm."); + +//farz and nearz +ConVar csm_nearz("csm_nearz", "90000"); +ConVar csm_farz("csm_farz", "200000"); + +ConVar csm_enable("csm_enable", "1"); + -//ConVar csm_ortho("csm_ortho", "0"); class CLightOrigin : public CPointEntity { @@ -46,7 +54,7 @@ private: CNetworkVector(LightEnvVector); }; -LINK_ENTITY_TO_CLASS(csmorigin, CLightOrigin); +LINK_ENTITY_TO_CLASS(csm_origin, CLightOrigin); BEGIN_DATADESC(CLightOrigin) DEFINE_FIELD(LightEnvVector, FIELD_VECTOR), @@ -89,6 +97,169 @@ void CLightOrigin::InitialThink() } +//----------------------------------------------------------------------------- +// Purpose: third csm +//----------------------------------------------------------------------------- + +class CEnvCascadeLightThird : public CPointEntity +{ + DECLARE_CLASS(CEnvCascadeLightThird, CPointEntity); +public: + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + CEnvCascadeLightThird(); + bool KeyValue(const char* szKeyName, const char* szValue); + + // Always transmit to clients + virtual int UpdateTransmitState(); + virtual void Activate(void); + + void InitialThink(void); + + CNetworkHandle(CBaseEntity, m_hTargetEntity); + CNetworkVector(m_LinearFloatLightColor); + CNetworkColor32(m_LightColor); + CNetworkVar(float, m_flNearZ); + CNetworkVar(float, m_flFarZ); + +private: + + CNetworkVar(bool, m_bState); + CNetworkVar(float, m_flLightFOV); + CNetworkVar(bool, m_bEnableShadows); + CNetworkVar(bool, m_bLightOnlyTarget); + CNetworkVar(bool, m_bLightWorld); + CNetworkVar(bool, m_bCameraSpace); + CNetworkVar(float, m_flAmbient); + CNetworkString(m_SpotlightTextureName, MAX_PATH); + CNetworkVar(int, m_nSpotlightTextureFrame); + CNetworkVar(int, m_nShadowQuality); + + +}; + +LINK_ENTITY_TO_CLASS(csm_third, CEnvCascadeLightThird); + +BEGIN_DATADESC(CEnvCascadeLightThird) +DEFINE_FIELD(m_hTargetEntity, FIELD_EHANDLE), +DEFINE_FIELD(m_bState, FIELD_BOOLEAN), +DEFINE_KEYFIELD(m_flLightFOV, FIELD_FLOAT, "lightfov"), +DEFINE_KEYFIELD(m_bEnableShadows, FIELD_BOOLEAN, "enableshadows"), +DEFINE_KEYFIELD(m_bLightOnlyTarget, FIELD_BOOLEAN, "lightonlytarget"), +DEFINE_KEYFIELD(m_bLightWorld, FIELD_BOOLEAN, "lightworld"), +DEFINE_KEYFIELD(m_bCameraSpace, FIELD_BOOLEAN, "cameraspace"), +DEFINE_KEYFIELD(m_flAmbient, FIELD_FLOAT, "ambient"), +DEFINE_AUTO_ARRAY_KEYFIELD(m_SpotlightTextureName, FIELD_CHARACTER, "texturename"), +DEFINE_KEYFIELD(m_nSpotlightTextureFrame, FIELD_INTEGER, "textureframe"), +DEFINE_KEYFIELD(m_flNearZ, FIELD_FLOAT, "nearz"), +DEFINE_KEYFIELD(m_flFarZ, FIELD_FLOAT, "farz"), +DEFINE_KEYFIELD(m_nShadowQuality, FIELD_INTEGER, "shadowquality"), +DEFINE_FIELD(m_LinearFloatLightColor, FIELD_VECTOR), +DEFINE_THINKFUNC(InitialThink), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST(CEnvCascadeLightThird, DT_EnvCascadeLightThird) +SendPropInt(SENDINFO(m_LightColor), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt), +SendPropEHandle(SENDINFO(m_hTargetEntity)), +SendPropBool(SENDINFO(m_bState)), +SendPropFloat(SENDINFO(m_flLightFOV)), +SendPropBool(SENDINFO(m_bEnableShadows)), +SendPropBool(SENDINFO(m_bLightOnlyTarget)), +SendPropBool(SENDINFO(m_bLightWorld)), +SendPropBool(SENDINFO(m_bCameraSpace)), +SendPropVector(SENDINFO(m_LinearFloatLightColor)), +SendPropFloat(SENDINFO(m_flAmbient)), +SendPropString(SENDINFO(m_SpotlightTextureName)), +SendPropInt(SENDINFO(m_nSpotlightTextureFrame)), +SendPropFloat(SENDINFO(m_flNearZ), 16, SPROP_ROUNDDOWN, 0.0f, 500.0f), +SendPropFloat(SENDINFO(m_flFarZ), 18, SPROP_ROUNDDOWN, 0.0f, 1500.0f), +SendPropInt(SENDINFO(m_nShadowQuality), 1, SPROP_UNSIGNED) // Just one bit for now +END_SEND_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CEnvCascadeLightThird::CEnvCascadeLightThird(void) +{ +#ifdef MAPBASE + m_LightColor.Init(255, 255, 255, 255); +#else + m_LightColor.Init(255, 255, 255, 1); +#endif + m_bState = csm_enable.GetBool(); + m_flLightFOV = 45.0f; + m_bEnableShadows = true; + m_bLightOnlyTarget = false; + m_bLightWorld = true; + m_bCameraSpace = false; + + Q_strcpy(m_SpotlightTextureName.GetForModify(), "tools\\fakecsm\\mask_ring"); + m_nSpotlightTextureFrame = 0; + m_LinearFloatLightColor.Init(1.0f, 1.0f, 1.0f); + m_flAmbient = 0.0f; + m_flNearZ = csm_nearz.GetFloat(); + m_flFarZ = csm_farz.GetFloat(); + m_nShadowQuality = 0; +} + +void UTIL_ColorStringToLinearFloatColorCSMFakeThird(Vector& color, const char* pString) +{ + float tmp[4]; + UTIL_StringToFloatArray(tmp, 4, pString); + if (tmp[3] <= 0.0f) + { + tmp[3] = 255.0f; + } + tmp[3] *= (1.0f / 255.0f); + color.x = GammaToLinear(tmp[0] * (1.0f / 255.0f)) * tmp[3]; + color.y = GammaToLinear(tmp[1] * (1.0f / 255.0f)) * tmp[3]; + color.z = GammaToLinear(tmp[2] * (1.0f / 255.0f)) * tmp[3]; +} + +bool CEnvCascadeLightThird::KeyValue(const char* szKeyName, const char* szValue) +{ + if (FStrEq(szKeyName, "lightcolor")) + { + Vector tmp; + UTIL_ColorStringToLinearFloatColorCSMFakeThird(tmp, szValue); + m_LinearFloatLightColor = tmp; + } + else + { + return BaseClass::KeyValue(szKeyName, szValue); + } + + return true; +} + +void CEnvCascadeLightThird::Activate(void) +{ + if (GetSpawnFlags() & ENV_CASCADE_STARTON) + { + m_bState = true; + } + + SetThink(&CEnvCascadeLightThird::InitialThink); + SetNextThink(gpGlobals->curtime + 0.1f); + + BaseClass::Activate(); +} + +void CEnvCascadeLightThird::InitialThink(void) +{ + m_bState = csm_enable.GetBool(); + float bibigon = defdist.GetFloat() / curdist.GetFloat(); + m_flLightFOV = csm_third_fov.GetFloat() * bibigon; + m_hTargetEntity = gEntList.FindEntityByName(NULL, m_target); +} + +int CEnvCascadeLightThird::UpdateTransmitState() +{ + return SetTransmitState(FL_EDICT_ALWAYS); +} + + //----------------------------------------------------------------------------- // Purpose: second csm //----------------------------------------------------------------------------- @@ -112,6 +283,8 @@ public: CNetworkHandle(CBaseEntity, m_hTargetEntity); CNetworkVector(m_LinearFloatLightColor); CNetworkColor32(m_LightColor); + CNetworkVar(float, m_flNearZ); + CNetworkVar(float, m_flFarZ); private: @@ -124,14 +297,12 @@ private: CNetworkVar(float, m_flAmbient); CNetworkString(m_SpotlightTextureName, MAX_PATH); CNetworkVar(int, m_nSpotlightTextureFrame); - CNetworkVar(float, m_flNearZ); - CNetworkVar(float, m_flFarZ); CNetworkVar(int, m_nShadowQuality); }; -LINK_ENTITY_TO_CLASS(second_csm, CEnvCascadeLightSecond); +LINK_ENTITY_TO_CLASS(csm_second, CEnvCascadeLightSecond); BEGIN_DATADESC(CEnvCascadeLightSecond) DEFINE_FIELD(m_hTargetEntity, FIELD_EHANDLE), @@ -190,8 +361,8 @@ CEnvCascadeLightSecond::CEnvCascadeLightSecond(void) m_nSpotlightTextureFrame = 0; m_LinearFloatLightColor.Init(1.0f, 1.0f, 1.0f); m_flAmbient = 0.0f; - m_flNearZ = 8000.0f; - m_flFarZ = 16000.0f; + m_flNearZ = csm_nearz.GetFloat(); + m_flFarZ = csm_farz.GetFloat(); m_nShadowQuality = 0; } @@ -293,6 +464,7 @@ private: CNetworkColor32(m_LightColor); CLightOrigin* csm_origin; CEnvCascadeLightSecond* SecondCSM; + CEnvCascadeLightThird* ThirdCSM; CNetworkVar(bool, m_bState); CNetworkVar(float, m_flLightFOV); CNetworkVar(bool, EnableAngleFromEnv); @@ -308,6 +480,8 @@ private: CNetworkVar(float, m_flFarZ); CNetworkVar(int, m_nShadowQuality); + bool m_bEnableThird; + QAngle DefaultAngle = QAngle(0, 0, 0); QAngle CurrentAngle = QAngle(0, 0, 0); }; @@ -318,6 +492,7 @@ BEGIN_DATADESC(CEnvCascadeLight) DEFINE_FIELD(m_hTargetEntity, FIELD_EHANDLE), DEFINE_FIELD(m_bState, FIELD_BOOLEAN), DEFINE_KEYFIELD(m_bEnableShadows, FIELD_BOOLEAN, "enableshadows"), +DEFINE_KEYFIELD(m_bEnableThird, FIELD_BOOLEAN, "enablethird"), DEFINE_KEYFIELD(m_bLightOnlyTarget, FIELD_BOOLEAN, "lightonlytarget"), DEFINE_KEYFIELD(m_bLightWorld, FIELD_BOOLEAN, "lightworld"), DEFINE_KEYFIELD(m_bCameraSpace, FIELD_BOOLEAN, "cameraspace"), @@ -387,23 +562,24 @@ CEnvCascadeLight::CEnvCascadeLight(void) m_nSpotlightTextureFrame = 0; m_LinearFloatLightColor.Init(1.0f, 1.0f, 1.0f); m_flAmbient = 0.0f; - m_flNearZ = 8000.0f; - m_flFarZ = 16000.0f; + m_flNearZ = csm_nearz.GetFloat(); + m_flFarZ = csm_farz.GetFloat(); m_nShadowQuality = 0; + m_bEnableThird = true; } void CEnvCascadeLight::Preparation() { - CreateEntityByName("csmorigin"); - CreateEntityByName("second_csm"); + CreateEntityByName("csm_origin"); + CreateEntityByName("csm_second"); defFOV.SetValue(m_flLightFOV); CBaseEntity* CSMOrigin = NULL; CBaseEntity* CSMSecond = NULL; - CSMOrigin = gEntList.FindEntityByClassname(CSMOrigin, "csmorigin"); - CSMSecond = gEntList.FindEntityByClassname(CSMSecond, "second_csm"); + CSMOrigin = gEntList.FindEntityByClassname(CSMOrigin, "csm_origin"); + CSMSecond = gEntList.FindEntityByClassname(CSMSecond, "csm_second"); //if origin is exist if (CSMOrigin) { @@ -413,16 +589,33 @@ void CEnvCascadeLight::Preparation() if (CSMSecond) { - SecondCSM = dynamic_cast(CSMSecond); SecondCSM->SetAbsAngles(GetAbsAngles()); SecondCSM->SetAbsOrigin(GetAbsOrigin()); SecondCSM->SetParent(GetBaseEntity()); - SecondCSM->m_LinearFloatLightColor = m_LinearFloatLightColor * csm_second_intensity.GetFloat(); + SecondCSM->m_LinearFloatLightColor = m_LinearFloatLightColor * ConVarRef("csm_second_intensity").GetFloat(); DispatchSpawn(SecondCSM); } + if (m_bEnableThird) + { + CreateEntityByName("csm_third"); + CBaseEntity* CSMThird = NULL; + + CSMThird = gEntList.FindEntityByClassname(CSMThird, "csm_third"); + if (CSMThird) + { + ThirdCSM = dynamic_cast(CSMThird); + ThirdCSM->SetAbsAngles(GetAbsAngles()); + ThirdCSM->SetAbsOrigin(GetAbsOrigin()); + ThirdCSM->SetParent(GetBaseEntity()); + ThirdCSM->m_LinearFloatLightColor = m_LinearFloatLightColor * ConVarRef("csm_second_intensity").GetFloat(); + + DispatchSpawn(ThirdCSM); + } + } + SetParent(csm_origin, 1); @@ -580,7 +773,11 @@ void CEnvCascadeLight::InputSetLightColor(inputdata_t& inputdata) { m_LightColor = inputdata.value.Color32(); SecondCSM->m_LightColor = inputdata.value.Color32(); - //m_LinearFloatLightColor.Init(1.0f, 1.0f, 1.0f); + + if (m_bEnableThird) + { + ThirdCSM->m_LightColor = inputdata.value.Color32(); + } } int CEnvCascadeLight::UpdateTransmitState()