From 399baccadb603690336f41a4aa6db969b2bc42c8 Mon Sep 17 00:00:00 2001 From: medievil1 <38597905+medievil1@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:15:41 -0500 Subject: [PATCH] fog stuff fix no fog issue which was incorrectly passing data into iFog instead of 1 when fog was disabled testing a move to pixel shader adjust passthrough template for move to pixel shader remove printf --- .../Direct3D9/CxbxPixelShaderTemplate.hlsl | 31 +++++++++++++++++-- .../CxbxVertexShaderPassthrough.hlsl | 25 ++------------- .../Direct3D9/CxbxVertexShaderTemplate.hlsl | 23 ++------------ src/core/hle/D3D8/Direct3D9/Direct3D9.cpp | 2 +- .../Direct3D9/FixedFunctionPixelShader.hlsl | 5 +-- .../Direct3D9/FixedFunctionVertexShader.hlsl | 14 ++------- src/core/hle/D3D8/XbPixelShader.cpp | 17 ++++++++-- 7 files changed, 54 insertions(+), 63 deletions(-) diff --git a/src/core/hle/D3D8/Direct3D9/CxbxPixelShaderTemplate.hlsl b/src/core/hle/D3D8/Direct3D9/CxbxPixelShaderTemplate.hlsl index f4ef3864e..198cca771 100644 --- a/src/core/hle/D3D8/Direct3D9/CxbxPixelShaderTemplate.hlsl +++ b/src/core/hle/D3D8/Direct3D9/CxbxPixelShaderTemplate.hlsl @@ -51,7 +51,8 @@ uniform const float4 FC1 : register(c17); // Note : Maps to PSH_XBOX_CONSTANT_FC uniform const float4 BEM[4] : register(c19); // Note : PSH_XBOX_CONSTANT_BEM for 4 texture stages uniform const float4 LUM[4] : register(c23); // Note : PSH_XBOX_CONSTANT_LUM for 4 texture stages uniform const float FRONTFACE_FACTOR : register(c27); // Note : PSH_XBOX_CONSTANT_LUM for 4 texture stages - +uniform const float4 FOGFACTOR : register(c28); +uniform float FOGENABLE : register(c29); #define CM_LT(c) if(c < 0) clip(-1); // = PS_COMPAREMODE_[RSTQ]_LT #define CM_GE(c) if(c >= 0) clip(-1); // = PS_COMPAREMODE_[RSTQ]_GE @@ -336,6 +337,32 @@ float3 DoBumpEnv(const float4 TexCoord, const float4 BumpEnvMat, const float4 sr PS_OUTPUT main(const PS_INPUT xIn) { + float fogEnable = xIn.iFog.x; + if (FOGENABLE == 0) + fogEnable = 1; + const float fogDepth = fogEnable; // Don't abs this value! Test-case : DolphinClassic xdk sampl + const int fogTableMode = FOGFACTOR.x; + const float fogDensity = FOGFACTOR.y; + const float fogStart = FOGFACTOR.z; + const float fogEnd = FOGFACTOR.w; + + const int FOG_TABLE_NONE = 0; + const int FOG_TABLE_EXP = 1; + const int FOG_TABLE_EXP2 = 2; + const int 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); + // Local constants const float4 zero = 0; const float4 half = 0.5; // = s_negbias(zero) @@ -369,7 +396,7 @@ PS_OUTPUT main(const PS_INPUT xIn) // Note : VFACE/FrontFace has been unreliable, investigate again if some test-case shows bland colors v0 = isFrontFace ? xIn.iD0 : xIn.iB0; // Diffuse front/back v1 = isFrontFace ? xIn.iD1 : xIn.iB1; // Specular front/back - fog = float4(c_fog.rgb, xIn.iFog); // color from PSH_XBOX_CONSTANT_FOG, alpha from vertex shader output / pixel shader input + fog = float4(c_fog.rgb, fogFactor); // color from PSH_XBOX_CONSTANT_FOG, alpha from vertex shader output / pixel shader input // Xbox shader program will be inserted here // diff --git a/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderPassthrough.hlsl b/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderPassthrough.hlsl index 9938662a5..ea1b7371e 100644 --- a/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderPassthrough.hlsl +++ b/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderPassthrough.hlsl @@ -91,33 +91,12 @@ VS_OUTPUT main(const VS_INPUT xIn) // Copy variables to output struct VS_OUTPUT xOut; - // Fogging - // TODO: deduplicate - 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 = fogFactor; // Note : Xbox clamps fog in pixel shader + xOut.oFog = oFog.x; // Note : Xbox clamps fog in pixel shader xOut.oPts = oPts.x; xOut.oB0 = saturate(oB0); xOut.oB1 = saturate(oB1); diff --git a/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl b/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl index ecb7307df..2e0a98702 100644 --- a/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl +++ b/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl @@ -332,31 +332,12 @@ VS_OUTPUT main(const VS_INPUT xIn) // Fogging // TODO deduplicate - const float fogDepth = oFog.x; // Don't abs this value! Test-case : DolphinClassic xdk sample - 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 = fogFactor; // Note : Xbox clamps fog in pixel shader -> *NEEDS TESTING* /was oFog.x + xOut.oFog = oFog.x; // 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 34a55e8b6..799463dda 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -7541,7 +7541,7 @@ void CxbxUpdateHostVertexShaderConstants() 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 }; + float fogStuff[4] = {fogTableMode, fogDensity, fogStart, fogEnd}; g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_FOGINFO, fogStuff, 1); } diff --git a/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsl b/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsl index fbe40b1e0..8e58c5019 100644 --- a/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsl +++ b/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsl @@ -1,8 +1,8 @@ #include "FixedFunctionPixelShader.hlsli" - +#include "FixedFunctionVertexShaderState.hlsli" uniform FixedFunctionPixelShaderState state : register(c0); sampler samplers[4] : register(s0); - +uniform FixedFunctionVertexShaderState state : register(c0); struct PS_INPUT // Declared identical to vertex shader output (see VS_OUTPUT) { float2 iPos : VPOS; // Screen space x,y pixel location @@ -239,6 +239,7 @@ float4 main(const PS_INPUT input) : COLOR { TexCoords = input.iT; + // Each stage is passed and returns // a set of texture arguments // And will usually update the CURRENT value diff --git a/src/core/hle/D3D8/Direct3D9/FixedFunctionVertexShader.hlsl b/src/core/hle/D3D8/Direct3D9/FixedFunctionVertexShader.hlsl index 5ae1bdb88..27bfa908c 100644 --- a/src/core/hle/D3D8/Direct3D9/FixedFunctionVertexShader.hlsl +++ b/src/core/hle/D3D8/Direct3D9/FixedFunctionVertexShader.hlsl @@ -289,19 +289,9 @@ float DoFog(const VS_INPUT xIn) if (state.Fog.DepthMode == FixedFunctionVertexShader::FOG_DEPTH_W) fogDepth = Projection.Position.w; - // Calculate the fog factor - // Some of this might be better done in the pixel shader? - float fogFactor; - if (state.Fog.TableMode == FixedFunctionVertexShader::FOG_TABLE_NONE) - fogFactor = fogDepth; - if (state.Fog.TableMode == FixedFunctionVertexShader::FOG_TABLE_EXP) - fogFactor = 1 / exp(fogDepth * state.Fog.Density); // 1 / e^(d * density) - if (state.Fog.TableMode == FixedFunctionVertexShader::FOG_TABLE_EXP2) - fogFactor = 1 / exp(pow(fogDepth * state.Fog.Density, 2)); // 1 / e^((d * density)^2) - if (state.Fog.TableMode == FixedFunctionVertexShader::FOG_TABLE_LINEAR) - fogFactor = (state.Fog.End - fogDepth) / (state.Fog.End - state.Fog.Start); // (end - d) / (end - start) + - return fogFactor; + return fogDepth; } float4 DoTexCoord(const uint stage, const VS_INPUT xIn) diff --git a/src/core/hle/D3D8/XbPixelShader.cpp b/src/core/hle/D3D8/XbPixelShader.cpp index 927a446e8..67f695f2b 100644 --- a/src/core/hle/D3D8/XbPixelShader.cpp +++ b/src/core/hle/D3D8/XbPixelShader.cpp @@ -662,7 +662,9 @@ constexpr int PSH_XBOX_CONSTANT_LUM = PSH_XBOX_CONSTANT_BEM + 4; // = 23..26 // Which winding order to consider as the front face constexpr int PSH_XBOX_CONSTANT_FRONTFACE_FACTOR = PSH_XBOX_CONSTANT_LUM + 4; // = 27 // This concludes the set of constants that need to be set on host : -constexpr int PSH_XBOX_CONSTANT_MAX = PSH_XBOX_CONSTANT_FRONTFACE_FACTOR + 1; // = 28 +constexpr int CXBX_D3DPS_CONSTREG_FOGINFO = PSH_XBOX_CONSTANT_FRONTFACE_FACTOR + 1; +constexpr int PSH_XBOX_CONSTANT_FOGENABLE = CXBX_D3DPS_CONSTREG_FOGINFO + 1; +constexpr int PSH_XBOX_CONSTANT_MAX = PSH_XBOX_CONSTANT_FOGENABLE + 1; // = 28 std::string_view GetD3DTOPString(int d3dtop) { static constexpr std::string_view opToString[] = { @@ -1164,7 +1166,18 @@ void DxbxUpdateActivePixelShader() // NOPATCH frontfaceFactor = cwFrontface ? 1.0 : -1.0; } fColor[PSH_XBOX_CONSTANT_FRONTFACE_FACTOR].r = frontfaceFactor; - + float fogEnable = XboxRenderStates.GetXboxRenderState(xbox::X_D3DRS_FOGENABLE) > 0; + 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); + + fColor[CXBX_D3DPS_CONSTREG_FOGINFO].r = fogTableMode; + fColor[CXBX_D3DPS_CONSTREG_FOGINFO].g = fogDensity; + fColor[CXBX_D3DPS_CONSTREG_FOGINFO].b = fogStart; + fColor[CXBX_D3DPS_CONSTREG_FOGINFO].a = fogEnd; + fColor[PSH_XBOX_CONSTANT_FOGENABLE].r = fogEnable; + // Assume all constants are in use (this is much easier than tracking them for no other purpose than to skip a few here) // Read the color from the corresponding render state slot : // Set all host constant values using a single call: