Fix front/back colour usage

This commit is contained in:
Anthony 2021-02-04 18:53:14 +13:00 committed by PatrickvL
parent 55f3c60ef2
commit 7745515588
3 changed files with 26 additions and 5 deletions

View File

@ -53,6 +53,7 @@ uniform const float4 FC0 : register(c16); // Note : Maps to PSH_XBOX_CONSTANT_FC
uniform const float4 FC1 : register(c17); // Note : Maps to PSH_XBOX_CONSTANT_FC1, must be generated as argument to xfc instead of C1
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
#define CM_LT(c) if(c < 0) clip(-1); // = PS_COMPAREMODE_[RSTQ]_LT
@ -335,11 +336,14 @@ PS_OUTPUT main(const PS_INPUT xIn)
float3 s; // Actual texture coordinate sampling coordinates (temporary)
float4 v; // Texture value (temporary)
// Determine if this is a front face or backface
bool isFrontFace = (xIn.iFF * FRONTFACE_FACTOR) >= 0;
// Initialize variables
r0 = r1 = black; // Note : r0.a/r1.a will be overwritten by t0.a/t1.a (opaque_black will be retained for PS_TEXTUREMODES_NONE)
// Note : VFACE/FrontFace has been unreliable, investigate again if some test-case shows bland colors
v0 = xIn.iFF > 0 ? xIn.iD0 : xIn.iB0; // Diffuse front/back
v1 = xIn.iFF > 0 ? xIn.iD1 : xIn.iB1; // Specular front/back
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
// Xbox shader program

View File

@ -1504,8 +1504,8 @@ const RenderStateInfo DxbxRenderStateInfo[1+xbox::X_D3DRS_DONOTCULLUNCOMPRESSED]
{ "D3DRS_VERTEXBLEND" /*= 137*/, 3424, xtD3DVERTEXBLENDFLAGS, NV2A_SKIN_MODE, D3DRS_VERTEXBLEND },
{ "D3DRS_FOGCOLOR" /*= 138*/, 3424, xtD3DCOLOR, NV2A_FOG_COLOR, D3DRS_FOGCOLOR }, // SwapRgb
{ "D3DRS_FILLMODE" /*= 139*/, 3424, xtD3DFILLMODE, NV2A_POLYGON_MODE_FRONT, D3DRS_FILLMODE },
{ "D3DRS_BACKFILLMODE" /*= 140*/, 3424, xtD3DFILLMODE, 0 }, // nsp.
{ "D3DRS_TWOSIDEDLIGHTING" /*= 141*/, 3424, xtBOOL, NV2A_POLYGON_MODE_BACK }, // nsp.
{ "D3DRS_BACKFILLMODE" /*= 140*/, 3424, xtD3DFILLMODE, NV2A_POLYGON_MODE_BACK }, // nsp.
{ "D3DRS_TWOSIDEDLIGHTING" /*= 141*/, 3424, xtBOOL, 0 }, // nsp. // FIXME map from NV2A_LIGHT_MODEL
{ "D3DRS_NORMALIZENORMALS" /*= 142*/, 3424, xtBOOL, NV2A_NORMALIZE_ENABLE, D3DRS_NORMALIZENORMALS },
{ "D3DRS_ZENABLE" /*= 143*/, 3424, xtBOOL, NV2A_DEPTH_TEST_ENABLE, D3DRS_ZENABLE }, // D3DZBUFFERTYPE?
{ "D3DRS_STENCILENABLE" /*= 144*/, 3424, xtBOOL, NV2A_STENCIL_ENABLE, D3DRS_STENCILENABLE },

View File

@ -630,8 +630,10 @@ constexpr int PSH_XBOX_CONSTANT_FOG = PSH_XBOX_CONSTANT_FC1 + 1; // = 18
constexpr int PSH_XBOX_CONSTANT_BEM = PSH_XBOX_CONSTANT_FOG + 1; // = 19..22
// Bump map Luminance registers
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_LUM + 4; // = 27
constexpr int PSH_XBOX_CONSTANT_MAX = PSH_XBOX_CONSTANT_FRONTFACE_FACTOR + 1; // = 28
void DxbxUpdateActivePixelShader() // NOPATCH
{
@ -768,6 +770,21 @@ void DxbxUpdateActivePixelShader() // NOPATCH
}
#endif
// Control whether to use front or back diffuse/specular colours
// This factor should be multipled with VFACE
// Test cases:
// Amped (snowboard trails should use front colours, but use both CW and CCW winding)
// TwoSidedLighting sample
float frontfaceFactor = 0; // 0 == always use the front colours
if (XboxRenderStates.GetXboxRenderState(xbox::X_D3DRS_TWOSIDEDLIGHTING)) {
LOG_TEST_CASE("Two sided lighting");
// VFACE is positive for clockwise faces
// If Xbox designates counter-clockwise as front-facing, we invert VFACE
auto cwFrontface = XboxRenderStates.GetXboxRenderState(xbox::X_D3DRS_FRONTFACE) == 0x900; // clockwise;
frontfaceFactor = cwFrontface ? 1 : -1;
}
fColor[PSH_XBOX_CONSTANT_FRONTFACE_FACTOR].r = frontfaceFactor;
// 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: