1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Use noperspective shade color only for triangles with screen-space coordinates.

noperspective works incorrect for polygons, which are partially out of view.

Fixed #2240 SM64 strange green textures
This commit is contained in:
Sergey Lipskiy 2020-05-04 19:17:23 +07:00
parent d494806186
commit 03b404bd4e
5 changed files with 97 additions and 53 deletions

View File

@ -296,11 +296,12 @@ public:
"OUT highp vec2 vTexCoord1; \n"
"OUT mediump vec2 vLodTexCoord; \n"
"OUT lowp float vNumLights; \n"
;
"OUT lowp vec4 vShadeColor; \n"
;
if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective OUT lowp vec4 vShadeColor; \n";
m_part += "noperspective OUT lowp vec4 vShadeColorNoperspective;\n";
else
m_part += "OUT lowp vec4 vShadeColor; \n";
m_part += "OUT lowp vec4 vShadeColorNoperspective; \n";
m_part +=
"mediump vec2 calcTexCoord(in vec2 texCoord, in int idx) \n"
"{ \n"
@ -316,6 +317,7 @@ public:
"{ \n"
" gl_Position = aPosition; \n"
" vShadeColor = aColor; \n"
" vShadeColorNoperspective = aColor; \n"
" vec2 texCoord = aTexCoord; \n"
" texCoord *= uTexScale; \n"
" if (uTexturePersp == 0 && aModify[2] == 0.0) texCoord *= 0.5;\n"
@ -366,17 +368,19 @@ public:
"uniform mediump vec2 uScreenCoordsScale; \n"
" \n"
"OUT lowp float vNumLights; \n"
;
"OUT lowp vec4 vShadeColor; \n"
;
if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective OUT lowp vec4 vShadeColor; \n";
m_part += "noperspective OUT lowp vec4 vShadeColorNoperspective;\n";
else
m_part += "OUT lowp vec4 vShadeColor; \n";
m_part += "OUT lowp vec4 vShadeColorNoperspective; \n";
m_part +=
" \n"
"void main() \n"
"{ \n"
" gl_Position = aPosition; \n"
" vShadeColor = aColor; \n"
" vShadeColorNoperspective = aColor; \n"
" vNumLights = aNumLights; \n"
" if (aModify != vec4(0.0)) { \n"
" if ((aModify[0]) != 0.0) { \n"
@ -417,17 +421,19 @@ public:
" \n"
"OUT highp vec2 vTexCoord0; \n"
"OUT highp vec2 vTexCoord1; \n"
;
"OUT lowp vec4 vShadeColor; \n"
;
if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective OUT lowp vec4 vShadeColor; \n";
m_part += "noperspective OUT lowp vec4 vShadeColorNoperspective;\n";
else
m_part += "OUT lowp vec4 vShadeColor; \n";
m_part += "OUT lowp vec4 vShadeColorNoperspective; \n";
m_part +=
"uniform lowp vec4 uRectColor; \n"
"void main() \n"
"{ \n"
" gl_Position = aRectPosition; \n"
" vShadeColor = uRectColor; \n"
" vShadeColorNoperspective = uRectColor; \n"
" vTexCoord0 = aTexCoord0; \n"
" vTexCoord1 = aTexCoord1; \n"
;
@ -442,17 +448,19 @@ public:
m_part =
"IN highp vec4 aRectPosition; \n"
" \n"
"OUT lowp vec4 vShadeColor; \n"
;
if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective OUT lowp vec4 vShadeColor; \n";
m_part += "noperspective OUT lowp vec4 vShadeColorNoperspective;\n";
else
m_part += "OUT lowp vec4 vShadeColor; \n";
m_part += "OUT lowp vec4 vShadeColorNoperspective; \n";
m_part +=
"uniform lowp vec4 uRectColor; \n"
"void main() \n"
"{ \n"
" gl_Position = aRectPosition; \n"
" vShadeColor = uRectColor; \n"
" vShadeColorNoperspective = uRectColor; \n"
;
}
};
@ -856,12 +864,16 @@ public:
"uniform lowp vec2 uTexMirror1; \n"
"uniform highp vec2 uTexScale0; \n"
"uniform highp vec2 uTexScale1; \n"
"uniform lowp int uFogUsage; \n"
"uniform lowp int uScreenSpaceTriangle; \n"
"highp vec2 texCoord0; \n"
"highp vec2 texCoord1; \n"
;
;
if (config.generalEmulation.enableLegacyBlending == 0) {
if (config.generalEmulation.enableLegacyBlending != 0) {
m_part +=
"uniform lowp int uFogUsage; \n"
;
} else {
m_part +=
"uniform lowp ivec4 uBlendMux1; \n"
"uniform lowp int uForceBlendCycle1;\n"
@ -896,23 +908,24 @@ public:
}
if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective IN lowp vec4 vShadeColor; \n";
m_part += "noperspective IN lowp vec4 vShadeColorNoperspective; \n";
else
m_part += "IN lowp vec4 vShadeColor; \n";
m_part += "IN lowp vec4 vShadeColorNoperspective; \n";
m_part +=
"IN highp vec2 vTexCoord0;\n"
"IN highp vec2 vTexCoord1;\n"
"IN mediump vec2 vLodTexCoord;\n"
"IN lowp float vNumLights; \n"
;
"IN lowp vec4 vShadeColor; \n"
"IN highp vec2 vTexCoord0; \n"
"IN highp vec2 vTexCoord1; \n"
"IN mediump vec2 vLodTexCoord; \n"
"IN lowp float vNumLights; \n"
;
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast && _glinfo.ext_fetch) {
m_part +=
"layout(location = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 1) inout highp vec4 depthZ; \n"
"layout(location = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 1) inout highp vec4 depthZ; \n"
"layout(location = 2) inout highp vec4 depthDeltaZ; \n"
;
;
} else {
m_part +=
"OUT lowp vec4 fragColor; \n"
@ -946,17 +959,18 @@ public:
"uniform lowp int uDepthSource; \n"
"uniform highp float uPrimDepth; \n"
"uniform mediump vec2 uScreenScale; \n"
;
"uniform lowp int uScreenSpaceTriangle; \n"
;
if (config.generalEmulation.enableLegacyBlending != 0) {
m_part +=
"uniform lowp int uFogUsage; \n"
;
;
} else {
m_part +=
"uniform lowp ivec4 uBlendMux1; \n"
"uniform lowp int uForceBlendCycle1;\n"
;
;
}
if (!_glinfo.isGLES2) {
@ -979,18 +993,21 @@ public:
}
if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective IN lowp vec4 vShadeColor; \n";
m_part += "noperspective IN lowp vec4 vShadeColorNoperspective; \n";
else
m_part += "IN lowp vec4 vShadeColor; \n";
m_part += "IN lowp vec4 vShadeColorNoperspective; \n";
m_part += "IN lowp float vNumLights; \n";
m_part +=
"IN lowp vec4 vShadeColor; \n"
"IN lowp float vNumLights; \n"
;
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast && _glinfo.ext_fetch) {
m_part +=
"layout(location = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 1) inout highp vec4 depthZ; \n"
"layout(location = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 1) inout highp vec4 depthZ; \n"
"layout(location = 2) inout highp vec4 depthDeltaZ; \n"
;
;
} else {
m_part +=
"OUT lowp vec4 fragColor; \n"
@ -1387,7 +1404,8 @@ public:
" lowp vec4 vec_color; \n"
" lowp float alpha1; \n"
" lowp vec3 color1, input_color; \n"
;
" lowp vec4 shadeColor = uScreenSpaceTriangle == 0 ? vShadeColor : vShadeColorNoperspective; \n"
;
m_part += "#define WRAP(x, low, high) mod((x)-(low), (high)-(low)) + (low) \n"; // Return wrapped value of x in interval [low, high)
// m_part += "#define WRAP(x, low, high) (x) - ((high)-(low)) * floor(((x)-(low))/((high)-(low))) \n"; // Perhaps more compatible?
// m_part += "#define WRAP(x, low, high) (x) + ((high)-(low)) * (1.0-step(low,x)) - ((high)-(low)) * step(high,x) \n"; // Step based version. Only wraps correctly if input is in the range [low-(high-low), high + (high-low)). Similar to old code.
@ -1413,6 +1431,7 @@ public:
" lowp vec4 vec_color, combined_color; \n"
" lowp float alpha1, alpha2; \n"
" lowp vec3 color1, color2, input_color; \n"
" lowp vec4 shadeColor = uScreenSpaceTriangle == 0 ? vShadeColor : vShadeColorNoperspective; \n"
;
m_part += "#define WRAP(x, low, high) mod((x)-(low), (high)-(low)) + (low) \n"; // Return wrapped value of x in interval [low, high)
// m_part += "#define WRAP(x, low, high) (x) - ((high)-(low)) * floor(((x)-(low))/((high)-(low))) \n"; // Perhaps more compatible?
@ -1428,7 +1447,7 @@ public:
if (config.generalEmulation.enableLegacyBlending == 0) {
m_part =
" lowp mat4 muxPM = mat4(vec4(0.0), vec4(0.0), uBlendColor, uFogColor); \n"
" lowp vec4 muxA = vec4(0.0, uFogColor.a, vShadeColor.a, 0.0); \n"
" lowp vec4 muxA = vec4(0.0, uFogColor.a, shadeColor.a, 0.0); \n"
" lowp vec4 muxB = vec4(0.0, 1.0, 1.0, 0.0); \n"
;
}
@ -2633,11 +2652,11 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
}
if (bUseHWLight)
ssShader << " calc_light(vNumLights, vShadeColor.rgb, input_color);" << std::endl;
ssShader << " calc_light(vNumLights, shadeColor.rgb, input_color);" << std::endl;
else
ssShader << " input_color = vShadeColor.rgb;" << std::endl;
ssShader << " input_color = shadeColor.rgb;" << std::endl;
ssShader << " vec_color = vec4(input_color, vShadeColor.a);" << std::endl;
ssShader << " vec_color = vec4(input_color, shadeColor.a);" << std::endl;
ssShader << strCombiner << std::endl;
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable)

View File

@ -198,6 +198,23 @@ private:
iUniform uMSAASamples;
};
class UScreenSpaceTriangleInfo : public UniformGroup
{
public:
UScreenSpaceTriangleInfo(GLuint _program) {
LocateUniform(uScreenSpaceTriangle);
}
void update(bool _force) override
{
uScreenSpaceTriangle.set(
(dwnd().getDrawer().getDrawingState() == DrawingState::ScreenSpaceTriangle) ? 1 : 0, _force);
}
private:
iUniform uScreenSpaceTriangle;
};
class UFrameBufferInfo : public UniformGroup
{
public:
@ -1059,6 +1076,7 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
UniformGroups & _uniforms)
{
_uniforms.emplace_back(new UNoiseTex(_program));
_uniforms.emplace_back(new UScreenSpaceTriangleInfo(_program));
if (!m_glInfo.isGLES2) {
_uniforms.emplace_back(new UDepthTex(_program));

View File

@ -727,17 +727,17 @@ void GraphicsDrawer::_updateStates(DrawingState _drawingState) const
}
}
void GraphicsDrawer::_prepareDrawTriangle()
void GraphicsDrawer::_prepareDrawTriangle(DrawingState _drawingState)
{
m_texrectDrawer.draw();
if ((m_modifyVertices & MODIFY_XY) != 0)
gSP.changed &= ~CHANGED_VIEWPORT;
if (gSP.changed || gDP.changed)
_updateStates(DrawingState::Triangle);
m_drawingState = _drawingState;
m_drawingState = DrawingState::Triangle;
if (gSP.changed || gDP.changed)
_updateStates(_drawingState);
bool bFlatColors = false;
if (!RSP.LLE && (gSP.geometryMode & G_LIGHTING) == 0) {
@ -764,7 +764,7 @@ void GraphicsDrawer::drawTriangles()
return;
}
_prepareDrawTriangle();
_prepareDrawTriangle(DrawingState::Triangle);
Context::DrawTriangleParameters triParams;
triParams.mode = drawmode::TRIANGLES;
@ -815,7 +815,7 @@ void GraphicsDrawer::drawScreenSpaceTriangle(u32 _numVtx, graphics::DrawModePara
m_modifyVertices = MODIFY_ALL;
gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode
_prepareDrawTriangle();
_prepareDrawTriangle(DrawingState::ScreenSpaceTriangle);
Context::DrawTriangleParameters triParams;
triParams.mode = _mode;
@ -846,7 +846,7 @@ void GraphicsDrawer::drawDMATriangles(u32 _numVtx)
{
if (_numVtx == 0 || !_canDraw())
return;
_prepareDrawTriangle();
_prepareDrawTriangle(DrawingState::Triangle);
Context::DrawTriangleParameters triParams;

View File

@ -22,11 +22,12 @@ struct FrameBuffer;
enum class DrawingState
{
Non = 0,
Line = 1,
Triangle = 2,
Rect = 3,
TexRect = 4,
Non,
Line,
Triangle,
ScreenSpaceTriangle,
Rect,
TexRect
};
struct RectVertex
@ -181,7 +182,7 @@ private:
void _updateDepthCompare() const;
void _updateTextures() const;
void _updateStates(DrawingState _drawingState) const;
void _prepareDrawTriangle();
void _prepareDrawTriangle(DrawingState _drawingState);
bool _canDraw() const;
void _drawThickLine(int _v0, int _v1, float _width);

View File

@ -1318,8 +1318,14 @@ void TextureCache::activateTexture(u32 _t, CachedTexture *_pTexture)
params.wrapT = _pTexture->clampT ? textureParameters::WRAP_CLAMP_TO_EDGE :
_pTexture->mirrorT ? textureParameters::WRAP_MIRRORED_REPEAT : textureParameters::WRAP_REPEAT;
if (dwnd().getDrawer().getDrawingState() == DrawingState::Triangle && config.texture.maxAnisotropyF > 0.0f)
params.maxAnisotropy = Parameter(config.texture.maxAnisotropyF);
if (config.texture.maxAnisotropyF > 0.0f) {
switch (dwnd().getDrawer().getDrawingState()) {
case DrawingState::Triangle:
case DrawingState::ScreenSpaceTriangle:
params.maxAnisotropy = Parameter(config.texture.maxAnisotropyF);
break;
}
}
}
gfxContext.setTextureParameters(params);