add FF fog move to Pixelshader

This commit is contained in:
medievil1 2024-01-20 15:14:02 -05:00
parent 0e25897f77
commit a03d50df56
4 changed files with 56 additions and 20 deletions

View File

@ -174,6 +174,14 @@ TextureArgs ExecuteTextureStage(
// Sample the texture
float4 t;
int type = TextureSampleType[i];
// Divide texcoords by w when sampling
// Which corresponds to D3DTTFF_PROJECTED behaviour
// The w component can be set by titles in vertex shaders
// without using texture transform flags
// Test case: DoA 3 reflections on 'Ice Stage'
//float4 coords;// = TexCoords[i].xyzw / TexCoords[i].w;
if (TexCoords[i].w > 1.0)
TexCoords[i].xyzw = TexCoords[i].xyzw / TexCoords[i].w;
if (type == SAMPLE_NONE)
t = 1; // Test case JSRF
else if (type == SAMPLE_2D)
@ -237,8 +245,22 @@ TextureArgs ExecuteTextureStage(
float4 main(const PS_INPUT input) : COLOR {
// Calculate the fog factor
// Some of this might be better done in the pixel shader?
float fogFactor;
if (state.FogTableMode == FOG_TABLE_NONE)
fogFactor = input.iFog;
if (state.FogTableMode == FOG_TABLE_EXP)
fogFactor = 1 / exp(input.iFog * state.FogDensity); // 1 / e^(d * density)
if (state.FogTableMode == FOG_TABLE_EXP2)
fogFactor = 1 / exp(pow(input.iFog * state.FogDensity, 2)); // 1 / e^((d * density)^2)
if (state.FogTableMode == FOG_TABLE_LINEAR)
fogFactor = (state.FogEnd - input.iFog) / (state.FogEnd - state.FogStart); // (end - d) / (end - start)
if (state.FogEnable == 0)
fogFactor = 1;
TexCoords = input.iT;
// Each stage is passed and returns
// a set of texture arguments
// And will usually update the CURRENT value
@ -284,7 +306,7 @@ float4 main(const PS_INPUT input) : COLOR {
// Add fog if enabled
if (state.FogEnable) {
ctx.CURRENT.rgb = lerp(state.FogColor.rgb, ctx.CURRENT.rgb, clamp(input.iFog, 0, 1));
ctx.CURRENT.rgb = lerp(state.FogColor.rgb, ctx.CURRENT.rgb, clamp(fogFactor, 0, 1));
}
// Add specular if enabled

View File

@ -63,10 +63,16 @@ namespace FixedFunctionPixelShader {
const float X_D3DTA_COMPLEMENT = 0x00000010; // take 1.0 - x (read modifier)
const float X_D3DTA_ALPHAREPLICATE = 0x00000020; // replicate alpha to color components (read modifier)
const int SAMPLE_NONE = 0;
const int SAMPLE_2D = 1;
const int SAMPLE_3D = 2;
const int SAMPLE_CUBE = 3;
const int SAMPLE_NONE = 0;
const int SAMPLE_2D = 1;
const int SAMPLE_3D = 2;
const int SAMPLE_CUBE = 3;
// https://docs.microsoft.com/en-us/windows/win32/direct3d9/fog-formulas
const float FOG_TABLE_NONE = 0;
const float FOG_TABLE_EXP = 1;
const float FOG_TABLE_EXP2 = 2;
const float FOG_TABLE_LINEAR = 3;
// This state is passed to the shader
struct PsTextureStageState {
@ -121,11 +127,15 @@ namespace FixedFunctionPixelShader {
struct FixedFunctionPixelShaderState {
alignas(16) arr(stages, PsTextureStageState, 4);
alignas(16) float4 TextureFactor;
alignas(16) float SpecularEnable;
alignas(16) float FogEnable;
alignas(16) float3 FogColor;
};
alignas(16) float4 TextureFactor;
alignas(16) float SpecularEnable;
alignas(16) float FogEnable;
alignas(16) float3 FogColor;
alignas(16) float FogTableMode;
alignas(16) float FogDensity;
alignas(16) float FogStart;
alignas(16) float FogEnd;
};
#ifdef __cplusplus
} // FixedFunctionPixelShader namespace
#endif

View File

@ -339,9 +339,9 @@ float4 DoTexCoord(const uint stage, const VS_INPUT xIn)
// TODO move alongside the texture transformation when it stops angering the HLSL compiler
const float componentCount = state.TexCoordComponentCount[texCoordIndex];
if (componentCount == 1)
texCoord.yzw = float3(1, 0, 0);
texCoord.yzw = float3(0, 0, 1);
if (componentCount == 2)
texCoord.zw = float2(1, 0);
texCoord.zw = float2(0, 1);
if (componentCount == 3)
texCoord.w = 1;
} // Generate texture coordinates
@ -378,14 +378,15 @@ float4 DoTexCoord(const uint stage, const VS_INPUT xIn)
// Test case: ProjectedTexture sample, which uses 3 coordinates
// We'll need to implement the divide when D3D stops handling it for us?
// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dtexturetransformflags
// padding makes no differences in LLE. LLE works with ProjectedTexture sample without padding, but to be devided by w is necessary.
if (projected)
{
if (countFlag == 1)
texCoord.yzw = texCoord.x;
if (countFlag == 2)
texCoord.zw = texCoord.y;
if (countFlag == 3)
texCoord.w = texCoord.z;
//if (countFlag == 1)
//texCoord.yz = texCoord.x;
//if (countFlag == 2)
//texCoord.z = texCoord.y;
//texCoord.xyzw = texCoord.xyzw / texCoord.w;
}
return texCoord;

View File

@ -973,7 +973,10 @@ void UpdateFixedFunctionPixelShaderState()
ffPsState.SpecularEnable = XboxRenderStates.GetXboxRenderState(xbox::X_D3DRS_SPECULARENABLE);
ffPsState.FogEnable = XboxRenderStates.GetXboxRenderState(xbox::X_D3DRS_FOGENABLE);
ffPsState.FogColor = (D3DXVECTOR3)((D3DXCOLOR)XboxRenderStates.GetXboxRenderState(xbox::X_D3DRS_FOGCOLOR));
ffPsState.FogTableMode = XboxRenderStates.GetXboxRenderState(xbox::_X_D3DRENDERSTATETYPE::X_D3DRS_FOGTABLEMODE);
ffPsState.FogDensity = XboxRenderStates.GetXboxRenderStateAsFloat(xbox::_X_D3DRENDERSTATETYPE::X_D3DRS_FOGDENSITY);
ffPsState.FogStart = XboxRenderStates.GetXboxRenderStateAsFloat(xbox::_X_D3DRENDERSTATETYPE::X_D3DRS_FOGSTART);
ffPsState.FogEnd = XboxRenderStates.GetXboxRenderStateAsFloat(xbox::_X_D3DRENDERSTATETYPE::X_D3DRS_FOGEND);
// Texture state
for (int i = 0; i < xbox::X_D3DTS_STAGECOUNT; i++) {