Add material struct, making it easier to apply properties thoughout the scene

This commit is contained in:
Peder Bergebakken Sundt 2019-03-19 20:13:51 +01:00
parent 3a6181f239
commit 8fc773e0f8
6 changed files with 190 additions and 44 deletions

View File

@ -133,22 +133,24 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
carNode = loadModelScene("../res/models/beetle/scene.gltf", {
{-1, Material::diffuse({0.3, 0.3, 1.0, 1.0}, 30)},// default
//{ 0, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Blue_Metal
//{ 1, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Metal
//{ 2, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Front_Light_Glass
{ 3, Material::diffuse({0.2, 0.2, 0.2, 1.0})},// Black_Rubber
//{ 4, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Mirror
//{ 5, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Black_Metal
//{ 6, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Plastic
{ 7, Material::diffuse({0.1, 0.1, 0.1, 1.0})},// Window_Glass
//{ 8, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Material
//{ 9, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Glossy_metal
//{10, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Rogh_Metal
//{11, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// License_Plate_Metal
//{12, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// License_Plate_Frame
//{13, Material::diffuse({1.0, 1.0, 1.0, 1.0})},//
{ 0, Material().diffuse({0.0, 0.0, 1.0}).diffuse_only().reflection_mapped(&t_reflection, 0.15)},// Blue_Metal
{ 1, Material().diffuse(vec3(0.85)).emissive(vec3(0.1)).reflection_mapped(&t_reflection, -1.0)},// Metal (decals)
//{ 2, Material().diffuse({1.0, 1.0, 1.0})},// Front_Light_Glass
// { 3, Material().diffuse({0.2, 0.2, 0.2})},// Black_Rubber
{ 4, Material().no_colors().reflection_mapped(&t_reflection, 1.0)},// Mirror
//{ 5, Material().diffuse({1.0, 1.0, 1.0})},// Black_Metal
//{ 6, Material().diffuse({1.0, 1.0, 1.0})},// Plastic
// { 7, Material().diffuse(vec3(0.2)).emissive(vec3(0.25)).specular(vec3(1.0), 70).reflection_mapped(&t_reflection, -0.8)},// Window_Glass
{ 7, Material().diffuse(vec3(0.2)).emissive(vec3(0.25)).specular(vec3(1.0), 70).reflection_mapped(&t_reflection, -0.8)},// Window_Glass
//{ 8, Material().diffuse({1.0, 1.0, 1.0})},// Material
{ 9, Material().diffuse(vec3(1.0)).emissive(vec3(0.2)).specular(vec3(0.4), 70).reflection_mapped(&t_reflection, -1.0)},// Glossy_metal
//{10, Material().diffuse({1.0, 1.0, 1.0})},// Rogh_Metal
// {11, Material().no_colors().reflection_mapped(&t_reflection, 1.0)},// License_Plate_Metal
{11, Material().no_colors().reflection_mapped(&t_reflection, 1.0)},// License_Plate_Metal
//{12, Material().diffuse({1.0, 1.0, 1.0})},// License_Plate_Frame
//{13, Material().diffuse({1.0, 1.0, 1.0})},//
});
//carNode->setMaterial(Material().reflection_mapped(&t_reflection, 0.0).no_colors().no_texture_reset(), true);
carNode->position = {500, 500, 100};
carNode->scale *= 100;
rootNode->children.push_back(carNode);
@ -293,6 +295,8 @@ void updateFrame(GLFWwindow* window, int windowWidth, int windowHeight) {
plainNode->uvOffset.y -= timeDelta*0.5;
if (boxNode) boxNode->rotation.z += timeDelta;
lightNode[1]->rotation.z -= timeDelta;
lightNode[1]->position.z = 80 + 40*glm::sin(5 * lightNode[1]->rotation.z);
//if(carNode) carNode->rotation.z += timeDelta;
}

View File

@ -14,6 +14,7 @@
#include <stdbool.h>
#include <utilities/glutils.h>
#include <utilities/shader.hpp>
#include <utilities/material.hpp>
#include <vector>
using glm::vec2;

104
src/utilities/material.cpp Normal file
View File

