video_core: Use epsilons for clip planes (#6945)
* video_core: Use epsilons for clip planes * video_core: Add comments
This commit is contained in:
parent
3e254d01ee
commit
6aa31d6ec2
|
@ -1717,7 +1717,12 @@ ShaderDecompiler::ProgramResult GenerateTrivialVertexShader(bool separable_shade
|
||||||
|
|
||||||
out += UniformBlockDef;
|
out += UniformBlockDef;
|
||||||
|
|
||||||
|
// Certain games render 2D elements very close to clip plane 0 resulting in very tiny
|
||||||
|
// negative/positive z values when computing with f32 precision,
|
||||||
|
// causing some vertices to get erroneously clipped. To workaround this problem,
|
||||||
|
// we can use a very small epsilon value for clip plane comparison.
|
||||||
out += R"(
|
out += R"(
|
||||||
|
const float EPSILON_Z = 0.00000001f;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
primary_color = vert_color;
|
primary_color = vert_color;
|
||||||
|
@ -1727,10 +1732,14 @@ void main() {
|
||||||
texcoord0_w = vert_texcoord0_w;
|
texcoord0_w = vert_texcoord0_w;
|
||||||
normquat = vert_normquat;
|
normquat = vert_normquat;
|
||||||
view = vert_view;
|
view = vert_view;
|
||||||
gl_Position = vert_position;
|
vec4 vtx_pos = vert_position;
|
||||||
|
if (abs(vtx_pos.z) < EPSILON_Z) {
|
||||||
|
vtx_pos.z = 0.f;
|
||||||
|
}
|
||||||
|
gl_Position = vtx_pos;
|
||||||
#if !defined(CITRA_GLES) || defined(GL_EXT_clip_cull_distance)
|
#if !defined(CITRA_GLES) || defined(GL_EXT_clip_cull_distance)
|
||||||
gl_ClipDistance[0] = -vert_position.z; // fixed PICA clipping plane z <= 0
|
gl_ClipDistance[0] = -vtx_pos.z; // fixed PICA clipping plane z <= 0
|
||||||
gl_ClipDistance[1] = dot(clip_coef, vert_position);
|
gl_ClipDistance[1] = dot(clip_coef, vtx_pos);
|
||||||
#endif // !defined(CITRA_GLES) || defined(GL_EXT_clip_cull_distance)
|
#endif // !defined(CITRA_GLES) || defined(GL_EXT_clip_cull_distance)
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
@ -1830,6 +1839,7 @@ struct Vertex {
|
||||||
return "0.0";
|
return "0.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
out += "const float EPSILON_Z = 0.00000001f;\n\n";
|
||||||
out += "vec4 GetVertexQuaternion(Vertex vtx) {\n";
|
out += "vec4 GetVertexQuaternion(Vertex vtx) {\n";
|
||||||
out += " return vec4(" + semantic(VSOutputAttributes::QUATERNION_X) + ", " +
|
out += " return vec4(" + semantic(VSOutputAttributes::QUATERNION_X) + ", " +
|
||||||
semantic(VSOutputAttributes::QUATERNION_Y) + ", " +
|
semantic(VSOutputAttributes::QUATERNION_Y) + ", " +
|
||||||
|
@ -1842,6 +1852,9 @@ struct Vertex {
|
||||||
semantic(VSOutputAttributes::POSITION_Y) + ", " +
|
semantic(VSOutputAttributes::POSITION_Y) + ", " +
|
||||||
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
||||||
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
||||||
|
out += " if (abs(vtx_pos.z) < EPSILON_Z) {\n";
|
||||||
|
out += " vtx_pos.z = 0.f;\n";
|
||||||
|
out += " }\n";
|
||||||
out += " gl_Position = vtx_pos;\n";
|
out += " gl_Position = vtx_pos;\n";
|
||||||
out += "#if !defined(CITRA_GLES) || defined(GL_EXT_clip_cull_distance)\n";
|
out += "#if !defined(CITRA_GLES) || defined(GL_EXT_clip_cull_distance)\n";
|
||||||
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
||||||
|
|
|
@ -27,6 +27,12 @@ using Pica::TexturingRegs;
|
||||||
using Pica::Texture::LookupTexture;
|
using Pica::Texture::LookupTexture;
|
||||||
using Pica::Texture::TextureInfo;
|
using Pica::Texture::TextureInfo;
|
||||||
|
|
||||||
|
// Certain games render 2D elements very close to clip plane 0 resulting in very tiny
|
||||||
|
// negative/positive z values when computing with f32 precision,
|
||||||
|
// causing some vertices to get erroneously clipped. To workaround this problem,
|
||||||
|
// we can use a very small epsilon value for clip plane comparison.
|
||||||
|
constexpr f32 EPSILON_Z = 0.00000001f;
|
||||||
|
|
||||||
struct Vertex : Pica::Shader::OutputVertex {
|
struct Vertex : Pica::Shader::OutputVertex {
|
||||||
Vertex(const OutputVertex& v) : OutputVertex(v) {}
|
Vertex(const OutputVertex& v) : OutputVertex(v) {}
|
||||||
|
|
||||||
|
@ -73,7 +79,7 @@ public:
|
||||||
: pos(f24::Zero()), coeffs(coeffs), bias(bias) {}
|
: pos(f24::Zero()), coeffs(coeffs), bias(bias) {}
|
||||||
|
|
||||||
bool IsInside(const Vertex& vertex) const {
|
bool IsInside(const Vertex& vertex) const {
|
||||||
return Common::Dot(vertex.pos + bias, coeffs) >= f24::Zero();
|
return Common::Dot(vertex.pos + bias, coeffs) >= f24::FromFloat32(-EPSILON_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsOutSide(const Vertex& vertex) const {
|
bool IsOutSide(const Vertex& vertex) const {
|
||||||
|
|
Reference in New Issue