1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-07 03:13:49 +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 highp vec2 vTexCoord1; \n"
"OUT mediump vec2 vLodTexCoord; \n" "OUT mediump vec2 vLodTexCoord; \n"
"OUT lowp float vNumLights; \n" "OUT lowp float vNumLights; \n"
"OUT lowp vec4 vShadeColor; \n"
; ;
if (!_glinfo.isGLESX || _glinfo.noPerspective) if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective OUT lowp vec4 vShadeColor; \n"; m_part += "noperspective OUT lowp vec4 vShadeColorNoperspective;\n";
else else
m_part += "OUT lowp vec4 vShadeColor; \n"; m_part += "OUT lowp vec4 vShadeColorNoperspective; \n";
m_part += m_part +=
"mediump vec2 calcTexCoord(in vec2 texCoord, in int idx) \n" "mediump vec2 calcTexCoord(in vec2 texCoord, in int idx) \n"
"{ \n" "{ \n"
@ -316,6 +317,7 @@ public:
"{ \n" "{ \n"
" gl_Position = aPosition; \n" " gl_Position = aPosition; \n"
" vShadeColor = aColor; \n" " vShadeColor = aColor; \n"
" vShadeColorNoperspective = aColor; \n"
" vec2 texCoord = aTexCoord; \n" " vec2 texCoord = aTexCoord; \n"
" texCoord *= uTexScale; \n" " texCoord *= uTexScale; \n"
" if (uTexturePersp == 0 && aModify[2] == 0.0) texCoord *= 0.5;\n" " if (uTexturePersp == 0 && aModify[2] == 0.0) texCoord *= 0.5;\n"
@ -366,17 +368,19 @@ public:
"uniform mediump vec2 uScreenCoordsScale; \n" "uniform mediump vec2 uScreenCoordsScale; \n"
" \n" " \n"
"OUT lowp float vNumLights; \n" "OUT lowp float vNumLights; \n"
"OUT lowp vec4 vShadeColor; \n"
; ;
if (!_glinfo.isGLESX || _glinfo.noPerspective) if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective OUT lowp vec4 vShadeColor; \n"; m_part += "noperspective OUT lowp vec4 vShadeColorNoperspective;\n";
else else
m_part += "OUT lowp vec4 vShadeColor; \n"; m_part += "OUT lowp vec4 vShadeColorNoperspective; \n";
m_part += m_part +=
" \n" " \n"
"void main() \n" "void main() \n"
"{ \n" "{ \n"
" gl_Position = aPosition; \n" " gl_Position = aPosition; \n"
" vShadeColor = aColor; \n" " vShadeColor = aColor; \n"
" vShadeColorNoperspective = aColor; \n"
" vNumLights = aNumLights; \n" " vNumLights = aNumLights; \n"
" if (aModify != vec4(0.0)) { \n" " if (aModify != vec4(0.0)) { \n"
" if ((aModify[0]) != 0.0) { \n" " if ((aModify[0]) != 0.0) { \n"
@ -417,17 +421,19 @@ public:
" \n" " \n"
"OUT highp vec2 vTexCoord0; \n" "OUT highp vec2 vTexCoord0; \n"
"OUT highp vec2 vTexCoord1; \n" "OUT highp vec2 vTexCoord1; \n"
"OUT lowp vec4 vShadeColor; \n"
; ;
if (!_glinfo.isGLESX || _glinfo.noPerspective) if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective OUT lowp vec4 vShadeColor; \n"; m_part += "noperspective OUT lowp vec4 vShadeColorNoperspective;\n";
else else
m_part += "OUT lowp vec4 vShadeColor; \n"; m_part += "OUT lowp vec4 vShadeColorNoperspective; \n";
m_part += m_part +=
"uniform lowp vec4 uRectColor; \n" "uniform lowp vec4 uRectColor; \n"
"void main() \n" "void main() \n"
"{ \n" "{ \n"
" gl_Position = aRectPosition; \n" " gl_Position = aRectPosition; \n"
" vShadeColor = uRectColor; \n" " vShadeColor = uRectColor; \n"
" vShadeColorNoperspective = uRectColor; \n"
" vTexCoord0 = aTexCoord0; \n" " vTexCoord0 = aTexCoord0; \n"
" vTexCoord1 = aTexCoord1; \n" " vTexCoord1 = aTexCoord1; \n"
; ;
@ -442,17 +448,19 @@ public:
m_part = m_part =
"IN highp vec4 aRectPosition; \n" "IN highp vec4 aRectPosition; \n"
" \n" " \n"
"OUT lowp vec4 vShadeColor; \n"
; ;
if (!_glinfo.isGLESX || _glinfo.noPerspective) if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective OUT lowp vec4 vShadeColor; \n"; m_part += "noperspective OUT lowp vec4 vShadeColorNoperspective;\n";
else else
m_part += "OUT lowp vec4 vShadeColor; \n"; m_part += "OUT lowp vec4 vShadeColorNoperspective; \n";
m_part += m_part +=
"uniform lowp vec4 uRectColor; \n" "uniform lowp vec4 uRectColor; \n"
"void main() \n" "void main() \n"
"{ \n" "{ \n"
" gl_Position = aRectPosition; \n" " gl_Position = aRectPosition; \n"
" vShadeColor = uRectColor; \n" " vShadeColor = uRectColor; \n"
" vShadeColorNoperspective = uRectColor; \n"
; ;
} }
}; };
@ -856,12 +864,16 @@ public:
"uniform lowp vec2 uTexMirror1; \n" "uniform lowp vec2 uTexMirror1; \n"
"uniform highp vec2 uTexScale0; \n" "uniform highp vec2 uTexScale0; \n"
"uniform highp vec2 uTexScale1; \n" "uniform highp vec2 uTexScale1; \n"
"uniform lowp int uFogUsage; \n" "uniform lowp int uScreenSpaceTriangle; \n"
"highp vec2 texCoord0; \n" "highp vec2 texCoord0; \n"
"highp vec2 texCoord1; \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 += m_part +=
"uniform lowp ivec4 uBlendMux1; \n" "uniform lowp ivec4 uBlendMux1; \n"
"uniform lowp int uForceBlendCycle1;\n" "uniform lowp int uForceBlendCycle1;\n"
@ -896,11 +908,12 @@ public:
} }
if (!_glinfo.isGLESX || _glinfo.noPerspective) if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective IN lowp vec4 vShadeColor; \n"; m_part += "noperspective IN lowp vec4 vShadeColorNoperspective; \n";
else else
m_part += "IN lowp vec4 vShadeColor; \n"; m_part += "IN lowp vec4 vShadeColorNoperspective; \n";
m_part += m_part +=
"IN lowp vec4 vShadeColor; \n"
"IN highp vec2 vTexCoord0; \n" "IN highp vec2 vTexCoord0; \n"
"IN highp vec2 vTexCoord1; \n" "IN highp vec2 vTexCoord1; \n"
"IN mediump vec2 vLodTexCoord; \n" "IN mediump vec2 vLodTexCoord; \n"
@ -946,6 +959,7 @@ public:
"uniform lowp int uDepthSource; \n" "uniform lowp int uDepthSource; \n"
"uniform highp float uPrimDepth; \n" "uniform highp float uPrimDepth; \n"
"uniform mediump vec2 uScreenScale; \n" "uniform mediump vec2 uScreenScale; \n"
"uniform lowp int uScreenSpaceTriangle; \n"
; ;
if (config.generalEmulation.enableLegacyBlending != 0) { if (config.generalEmulation.enableLegacyBlending != 0) {
@ -979,11 +993,14 @@ public:
} }
if (!_glinfo.isGLESX || _glinfo.noPerspective) if (!_glinfo.isGLESX || _glinfo.noPerspective)
m_part += "noperspective IN lowp vec4 vShadeColor; \n"; m_part += "noperspective IN lowp vec4 vShadeColorNoperspective; \n";
else 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) { if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast && _glinfo.ext_fetch) {
m_part += m_part +=
@ -1387,6 +1404,7 @@ public:
" lowp vec4 vec_color; \n" " lowp vec4 vec_color; \n"
" lowp float alpha1; \n" " lowp float alpha1; \n"
" lowp vec3 color1, input_color; \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) 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)) * floor(((x)-(low))/((high)-(low))) \n"; // Perhaps more compatible?
@ -1413,6 +1431,7 @@ public:
" lowp vec4 vec_color, combined_color; \n" " lowp vec4 vec_color, combined_color; \n"
" lowp float alpha1, alpha2; \n" " lowp float alpha1, alpha2; \n"
" lowp vec3 color1, color2, input_color; \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) 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)) * floor(((x)-(low))/((high)-(low))) \n"; // Perhaps more compatible?
@ -1428,7 +1447,7 @@ public:
if (config.generalEmulation.enableLegacyBlending == 0) { if (config.generalEmulation.enableLegacyBlending == 0) {
m_part = m_part =
" lowp mat4 muxPM = mat4(vec4(0.0), vec4(0.0), uBlendColor, uFogColor); \n" " 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" " lowp vec4 muxB = vec4(0.0, 1.0, 1.0, 0.0); \n"
; ;
} }
@ -2633,11 +2652,11 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
} }
if (bUseHWLight) if (bUseHWLight)
ssShader << " calc_light(vNumLights, vShadeColor.rgb, input_color);" << std::endl; ssShader << " calc_light(vNumLights, shadeColor.rgb, input_color);" << std::endl;
else 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; ssShader << strCombiner << std::endl;
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable)