@ -0,0 +1,104 @@
#include <glm/glm.hpp>
#include "material.hpp"
#include "imageLoader.hpp"
Material Material::apply(const Material& other) const {
Material out(*this);
if (!other.ignore_diffuse) out.diffuse_color = other.diffuse_color;
if (!other.ignore_emissive) out.emissive_color = other.emissive_color;
if (!other.ignore_specular) out.specular_color = other.specular_color;
if (!other.ignore_specular) out.shininess = other.shininess;
if (!other.ignore_diffuse) out.ignore_diffuse = false;
if (!other.ignore_emissive) out.ignore_emissive = false;
if (!other.ignore_specular) out.ignore_specular = false;
if (!other.texture_reset) out.texture_reset = true;
if (other.texture_reset || other.diffuse_texture) out.diffuse_texture = other.diffuse_texture;
if (other.texture_reset || other.normal_texture) out.normal_texture = other.normal_texture;
if (other.texture_reset || other.displacement_texture) out.displacement_texture = other.displacement_texture;
if (other.texture_reset || other.reflection_texture) out.reflection_texture = other.reflection_texture;
if (other.texture_reset || other.reflection_texture) out.reflexiveness = other.reflexiveness;
return out;
}
Material Material::diffuse(glm::vec3 color) const {
Material out(*this);
out.diffuse_color = color;
return out;
}
Material Material::specular(glm::vec3 color, float shininess) const {
Material out(*this);
out.specular_color = color;
out.shininess = shininess;
return out;
}
Material Material::emissive(glm::vec3 color) const {
Material out(*this);
out.emissive_color = color;
return out;
}
Material Material::textured(PNGImage* diffuse) const {
Material out(*this);
out.diffuse_texture = diffuse;
return out;
}
Material Material::normal_mapped(PNGImage* normal) const {
Material out(*this);
out.normal_texture = normal;
return out;
}
Material Material::diffuse_mapped(PNGImage* diffuse) const {
Material out(*this);
out.diffuse_texture = diffuse;
return out;
}
Material Material::displacement_mapped(PNGImage* displacement) const {
Material out(*this);
out.displacement_texture = displacement;
return out;
}
Material Material::reflection_mapped(PNGImage* reflection, float reflexiveness) const {
Material out(*this);
out.reflection_texture = reflection;
out.reflexiveness = reflexiveness;
return out;
}
Material Material::no_texture_reset() const {
Material out(*this);
out.texture_reset = false;
return out;
}
Material Material::no_colors() const {
Material out(*this);
out.ignore_diffuse = true;
out.ignore_emissive = true;
out.ignore_specular = true;
return out;
}
Material Material::no_diffuse() const {
Material out(*this);
out.ignore_diffuse = true;
return out;
}
Material Material::no_emissive() const {
Material out(*this);
out.ignore_emissive = true;
return out;
}
Material Material::no_specular() const {
Material out(*this);
out.ignore_specular = true;
return out;
}
Material Material::diffuse_only() const {
return this->no_emissive().no_specular();
}
Material Material::emissive_only() const {
return this->no_diffuse().no_specular();
}
Material Material::specular_only() const {
return this->no_diffuse().no_emissive();
}

View File

@ -0,0 +1,43 @@
#pragma once
#include <glm/glm.hpp>
#include "imageLoader.hpp"
struct Material {
float opacity = 1.0;
float shininess = 1; // specular
float reflexiveness = 0;
glm::vec3 diffuse_color = glm::vec3(1.0);
glm::vec3 emissive_color = glm::vec3(0.5);
glm::vec3 specular_color = glm::vec3(0.2);
PNGImage* diffuse_texture = nullptr;
PNGImage* normal_texture = nullptr;
PNGImage* displacement_texture = nullptr;
PNGImage* reflection_texture = nullptr;
bool ignore_diffuse = false;
bool ignore_emissive = false;
bool ignore_specular = false;
bool texture_reset = true;
Material apply(const Material& other) const;
Material diffuse(glm::vec3 color) const;
Material specular(glm::vec3 color, float shininess) const;
Material emissive(glm::vec3 color) const;
Material textured(PNGImage* diffuse) const;
Material normal_mapped(PNGImage* normal) const;
Material diffuse_mapped(PNGImage* diffuse) const;
Material displacement_mapped(PNGImage* displacement) const;
Material reflection_mapped(PNGImage* reflection, float reflexiveness) const;
// avoid touching these:
Material no_texture_reset() const;
Material no_colors() const; // leave all colors alone
Material no_diffuse() const;
Material no_emissive() const;
Material no_specular() const;
Material diffuse_only() const; // and not the other two
Material emissive_only() const; // and not the other two
Material specular_only() const; // and not the other two
};

