diff --git a/qglengine/core/glmaterial.cpp b/qglengine/core/glmaterial.cpp index 3c45fc3..b2c28ee 100644 --- a/qglengine/core/glmaterial.cpp +++ b/qglengine/core/glmaterial.cpp @@ -88,6 +88,7 @@ Map::Map() { color_amount = 1.f; color_offset = 0.f; bitmap_scale = QPointF(1., 1.); + use_bitmap = false; _changed = true; _layer = 0; } @@ -109,7 +110,7 @@ void Map::copyToQGLMap(QGLMap & m) const { m.amount = color_amount; m.offset = color_offset; m.scale = QVector2D(bitmap_scale); - if (hasBitmap()) { + if (hasBitmap() && use_bitmap) { m.array_index = tarMaps; m.map_index = _layer; } else { @@ -124,12 +125,12 @@ void Map::copyToQGLMap(QGLMap & m) const { Material::Material(const QString _name)/*: map_reflection(512)*/ { setTypes(); name = _name; - color_diffuse = color_specular = Qt::darkGray; + color_diffuse = Qt::white; color_emission = Qt::black; glass = false; transparency = reflectivity = 0.f; map_roughness.color_amount = 0.75f; - map_specular.color_amount = 1.f; + map_metalness.color_amount = 0.25f; iof = 1.f; dispersion = 0.05f; _changed = true; @@ -150,7 +151,7 @@ bool Material::hasTransparency() const { bool Material::isMapsChanged() const { return map_diffuse ._changed || map_normal ._changed || - map_specular ._changed || + map_metalness._changed || map_roughness._changed || map_emission ._changed || map_relief ._changed; @@ -161,7 +162,7 @@ bool Material::isMapChanged(int type) const { switch (type) { case mtDiffuse : return map_diffuse ._changed; case mtNormal : return map_normal ._changed; - case mtSpecular : return map_specular ._changed; + case mtMetalness: return map_metalness._changed; case mtRoughness: return map_roughness._changed; case mtEmission : return map_emission ._changed; case mtRelief : return map_relief ._changed; @@ -173,7 +174,7 @@ bool Material::isMapChanged(int type) const { void Material::load(TextureManager * tm) { map_diffuse .load(tm); map_normal .load(tm); - map_specular .load(tm); + map_metalness.load(tm); map_roughness.load(tm); map_emission .load(tm); map_relief .load(tm); @@ -183,7 +184,7 @@ void Material::load(TextureManager * tm) { void Material::setMapsChanged() { map_diffuse ._changed = true; map_normal ._changed = true; - map_specular ._changed = true; + map_metalness._changed = true; map_roughness._changed = true; map_emission ._changed = true; map_relief ._changed = true; @@ -191,10 +192,10 @@ void Material::setMapsChanged() { void Material::setTypes() { - map_diffuse ._type = mtDiffuse; - map_normal ._type = mtNormal; - map_specular ._type = mtSpecular; + map_diffuse ._type = mtDiffuse ; + map_normal ._type = mtNormal ; + map_metalness._type = mtMetalness; map_roughness._type = mtRoughness; - map_emission ._type = mtEmission; - map_relief ._type = mtRelief; + map_emission ._type = mtEmission ; + map_relief ._type = mtRelief ; } diff --git a/qglengine/core/glmaterial.h b/qglengine/core/glmaterial.h index d1fb6a0..90a3143 100644 --- a/qglengine/core/glmaterial.h +++ b/qglengine/core/glmaterial.h @@ -83,11 +83,12 @@ public: void load(TextureManager * tm); void copyToQGLMap(QGLEngineShaders::QGLMap & m) const; QString bitmap_path; - GLuint bitmap_id; + GLuint bitmap_id; QPointF bitmap_offset; QPointF bitmap_scale; float color_amount; float color_offset; + bool use_bitmap; bool _changed; int _type, _layer; @@ -105,7 +106,6 @@ public: void setTypes(); QString name; QColor color_diffuse; - QColor color_specular; QColor color_emission; bool glass; float transparency; @@ -114,7 +114,7 @@ public: float dispersion; Map map_diffuse ; Map map_normal ; - Map map_specular ; + Map map_metalness; Map map_roughness; Map map_emission ; Map map_relief ; @@ -126,21 +126,23 @@ public: inline QDataStream & operator <<(QDataStream & s, const Map & m) { ChunkStream cs; - cs.add(1, m.bitmap_path).add(2, m.color_amount).add(3, m.color_offset).add(6, m.bitmap_scale); + cs.add(1, m.bitmap_path).add(2, m.color_amount).add(3, m.color_offset).add(6, m.bitmap_scale) + .add(7, m.use_bitmap); s << cs.data(); return s; } inline QDataStream & operator >>(QDataStream & s, Map & m) { ChunkStream cs(s); cs.readAll(); - cs.get(1, m.bitmap_path).get(2, m.color_amount).get(3, m.color_offset).get(6, m.bitmap_scale); + cs.get(1, m.bitmap_path).get(2, m.color_amount).get(3, m.color_offset).get(6, m.bitmap_scale) + .get(7, m.use_bitmap); return s; } inline QDataStream & operator <<(QDataStream & s, const Material * m) { ChunkStream cs; - cs.add(1, m->name).add(2, m->color_diffuse).add(3, m->color_specular).add(4, m->color_emission) + cs.add(1, m->name).add(2, m->color_diffuse).add(4, m->color_emission) .add(5, m->transparency).add(6, m->reflectivity).add(7, m->glass).add(8, m->map_diffuse).add(9, m->map_normal) - .add(10, m->map_relief).add(11, m->map_specular).add(12, m->map_roughness).add(13, m->map_emission); + .add(10, m->map_relief).add(11, m->map_metalness).add(12, m->map_roughness).add(13, m->map_emission); s << /*qCompress*/(cs.data()); return s; } inline QDataStream & operator >>(QDataStream & s, Material *& m) { @@ -153,7 +155,6 @@ inline QDataStream & operator >>(QDataStream & s, Material *& m) { switch (cs.read()) { case 1: cs.get(m->name); break; case 2: cs.get(m->color_diffuse); break; - case 3: cs.get(m->color_specular); break; case 4: cs.get(m->color_emission); break; case 5: cs.get(m->transparency); break; case 6: cs.get(m->reflectivity); break; @@ -161,7 +162,7 @@ inline QDataStream & operator >>(QDataStream & s, Material *& m) { case 8: cs.get(m->map_diffuse); break; case 9: cs.get(m->map_normal); break; case 10: cs.get(m->map_relief); break; - case 11: cs.get(m->map_specular); break; + case 11: cs.get(m->map_metalness); break; case 12: cs.get(m->map_roughness); break; case 13: cs.get(m->map_emission); break; } diff --git a/qglengine/core/glshaders_headers.h b/qglengine/core/glshaders_headers.h index 8ddd960..df8827a 100644 --- a/qglengine/core/glshaders_headers.h +++ b/qglengine/core/glshaders_headers.h @@ -70,7 +70,7 @@ const char qgl_structs[] = "#define QGL_MAPS_COUNT 6\n" "#define QGL_MAP_DIFFUSE 0\n" "#define QGL_MAP_NORMAL 1\n" - "#define QGL_MAP_SPECULAR 2\n" + "#define QGL_MAP_METALNESS 2\n" "#define QGL_MAP_ROUGHNESS 3\n" "#define QGL_MAP_EMISSION 4\n" "#define QGL_MAP_RELIEF 5\n" @@ -85,7 +85,7 @@ const char qgl_structs[] = "};\n" "struct QGLMaterial {\n" " vec4 color_diffuse;\n" - " vec4 color_specular;\n" + //" vec4 color_specular;\n" " vec4 color_emission;\n" " float transparency;\n" " float reflectivity;\n" diff --git a/qglengine/core/glshaders_types.cpp b/qglengine/core/glshaders_types.cpp index 0564c61..4051e47 100644 --- a/qglengine/core/glshaders_types.cpp +++ b/qglengine/core/glshaders_types.cpp @@ -29,8 +29,7 @@ QGLEngineShaders::QGLMap::QGLMap() { QGLEngineShaders::QGLMaterial::QGLMaterial() { - color_diffuse = QVector4D(.5, .5, .5, 0.); - color_specular = QVector4D(.5, .5, .5, 0.); + color_diffuse = QVector4D(1., 1., 1., 0.); color_emission = QVector4D(0., 0., 0., 0.); transparency = 0.; reflectivity = 0.; @@ -38,6 +37,7 @@ QGLEngineShaders::QGLMaterial::QGLMaterial() { dispersion = 0.; map[mtNormal].map_index = emrBlue; map[mtRoughness].amount = 0.75; + map[mtMetalness].amount = 0.25; } diff --git a/qglengine/core/glshaders_types.h b/qglengine/core/glshaders_types.h index a7b7180..2b6bb82 100644 --- a/qglengine/core/glshaders_types.h +++ b/qglengine/core/glshaders_types.h @@ -87,7 +87,7 @@ enum BindingPoints { enum MapType { mtDiffuse = 0, mtNormal = 1, - mtSpecular = 2, + mtMetalness = 2, mtRoughness = 3, mtEmission = 4, mtRelief = 5, @@ -114,7 +114,6 @@ struct QGLMap { struct QGLMaterial { QGLMaterial(); QVector4D color_diffuse; - QVector4D color_specular; QVector4D color_emission; GLfloat transparency; GLfloat reflectivity; diff --git a/qglengine/formats/loader_assimp.cpp b/qglengine/formats/loader_assimp.cpp index 8ea663c..d848a06 100644 --- a/qglengine/formats/loader_assimp.cpp +++ b/qglengine/formats/loader_assimp.cpp @@ -112,16 +112,15 @@ Material * assimpMaterial(const aiMaterial * m) { // qDebug()<< fromAiString(m->mProperties[i]->mKey);// << "=" << aiMatFloat(m, m->mProperties[i]->mKey.C_Str(), 0, 0); //} ret->color_diffuse = aiMatColor(m, AI_MATKEY_COLOR_DIFFUSE); - ret->color_specular = aiMatColor(m, AI_MATKEY_COLOR_SPECULAR); ret->color_emission = aiMatColor(m, AI_MATKEY_COLOR_EMISSIVE); float shine = aiMatFloat(m, AI_MATKEY_SHININESS, -1.f); if (shine >= 0) { - ret->map_roughness.color_amount = 1.f - (shine / 100.f); + ret->map_roughness.color_amount = 0.8f - (shine / 100.f * 0.6f); //qDebug() << "shine" << shine; } ret->map_diffuse .bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_DIFFUSE(0)); ret->map_normal .bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_NORMALS(0)); - ret->map_specular .bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_SPECULAR(0)); + //ret->map_metalness.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_SPECULAR(0)); ret->map_roughness.bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_SHININESS(0)); ret->map_emission .bitmap_path = aiMatString(m, AI_MATKEY_TEXTURE_EMISSIVE(0)); ret->transparency = 1.f - aiMatFloat(m, AI_MATKEY_OPACITY, 1.f); diff --git a/qglengine/globject.cpp b/qglengine/globject.cpp index 5224aea..a592709 100644 --- a/qglengine/globject.cpp +++ b/qglengine/globject.cpp @@ -379,7 +379,7 @@ void ObjectBase::setMaterial(Material * m, bool with_children) { if (with_children) foreach (ObjectBase * i, children_) i->setMaterial(m, true); setObjectsChanged(); - if (scene_) scene_->mat_changed = true; + if (scene_) scene_->mat_changed = scene_->tree_changed = true; } diff --git a/qglengine/glscene.cpp b/qglengine/glscene.cpp index 75399b0..f8923c5 100644 --- a/qglengine/glscene.cpp +++ b/qglengine/glscene.cpp @@ -442,8 +442,6 @@ bool Scene::prepare() { if (!tree_changed && !mat_changed) return false; aol = root_->children(true); if (tree_changed) { - tree_changed = false; - lights_changed = true; geometries_used[rpSolid ].clear(); geometries_used[rpTransparent].clear(); lights_used.clear(); @@ -453,6 +451,8 @@ bool Scene::prepare() { cleanUnused(); QMetaObject::invokeMethod(this, "treeChanged", Qt::QueuedConnection); } + tree_changed = false; + lights_changed = true; } mat_changed = false; return true; diff --git a/qglengine/renderer.cpp b/qglengine/renderer.cpp index d2721d2..a7f0aaa 100644 --- a/qglengine/renderer.cpp +++ b/qglengine/renderer.cpp @@ -89,6 +89,7 @@ void Renderer::init(int width, int height) { tone_proc.init(); initQuad(quad); initTextureArrays(); + initCoeffTextures(); need_init_shaders = true; } @@ -155,6 +156,8 @@ void Renderer::initShaders() { if (!bindShader(roles[p], &prog)) continue; for (int i = 0; i < 5; ++i) prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i); + //prog->setUniformValue("tex_coeffs[0]", (int)Renderer::dbrBuffersCount); + //prog->setUniformValue("tex_coeffs[1]", (int)Renderer::dbrBuffersCount+1); } if (bindShader(srFinalPass, &prog)) { prog->setUniformValue("tex_g1" , 0); @@ -226,17 +229,26 @@ void Renderer::renderObjects(Scene & scene, RenderPass pass) { } -void Renderer::renderLight(int first_wr_buff) { +void Renderer::renderLight(int first_wr_buff, bool clear_only) { QOpenGLShaderProgram * prog = 0; Camera * cam = view->camera(); + for (int i = 0; i < 2; ++i) { + view->glActiveTexture(GL_TEXTURE0 + Renderer::dbrBuffersCount + i); + view->glBindTexture(GL_TEXTURE_2D, tex_coeff[i]); + } fbo_ds.bindColorTextures(); fbo_out.bind(); //int ri = 1, wi = 0; typedef QPair PassPair; QVector passes; passes << PassPair(srLightOmniPass, Light::Omni) << PassPair(srLightSpotPass, Light::Cone); + QColor back = view->fogColor_; + back.setAlpha(0); foreach (PassPair pass, passes) { if (bindShader(pass.first, &prog)) { + fbo_out.setWriteBuffer(first_wr_buff + pass.second); + glClearFramebuffer(back, false); + if (clear_only) continue; setUniformCamera(prog, cam); setUniformViewCorners(prog, cam); prog->setUniformValue("lights_start", lights_start[pass.second]); @@ -244,8 +256,6 @@ void Renderer::renderLight(int first_wr_buff) { prog->setUniformValue("fog_color", view->fogColor_); prog->setUniformValue("fog_decay", qMax(view->fogDecay_, 0.001f)); prog->setUniformValue("fog_density", view->fogDensity_); - fbo_out.setWriteBuffer(first_wr_buff + pass.second); - glClearFramebuffer(Qt::black, false); renderQuad(prog, quad, cam); } } @@ -307,7 +317,7 @@ void Renderer::renderScene() { fbo_ds.release(); /// lighting passes - renderLight(obrSolidOmni); + renderLight(obrSolidOmni, scene.geometries_used[rpSolid].isEmpty()); /// transparent geometry pass fbo_ds.bind(); @@ -319,7 +329,7 @@ void Renderer::renderScene() { fbo_ds.release(); /// lighting passes - renderLight(obrTransparentOmni); + renderLight(obrTransparentOmni, scene.geometries_used[rpTransparent].isEmpty()); /// blending layers if (bindShader(srFinalPass, &prog)) { diff --git a/qglengine/renderer.h b/qglengine/renderer.h index 150f012..4e1595f 100644 --- a/qglengine/renderer.h +++ b/qglengine/renderer.h @@ -30,6 +30,7 @@ class Renderer: public RendererBase { friend class QGLView; friend class MouseController; + friend class RendererBase; friend class RendererMaterial; friend class RendererService; friend class RendererSelection; @@ -58,7 +59,9 @@ class Renderer: public RendererBase { dbrNormalZ, dbrSpecularReflect, dbrEmissionRough, - //dbrSpeedBitangXY, + dbrSpeedBitangXY, + + dbrBuffersCount, }; enum OutBufferRole { obrTonemap, @@ -89,7 +92,7 @@ protected: void fillObjectsBuffer(const ObjectBaseList & ol, RenderPass pass); void reloadObjects(); void renderObjects(Scene & scene, RenderPass pass); - void renderLight(int first_wr_buff); + void renderLight(int first_wr_buff, bool clear_only); bool bindShader(ShaderRole role, QOpenGLShaderProgram ** ret = 0); bool bindShader(QOpenGLShaderProgram * sp); diff --git a/qglengine/renderer_base.cpp b/qglengine/renderer_base.cpp index e22e877..5f63039 100644 --- a/qglengine/renderer_base.cpp +++ b/qglengine/renderer_base.cpp @@ -19,6 +19,7 @@ #define GL_GLEXT_PROTOTYPES #include #include "renderer_base.h" +#include "renderer.h" #include "qglview.h" #include "glmesh.h" #include "gltexture_manager.h" @@ -38,6 +39,7 @@ RendererBase::RendererBase(QGLView * view_): textures_manager = new TextureManager(view); maps_size = QSize(512, 512); maps_hash = 0; + tex_coeff[0] = tex_coeff[1] = 0; } @@ -145,7 +147,7 @@ void RendererBase::reloadMaterials(Scene & scene) { foreach (Material * m, scene.materials) { if (m->map_diffuse .hasBitmap()) maps[0] << &(m->map_diffuse ); if (m->map_normal .hasBitmap()) maps[1] << &(m->map_normal ); - if (m->map_specular .hasBitmap()) maps[0] << &(m->map_specular ); + if (m->map_metalness.hasBitmap()) maps[0] << &(m->map_metalness); if (m->map_roughness.hasBitmap()) maps[0] << &(m->map_roughness); if (m->map_emission .hasBitmap()) maps[0] << &(m->map_emission ); if (m->map_relief .hasBitmap()) maps[0] << &(m->map_relief ); @@ -189,7 +191,6 @@ void RendererBase::reloadMaterials(Scene & scene) { m->_index = cur_materials_.size(); m->_changed = false; glm.color_diffuse = QColor2QVector(m->color_diffuse ); - glm.color_specular = QColor2QVector(m->color_specular); glm.color_emission = QColor2QVector(m->color_emission); glm.transparency = m->transparency; glm.reflectivity = m->reflectivity; @@ -197,7 +198,7 @@ void RendererBase::reloadMaterials(Scene & scene) { glm.dispersion = m->dispersion ; m->map_diffuse .copyToQGLMap(glm.map[mtDiffuse ]); m->map_normal .copyToQGLMap(glm.map[mtNormal ]); - m->map_specular .copyToQGLMap(glm.map[mtSpecular ]); + m->map_metalness.copyToQGLMap(glm.map[mtMetalness ]); m->map_roughness.copyToQGLMap(glm.map[mtRoughness]); m->map_emission .copyToQGLMap(glm.map[mtEmission ]); m->map_relief .copyToQGLMap(glm.map[mtRelief ]); @@ -298,3 +299,50 @@ void RendererBase::renderQuad(QOpenGLShaderProgram * prog, Mesh * mesh, Camera * setUniformCamera(prog, cam, false); mesh->draw(view, 1); } + + +void RendererBase::initCoeffTextures() { + /*const int size = 512; + QVector data_diff(size*size), data_spec(size*size); + double r, c, c2; + int ind = -1; + for (int x = 0; x < size; ++x) { + c = x / double(size - 1); + c = sqrt(c); + c = piMax(1.E-16, c); + c2 = c*c; + for (int y = 0; y < size; ++y) { + r = y / double(size - 1); + double r_d = r; + double r_s = r*r*r; + r_d = piMax(1.E-16, r_d); + r_s = piMax(1.E-16, r_s); + + double ndlc = (1. - c2) / c2; + double diff = 2. / (1. + sqrt(1. + (1. - r_d) * ndlc)); + + double spec = c2 * (r_s + ndlc); + spec = r_s / (spec * spec) / M_PI; + + ++ind; + data_diff[ind] = piClamp(diff, 1.E-12, 1.E+36); + data_spec[ind] = piClamp(spec, 1.E-12, 1.E+36); + } + } + createCoeffTexture(tex_coeff[0], data_diff, size); + createCoeffTexture(tex_coeff[1], data_spec, size);*/ +} + + +void RendererBase::createCoeffTexture(GLuint & id, const QVector & data, int size) { + 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_CLAMP_TO_EDGE ); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + f->glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, size, size, 0, GL_RED, GL_FLOAT, data.constData()); +} diff --git a/qglengine/renderer_base.h b/qglengine/renderer_base.h index 0019d91..9cb4370 100644 --- a/qglengine/renderer_base.h +++ b/qglengine/renderer_base.h @@ -45,6 +45,8 @@ protected: void setMapsSize(QSize sz); void initQuad(Mesh * mesh, QMatrix4x4 mat = QMatrix4x4()); void renderQuad(QOpenGLShaderProgram * prog, Mesh * mesh, Camera * cam = 0, bool uniforms = true); + void initCoeffTextures(); + void createCoeffTexture(GLuint & id, const QVector & data, int size); QGLView * view; TextureManager * textures_manager; @@ -57,6 +59,7 @@ protected: Texture2DArray textures_empty, textures_maps; QSize maps_size; uint maps_hash; + GLuint tex_coeff[2]; QMap lights_start; QList current_lights; diff --git a/qglengine/renderer_material.cpp b/qglengine/renderer_material.cpp index c111e87..31ff9ac 100644 --- a/qglengine/renderer_material.cpp +++ b/qglengine/renderer_material.cpp @@ -66,7 +66,7 @@ void RendererMaterial::renderMaterial(Material * m) { QOpenGLExtraFunctions * f = r->view; fbo_mat_thumb.bind(); glEnableDepth(); - glClearFramebuffer(); + glClearFramebuffer(QColor(0,0,0,0)); if (r->bindShader(Renderer::srGeometryPass, &prog)) { r->setUniformMaps(prog); r->setUniformCamera(prog, mat_camera, true, fbo_mat_thumb.size()); diff --git a/qglengine/shaders/ds_geom.glsl b/qglengine/shaders/ds_geom.glsl index 2d7967a..617a6ee 100644 --- a/qglengine/shaders/ds_geom.glsl +++ b/qglengine/shaders/ds_geom.glsl @@ -42,7 +42,8 @@ void main(void) { dn *= dn_sl / (length(dn) + 1E-6); normal = normalize(geom_normal + dn); - vec4 specular = qgl_materialTexture(QGL_MAP_SPECULAR, tc, vec4(0)) * qgl_material[qgl_MaterialIndex].color_specular; + float metalness = dot(qgl_materialTexture(QGL_MAP_METALNESS, tc, vec4(0)).rgb, luma); + metalness = clamp(metalness, 0, 1); float roughness = dot(qgl_materialTexture(QGL_MAP_ROUGHNESS, tc, vec4(0)).rgb, luma); roughness = clamp(roughness, 0.0001, 0.9999); @@ -60,8 +61,8 @@ void main(void) { qgl_FragData[0] = vec4(diffuse .rgba); qgl_FragData[1] = vec4(normal .xyz, z); - qgl_FragData[2] = vec4(specular.rgb, reflectivity); - qgl_FragData[3] = vec4(emission.rgb, roughness/*bn.x*/); + qgl_FragData[2] = vec4(metalness, roughness, reflectivity, 0); + qgl_FragData[3] = vec4(emission.rgb, 0/*bn.x*/); //qgl_FragData[4] = vec4(speed.xy, bn.yz); //ivec2 itc = ivec2(gl_FragCoord.xy); diff --git a/qglengine/shaders/ds_light.glsl b/qglengine/shaders/ds_light.glsl index 86581c6..ebb79b2 100644 --- a/qglengine/shaders/ds_light.glsl +++ b/qglengine/shaders/ds_light.glsl @@ -5,6 +5,7 @@ out vec3 view_dir; uniform vec4 view_corners[4]; void main(void) { + qgl_FragTexture = qgl_Texture; gl_Position = qgl_ftransform(); view_dir = view_corners[gl_VertexID].xyz; } @@ -16,6 +17,7 @@ in vec3 view_dir; uniform vec2 dt; uniform float z_near; +uniform sampler2D tex_coeffs[2]; uniform sampler2D tex_0, tex_1, tex_2, tex_3, tex_4; uniform int lights_start, lights_count; @@ -23,12 +25,12 @@ uniform vec4 fog_color = vec4(0.5, 0.5, 0.5, 1); uniform float fog_decay = 10, fog_density = 0; const vec3 luma = vec3(0.299, 0.587, 0.114); -const float _pe = 2.4e-7, _min_rough = 1.e-8; +const float _min_rough = 1.e-8; vec4 pos, lpos, shp; vec3 li, si, ldir, halfV, bn, bn2, lwdir; //vec3 vds, vds2; -float shm_diff, shm_spec, dist, NdotL, NdotH, spot, ldist, diff, sdist, shadow; +float rough_diff, rough_spec, dist, NdotL, NdotH, spot, ldist, diff, spec, sdist, shadow; void calcLight(in int index, in vec3 n, in vec3 v) { lpos = qgl_light_position[index].position; @@ -77,17 +79,20 @@ void calcLight(in int index, in vec3 n, in vec3 v) { #endif vec3 dist_decay = vec3(1, ldist, ldist*ldist); spot /= dot(qgl_light_parameter[index].decay_intensity.xyz, dist_decay); + float NdotLs = NdotL*NdotL; float NdotHs = NdotH*NdotH; float ndlc = (1. - NdotLs) / NdotLs; - float der = NdotLs * (shm_diff + ndlc); - diff = 2. / (1. + sqrt(1. + (1. - shm_diff) * ndlc)); + diff = 2. / (1. + sqrt(1. + (1. - rough_diff) * ndlc)); + //diff = texture(tex_coeffs[0], vec2(roughness, (NdotLs))).r; li += spot * diff * qgl_light_parameter[index].color.rgb; ndlc = (1. - NdotHs) / NdotHs; - der = NdotHs * (shm_spec + ndlc); - si += spot * (shm_spec / (der*der) / 3.1416) * qgl_light_parameter[index].color.rgb; + float der = NdotHs * (rough_spec + ndlc); + spec = rough_spec / (der*der) / 3.1416; + //spec = texture(tex_coeffs[1], vec2(roughness, (NdotHs))).r; + si += spot * spec * qgl_light_parameter[index].color.rgb; } void main(void) { @@ -95,8 +100,7 @@ void main(void) { vec4 v1 = texelFetch(tex_1, tc, 0); float z = v1.w; if (z == 1.) { - qgl_FragColor = vec4(fog_color.rgb, 0); - return; + discard; } pos.w = 1; pos.xyz = view_dir * z; @@ -109,23 +113,25 @@ void main(void) { vec3 diffuse = v0.rgb; vec3 normal = v1.xyz; - vec3 specular = v2.rgb; vec3 emission = v3.rgb; float alpha = v0.a; - float reflectivity = v2.w; - float roughness = v3.w; + float metalness = v2.r; + float roughness = v2.g; + float reflectivity = v2.b; //bn = normalize(vec3(v3.w, v4.zw)); //bn2 = normalize(cross(n, bn)); - roughness = max(roughness, _min_rough); + rough_diff = max(roughness, _min_rough); + rough_spec = max(roughness*roughness*roughness, _min_rough); + float shlick = clamp(metalness + (1 - metalness) * pow(1 - dot(normal, v), 5), 0, 1); - shm_diff = roughness; - shm_spec = max(roughness*roughness*roughness, _min_rough); - //sh_pow = 1. / max(roughness, 0.00001); li = vec3(0.);//qgl_AmbientLight.color.rgb * qgl_AmbientLight.intensity; si = vec3(0.); for (int i = 0; i < lights_count; ++i) calcLight(lights_start + i, normal, v); - vec3 res_col = max(vec3(0), li * diffuse + si * specular + emission); + si *= shlick; + li *= (1 - shlick); + alpha = min(1, alpha * (1 + shlick)); + vec3 res_col = max(vec3(0), li * diffuse + si * mix(vec3(1), diffuse, metalness) + emission); float plen = length(pos.xyz); float fog = 1 - exp(-plen / fog_decay); @@ -133,5 +139,7 @@ void main(void) { res_col = mix(res_col, fog_color.rgb, fog); qgl_FragColor = vec4(res_col, alpha); - //qgl_FragColor.rgb = vec3(normal); + + //qgl_FragColor.rgb = vec3(texture(tex_coeffs[0], qgl_FragTexture.xy).r); + //qgl_FragColor.rgb = vec3(ldir); } diff --git a/qglengine/widgets/material_editor.cpp b/qglengine/widgets/material_editor.cpp index 1456296..c7ecbb5 100644 --- a/qglengine/widgets/material_editor.cpp +++ b/qglengine/widgets/material_editor.cpp @@ -24,11 +24,18 @@ MaterialEditor::MaterialEditor(QWidget * parent): QWidget(parent) { ui = new Ui::MaterialEditor(); ui->setupUi(this); + ui->mapDiffuse ->configure(tr("Diffuse"), true); + ui->mapNormal ->configure(tr("Normal")); + ui->mapMetalness->configure(tr("Metalness")); + ui->mapRoughness->configure(tr("Roughness")); + ui->mapEmission ->configure(tr("Emission"), true); + ui->mapRelief ->configure(tr("Relief")); ui->checkGlass->hide(); ui->frameReflection->hide(); ui->label_13->hide(); mat = 0; active = true; + ignore_next = 0; } @@ -46,27 +53,30 @@ void MaterialEditor::changeEvent(QEvent * e) { void MaterialEditor::materialChanged() { if (!active || !mat) return; + ignore_next = 2; mat->_changed = true; - mat->color_diffuse = ui->colorDiffuse ->color(); - mat->color_specular = ui->colorSpecular->color(); - mat->color_emission = ui->colorEmission->color(); + mat->color_diffuse = ui->mapDiffuse ->color(); + mat->color_emission = ui->mapEmission->color(); mat->transparency = ui->spinTransparent->value(); mat->reflectivity = ui->spinReflect->value(); mat->iof = ui->spinIOF->value(); mat->dispersion = ui->spinDispersion->value(); mat->glass = ui->checkGlass->isChecked(); - emit changed(); + //emit changed(); } void MaterialEditor::setMaterial(Material * m) { + if (ignore_next > 0) { + //ignore_next = false; + return; + } active = false; mat = m; setEnabled(m); if (!mat) return; - ui->colorDiffuse ->setColor(mat->color_diffuse ); - ui->colorSpecular->setColor(mat->color_specular); - ui->colorEmission->setColor(mat->color_emission); + ui->mapDiffuse ->setColor(mat->color_diffuse ); + ui->mapEmission->setColor(mat->color_emission); ui->spinTransparent->setValue(mat->transparency); ui->spinReflect->setValue(mat->reflectivity); ui->spinIOF->setValue(mat->iof); @@ -74,7 +84,7 @@ void MaterialEditor::setMaterial(Material * m) { ui->checkGlass->setChecked(mat->glass); ui->mapDiffuse ->setMap(&(mat->map_diffuse )); ui->mapNormal ->setMap(&(mat->map_normal )); - ui->mapSpecular ->setMap(&(mat->map_specular )); + ui->mapMetalness->setMap(&(mat->map_metalness)); ui->mapRoughness->setMap(&(mat->map_roughness)); ui->mapEmission ->setMap(&(mat->map_emission )); ui->mapRelief ->setMap(&(mat->map_relief )); diff --git a/qglengine/widgets/material_editor.h b/qglengine/widgets/material_editor.h index 315f050..d0eae41 100644 --- a/qglengine/widgets/material_editor.h +++ b/qglengine/widgets/material_editor.h @@ -28,6 +28,7 @@ namespace Ui { class MaterialEditor: public QWidget { + friend class MaterialsEditor; Q_OBJECT public: explicit MaterialEditor(QWidget * parent = 0); @@ -38,6 +39,7 @@ protected: void changeEvent(QEvent * e); bool active; + int ignore_next; Ui::MaterialEditor * ui; Material * mat; diff --git a/qglengine/widgets/material_editor.ui b/qglengine/widgets/material_editor.ui index 8912e7c..307d6a7 100644 --- a/qglengine/widgets/material_editor.ui +++ b/qglengine/widgets/material_editor.ui @@ -7,7 +7,7 @@ 0 0 435 - 817 + 535 @@ -24,276 +24,87 @@ 0 - + - font:bold; + font:normal; - - Diffuse - - - true - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - font:normal; - - - Color: - - - - - - - Qt::NoFocus - - - font:normal; - - - true - - - - - - - font:normal; - - - - - - - - - - font:bold; + + + Qt::Horizontal - - Normal - - - true - - - - - - font:normal; - - - - - + - font:bold; + font:normal; - - Specular - - - true - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - font:normal; - - - Color: - - - - - - - Qt::NoFocus - - - font:normal; - - - true - - - - - - - font:normal; - - - - - - - - - - font:bold; + + + Qt::Horizontal - - Roughness - - - true - - - - - - font:normal; - - - - - + - font:bold; + font:normal; - - Emisson - - - true - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - font:normal; - - - Color: - - - - - - - Qt::NoFocus - - - font:normal; - - - true - - - - - - - font:normal; - - - - - - - - + + + Qt::Horizontal + + + + + - font:bold; + font:normal; - - Relief + + + + + + Qt::Horizontal - - true + + + + + + font:normal; + + + + + + + Qt::Horizontal + + + + + + + font:normal; + + + + + + + Qt::Horizontal - - - - - font:normal; - - - - @@ -631,11 +442,6 @@ QWidget
spinslider.h
- - ColorButton - QPushButton -
colorbutton.h
-
MaterialMapEditor QWidget @@ -648,38 +454,6 @@ - - colorDiffuse - colorChanged(QColor) - MaterialEditor - materialChanged() - - - 326 - 49 - - - 282 - 17 - - - - - colorSpecular - colorChanged(QColor) - MaterialEditor - materialChanged() - - - 376 - 202 - - - 284 - 45 - - - spinTransparent valueChanged(double) @@ -688,7 +462,7 @@ 433 - 497 + 468 283 @@ -704,7 +478,7 @@ 433 - 526 + 497 284 @@ -720,7 +494,7 @@ 433 - 555 + 526 284 @@ -736,7 +510,7 @@ 433 - 468 + 439 284 @@ -744,22 +518,6 @@ - - colorEmission - colorChanged(QColor) - MaterialEditor - materialChanged() - - - 421 - 351 - - - 326 - 63 - - - spinDispersion valueChanged(double) @@ -768,7 +526,7 @@ 433 - 584 + 555 326 @@ -793,14 +551,14 @@ - mapSpecular + mapMetalness changed() MaterialEditor materialChanged() 421 - 218 + 189 434 @@ -816,7 +574,7 @@ 421 - 367 + 338 434 @@ -848,7 +606,7 @@ 421 - 427 + 398 434 @@ -864,7 +622,7 @@ 421 - 278 + 249 434 @@ -872,102 +630,6 @@ - - groupDiffuse - toggled(bool) - widgetDiffuse - setVisible(bool) - - - 40 - 10 - - - 47 - 56 - - - - - groupNormal - toggled(bool) - mapNormal - setVisible(bool) - - - 54 - 103 - - - 55 - 123 - - - - - groupSpecular - toggled(bool) - widgetSpecular - setVisible(bool) - - - 72 - 162 - - - 71 - 205 - - - - - groupRoughness - toggled(bool) - mapRoughness - setVisible(bool) - - - 56 - 246 - - - 55 - 273 - - - - - groupEmission - toggled(bool) - widgetEmission - setVisible(bool) - - - 67 - 314 - - - 71 - 353 - - - - - groupRelief - toggled(bool) - mapRelief - setVisible(bool) - - - 42 - 397 - - - 44 - 422 - - - materialChanged() diff --git a/qglengine/widgets/material_map_editor.cpp b/qglengine/widgets/material_map_editor.cpp index 95c93d8..7f96f8e 100644 --- a/qglengine/widgets/material_map_editor.cpp +++ b/qglengine/widgets/material_map_editor.cpp @@ -25,6 +25,7 @@ MaterialMapEditor::MaterialMapEditor(QWidget * parent): QWidget(parent) { ui = new Ui::MaterialMapEditor(); ui->setupUi(this); + ui->widgetMap->hide(); active = true; } @@ -42,8 +43,9 @@ void MaterialMapEditor::changeEvent(QEvent * e) { void MaterialMapEditor::resizeEvent(QResizeEvent * e) { - ui->iconedLabel->setFixedWidth(ui->iconedLabel->height()); - ui->iconedLabel->setIconSize(ui->iconedLabel->size()); + QSize sz = preferredIconSize(6, this); + ui->iconedLabel->setFixedSize(sz); + ui->iconedLabel->setIconSize(sz); } @@ -54,10 +56,18 @@ void MaterialMapEditor::updateIcon() { void MaterialMapEditor::mapChanged() { if (!active || !map) return; - map->color_amount = ui->sliderAmount->value(); - map->color_offset = ui->sliderOffset->value(); + active = false; + map->use_bitmap = ui->checkMap->isChecked(); + if (ui->checkMap->isChecked()) { + map->color_amount = ui->sliderAmount->value(); + map->color_offset = ui->sliderOffset->value(); + } else { + map->color_amount = ui->sliderValue->value(); + map->color_offset = 0.f; + } map->bitmap_scale.setX(ui->spinScaleX->value()); map->bitmap_scale.setY(ui->spinScaleY->value()); + active = true; emit changed(); } @@ -67,6 +77,9 @@ void MaterialMapEditor::setMap(Map * m) { map = m; setEnabled(m); if (!map) return; + ui->stackedWidget->setCurrentIndex(map->use_bitmap ? 1 : 0); + ui->checkMap->setChecked(map->use_bitmap); + ui->sliderValue->setValue(map->color_amount); ui->sliderAmount->setValue(map->color_amount); ui->sliderOffset->setValue(map->color_offset); ui->spinScaleX->setValue(map->bitmap_scale.x()); @@ -76,6 +89,24 @@ void MaterialMapEditor::setMap(Map * m) { active = true; } + +void MaterialMapEditor::configure(QString title, bool has_color) { + ui->labelTitle->setText(title); + ui->colorButton->setVisible(has_color); +} + + +void MaterialMapEditor::setColor(QColor c) { + active = false; + ui->colorButton->setColor(c); + active = true; +} + + +QColor MaterialMapEditor::color() const { + return ui->colorButton->color(); +} + /* Map MaterialMapEditor::map() { Map m; @@ -106,3 +137,14 @@ void MaterialMapEditor::on_buttonClear_clicked() { updateIcon(); mapChanged(); } + + +void MaterialMapEditor::on_checkMap_toggled(bool checked) { + if (checked) { + ui->sliderAmount->setValue(ui->sliderValue->value()); + resizeEvent(0); + } else + ui->sliderValue->setValue(ui->sliderAmount->value()); + ui->stackedWidget->setCurrentIndex(checked ? 1 : 0); + mapChanged(); +} diff --git a/qglengine/widgets/material_map_editor.h b/qglengine/widgets/material_map_editor.h index 65e2a5f..c0c9f91 100644 --- a/qglengine/widgets/material_map_editor.h +++ b/qglengine/widgets/material_map_editor.h @@ -33,6 +33,9 @@ public: explicit MaterialMapEditor(QWidget * parent = 0); void setMap(Map * m); + void configure(QString title, bool has_color = false); + void setColor(QColor c); + QColor color() const; protected: void changeEvent(QEvent * e); @@ -47,6 +50,7 @@ private slots: void mapChanged(); void on_buttonSelect_clicked(); void on_buttonClear_clicked(); + void on_checkMap_toggled(bool checked); signals: void changed(); diff --git a/qglengine/widgets/material_map_editor.ui b/qglengine/widgets/material_map_editor.ui index 668e97d..33ca383 100644 --- a/qglengine/widgets/material_map_editor.ui +++ b/qglengine/widgets/material_map_editor.ui @@ -6,11 +6,11 @@ 0 0 - 587 - 138 + 725 + 218 - + 0 @@ -24,197 +24,313 @@ 0 - - - IconedLabel::RightToLeft - - - - - - - - - 2 + + + + + + 0 + 0 + + + + font: bold; - - - - - - - - :/icons/edit-delete.png:/icons/edit-delete.png - - - - - - - - :/icons/document-open.png:/icons/document-open.png - - - - - - - - Amount: + title: - - - - -1.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - 2 - - - 0.050000000000000 - - - 0.200000000000000 - - - -99.000000000000000 - - - 99.000000000000000 + + + + + 0 + 0 + - - + + + + + 0 + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + 2 + + + 0.050000000000000 + + + 0.200000000000000 + + + 0.000000000000000 + + + 1.000000000000000 + + + + + + + + + + + + + 0 + 0 + + - Offset: + Map - - - - -1.000000000000000 - - - 1.000000000000000 - - - 2 - - - 0.050000000000000 - - - 0.200000000000000 - - - -99.000000000000000 - - - 99.000000000000000 - - - - - - - - - - 0 - 0 - - - - Scale X: - - - - - - - 9999.000000000000000 - - - 0.100000000000000 - - - 1.000000000000000 - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 20 - 20 - - - - - - - - - 0 - 0 - - - - Scale Y: - - - - - - - 9999.000000000000000 - - - 0.100000000000000 - - - 1.000000000000000 - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 1 - 20 - - - - - - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + IconedLabel::RightToLeft + + + + + + + + + 2 + + + + + + + + + :/icons/edit-delete.png:/icons/edit-delete.png + + + + + + + + :/icons/document-open.png:/icons/document-open.png + + + + + + + + + Amount: + + + + + + + -1.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + 2 + + + 0.050000000000000 + + + 0.200000000000000 + + + -99.000000000000000 + + + 99.000000000000000 + + + + + + + Offset: + + + + + + + -1.000000000000000 + + + 1.000000000000000 + + + 2 + + + 0.050000000000000 + + + 0.200000000000000 + + + -99.000000000000000 + + + 99.000000000000000 + + + + + + + + + + 0 + 0 + + + + Scale X: + + + + + + + 9999.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 20 + 20 + + + + + + + + + 0 + 0 + + + + Scale Y: + + + + + + + 9999.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 1 + 20 + + + + + + + + + + + @@ -223,6 +339,11 @@ QWidget
spinslider.h
+ + ColorButton + QPushButton +
colorbutton.h
+
IconedLabel QFrame @@ -230,8 +351,8 @@ - - + + @@ -241,8 +362,8 @@ mapChanged() - 471 - 22 + 598 + 55 99 @@ -257,8 +378,8 @@ mapChanged() - 440 - 38 + 655 + 87 512 @@ -273,8 +394,8 @@ mapChanged() - 497 - 66 + 655 + 116 511 @@ -289,8 +410,8 @@ mapChanged() - 377 - 104 + 491 + 146 332 @@ -305,8 +426,8 @@ mapChanged() - 519 - 110 + 647 + 146 493 @@ -314,6 +435,70 @@ + + checkMap + toggled(bool) + sliderValue + setHidden(bool) + + + 693 + 15 + + + 626 + 14 + + + + + checkMap + toggled(bool) + widgetMap + setVisible(bool) + + + 686 + 9 + + + 695 + 62 + + + + + sliderValue + valueChanged(double) + MaterialMapEditor + mapChanged() + + + 99 + 15 + + + 130 + 28 + + + + + colorButton + colorChanged(QColor) + MaterialMapEditor + mapChanged() + + + 60 + 11 + + + 75 + 27 + + + mapChanged() diff --git a/qglengine/widgets/materials_editor.cpp b/qglengine/widgets/materials_editor.cpp index 3b9b932..7ae6147 100644 --- a/qglengine/widgets/materials_editor.cpp +++ b/qglengine/widgets/materials_editor.cpp @@ -114,6 +114,10 @@ void MaterialsEditor::selectionChanged() { void MaterialsEditor::materialsChanged() { + if (ui->widgetMaterial->ignore_next > 0) { + ui->widgetMaterial->ignore_next--; + return; + } Material * cm = currentMaterial(); ui->comboMaterial->clear(); if (!view) return;