View File

@ -198,6 +198,23 @@ private:
iUniform uMSAASamples; 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 class UFrameBufferInfo : public UniformGroup
{ {
public: public:
@ -1059,6 +1076,7 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
UniformGroups & _uniforms) UniformGroups & _uniforms)
{ {
_uniforms.emplace_back(new UNoiseTex(_program)); _uniforms.emplace_back(new UNoiseTex(_program));
_uniforms.emplace_back(new UScreenSpaceTriangleInfo(_program));
if (!m_glInfo.isGLES2) { if (!m_glInfo.isGLES2) {
_uniforms.emplace_back(new UDepthTex(_program)); _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(); m_texrectDrawer.draw();
if ((m_modifyVertices & MODIFY_XY) != 0) if ((m_modifyVertices & MODIFY_XY) != 0)
gSP.changed &= ~CHANGED_VIEWPORT; gSP.changed &= ~CHANGED_VIEWPORT;
if (gSP.changed || gDP.changed) m_drawingState = _drawingState;
_updateStates(DrawingState::Triangle);
m_drawingState = DrawingState::Triangle; if (gSP.changed || gDP.changed)
_updateStates(_drawingState);
bool bFlatColors = false; bool bFlatColors = false;
if (!RSP.LLE && (gSP.geometryMode & G_LIGHTING) == 0) { if (!RSP.LLE && (gSP.geometryMode & G_LIGHTING) == 0) {
@ -764,7 +764,7 @@ void GraphicsDrawer::drawTriangles()
return; return;
} }
_prepareDrawTriangle(); _prepareDrawTriangle(DrawingState::Triangle);
Context::DrawTriangleParameters triParams; Context::DrawTriangleParameters triParams;
triParams.mode = drawmode::TRIANGLES; triParams.mode = drawmode::TRIANGLES;
@ -815,7 +815,7 @@ void GraphicsDrawer::drawScreenSpaceTriangle(u32 _numVtx, graphics::DrawModePara
m_modifyVertices = MODIFY_ALL; m_modifyVertices = MODIFY_ALL;
gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode gSP.changed &= ~CHANGED_GEOMETRYMODE; // Don't update cull mode
_prepareDrawTriangle(); _prepareDrawTriangle(DrawingState::ScreenSpaceTriangle);
Context::DrawTriangleParameters triParams; Context::DrawTriangleParameters triParams;
triParams.mode = _mode; triParams.mode = _mode;
@ -846,7 +846,7 @@ void GraphicsDrawer::drawDMATriangles(u32 _numVtx)
{ {
if (_numVtx == 0 || !_canDraw()) if (_numVtx == 0 || !_canDraw())
return; return;
_prepareDrawTriangle(); _prepareDrawTriangle(DrawingState::Triangle);
Context::DrawTriangleParameters triParams; Context::DrawTriangleParameters triParams;

View File

@ -22,11 +22,12 @@ struct FrameBuffer;
enum class DrawingState enum class DrawingState
{ {
Non = 0, Non,
Line = 1, Line,
Triangle = 2, Triangle,
Rect = 3, ScreenSpaceTriangle,
TexRect = 4, Rect,
TexRect
}; };
struct RectVertex struct RectVertex
@ -181,7 +182,7 @@ private:
void _updateDepthCompare() const; void _updateDepthCompare() const;
void _updateTextures() const; void _updateTextures() const;
void _updateStates(DrawingState _drawingState) const; void _updateStates(DrawingState _drawingState) const;
void _prepareDrawTriangle(); void _prepareDrawTriangle(DrawingState _drawingState);
bool _canDraw() const; bool _canDraw() const;
void _drawThickLine(int _v0, int _v1, float _width); 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 : params.wrapT = _pTexture->clampT ? textureParameters::WRAP_CLAMP_TO_EDGE :
_pTexture->mirrorT ? textureParameters::WRAP_MIRRORED_REPEAT : textureParameters::WRAP_REPEAT; _pTexture->mirrorT ? textureParameters::WRAP_MIRRORED_REPEAT : textureParameters::WRAP_REPEAT;
if (dwnd().getDrawer().getDrawingState() == DrawingState::Triangle && config.texture.maxAnisotropyF > 0.0f) if (config.texture.maxAnisotropyF > 0.0f) {
switch (dwnd().getDrawer().getDrawingState()) {
case DrawingState::Triangle:
case DrawingState::ScreenSpaceTriangle:
params.maxAnisotropy = Parameter(config.texture.maxAnisotropyF); params.maxAnisotropy = Parameter(config.texture.maxAnisotropyF);
break;
}
}
} }
gfxContext.setTextureParameters(params); gfxContext.setTextureParameters(params);