View File

@ -52,10 +52,7 @@ SceneNode* buildSceneNodes(
out->children.push_back(mesh_node);
uint meshidx = node->mMeshes[i];
mesh_node->basecolor = mat_lookup[meshidx]->basecolor;
mesh_node->shininess = mat_lookup[meshidx]->shininess;
// mesh_node.setTexture(&meshes[node->mMeshes[i]]);
mesh_node->setMaterial(*mat_lookup[meshidx]);
mesh_node->setMesh(&meshes[meshidx]);
}
@ -85,7 +82,7 @@ SceneNode* loadModelScene(const std::string& filename, const map<int, Material>&
// read materials
uint j=0;
Material default_material = Material::diffuse({1, 1, 1, 1});
Material default_material = Material().diffuse({1, 1, 1});
vector<Material> materials(scene->mNumMaterials);
for (Material& material : materials) {
const aiMaterial* aimat = scene->mMaterials[j++];
@ -98,21 +95,30 @@ SceneNode* loadModelScene(const std::string& filename, const map<int, Material>&
cout << " " << aimat->mProperties[i]->mKey.C_Str() << endl;
}
aiColor4D diffuse (1,1,1,1);
aimat->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
//aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0, &diffuse);
//aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0, &diffuse);
//aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0, &diffuse);
material.basecolor = {diffuse.r, diffuse.g, diffuse.b, diffuse.a};
aiColor3D color (1,1,1);
aiColor4D color4 (1,1,1,0);
if (AI_SUCCESS == aimat->Get(AI_MATKEY_COLOR_DIFFUSE, color))
material.diffuse_color = {color.r, color.g, color.b};
if (AI_SUCCESS == aimat->Get(AI_MATKEY_COLOR_EMISSIVE, color))
material.emissive_color = {color.r, color.g, color.b};
if (AI_SUCCESS == aimat->Get(AI_MATKEY_COLOR_SPECULAR, color))
material.specular_color = {color.r, color.g, color.b};
//if (AI_SUCCESS == aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0, &color4))
// material.diffuse_color = {color4.r, color4.g, color4.b};
//if (AI_SUCCESS == aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0, &color4))
// material.emissive_color *= vec3{color4.r, color4.g, color4.b};
//if (AI_SUCCESS == aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0, &color4))
// material.specular_color = {color4.r, color4.g, color4.b};
aimat->Get(AI_MATKEY_SHININESS, material.shininess);
}
for (auto override : overrides)
((override.first>=0)
for (auto override : overrides) {
Material& mat = (override.first>=0)
? materials[override.first]
: default_material
) = override.second;
: default_material;
mat = mat.apply(override.second);
}
vector<Mesh> meshes( scene->mNumMeshes);
vector<PNGImage> textures(scene->mNumTextures);
@ -135,7 +141,7 @@ SceneNode* loadModelScene(const std::string& filename, const map<int, Material>&
});
}
mat_lookup[j-1] = (aimesh->mMaterialIndex)
mat_lookup[j-1] = (aimesh->mMaterialIndex < meshes.size())
? &materials[aimesh->mMaterialIndex]
: &default_material;

View File

@ -1,24 +1,12 @@
#pragma once
#include "../sceneGraph.hpp"
#include "material.hpp"
#include <string>
#include <map>
#define DEBUG false
struct Material {
vec4 basecolor;
float shininess = 10;
int texture_id = -1;
static Material diffuse(vec4 color, float shininess = 10){
Material out;
out.basecolor = color;
out.shininess = shininess;
return out;
}
};
SceneNode* loadModelScene(
const std::string& filename,
const std::map<int, Material>& overrides={});