diff --git a/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl b/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl index 9b0e326c1..ebaca85f2 100644 --- a/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl +++ b/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl @@ -28,6 +28,9 @@ struct VS_OUTPUT // Declared identical to pixel shader input (see PS_INPUT) // Xbox constant registers uniform float4 C[X_D3DVS_CONSTREG_COUNT] : register(c0); +// Parameters for mapping the shader's fog output value to a fog factor +uniform float4 CxbxFogInfo: register(c218); // = CXBX_D3DVS_CONSTREG_FOGINFO + // Default values for vertex registers, and whether to use them uniform float4 vRegisterDefaultValues[16] : register(c192); uniform float4 vRegisterDefaultFlagsPacked[4] : register(c208); @@ -324,12 +327,33 @@ VS_OUTPUT main(const VS_INPUT xIn) R"DELIMITER( // Copy variables to output struct - VS_OUTPUT xOut; + VS_OUTPUT xOut; + const float fogDepth = abs(oFog.x); + const float fogTableMode = CxbxFogInfo.x; + const float fogDensity = CxbxFogInfo.y; + const float fogStart = CxbxFogInfo.z; + const float fogEnd = CxbxFogInfo.w; + + const float FOG_TABLE_NONE = 0; + const float FOG_TABLE_EXP = 1; + const float FOG_TABLE_EXP2 = 2; + const float FOG_TABLE_LINEAR = 3; + + float fogFactor; + if(fogTableMode == FOG_TABLE_NONE) + fogFactor = fogDepth; + if(fogTableMode == FOG_TABLE_EXP) + fogFactor = 1 / exp(fogDepth * fogDensity); /* / 1 / e^(d * density)*/ + if(fogTableMode == FOG_TABLE_EXP2) + fogFactor = 1 / exp(pow(fogDepth * fogDensity, 2)); /* / 1 / e^((d * density)^2)*/ + if(fogTableMode == FOG_TABLE_LINEAR) + fogFactor = (fogEnd - fogDepth) / (fogEnd - fogStart) ; + xOut.oPos = reverseScreenspaceTransform(oPos); xOut.oD0 = saturate(oD0); xOut.oD1 = saturate(oD1); - xOut.oFog = oFog.x; // Note : Xbox clamps fog in pixel shader + xOut.oFog = fogFactor; // Note : Xbox clamps fog in pixel shader -> *NEEDS TESTING* /was oFog.x xOut.oPts = oPts.x; xOut.oB0 = saturate(oB0); xOut.oB1 = saturate(oB1); diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index a65d91eb4..982ce4861 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -7650,6 +7650,14 @@ void CxbxUpdateHostVertexShaderConstants() // Need for Speed: Hot Pursuit 2 (car select) CxbxUpdateHostViewPortOffsetAndScaleConstants(); } + + // Placed this here until we find a better place + const uint32_t fogTableMode = XboxRenderStates.GetXboxRenderState(xbox::_X_D3DRENDERSTATETYPE::X_D3DRS_FOGTABLEMODE); + const float fogDensity = XboxRenderStates.GetXboxRenderStateAsFloat(xbox::_X_D3DRENDERSTATETYPE::X_D3DRS_FOGDENSITY); + const float fogStart = XboxRenderStates.GetXboxRenderStateAsFloat(xbox::_X_D3DRENDERSTATETYPE::X_D3DRS_FOGSTART); + const float fogEnd = XboxRenderStates.GetXboxRenderStateAsFloat(xbox::_X_D3DRENDERSTATETYPE::X_D3DRS_FOGEND); + float fogStuff[4] = { (float)fogTableMode, fogDensity, fogStart, fogEnd }; + g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_FOGINFO, fogStuff, 1); } void CxbxUpdateHostViewport() { diff --git a/src/core/hle/D3D8/XbD3D8Types.h b/src/core/hle/D3D8/XbD3D8Types.h index c5d5dc88d..33040d5c0 100644 --- a/src/core/hle/D3D8/XbD3D8Types.h +++ b/src/core/hle/D3D8/XbD3D8Types.h @@ -1039,10 +1039,8 @@ typedef DWORD X_VERTEXSHADERCONSTANTMODE; // TODO co-locate shader workaround constants with shader code #define CXBX_D3DVS_CONSTREG_VREGDEFAULTS_BASE (X_D3DVS_CONSTREG_COUNT) #define CXBX_D3DVS_CONSTREG_VREGDEFAULTS_SIZE 16 - #define CXBX_D3DVS_CONSTREG_VREGDEFAULTS_FLAG_BASE (CXBX_D3DVS_CONSTREG_VREGDEFAULTS_BASE + CXBX_D3DVS_CONSTREG_VREGDEFAULTS_SIZE) #define CXBX_D3DVS_CONSTREG_VREGDEFAULTS_FLAG_SIZE 4 - #define CXBX_D3DVS_SCREENSPACE_SCALE_BASE (CXBX_D3DVS_CONSTREG_VREGDEFAULTS_FLAG_BASE + CXBX_D3DVS_CONSTREG_VREGDEFAULTS_FLAG_SIZE) #define CXBX_D3DVS_NORMALIZE_SCALE_SIZE 1 @@ -1052,6 +1050,8 @@ typedef DWORD X_VERTEXSHADERCONSTANTMODE; #define CXBX_D3DVS_TEXTURES_SCALE_BASE (CXBX_D3DVS_SCREENSPACE_OFFSET_BASE + CXBX_D3DVS_NORMALIZE_OFFSET_SIZE) #define CXBX_D3DVS_TEXTURES_SCALE_SIZE 4 +#define CXBX_D3DVS_CONSTREG_FOGINFO (CXBX_D3DVS_TEXTURES_SCALE_BASE + CXBX_D3DVS_TEXTURES_SCALE_SIZE) + #define X_D3DSCM_RESERVED_CONSTANT_SCALE_CORRECTED (X_D3DSCM_RESERVED_CONSTANT_SCALE + X_D3DSCM_CORRECTION) #define X_D3DSCM_RESERVED_CONSTANT_OFFSET_CORRECTED (X_D3DSCM_RESERVED_CONSTANT_OFFSET + X_D3DSCM_CORRECTION)