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

Fix near-palne clipping for GLES.

Fixes #2449 Cruis'n world invisible car
This commit is contained in:
Sergey Lipskiy 2021-02-13 20:12:31 +07:00
parent 090b38e2d3
commit 442d4ed894
3 changed files with 69 additions and 23 deletions

View File

@ -256,7 +256,8 @@ public:
ss << "# define IN in" << std::endl << "# define OUT out" << std::endl;
if (_glinfo.noPerspective) {
ss << "#extension GL_NV_shader_noperspective_interpolation : enable" << std::endl
<< "noperspective OUT highp float vZCoord;" << std::endl;
<< "noperspective OUT highp float vZCoord;" << std::endl
<< "uniform lowp int uClampMode;" << std::endl;
}
m_part = ss.str();
}
@ -489,17 +490,17 @@ public:
m_part =
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
;
} else if (config.generalEmulation.enableFragmentDepthWrite != 0 && _glinfo.noPerspective) {
m_part =
" vZCoord = gl_Position.z / gl_Position.w; \n"
" if (uClampMode > 0) \n"
" gl_Position.z = 0.0; \n"
;
} else if (config.generalEmulation.enableClipping != 0) {
if (config.generalEmulation.enableFragmentDepthWrite != 0 && _glinfo.noPerspective) {
m_part = " vZCoord = gl_Position.z / gl_Position.w; \n";
m_part += " gl_Position.z = 0.0; \n";
} else {
// Move the near plane towards the camera.
// It helps to avoid issues with near-plane clipping in games, which do not use it.
// Z must be scaled back in fragment shader.
m_part = " gl_Position.z /= 8.0; \n";
}
// Move the near plane towards the camera.
// It helps to avoid issues with near-plane clipping in games, which do not use it.
// Z must be scaled back in fragment shader.
m_part = " gl_Position.z /= 8.0; \n";
}
m_part +=
" gl_Position.zw *= vec2(uClipRatio); \n"
@ -1181,6 +1182,7 @@ public:
m_part =
"noperspective IN highp float vZCoord; \n"
"uniform lowp float uPolygonOffset; \n"
"uniform lowp int uClampMode; \n"
+ m_part
;
}
@ -1930,17 +1932,23 @@ public:
"highp float writeDepth() \n"
"{ \n"
;
if (_glinfo.isGLESX && config.generalEmulation.enableClipping != 0) {
if (_glinfo.isGLESX) {
if (_glinfo.noPerspective) {
m_part +=
" highp float FragDepth = (uDepthSource != 0) ? uPrimDepth : \n"
" clamp((vZCoord - uPolygonOffset) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n"
;
" if (uClampMode == 1 && (vZCoord > 1.0)) discard; \n"
" highp float FragDepth = (uDepthSource != 0) ? uPrimDepth : \n"
" clamp((vZCoord - uPolygonOffset) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n"
;
} else if (config.generalEmulation.enableClipping != 0) {
m_part +=
" highp float FragDepth = (uDepthSource != 0) ? uPrimDepth : \n"
" clamp(8.0 * (gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n"
;
} else {
m_part +=
" highp float FragDepth = (uDepthSource != 0) ? uPrimDepth : \n"
" clamp(8.0 * (gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n"
;
" highp float FragDepth = (uDepthSource != 0) ? uPrimDepth : \n"
" clamp((gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n"
;
}
} else {
m_part +=
@ -1957,25 +1965,33 @@ public:
"} \n"
;
} else {
if (_glinfo.isGLESX && config.generalEmulation.enableClipping != 0) {
if (_glinfo.isGLESX) {
if (_glinfo.noPerspective) {
m_part =
"highp float writeDepth() \n"
"{ \n"
" if (uClampMode == 1 && (vZCoord > 1.0)) discard; \n"
" if (uDepthSource != 0) return uPrimDepth; \n"
" return clamp((vZCoord - uPolygonOffset) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n"
"} \n"
;
} else {
;
} else if (config.generalEmulation.enableClipping != 0) {
m_part =
"highp float writeDepth() \n"
"{ \n"
" if (uDepthSource != 0) return uPrimDepth; \n"
" return clamp(8.0 * (gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n"
"} \n"
;
} else {
m_part =
"highp float writeDepth() \n"
"{ \n"
" if (uDepthSource != 0) return uPrimDepth; \n"
" return clamp((gl_FragCoord.z * 2.0 - 1.0) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n"
"} \n"
;
}
} else {
m_part =
"highp float writeDepth() \n"

View File

@ -709,6 +709,35 @@ private:
iUniform uRenderTarget;
};
class UClampMode : public UniformGroup
{
public:
UClampMode(GLuint _program) {
LocateUniform(uClampMode);
}
void update(bool _force) override
{
int clampMode = -1;
switch (gfxContext.getClampMode())
{
case graphics::ClampMode::ClippingEnabled:
clampMode = 0;
break;
case graphics::ClampMode::NoNearPlaneClipping:
clampMode = 1;
break;
case graphics::ClampMode::NoClipping:
clampMode = 2;
break;
}
uClampMode.set(clampMode, _force);
}
private:
iUniform uClampMode;
};
class UClipRatio : public UniformGroup
{
public:
@ -1132,6 +1161,7 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
_uniforms.emplace_back(new URenderTarget(_program));
if (m_glInfo.isGLESX && m_glInfo.noPerspective) {
_uniforms.emplace_back(new UClampMode(_program));
_uniforms.emplace_back(new UPolygonOffset(_program));
}

View File

@ -20,7 +20,7 @@ namespace glsl {
bool _saveCombinerKeys(const graphics::Combiners & _combiners) const;
bool _loadFromCombinerKeys(graphics::Combiners & _combiners);
const u32 m_formatVersion = 0x31U;
const u32 m_formatVersion = 0x32U;
const u32 m_keysFormatVersion = 0x05;
const opengl::GLInfo & m_glinfo;
opengl::CachedUseProgram * m_useProgram;