soft shadows optimization

This commit is contained in:
2023-02-22 15:48:50 +03:00
parent 91bc31e7db
commit 7455a7341c
6 changed files with 58 additions and 40 deletions

View File

@@ -172,7 +172,7 @@ void calcLight(in int index, in vec3 n, in vec3 v) {
spot *= light_map_pix.a; spot *= light_map_pix.a;
#endif #endif
if (int(round(qgl_light_parameter[index].flags)) == 1 && bitfieldExtract(flags, 3, 1) == 1) { if (int(round(qgl_light_parameter[index].flags)) == 1 && bitfieldExtract(flags, 3, 1) == 1 && (spot > 1E-4)) {
vec3 odir = -(view_mat * ldir); vec3 odir = -(view_mat * ldir);
int layer = index - lights_start; int layer = index - lights_start;
float shadow = 0.; float shadow = 0.;
@@ -187,13 +187,15 @@ void calcLight(in int index, in vec3 n, in vec3 v) {
const int gm_size = 3; const int gm_size = 3;
for (int i = -gm_size; i <= gm_size; ++i) { for (int i = -gm_size; i <= gm_size; ++i) {
for (int j = -gm_size; j <= gm_size; ++j) { for (int j = -gm_size; j <= gm_size; ++j) {
depth = min(depth, textureOffset(tex_depths_cone, vec3(shp.xy, layer), ivec2(i, j)).r); depth = min(depth, textureOffset(tex_depths_cone, vec3(shp.xy, layer), ivec2(i, j)).x);
} }
} }
depth = 1 / (1 - depth) - 1 + z_near; depth = 1 / (1 - depth) - 1 + z_near;
float dz = max(0, shp.z - depth); float dz = max(0, shp.z - depth);
float ds = qgl_light_parameter[index].size * dz / (ldist - dz); float ds = qgl_light_parameter[index].size * dz / (ldist - dz);
//qgl_FragColor.rgb = vec3(0); //qgl_FragColor.rgb = vec3(-texture(tex_depths_cone, vec3(shp.xy,layer)).r*1000);
//qgl_FragColor.rgb = vec3(depth);
//qgl_FragColor.rgb = vec3(dz);
#else #else
float depth = 1; float depth = 1;
const int gm_size = 3; const int gm_size = 3;
@@ -207,17 +209,18 @@ void calcLight(in int index, in vec3 n, in vec3 v) {
depth = 1 / (1 - depth) - 1 + z_near; depth = 1 / (1 - depth) - 1 + z_near;
float dz = max(0, ldist - depth); float dz = max(0, ldist - depth);
float ds = qgl_light_parameter[index].size * dz / (ldist - dz); float ds = qgl_light_parameter[index].size * dz / (ldist - dz);
//qgl_FragColor.rgb = vec3(dz/5);
//float ds = (ldist / 2.) / qgl_light_parameter[index].size; //float ds = (ldist / 2.) / qgl_light_parameter[index].size;
//qgl_FragColor.rgb = vec3(ds);
#endif #endif
int samples = clamp(1, soft_shadows_samples, int(round(ds * float(soft_shadows_samples))));
vds = ds * bn.xyz; vds = ds * bn.xyz;
vds2 = ds * bn2.xyz; vds2 = ds * bn2.xyz;
vec2 so; vec2 so;
ivec2 sotc = tc; ivec2 sotc = tc;
noise2init(vec2(hash(ivec2(tc.x * 2 + 1, tc.y)), hash(ivec2(tc.x, (tc.y * 2 + 1))))); noise2init(vec2(hash(ivec2(tc.x * 2 + 1, tc.y)), hash(ivec2(tc.x, (tc.y * 2 + 1)))));
for (int i = 1; i <= soft_shadows_samples; ++i) { for (int i = 1; i <= samples; ++i) {
so = noise2(); so = noise2();
#ifdef SPOT #ifdef SPOT
//vec4 nc = texelFetch(tex_noise, sotc % noise_size, 0); //vec4 nc = texelFetch(tex_noise, sotc % noise_size, 0);
@@ -239,7 +242,7 @@ void calcLight(in int index, in vec3 n, in vec3 v) {
#endif #endif
} }
spot *= min(1, 2. * shadow / soft_shadows_samples); spot *= min(1, 2. * shadow / samples);
//spot *= shadow / soft_shadows_samples; //spot *= shadow / soft_shadows_samples;
//spot *= shadow / soft_shadows_samples + 1; //spot *= shadow / soft_shadows_samples + 1;
@@ -340,20 +343,22 @@ void main(void) {
} }
qgl_FragColor = vec4(res_col, alpha); qgl_FragColor = vec4(res_col, alpha);
//qgl_FragColor.a = alpha;
//qgl_FragColor.rgb = vec3(bn.z); //qgl_FragColor.rgb = vec3(bn.z);
//qgl_FragColor.rgba = vec4(vec3(0), 0.5);
#ifdef SPOT #ifdef SPOT
vec4 shp = mapScreenToShadow(0, vec3(0)); //vec4 shp = mapScreenToShadow(0, vec3(0));
shp.xy /= shp.w; //shp.xy /= shp.w;
float depth = texture(tex_depths_cone, vec3(shp.xy, 0)).r; //float depth = texture(tex_depths_cone, vec3(shp.xy, 0)).r;
depth = 1 / (1 - depth) - 1 + z_near; ////depth = 1 / (1 - depth) - 1 + z_near;
float dz = max(0, shp.z - depth); //float dz = max(0, shp.z - depth);
//shp.z -= bias; //shp.z -= bias;
//for (int xi = -2; xi <= 2; ++xi) { //for (int xi = -2; xi <= 2; ++xi) {
// for (int yi = -2; yi <= 2; ++yi) { // for (int yi = -2; yi <= 2; ++yi) {
//qgl_FragColor.rgb = vec3(step(shp.z, texture(tex_shadows_cone, vec3(shp.xy, 0)).r)); //qgl_FragColor.rgb = vec3(step(shp.z, texture(tex_shadows_cone, vec3(shp.xy, 0)).r));
//qgl_FragColor.r = texture(tex_shadows_cone, vec3(0)).r; //qgl_FragColor.r = texture(tex_shadows_cone, vec3(0)).r;
//qgl_FragColor.gb = vec2(1); //qgl_FragColor.rgb = vec3(abs(depth) + 1);
//float _d = texture(tex_depths_cone, vec3(shp.xy, 0)).r; //float _d = texture(tex_depths_cone, vec3(shp.xy, 0)).r;
//_d = 1 / (1 - _d) - 1 + z_near; //_d = 1 / (1 - _d) - 1 + z_near;
//qgl_FragColor.rgb = vec3(texelFetch(tex_noise, tc % noise_size, 0).b);//vec4(res_col, alpha); //qgl_FragColor.rgb = vec3(texelFetch(tex_noise, tc % noise_size, 0).b);//vec4(res_col, alpha);

View File

@@ -27,18 +27,21 @@ const float _pe = 2.4e-7;
void main(void) { void main(void) {
if (bitfieldExtract(object_flags, 2, 1) == 0) if (bitfieldExtract(object_flags, 2, 1) == 0)
discard; discard;
vec4 diffuse = qgl_materialTexture(QGL_MAP_DIFFUSE, qgl_FragTexture.xy, vec4(0)); vec4 diffuse = qgl_materialTexture(QGL_MAP_DIFFUSE, qgl_FragTexture.xy, vec4(0.f));
if(diffuse.a < 0.5) if(diffuse.a < 0.5f)
discard; discard;
float z = gl_FragCoord.z; //float z = gl_FragCoord.z;
z = z + z - 1; //z = z + z - 1;
z = ((_pe - 2.) * z_near) / (z + z + _pe - 2.); // infinite depth //z = ((_pe - 2.) * z_near) / (z + z + _pe - 2.); // infinite depth
#ifdef OMNI #ifdef OMNI
gl_FragDepth = 1 - 1 / (length(pos.xyz) - z_near + 1); float z = length(pos.xyz);
#else #else
gl_FragDepth = 1 - 1 / (pos.z - z_near + 1); float z = pos.z;
#endif #endif
z = 1.f - 1.f / (z - z_near + 1.f);
gl_FragDepth = z;
qgl_FragData[0].r = z;
//qgl_FragData[0].r = length(vec3(pos.xy, z));//1/gl_FragCoord.w; //qgl_FragData[0].r = length(vec3(pos.xy, z));//1/gl_FragCoord.w;
} }

View File

@@ -107,8 +107,10 @@ enum MapType {
enum TextureArrayRole { enum TextureArrayRole {
tarEmpty = 10, tarEmpty = 10,
tarMaps = 11, tarMaps = 11,
tarShadowsCone = 12, tarShadowsCone = 16,
tarShadowsOmni = 13, tarShadowsOmni = 17,
tarDepthsCone = 18,
tarDepthsOmni = 19,
}; };
enum EmptyMapRole { enum EmptyMapRole {
emrWhite = 0, emrWhite = 0,

View File

@@ -118,6 +118,8 @@ void Renderer::init(int width, int height) {
textures_empty.reinit(); textures_empty.reinit();
shadow_maps_cone.reinit(); shadow_maps_cone.reinit();
shadow_maps_omni.reinit(); shadow_maps_omni.reinit();
depth_maps_cone.reinit();
depth_maps_omni.reinit();
resize(width, height); resize(width, height);
rend_mat.init(width, height); rend_mat.init(width, height);
rend_service.init(width, height); rend_service.init(width, height);
@@ -152,7 +154,7 @@ void Renderer::reloadShaders() {
shader_fxaa = nullptr; shader_fxaa = nullptr;
if (tone_proc.shader_sum) delete tone_proc.shader_sum; if (tone_proc.shader_sum) delete tone_proc.shader_sum;
tone_proc.shader_sum = nullptr; tone_proc.shader_sum = nullptr;
QString dir = ":/shaders/"; QString dir = "./shaders/";
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key())); loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key()));
@@ -207,7 +209,6 @@ void Renderer::initShaders() {
prog->setUniformValue("tex_env", (int)Renderer::dbrBuffersCount + 1); prog->setUniformValue("tex_env", (int)Renderer::dbrBuffersCount + 1);
prog->setUniformValue("tex_noise", (int)Renderer::dbrBuffersCount + 2); prog->setUniformValue("tex_noise", (int)Renderer::dbrBuffersCount + 2);
setUniformMaps(prog); setUniformMaps(prog);
prog->setUniformValue("tex_shadows_cone", (int)tarShadowsCone);
} }
if (bindShader(srFinalPass, &prog)) { if (bindShader(srFinalPass, &prog)) {
prog->setUniformValue("tex_g1", 0); prog->setUniformValue("tex_g1", 0);
@@ -345,12 +346,12 @@ void Renderer::renderLight(int first_wr_buff, bool clear_only) {
prog->setUniformValue("view_mat", cam->viewMatrix().inverted().toGenericMatrix<3, 3>()); prog->setUniformValue("view_mat", cam->viewMatrix().inverted().toGenericMatrix<3, 3>());
prog->setUniformValue("shadow_size", view->shadow_map_size); prog->setUniformValue("shadow_size", view->shadow_map_size);
prog->setUniformValue("noise_size", noise_size); prog->setUniformValue("noise_size", noise_size);
prog->setUniformValue("tex_shadows_cone", (int)tarShadowsCone);
prog->setUniformValue("tex_shadows_omni", (int)tarShadowsOmni);
prog->setUniformValue("tex_depths_cone", (int)tarShadowsCone);
prog->setUniformValue("tex_depths_omni", (int)tarShadowsOmni);
prog->setUniformValue("soft_shadows_enabled", view->soft_shadows); prog->setUniformValue("soft_shadows_enabled", view->soft_shadows);
prog->setUniformValue("soft_shadows_samples", view->soft_shadows_samples); prog->setUniformValue("soft_shadows_samples", view->soft_shadows_samples);
prog->setUniformValue("tex_shadows_cone", (int)tarShadowsCone);
prog->setUniformValue("tex_shadows_omni", (int)tarShadowsOmni);
prog->setUniformValue("tex_depths_cone", (int)tarDepthsCone);
prog->setUniformValue("tex_depths_omni", (int)tarDepthsOmni);
GLenum filter = view->softShadows() ? GL_NEAREST : GL_LINEAR; GLenum filter = view->softShadows() ? GL_NEAREST : GL_LINEAR;
shadow_maps_cone.bind(view, tarShadowsCone); shadow_maps_cone.bind(view, tarShadowsCone);
view->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, filter); view->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, filter);
@@ -358,6 +359,8 @@ void Renderer::renderLight(int first_wr_buff, bool clear_only) {
shadow_maps_omni.bind(view, tarShadowsOmni); shadow_maps_omni.bind(view, tarShadowsOmni);
view->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, filter); view->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, filter);
view->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, filter); view->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, filter);
depth_maps_cone.bind(view, tarDepthsCone);
depth_maps_omni.bind(view, tarDepthsOmni);
renderQuad(prog, quad, cam); renderQuad(prog, quad, cam);
} }
} }
@@ -378,6 +381,7 @@ void Renderer::renderConeShadows() {
f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS); f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
} }
depth_maps_cone.resize(f, view->shadow_map_size, cone_ll.size());
for (int i = 0; i < cone_ll.size(); ++i) { for (int i = 0; i < cone_ll.size(); ++i) {
Light * l = cone_ll[i]; Light * l = cone_ll[i];
QMatrix4x4 pm = glMatrixPerspective(l->angle_end, 1., 0.1), om, vm; QMatrix4x4 pm = glMatrixPerspective(l->angle_end, 1., 0.1), om, vm;
@@ -407,12 +411,10 @@ void Renderer::renderOmniShadows() {
textures_maps.bind(f, tarMaps); textures_maps.bind(f, tarMaps);
auto omni_ll = cur_lights.value(Light::Omni); auto omni_ll = cur_lights.value(Light::Omni);
if (shadow_maps_omni.resize(f, view->shadow_map_size, omni_ll.size())) { if (shadow_maps_omni.resize(f, view->shadow_map_size, omni_ll.size())) {
// f->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
// f->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// f->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
f->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); f->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
f->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS); f->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
} }
depth_maps_omni.resize(f, view->shadow_map_size, omni_ll.size());
for (int i = 0; i < omni_ll.size(); ++i) { for (int i = 0; i < omni_ll.size(); ++i) {
Light * l = omni_ll[i]; Light * l = omni_ll[i];
QMatrix4x4 om; QMatrix4x4 om;
@@ -439,8 +441,8 @@ void Renderer::renderConeShadow(int index, Light * light) {
light->shadow_map.bind(); light->shadow_map.bind();
view->glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadow_maps_cone.ID(), 0, index); view->glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadow_maps_cone.ID(), 0, index);
// glDrawBuffer(GL_COLOR_ATTACHMENT0); view->glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, depth_maps_cone.ID(), 0, index);
// glClearDepth(0.); glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearFramebuffer(); glClearFramebuffer();
renderObjects(scene, rpSolid); renderObjects(scene, rpSolid);
light->shadow_map.release(); light->shadow_map.release();
@@ -460,8 +462,8 @@ void Renderer::renderOmniShadow(int index, Light * light, QOpenGLShaderProgram *
for (int i = 0; i < 6; ++i) { for (int i = 0; i < 6; ++i) {
QMatrix4x4 vm = mat_proj_90 * mat_faces[i] * om; QMatrix4x4 vm = mat_proj_90 * mat_faces[i] * om;
prog->setUniformValue("qgl_ViewProjMatrix", vm); prog->setUniformValue("qgl_ViewProjMatrix", vm);
int buff_ind = GL_COLOR_ATTACHMENT0 + i;
view->glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadow_maps_omni.ID(), 0, index * 6 + i); view->glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadow_maps_omni.ID(), 0, index * 6 + i);
view->glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, depth_maps_omni.ID(), 0, index * 6 + i);
// static GLenum faces[6] = {GL_COLOR_ATTACHMENT0, // static GLenum faces[6] = {GL_COLOR_ATTACHMENT0,
// GL_COLOR_ATTACHMENT1, // GL_COLOR_ATTACHMENT1,
// GL_COLOR_ATTACHMENT2, // GL_COLOR_ATTACHMENT2,
@@ -469,7 +471,7 @@ void Renderer::renderOmniShadow(int index, Light * light, QOpenGLShaderProgram *
// GL_COLOR_ATTACHMENT4, // GL_COLOR_ATTACHMENT4,
// GL_COLOR_ATTACHMENT5}; // GL_COLOR_ATTACHMENT5};
// view->glDrawBuffers(6, faces); // view->glDrawBuffers(6, faces);
// glDrawBuffer(buff_ind); glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearFramebuffer(); glClearFramebuffer();
renderObjects(scene, rpSolid); renderObjects(scene, rpSolid);
} }
@@ -676,6 +678,8 @@ void Renderer::renderScene() {
tprog->bind(); tprog->bind();
tprog->setUniformValue("tex_cone", (int)tarShadowsCone); tprog->setUniformValue("tex_cone", (int)tarShadowsCone);
tprog->setUniformValue("tex_omni", (int)tarShadowsOmni); tprog->setUniformValue("tex_omni", (int)tarShadowsOmni);
tprog->setUniformValue("dep_cone", (int)tarDepthsCone);
tprog->setUniformValue("dep_omni", (int)tarDepthsOmni);
QMatrix4x4 mat; QMatrix4x4 mat;
double sz = 0.33; double sz = 0.33;
mat.translate(sz - 1, sz - 1); mat.translate(sz - 1, sz - 1);
@@ -686,8 +690,10 @@ void Renderer::renderScene() {
tprog->bind(); tprog->bind();
shadow_maps_cone.bind(f, tarShadowsCone); shadow_maps_cone.bind(f, tarShadowsCone);
shadow_maps_omni.bind(f, tarShadowsOmni); shadow_maps_omni.bind(f, tarShadowsOmni);
depth_maps_cone.bind(f, tarDepthsCone);
depth_maps_omni.bind(f, tarDepthsOmni);
quad->draw(f, 1); quad->draw(f, 1);
*/ */
} }

View File

@@ -38,7 +38,9 @@ RendererBase::RendererBase(QGLView * view_)
, textures_empty(GL_RGBA, false) , textures_empty(GL_RGBA, false)
, textures_maps(GL_RGBA, true) , textures_maps(GL_RGBA, true)
, shadow_maps_cone(GL_DEPTH_COMPONENT, false) , shadow_maps_cone(GL_DEPTH_COMPONENT, false)
, shadow_maps_omni(GL_DEPTH_COMPONENT, false) { , depth_maps_cone(GL_R32F, false)
, shadow_maps_omni(GL_DEPTH_COMPONENT, false)
, depth_maps_omni(GL_R32F, false) {
textures_manager = new TextureManager(view); textures_manager = new TextureManager(view);
maps_size = QSize(1024, 1024); maps_size = QSize(1024, 1024);
maps_hash = 0; maps_hash = 0;
@@ -64,9 +66,9 @@ void RendererBase::initTextureArrays() {
textures_empty.load(f, im, emrBlue); textures_empty.load(f, im, emrBlue);
shadow_maps_cone.init(f); shadow_maps_cone.init(f);
shadow_maps_omni.init(f); shadow_maps_omni.init(f);
depth_maps_cone.init(f);
depth_maps_omni.init(f);
shadow_maps_cone.bind(f, tarShadowsCone); shadow_maps_cone.bind(f, tarShadowsCone);
f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);

View File

@@ -60,8 +60,8 @@ protected:
QVector<QGLEngineShaders::QGLLightPosition> cur_lights_pos_; QVector<QGLEngineShaders::QGLLightPosition> cur_lights_pos_;
Buffer buffer_materials; Buffer buffer_materials;
Buffer buffer_lights, buffer_lights_pos; Buffer buffer_lights, buffer_lights_pos;
Texture2DArray textures_empty, textures_maps, shadow_maps_cone; Texture2DArray textures_empty, textures_maps, shadow_maps_cone, depth_maps_cone;
CubeMapArray shadow_maps_omni; CubeMapArray shadow_maps_omni, depth_maps_omni;
QSize maps_size; QSize maps_size;
uint maps_hash; uint maps_hash;
GLuint tex_coeff[3]; GLuint tex_coeff[3];