mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 00:49:19 +02:00
use textureGather for shadow PCF
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include "shader.h"
|
||||
#include "glsl_common.h"
|
||||
#include "utilities/Logs.h"
|
||||
@@ -13,6 +14,44 @@ inline bool strcend(std::string const &value, std::string const &ending)
|
||||
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// The project's glad config only generates GLAD_GL_ARB_texture_filter_anisotropic
|
||||
// among the ARB/EXT extension flags -- GL_ARB_texture_gather (desktop) and
|
||||
// GL_EXT_gpu_shader5 (GLES 3.1) aren't compiled in, so we can't gate the
|
||||
// shadow textureGather() optimisation on a GLAD constant. Query the live
|
||||
// extension string instead. The first call walks the extension list once
|
||||
// (no extension count in the dozens is large enough to matter here) and
|
||||
// the result is cached in the static bool inside has_gl_extension(), so
|
||||
// every subsequent shader compile is a plain bool read.
|
||||
//
|
||||
// SHADERVALIDATOR_STANDALONE gates out the GL queries because the offline
|
||||
// shader validator tool links glad.c but never calls gladLoadGL(); the
|
||||
// function pointers stay null and a real call would crash. Returning
|
||||
// false there means the standalone validator simply compiles the original
|
||||
// 16-tap PCF fallback path in light_common.glsl, which is what we want.
|
||||
bool has_gl_extension(char const *name) {
|
||||
#ifdef SHADERVALIDATOR_STANDALONE
|
||||
(void)name;
|
||||
return false;
|
||||
#else
|
||||
if (!glGetIntegerv || !glGetStringi) {
|
||||
return false;
|
||||
}
|
||||
GLint count = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
||||
for (GLint i = 0; i < count; ++i) {
|
||||
char const *ext = reinterpret_cast<char const *>(glGetStringi(GL_EXTENSIONS, i));
|
||||
if (ext != nullptr && std::strcmp(ext, name) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
std::string gl::shader::read_file(const std::string &filename)
|
||||
{
|
||||
std::stringstream stream;
|
||||
@@ -91,11 +130,33 @@ std::pair<GLuint, std::string> gl::shader::process_source(const std::string &fil
|
||||
if (!Global.gfx_usegles)
|
||||
{
|
||||
str += "#version 330 core\n";
|
||||
// textureGather() on sampler2DArrayShadow is core in GLSL 4.0. On 3.30
|
||||
// desktop it requires GL_ARB_gpu_shader5 -- the older
|
||||
// GL_ARB_texture_gather (2010) only adds the non-shadow and the plain
|
||||
// sampler2DShadow overloads, NOT the sampler2DArrayShadow one we need
|
||||
// for cascaded shadow PCF. Some drivers advertise texture_gather but
|
||||
// reject the shadow-array overload because the spec for it lives in
|
||||
// gpu_shader5; so emit only when gpu_shader5 is advertised. When the
|
||||
// extension is missing, calc_shadow() in light_common.glsl falls back
|
||||
// to the original 16-tap hardware-PCF loop via #ifndef.
|
||||
// (Project's glad config doesn't generate GLAD_GL_ARB_gpu_shader5,
|
||||
// so we query the live extension list -- see has_gl_extension above.)
|
||||
static bool const have_gpu_shader5 = has_gl_extension("GL_ARB_gpu_shader5");
|
||||
if (have_gpu_shader5)
|
||||
str += "#extension GL_ARB_gpu_shader5 : enable\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GLAD_GL_ES_VERSION_3_1) {
|
||||
str += "#version 310 es\n";
|
||||
// GLES 3.1 lacks textureGather on shadow samplers in core; the
|
||||
// EXT_gpu_shader5 extension adds it. Only emit the directive when
|
||||
// the driver advertises support (see desktop comment above).
|
||||
// (Glad config doesn't generate GLAD_GL_EXT_gpu_shader5 -- query
|
||||
// the live extension string the same way.)
|
||||
static bool const have_gpu_shader5 = has_gl_extension("GL_EXT_gpu_shader5");
|
||||
if (have_gpu_shader5)
|
||||
str += "#extension GL_EXT_gpu_shader5 : enable\n";
|
||||
if (type == GL_GEOMETRY_SHADER)
|
||||
str += "#extension GL_EXT_geometry_shader : require\n";
|
||||
} else {
|
||||
|
||||
7
gl/ubo.h
7
gl/ubo.h
@@ -81,7 +81,12 @@ namespace gl
|
||||
void set_modelview(const glm::mat4 &mv)
|
||||
{
|
||||
modelview = mv;
|
||||
modelviewnormal = glm::mat3x4(glm::mat3(glm::transpose(glm::inverse(mv))));
|
||||
// normal matrix = transpose(inverse(modelview)). The modelview is
|
||||
// always affine, so its 3x3 normal matrix depends only on the
|
||||
// upper-left 3x3 block; inverting that mat3 directly is markedly
|
||||
// cheaper than a full mat4 inverse and yields an identical result
|
||||
// (for affine M, mat3(inverse(M)) == inverse(mat3(M))).
|
||||
modelviewnormal = glm::mat3x4(glm::transpose(glm::inverse(glm::mat3(mv))));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user