diff --git a/include/Model.h b/include/Model.h index 097f1b0..0fbfdad 100644 --- a/include/Model.h +++ b/include/Model.h @@ -59,15 +59,16 @@ class Node // Материал модели struct Material { - alignas(16) glm::vec3 ka; // коэф. фонового отражения (цвет фонового освещения) - alignas(16) glm::vec3 kd; // коэф. диффузного отражения (цвет объекта) - alignas(16) glm::vec3 ks; // коэф. зеркального блика - float p; // показатель глянцевости + alignas(16) glm::vec3 base_color; // Базовый цвет материала + float roughness; // Шероховатость поверхности + float metallic; // Металличность поверхности + float specular; // Интенсивность блика диэлектриков + alignas(16) glm::vec3 emitted; // Излучаемый поверхностью свет int normalmapped; // Использование карт нормалей int parallaxmapped; // Использование параллакса int displacementmapped; // Использование карт высот для сдвига вершин // Значения по умолчанию - Material() : ka(0.2f), kd(0.2f), ks(0.2f), p(1), normalmapped(false), parallaxmapped(false), displacementmapped(false) { }; + Material() : base_color(0.8f), roughness(0.5f), metallic(0.0f), specular(0.5f), emitted(0.0f), normalmapped(false), parallaxmapped(false), displacementmapped(false) { }; }; // Идентификатор модели @@ -108,9 +109,11 @@ class Model : public Node BO tangent_vbo, bitangent_vbo; // буферы с касательными и бикасательными векторами GLuint verteces_count; // Количество вершин size_t first_index_byteOffset, indices_count; // Сдвиг в байтах для первого и количество индексов - Texture texture_diffuse; // Диффузная текстура - Texture texture_ambient; // Текстура фонового освщения - Texture texture_specular; // Текстура зеркального отражения + Texture texture_albedo; // Текстура альбедо (цвет поверхности) + Texture texture_roughness; // Текстура шероховатостей + Texture texture_metallic; // Текстура металличности + Texture texture_specular; // Текстура интенсивности блика диэлектриков + Texture texture_emitted; // Текстура излучаемого света Texture texture_heights; // Текстура высот Texture texture_normals; // Текстура нормалей }; diff --git a/include/Texture.h b/include/Texture.h index 0aa2a95..fcc365e 100644 --- a/include/Texture.h +++ b/include/Texture.h @@ -7,9 +7,11 @@ #include enum TexType { - TEX_DIFFUSE, - TEX_AMBIENT, + TEX_ALBEDO, + TEX_ROUGHNESS, + TEX_METALLIC, TEX_SPECULAR, + TEX_EMITTED, TEX_HEIGHTS, TEX_NORMAL, TEX_AVAILABLE_COUNT @@ -36,13 +38,13 @@ class Texture : public BaseTexture { public: Texture(GLuint type = TEX_AVAILABLE_COUNT, const std::string& filename = ""); // Загрузка текстуры с диска или использование "пустой" - Texture(GLuint width, GLuint height, GLuint attachment, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера для использования в буфере - Texture(GLuint width, GLuint height, void* data, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера без привязки к буферу с загрузкой пикселей по указателю + Texture(GLuint width, GLuint height, GLuint attachment, GLuint texType = TEX_ALBEDO, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера для использования в буфере + Texture(GLuint width, GLuint height, void* data, GLuint texType = TEX_ALBEDO, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера без привязки к буферу с загрузкой пикселей по указателю Texture(const Texture& other); // Конструктор копирования Texture& operator=(const Texture& other); // Оператор присваивания - void reallocate(GLuint width, GLuint height, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора + void reallocate(GLuint width, GLuint height, GLuint texType = TEX_ALBEDO, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора virtual void use(); // Привязка текстуры }; @@ -51,12 +53,12 @@ class Texture : public BaseTexture class TextureArray : public BaseTexture { public: - TextureArray(GLuint levels, GLuint width, GLuint height, GLuint attachment, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера для использования в буфере + TextureArray(GLuint levels, GLuint width, GLuint height, GLuint attachment, GLuint texType = TEX_ALBEDO, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера для использования в буфере TextureArray(const TextureArray& other); // Конструктор копирования TextureArray& operator=(const TextureArray& other); // Оператор присваивания - void reallocate(GLuint levels, GLuint width, GLuint height, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора + void reallocate(GLuint levels, GLuint width, GLuint height, GLuint texType = TEX_ALBEDO, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора virtual void use(); // Привязка текстуры }; @@ -66,12 +68,12 @@ class TextureCube : public BaseTexture { public: TextureCube(GLuint type = TEX_AVAILABLE_COUNT, const std::string (&filename)[6] = {""}); // Загрузка текстуры с диска или использование "пустой" - TextureCube(GLuint width, GLuint height, GLuint attachment, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера для использования в буфере + TextureCube(GLuint width, GLuint height, GLuint attachment, GLuint texType = TEX_ALBEDO, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера для использования в буфере TextureCube(const TextureCube& other); // Конструктор копирования TextureCube& operator=(const TextureCube& other); // Оператор присваивания - void reallocate(GLuint width, GLuint height, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора + void reallocate(GLuint width, GLuint height, GLuint texType = TEX_ALBEDO, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора virtual void use(); // Привязка текстуры }; @@ -80,12 +82,12 @@ class TextureCube : public BaseTexture class TextureCubeArray : public BaseTexture { public: - TextureCubeArray(GLuint levels, GLuint width, GLuint height, GLuint attachment, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера для использования в буфере + TextureCubeArray(GLuint levels, GLuint width, GLuint height, GLuint attachment, GLuint texType = TEX_ALBEDO, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Конструктор текстуры заданного размера для использования в буфере TextureCubeArray(const TextureCubeArray& other); // Конструктор копирования TextureCubeArray& operator=(const TextureCubeArray& other); // Оператор присваивания - void reallocate(GLuint levels, GLuint width, GLuint height, GLuint texType = TEX_DIFFUSE, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора + void reallocate(GLuint levels, GLuint width, GLuint height, GLuint texType = TEX_ALBEDO, GLint internalformat = GL_RGBA, GLint format = GL_RGBA, GLenum dataType = GL_FLOAT); // Пересоздает текстуру для имеющегося дескриптора virtual void use(); // Привязка текстуры }; diff --git a/src/Lights.cpp b/src/Lights.cpp index eeb683c..058b10c 100644 --- a/src/Lights.cpp +++ b/src/Lights.cpp @@ -218,7 +218,7 @@ void Light::render(ShaderProgram &shaderProgram, UBO &material_buffer) bulb.root.e_position() = data[i].position; sphere.e_scale() = glm::vec3(data[i].attenuation.r); // Масштабирование сферы // Задание цвета - bulb.models.begin()->material.ka = sphere.material.ka = data[i].color; + bulb.models.begin()->material.base_color = sphere.material.base_color = data[i].color; // Вызов отрисовки bulb.render(shaderProgram, material_buffer); diff --git a/src/Model.cpp b/src/Model.cpp index b4e60ed..ecc971e 100644 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -216,7 +216,7 @@ vao(copy.vao), verteces_count(copy.verteces_count), first_index_byteOffset(copy.first_index_byteOffset), indices_count(copy.indices_count), vertex_vbo(copy.vertex_vbo), index_vbo(copy.index_vbo), normals_vbo(copy.normals_vbo), texCoords_vbo(copy.texCoords_vbo), tangent_vbo(copy.tangent_vbo), bitangent_vbo(copy.bitangent_vbo), -texture_diffuse(copy.texture_diffuse), texture_ambient(copy.texture_ambient), texture_specular(copy.texture_specular), +texture_albedo(copy.texture_albedo), texture_roughness(copy.texture_roughness), texture_metallic(copy.texture_metallic), texture_specular(copy.texture_specular), texture_emitted(copy.texture_emitted), texture_heights(copy.texture_heights), texture_normals(copy.texture_normals), material(copy.material) { @@ -242,10 +242,12 @@ Model& Model::operator=(const Model& other) tangent_vbo = other.tangent_vbo; bitangent_vbo = other.bitangent_vbo; - texture_diffuse = other.texture_diffuse; - texture_ambient = other.texture_ambient; - texture_specular = other.texture_specular; - + texture_albedo = other.texture_albedo; + texture_roughness = other.texture_roughness; + texture_metallic = other.texture_metallic; + texture_specular = other.texture_specular; + texture_emitted = other.texture_emitted; + texture_heights = other.texture_heights; texture_normals = other.texture_normals; @@ -285,9 +287,11 @@ void Model::render(ShaderProgram &shaderProgram, UBO &material_buffer) glUniformMatrix4fv(shaderProgram.getUniformLoc("model"), 1, GL_FALSE, &this->getTransformMatrix()[0][0]); // Подключаем текстуры - texture_diffuse.use(); - texture_ambient.use(); + texture_albedo.use(); + texture_roughness.use(); + texture_metallic.use(); texture_specular.use(); + texture_emitted.use(); texture_heights.use(); texture_normals.use(); @@ -408,14 +412,25 @@ void Model::set_texture(Texture& texture) GLuint type = texture.getType(); switch(type) { - case TEX_DIFFUSE: - texture_diffuse = texture; + case TEX_ALBEDO: + texture_albedo = texture; + material.base_color.r = -1; break; - case TEX_AMBIENT: - texture_ambient = texture; + case TEX_ROUGHNESS: + texture_roughness = texture; + material.roughness = -1; + break; + case TEX_METALLIC: + texture_metallic = texture; + material.metallic = -1; break; case TEX_SPECULAR: texture_specular = texture; + material.specular = -1; + break; + case TEX_EMITTED: + texture_emitted = texture; + material.emitted.r = -1; break; case TEX_HEIGHTS: texture_heights = texture; diff --git a/src/Scene.cpp b/src/Scene.cpp index d8870b4..40fff1b 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -215,23 +215,39 @@ Scene loadOBJtoScene(const char* filename, const char* mtl_directory, const char auto s = --result.models.end(); s->set_index_range(materials_range[i]*sizeof(GLuint), materials_range[i+1]-materials_range[i]); - // Текстуры - Texture diffuse(TEX_DIFFUSE, texture_directory + materials[materials_ids[i]].diffuse_texname); - s->set_texture(diffuse); - Texture ambient(TEX_AMBIENT, texture_directory + materials[materials_ids[i]].ambient_texname); - s->set_texture(ambient); - Texture specular(TEX_SPECULAR, texture_directory + materials[materials_ids[i]].specular_texname); - s->set_texture(specular); - Texture normal(TEX_NORMAL, texture_directory + materials[materials_ids[i]].normal_texname); - s->set_texture(normal); - Texture heights(TEX_HEIGHTS, texture_directory + materials[materials_ids[i]].bump_texname); - s->set_texture(heights); - // Материал - s->material.ka = pow(glm::vec3(materials[materials_ids[i]].ambient[0], materials[materials_ids[i]].ambient[1], materials[materials_ids[i]].ambient[2]), glm::vec3(1/inv_gamma)); - s->material.kd = pow(glm::vec3(materials[materials_ids[i]].diffuse[0], materials[materials_ids[i]].diffuse[1], materials[materials_ids[i]].diffuse[2]), glm::vec3(1/inv_gamma)); - s->material.ks = glm::vec3(materials[materials_ids[i]].specular[0], materials[materials_ids[i]].specular[1], materials[materials_ids[i]].specular[2]); - s->material.p = (materials[materials_ids[i]].shininess > 0.0f) ? 1000.0f / materials[materials_ids[i]].shininess : 1000.0f; + s->material.base_color = pow(glm::vec3(materials[materials_ids[i]].diffuse[0], materials[materials_ids[i]].diffuse[1], materials[materials_ids[i]].diffuse[2]), glm::vec3(1/inv_gamma)); + s->material.roughness = 1 - sqrt(materials[materials_ids[i]].shininess/1000); // шероховатость поверхности + s->material.metallic = (materials[materials_ids[i]].ambient[0] + materials[materials_ids[i]].ambient[1] + materials[materials_ids[i]].ambient[2]) / 3.0f; + s->material.specular = (materials[materials_ids[i]].specular[0] + materials[materials_ids[i]].specular[1] + materials[materials_ids[i]].specular[2]) / 3.0f; + s->material.emitted = pow(glm::vec3(materials[materials_ids[i]].emission[0], materials[materials_ids[i]].emission[1], materials[materials_ids[i]].emission[2]), glm::vec3(1/inv_gamma)); + + // Текстуры + if (!materials[materials_ids[i]].diffuse_texname.empty()) + { + Texture diffuse(TEX_ALBEDO, texture_directory + materials[materials_ids[i]].diffuse_texname); + s->set_texture(diffuse); + } + if (!materials[materials_ids[i]].ambient_texname.empty()) + { + Texture ambient(TEX_METALLIC, texture_directory + materials[materials_ids[i]].ambient_texname); + s->set_texture(ambient); + } + if (!materials[materials_ids[i]].specular_texname.empty()) + { + Texture specular(TEX_SPECULAR, texture_directory + materials[materials_ids[i]].specular_texname); + s->set_texture(specular); + } + if (!materials[materials_ids[i]].normal_texname.empty()) + { + Texture normal(TEX_NORMAL, texture_directory + materials[materials_ids[i]].normal_texname); + s->set_texture(normal); + } + if (!materials[materials_ids[i]].bump_texname.empty()) + { + Texture heights(TEX_HEIGHTS, texture_directory + materials[materials_ids[i]].bump_texname); + s->set_texture(heights); + } } return result; diff --git a/src/main.cpp b/src/main.cpp index 21fb483..38ab2e3 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -153,9 +153,7 @@ int main(void) Scene scene = loadOBJtoScene("../resources/models/blob.obj", "../resources/models/", "../resources/textures/"); scene.root.e_scale() = glm::vec3(0.01); scene.root.e_position().z = 1; - scene.models.begin()->material.kd = {0.5,0.5,0.5}; - scene.models.begin()->material.ka = {0.05,0.05,0.05}; - scene.set_group_id((GLuint64) &scene); + scene.set_group_id((GLuint64) &scene.root); // Установка цвета очистки буфера цвета glClearColor(0.0f, 0.0f, 0.0f, 1.0f); @@ -350,7 +348,7 @@ int main(void) rectangle.root.e_scale() = glm::vec3(4); // Текстуры для прямоугольника - Texture rectangle_diffuse(TEX_DIFFUSE, "../resources/textures/rekovalev_diffusemap.png"); + Texture rectangle_diffuse(TEX_ALBEDO, "../resources/textures/rekovalev_diffusemap.png"); rectangle.models.begin()->set_texture(rectangle_diffuse); Texture rectangle_normal(TEX_NORMAL, "../resources/textures/rekovalev_normalmap.png"); rectangle.models.begin()->set_texture(rectangle_normal); @@ -412,7 +410,7 @@ int main(void) // Модель скайбокса Model skybox; skybox.load_verteces(skybox_verticies, sizeof(skybox_verticies)/sizeof(glm::vec3)); - TextureCube skybox_texture(TEX_DIFFUSE, { "../resources/textures/skybox/px.jpg" + TextureCube skybox_texture(TEX_ALBEDO, { "../resources/textures/skybox/px.jpg" , "../resources/textures/skybox/nx.jpg" , "../resources/textures/skybox/py.jpg" , "../resources/textures/skybox/ny.jpg"