first works of omni shadows
This commit is contained in:
@@ -40,6 +40,31 @@ Renderer::Renderer(QGLView * view_)
|
||||
, rend_selection(this)
|
||||
, tone_proc(this)
|
||||
, tex_env(view_, 512) {
|
||||
mat_norm_to_tex_coord.scale(0.5, 0.5);
|
||||
mat_norm_to_tex_coord.translate(1, 1);
|
||||
mat_proj_90 = glMatrixPerspective(90., 1., 0.1);
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
QMatrix4x4 fvm;
|
||||
switch (i) {
|
||||
case 0:
|
||||
fvm.rotate(-90., QVector3D(0, 1, 0));
|
||||
fvm.rotate(180., QVector3D(0, 0, 1));
|
||||
break;
|
||||
case 1:
|
||||
fvm.rotate(90., QVector3D(0, 1, 0));
|
||||
fvm.rotate(180., QVector3D(0, 0, 1));
|
||||
break;
|
||||
case 2: fvm.rotate(-90., QVector3D(1, 0, 0)); break;
|
||||
case 3: fvm.rotate(90., QVector3D(1, 0, 0)); break;
|
||||
case 4:
|
||||
fvm.rotate(180., QVector3D(0, 0, 1));
|
||||
fvm.rotate(180., QVector3D(0, 1, 0));
|
||||
break;
|
||||
case 5: fvm.rotate(180., QVector3D(0, 0, 1)); break;
|
||||
}
|
||||
mat_faces[i] = fvm;
|
||||
}
|
||||
|
||||
quad = Primitive::plane(2., 2.);
|
||||
cam_light = new Light();
|
||||
cam_light->intensity = 0.75;
|
||||
@@ -61,10 +86,12 @@ Renderer::Renderer(QGLView * view_)
|
||||
shader_files[srFinalPass] = "ds_final.glsl";
|
||||
shader_files[srTonemapPass] = "ds_tonemap.glsl";
|
||||
|
||||
shader_files[srShadowPass] = "shadow.glsl";
|
||||
shader_files[srShadowConePass] = "shadow.glsl";
|
||||
shader_files[srShadowOmniPass] = "shadow.glsl";
|
||||
|
||||
shader_defines[srGeometrySolidPass] << "SOLID";
|
||||
shader_defines[srLightSpotPass] << "SPOT";
|
||||
shader_defines[srShadowOmniPass] << "OMNI";
|
||||
|
||||
edit_mode = need_init_shaders = true;
|
||||
camera_light_mode = QGLView::clmAuto;
|
||||
@@ -89,6 +116,7 @@ void Renderer::init(int width, int height) {
|
||||
textures_maps.reinit();
|
||||
textures_empty.reinit();
|
||||
shadow_maps_cone.reinit();
|
||||
shadow_maps_omni.reinit();
|
||||
resize(width, height);
|
||||
rend_mat.init(width, height);
|
||||
rend_service.init(width, height);
|
||||
@@ -115,6 +143,7 @@ void Renderer::resize(int width, int height) {
|
||||
|
||||
|
||||
void Renderer::reloadShaders() {
|
||||
__reinit_debug = true;
|
||||
QMapIterator<ShaderRole, QString> it(shader_files);
|
||||
qDeleteAll(shaders.values());
|
||||
shaders.clear();
|
||||
@@ -122,7 +151,7 @@ void Renderer::reloadShaders() {
|
||||
shader_fxaa = nullptr;
|
||||
if (tone_proc.shader_sum) delete tone_proc.shader_sum;
|
||||
tone_proc.shader_sum = nullptr;
|
||||
QString dir = ":/shaders/";
|
||||
QString dir = "./shaders/";
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key()));
|
||||
@@ -165,9 +194,6 @@ bool Renderer::bindShader(QOpenGLShaderProgram * sp) {
|
||||
void Renderer::initShaders() {
|
||||
if (!need_init_shaders) return;
|
||||
need_init_shaders = false;
|
||||
// initUniformBuffer(shaders.value(srGeometrySolidPass), &buffer_materials, bpMaterials, "QGLMaterialData");
|
||||
// initUniformBuffer(shaders.value(srGeometryTransparentPass), &buffer_materials, bpMaterials, "QGLMaterialData");
|
||||
// initUniformBuffer(shaders.value(srShadowPass), &buffer_materials, bpMaterials, "QGLMaterialData");
|
||||
QOpenGLShaderProgram * prog = 0;
|
||||
for (ShaderRole role: {srLightOmniPass, srLightSpotPass}) {
|
||||
if (!bindShader(role, &prog)) continue;
|
||||
@@ -188,7 +214,7 @@ void Renderer::initShaders() {
|
||||
prog->setUniformValue("tex_t_0", 3);
|
||||
prog->setUniformValue("tex_t_1", 4);
|
||||
}
|
||||
for (ShaderRole role: {srGeometrySolidPass, srGeometryTransparentPass, srShadowPass}) {
|
||||
for (ShaderRole role: {srGeometrySolidPass, srGeometryTransparentPass, srShadowConePass, srShadowOmniPass}) {
|
||||
if (!bindShader(role, &prog)) continue;
|
||||
initUniformBuffer(prog, &buffer_materials, bpMaterials, "QGLMaterialData");
|
||||
setUniformMaps(prog);
|
||||
@@ -317,16 +343,71 @@ void Renderer::renderLight(int first_wr_buff, bool clear_only) {
|
||||
prog->setUniformValue("view_mat", cam->viewMatrix().inverted().toGenericMatrix<3, 3>());
|
||||
prog->setUniformValue("shadow_size", view->shadow_map_size);
|
||||
prog->setUniformValue("tex_shadows_cone", (int)tarShadowsCone);
|
||||
prog->setUniformValue("tex_shadows_omni", (int)tarShadowsOmni);
|
||||
prog->setUniformValue("soft_shadows_enabled", view->soft_shadows);
|
||||
prog->setUniformValue("soft_shadows_samples", view->soft_shadows_samples);
|
||||
shadow_maps_cone.bind(view, tarShadowsCone);
|
||||
shadow_maps_omni.bind(view, tarShadowsOmni);
|
||||
renderQuad(prog, quad, cam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Renderer::renderShadow(int index, Light * light) {
|
||||
void Renderer::renderConeShadows() {
|
||||
QOpenGLExtraFunctions * f = view;
|
||||
QOpenGLShaderProgram * prog = 0;
|
||||
if (bindShader(srShadowConePass, &prog)) {
|
||||
glEnableDepth();
|
||||
textures_empty.bind(f, tarEmpty);
|
||||
textures_maps.bind(f, tarMaps);
|
||||
auto cone_ll = cur_lights.value(Light::Cone);
|
||||
shadow_maps_cone.resize(f, view->shadow_map_size, cone_ll.size());
|
||||
for (int i = 0; i < cone_ll.size(); ++i) {
|
||||
Light * l = cone_ll[i];
|
||||
QMatrix4x4 pm = glMatrixPerspective(l->angle_end, 1., 0.1), om, vm;
|
||||
om.translate(-l->worldAim());
|
||||
vm.translate(0., 0., -l->distance());
|
||||
// vm.rotate(-roll_, 0., 0., 1.);
|
||||
QMatrix4x4 pmat = l->worldTransform();
|
||||
pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.;
|
||||
vm *= pmat.inverted();
|
||||
auto vpm = pm * (vm * om);
|
||||
if (l->isCastShadows()) {
|
||||
prog->setUniformValue("qgl_ViewProjMatrix", vpm);
|
||||
renderConeShadow(i, l);
|
||||
}
|
||||
l->shadow_matrix = mat_norm_to_tex_coord * vpm * mat_camera_fullview_inv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Renderer::renderOmniShadows() {
|
||||
QOpenGLExtraFunctions * f = view;
|
||||
QOpenGLShaderProgram * prog = 0;
|
||||
if (bindShader(srShadowOmniPass, &prog)) {
|
||||
glEnableDepth();
|
||||
textures_empty.bind(f, tarEmpty);
|
||||
textures_maps.bind(f, tarMaps);
|
||||
auto omni_ll = cur_lights.value(Light::Omni);
|
||||
shadow_maps_omni.resize(f, view->shadow_map_size, omni_ll.size());
|
||||
for (int i = 0; i < omni_ll.size(); ++i) {
|
||||
Light * l = omni_ll[i];
|
||||
QMatrix4x4 om;
|
||||
om.translate(-l->worldPos());
|
||||
// vm.translate(0., 0., -l->distance());
|
||||
// vm.rotate(-roll_, 0., 0., 1.);
|
||||
if (l->isCastShadows()) {
|
||||
renderOmniShadow(i, l, prog, om);
|
||||
}
|
||||
// l->shadow_matrix = mat_norm_to_tex_coord * vpm * mat_camera_fullview_inv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Renderer::renderConeShadow(int index, Light * light) {
|
||||
Scene & scene(*(view->scene()));
|
||||
bool force_resize = false;
|
||||
if (!light->shadow_map.isInit()) {
|
||||
@@ -336,13 +417,7 @@ void Renderer::renderShadow(int index, Light * light) {
|
||||
light->shadow_map.resize(view->shadow_map_size, force_resize);
|
||||
light->shadow_map.bind();
|
||||
|
||||
if (!framebufferTextureLayer) {
|
||||
framebufferTextureLayer = view->context()->getProcAddress("glFramebufferTextureLayer");
|
||||
}
|
||||
if (framebufferTextureLayer) {
|
||||
((PFNGLFRAMEBUFFERTEXTURELAYERPROC)framebufferTextureLayer)(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadow_maps_cone.ID(), 0, index);
|
||||
// glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadow_maps_cone.ID(), 0, index);
|
||||
}
|
||||
view->glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadow_maps_cone.ID(), 0, index);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glClearFramebuffer();
|
||||
renderObjects(scene, rpSolid);
|
||||
@@ -350,6 +425,36 @@ void Renderer::renderShadow(int index, Light * light) {
|
||||
}
|
||||
|
||||
|
||||
void Renderer::renderOmniShadow(int index, Light * light, QOpenGLShaderProgram * prog, QMatrix4x4 om) {
|
||||
Scene & scene(*(view->scene()));
|
||||
bool force_resize = false;
|
||||
if (!light->shadow_map.isInit()) {
|
||||
light->shadow_map.reinit(view);
|
||||
force_resize = true;
|
||||
}
|
||||
light->shadow_map.resize(view->shadow_map_size, force_resize);
|
||||
light->shadow_map.bind();
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
QMatrix4x4 vm = mat_proj_90 * mat_faces[i] * om;
|
||||
prog->setUniformValue("qgl_ViewProjMatrix", vm);
|
||||
int buff_ind = GL_COLOR_ATTACHMENT0 + i;
|
||||
view->glFramebufferTextureLayer(GL_FRAMEBUFFER, buff_ind, shadow_maps_omni.ID(), 0, index * 6 + i);
|
||||
// static GLenum faces[6] = {GL_COLOR_ATTACHMENT0,
|
||||
// GL_COLOR_ATTACHMENT1,
|
||||
// GL_COLOR_ATTACHMENT2,
|
||||
// GL_COLOR_ATTACHMENT3,
|
||||
// GL_COLOR_ATTACHMENT4,
|
||||
// GL_COLOR_ATTACHMENT5};
|
||||
// view->glDrawBuffers(6, faces);
|
||||
glDrawBuffer(buff_ind);
|
||||
glClearFramebuffer();
|
||||
renderObjects(scene, rpSolid);
|
||||
}
|
||||
light->shadow_map.release();
|
||||
}
|
||||
|
||||
|
||||
void Renderer::renderScene() {
|
||||
timings.clear();
|
||||
Measurer phase(&timings);
|
||||
@@ -363,6 +468,7 @@ void Renderer::renderScene() {
|
||||
QOpenGLShaderProgram * prog = 0;
|
||||
bool scene_changed = scene.prepare();
|
||||
cur_lights = scene.lights_used;
|
||||
mat_camera_fullview_inv = cam->fullViewMatrix().inverted();
|
||||
scene.destroyUnused(f);
|
||||
phase.end();
|
||||
|
||||
@@ -383,35 +489,14 @@ void Renderer::renderScene() {
|
||||
}
|
||||
phase.end();
|
||||
|
||||
/// shadows and shadow matrix
|
||||
phase.begin("shadows");
|
||||
if (bindShader(srShadowPass, &prog)) {
|
||||
glEnableDepth();
|
||||
textures_empty.bind(f, tarEmpty);
|
||||
textures_maps.bind(f, tarMaps);
|
||||
auto cam_ivm = cam->fullViewMatrix().inverted();
|
||||
auto cone_ll = cur_lights.value(Light::Cone);
|
||||
shadow_maps_cone.resize(f, view->shadow_map_size, cone_ll.size());
|
||||
QMatrix4x4 mat_vp;
|
||||
mat_vp.scale(0.5, 0.5);
|
||||
mat_vp.translate(1, 1);
|
||||
for (int i = 0; i < cone_ll.size(); ++i) {
|
||||
Light * l = cone_ll[i];
|
||||
QMatrix4x4 pm = glMatrixPerspective(l->angle_end, 1., 0.1), om, vm;
|
||||
om.translate(-l->worldAim());
|
||||
vm.translate(0., 0., -l->distance());
|
||||
// vm.rotate(-roll_, 0., 0., 1.);
|
||||
QMatrix4x4 pmat = l->worldTransform();
|
||||
pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.;
|
||||
vm *= pmat.inverted();
|
||||
auto vpm = pm * (vm * om);
|
||||
if (l->isCastShadows()) {
|
||||
prog->setUniformValue("qgl_ViewProjMatrix", vpm);
|
||||
renderShadow(i, l);
|
||||
}
|
||||
l->shadow_matrix = mat_vp * vpm * cam_ivm;
|
||||
}
|
||||
}
|
||||
/// cone shadows and shadow matrix
|
||||
phase.begin("shadows cone");
|
||||
renderConeShadows();
|
||||
phase.end();
|
||||
|
||||
/// omni shadows and shadow matrix
|
||||
phase.begin("shadows omni");
|
||||
renderOmniShadows();
|
||||
phase.end();
|
||||
|
||||
/// lights
|
||||
@@ -558,13 +643,29 @@ void Renderer::renderScene() {
|
||||
// qDebug() << last_img.size();
|
||||
}
|
||||
phase.end();
|
||||
|
||||
/*
|
||||
auto cone_ll = cur_lights.value(Light::Cone);
|
||||
if (!cone_ll.isEmpty()) {
|
||||
Light * l = cone_ll[0];
|
||||
l->shadow_map.blit(0, 0, 0, l->shadow_map.rect(), l->shadow_map.rect());
|
||||
static QOpenGLShaderProgram * tprog = nullptr;
|
||||
if (tprog && __reinit_debug) {
|
||||
delete tprog;
|
||||
tprog = nullptr;
|
||||
}
|
||||
*/
|
||||
if (!tprog) {
|
||||
loadShadersMulti(tprog, "./shaders/debug.glsl");
|
||||
tprog->bind();
|
||||
tprog->setUniformValue("tex_cone", (int)tarShadowsCone);
|
||||
tprog->setUniformValue("tex_omni", (int)tarShadowsOmni);
|
||||
QMatrix4x4 mat;
|
||||
double sz = 0.33;
|
||||
mat.translate(sz - 1, sz - 1);
|
||||
mat.scale(sz, sz);
|
||||
tprog->setUniformValue("qgl_ViewProjMatrix", mat);
|
||||
}
|
||||
__reinit_debug = false;
|
||||
tprog->bind();
|
||||
shadow_maps_cone.bind(f, tarShadowsCone);
|
||||
shadow_maps_omni.bind(f, tarShadowsOmni);
|
||||
quad->draw(f, 1);*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user