soft shadows done

This commit is contained in:
2023-02-18 19:12:16 +03:00
parent eb5f50fc9d
commit 91bc31e7db
6 changed files with 157 additions and 25 deletions

View File

@@ -21,6 +21,7 @@
#include "qglview.h"
#include <QPainter>
#include <QRandomGenerator>
QString readCharsUntilNull(QDataStream & s) {
@@ -387,3 +388,21 @@ QVector3D vectorFromString(const QString & str) {
ret.setZ(f);
return ret;
}
QImage generateNoise(QSize sz) {
QImage im(sz, QImage::Format_ARGB32);
QRandomGenerator rg[2] = {1, 2};
uint pcnt = im.sizeInBytes() / sizeof(QRgb);
QRgb * data = (QRgb *)im.bits();
for (uint i = 0; i < pcnt; ++i) {
double r = rg[0].generateDouble();
double a = rg[0].generateDouble() * M_2PI;
double x = r * cos(a) / 2. + 0.5, y = r * sin(a) / 2. + 0.5;
data[i] = qRgba(qRound(x * 256),
qRound(y * 256),
(rg[1].generate() % sz.width()) % 256,
(rg[1].generate() % sz.height()) % 256); // argb GLSL
}
return im;
}

View File

@@ -494,6 +494,7 @@ inline QVector3D directionFromAngles(const QVector3D & a) {
inline float frac(const float & x, const float & b) {
return x - int(x / b) * b;
}
QImage generateNoise(QSize sz);
#endif // GLTYPES_H

View File

@@ -205,6 +205,7 @@ void Renderer::initShaders() {
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
prog->setUniformValue("tex_coeffs[0]", (int)Renderer::dbrBuffersCount);
prog->setUniformValue("tex_env", (int)Renderer::dbrBuffersCount + 1);
prog->setUniformValue("tex_noise", (int)Renderer::dbrBuffersCount + 2);
setUniformMaps(prog);
prog->setUniformValue("tex_shadows_cone", (int)tarShadowsCone);
}
@@ -309,7 +310,7 @@ void Renderer::renderObjects(Scene & scene, RenderPass pass) {
void Renderer::renderLight(int first_wr_buff, bool clear_only) {
QOpenGLShaderProgram * prog = 0;
Camera * cam = view->camera();
for (int i = 0; i < 2; ++i) {
for (int i = 0; i < 3; ++i) {
view->glActiveTexture(GL_TEXTURE0 + Renderer::dbrBuffersCount + i);
view->glBindTexture(GL_TEXTURE_2D, tex_coeff[i]);
}
@@ -343,12 +344,20 @@ void Renderer::renderLight(int first_wr_buff, bool clear_only) {
prog->setUniformValue("fog_density", view->fogDensity());
prog->setUniformValue("view_mat", cam->viewMatrix().inverted().toGenericMatrix<3, 3>());
prog->setUniformValue("shadow_size", view->shadow_map_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_samples", view->soft_shadows_samples);
GLenum filter = view->softShadows() ? GL_NEAREST : GL_LINEAR;
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_MAG_FILTER, filter);
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_MAG_FILTER, filter);
renderQuad(prog, quad, cam);
}
}
@@ -364,8 +373,6 @@ void Renderer::renderConeShadows() {
textures_maps.bind(f, tarMaps);
auto cone_ll = cur_lights.value(Light::Cone);
if (shadow_maps_cone.resize(f, view->shadow_map_size, cone_ll.size())) {
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_T, GL_CLAMP_TO_EDGE);
f->glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
@@ -400,8 +407,6 @@ void Renderer::renderOmniShadows() {
textures_maps.bind(f, tarMaps);
auto omni_ll = cur_lights.value(Light::Omni);
if (shadow_maps_omni.resize(f, view->shadow_map_size, omni_ll.size())) {
f->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
f->glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 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);
@@ -550,7 +555,6 @@ void Renderer::renderScene() {
setUniformCamera(prog, cam);
textures_empty.bind(f, tarEmpty);
textures_maps.bind(f, tarMaps);
shadow_maps_cone.bind(f, tarShadowsCone);
glPolygonMode(GL_FRONT_AND_BACK, view->renderMode());
renderObjects(scene, rpSolid);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

View File

@@ -42,7 +42,7 @@ RendererBase::RendererBase(QGLView * view_)
textures_manager = new TextureManager(view);
maps_size = QSize(1024, 1024);
maps_hash = 0;
tex_coeff[0] = tex_coeff[1] = 0;
tex_coeff[0] = tex_coeff[1] = tex_coeff[2] = 0;
}
@@ -400,6 +400,7 @@ void RendererBase::initCoeffTextures() {
}
}
createCoeffTexture(tex_coeff[0], data.constData(), size, 2);
createNoiseTexture(tex_coeff[2]);
}
@@ -428,3 +429,17 @@ void RendererBase::createCoeffTexture(GLuint & id, const void * data, int size,
}
f->glTexImage2D(GL_TEXTURE_2D, 0, iformat, size, size, 0, format, GL_FLOAT, data);
}
void RendererBase::createNoiseTexture(GLuint & id) {
QOpenGLExtraFunctions * f = view;
deleteGLTexture(f, id);
f->glGenTextures(1, &id);
f->glBindTexture(GL_TEXTURE_2D, id);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
QImage im = generateNoise(QSize(noise_size, noise_size));
f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, im.width(), im.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, im.bits());
}

View File

@@ -50,6 +50,7 @@ protected:
void renderQuad(QOpenGLShaderProgram * prog, Mesh * mesh, Camera * cam = 0, bool uniforms = true);
void initCoeffTextures();
void createCoeffTexture(GLuint & id, const void * data, int size, int channels = 1);
void createNoiseTexture(GLuint & id);
QGLView * view;
TextureManager * textures_manager;
@@ -63,9 +64,10 @@ protected:
CubeMapArray shadow_maps_omni;
QSize maps_size;
uint maps_hash;
GLuint tex_coeff[2];
GLuint tex_coeff[3];
QMap<int, int> lights_start;
QList<Light *> current_lights;
int noise_size = 256;
};
#endif // RENDERER_BASE_H