Revamp color system, again. Moving color components to scene objects instead
This commit is contained in:
parent
50e3b60c28
commit
3a6181f239
|
@ -16,12 +16,16 @@ uniform mat4 MVP;
|
||||||
uniform mat4 MV;
|
uniform mat4 MV;
|
||||||
uniform mat4 MVnormal;
|
uniform mat4 MVnormal;
|
||||||
|
|
||||||
|
// material
|
||||||
|
uniform float opacity;
|
||||||
uniform float shininess;
|
uniform float shininess;
|
||||||
uniform vec4 basecolor;
|
uniform vec3 diffuse_color;
|
||||||
|
uniform vec3 specular_color;
|
||||||
|
uniform vec3 emissive_color;
|
||||||
|
|
||||||
uniform bool isIlluminated;
|
uniform bool isIlluminated;
|
||||||
uniform bool isTextured;
|
uniform bool isTextured;
|
||||||
uniform bool isColorMapped;
|
uniform bool isVertexColored;
|
||||||
uniform bool isNormalMapped;
|
uniform bool isNormalMapped;
|
||||||
uniform bool isDisplacementMapped;
|
uniform bool isDisplacementMapped;
|
||||||
uniform bool isInverted;
|
uniform bool isInverted;
|
||||||
|
@ -30,13 +34,11 @@ uniform bool isInverted;
|
||||||
struct Light { // point lights, coordinates in MV space
|
struct Light { // point lights, coordinates in MV space
|
||||||
vec3 position;
|
vec3 position;
|
||||||
vec3 attenuation; // 1 / (x + y*l + z*l*l)
|
vec3 attenuation; // 1 / (x + y*l + z*l*l)
|
||||||
vec3 color_emissive;
|
vec3 color;
|
||||||
vec3 color_diffuse;
|
|
||||||
vec3 color_specular;
|
|
||||||
|
|
||||||
bool is_spot; // false means point light
|
bool is_spot; // false means point light
|
||||||
vec3 spot_target;
|
vec3 spot_direction;
|
||||||
float spot_cuttof_angle;
|
float spot_cuttof_cos;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define N_LIGHTS 1
|
#define N_LIGHTS 1
|
||||||
|
@ -46,7 +48,7 @@ uniform Light light[N_LIGHTS];
|
||||||
out vec4 color_out;
|
out vec4 color_out;
|
||||||
|
|
||||||
|
|
||||||
vec4 phong(vec4 basecolor) {
|
vec3 phong(vec3 basecolor) {
|
||||||
vec3 nnormal; // normalized normal
|
vec3 nnormal; // normalized normal
|
||||||
if (isNormalMapped) {
|
if (isNormalMapped) {
|
||||||
mat3 TBN;
|
mat3 TBN;
|
||||||
|
@ -72,8 +74,8 @@ vec4 phong(vec4 basecolor) {
|
||||||
else {
|
else {
|
||||||
if (isDisplacementMapped) {
|
if (isDisplacementMapped) {
|
||||||
float o = texture(displacementTexture, UV).r * 2.0 - 1.0;
|
float o = texture(displacementTexture, UV).r * 2.0 - 1.0;
|
||||||
float u = (texture(displacementTexture, UV + vec2(0.0001, 0.0)).r*2.0-1.0 - o) / 0.0004;
|
float u = (texture(displacementTexture, UV + vec2(0.00001, 0.0)).r*2.0-1.0 - o) / 0.00004;
|
||||||
float v = (texture(displacementTexture, UV + vec2(0.0, 0.0001)).r*2.0-1.0 - o) / 0.0004;
|
float v = (texture(displacementTexture, UV + vec2(0.0, 0.00001)).r*2.0-1.0 - o) / 0.00004;
|
||||||
nnormal = normalize(cross(tangent + normal*u, bitangent + normal*v));
|
nnormal = normalize(cross(tangent + normal*u, bitangent + normal*v));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -81,9 +83,10 @@ vec4 phong(vec4 basecolor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 emmissive_component = vec3(0.0);
|
|
||||||
vec3 diffuse_component = vec3(0.0);
|
vec3 diffuse_component = vec3(0.0);
|
||||||
vec3 specular_component = vec3(0.0);
|
vec3 specular_component = vec3(0.0);
|
||||||
|
float diffuse_i_sum = 0.0;
|
||||||
|
//vec3 emissive_component = vec3(0.0);
|
||||||
|
|
||||||
for (int i = 0; i<N_LIGHTS; i++) {
|
for (int i = 0; i<N_LIGHTS; i++) {
|
||||||
vec3 L = light[i].position - vertex;
|
vec3 L = light[i].position - vertex;
|
||||||
|
@ -91,7 +94,7 @@ vec4 phong(vec4 basecolor) {
|
||||||
L = normalize(L);
|
L = normalize(L);
|
||||||
|
|
||||||
if (light[i].is_spot) {
|
if (light[i].is_spot) {
|
||||||
if (dot(normalize(light[i].position - light[i].spot_target), L) < light[i].spot_cuttof_angle) {
|
if (dot(light[i].spot_direction, -L) < light[i].spot_cuttof_cos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,19 +111,24 @@ vec4 phong(vec4 basecolor) {
|
||||||
? pow(specular_i, shininess)
|
? pow(specular_i, shininess)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
emmissive_component += light[i].color_emissive;
|
specular_component += specular_color * light[i].color * specular_i * attenuation;
|
||||||
specular_component += light[i].color_specular * specular_i * attenuation;
|
if (diffuse_i>0) diffuse_component += diffuse_color * light[i].color * diffuse_i * attenuation;
|
||||||
if (diffuse_i>0) diffuse_component += light[i].color_diffuse * diffuse_i * attenuation;
|
//emissive_component += emissive_color*light[i].color*attenuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec4(basecolor.rgb * (emmissive_component + diffuse_component) + specular_component, basecolor.a);
|
basecolor *= (emissive_color + diffuse_component);
|
||||||
|
return basecolor + specular_component;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 c = basecolor;
|
vec4 c = vec4(vec3(1.0), opacity);
|
||||||
if (isColorMapped) c *= color;
|
if (isVertexColored) c *= color;
|
||||||
if (isTextured) c *= texture(diffuseTexture, UV);
|
if (isTextured) c *= texture(diffuseTexture, UV);
|
||||||
if (isIlluminated) c = phong(c);
|
|
||||||
if (isInverted) c.rgb = 1 - c.rgb;
|
if (isInverted) c.rgb = 1 - c.rgb;
|
||||||
|
if (isIlluminated) c.rgb = phong(c.rgb);
|
||||||
|
else c.rgb *= diffuse_color;
|
||||||
|
//c.rgb = diffuse_color;
|
||||||
|
//c.rgb = emissive_color;
|
||||||
|
//c.rgb = specular_color;
|
||||||
color_out = c;
|
color_out = c;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ in layout(location = 3) vec4 color;
|
||||||
in layout(location = 4) vec3 tangent;
|
in layout(location = 4) vec3 tangent;
|
||||||
in layout(location = 5) vec3 bitangent;
|
in layout(location = 5) vec3 bitangent;
|
||||||
|
|
||||||
|
layout(binding = 0) uniform sampler2D diffuseTexture;
|
||||||
|
layout(binding = 1) uniform sampler2D normalTexture;
|
||||||
layout(binding = 2) uniform sampler2D displacementTexture;
|
layout(binding = 2) uniform sampler2D displacementTexture;
|
||||||
uniform float displacementCoefficient;
|
uniform float displacementCoefficient;
|
||||||
|
|
||||||
|
@ -14,13 +16,20 @@ uniform mat4 MVP;
|
||||||
uniform mat4 MV;
|
uniform mat4 MV;
|
||||||
uniform mat4 MVnormal;
|
uniform mat4 MVnormal;
|
||||||
|
|
||||||
uniform float shininess;
|
// material
|
||||||
uniform vec2 uvOffset;
|
uniform vec2 uvOffset;
|
||||||
|
uniform float opacity;
|
||||||
|
uniform float shininess;
|
||||||
|
uniform vec3 diffuse_color;
|
||||||
|
uniform vec3 specular_color;
|
||||||
|
uniform vec3 emissive_color;
|
||||||
|
|
||||||
uniform bool isIlluminated;
|
uniform bool isIlluminated;
|
||||||
uniform bool isTextured;
|
uniform bool isTextured;
|
||||||
|
uniform bool isVertexColored;
|
||||||
uniform bool isNormalMapped;
|
uniform bool isNormalMapped;
|
||||||
uniform bool isDisplacementMapped;
|
uniform bool isDisplacementMapped;
|
||||||
|
uniform bool isReflectionMapped;
|
||||||
uniform bool isInverted;
|
uniform bool isInverted;
|
||||||
|
|
||||||
out layout(location = 0) vec3 vertex_out;
|
out layout(location = 0) vec3 vertex_out;
|
||||||
|
|
|
@ -172,20 +172,19 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
|
||||||
boxNode->shininess = 20;
|
boxNode->shininess = 20;
|
||||||
boxNode->displacementCoefficient = 40;
|
boxNode->displacementCoefficient = 40;
|
||||||
rootNode->children.push_back(boxNode);
|
rootNode->children.push_back(boxNode);
|
||||||
|
|
||||||
sphereNode = createSceneNode();
|
|
||||||
sphereNode->setTexture(&t_cobble_diff, &t_cobble_normal);
|
|
||||||
sphereNode->setMesh(&sphere);
|
|
||||||
sphereNode->scale *= 2;
|
|
||||||
sphereNode->scale.z *= 20;
|
|
||||||
//lightNode[1]->children.push_back(sphereNode);
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
sphereNode = createSceneNode();
|
||||||
|
//sphereNode->setTexture(&t_cobble_diff, &t_cobble_normal);
|
||||||
|
sphereNode->setMesh(&sphere);
|
||||||
|
sphereNode->position = {500, 500, 100};
|
||||||
|
sphereNode->scale *= 15;
|
||||||
|
sphereNode->diffuse_color;
|
||||||
|
sphereNode->setMaterial(Material().reflection_mapped(&t_reflection, 0.5).no_colors().no_texture_reset(), true);
|
||||||
|
//rootNode->children.push_back(sphereNode);
|
||||||
|
|
||||||
lightNode[0]->position = {-600, 1400, 800};
|
lightNode[0]->position = {-600, 1400, 800};
|
||||||
lightNode[0]->color_emissive = vec3(0.35);
|
lightNode[0]->attenuation = vec3(1.8, 0.0, 0.0);
|
||||||
lightNode[0]->color_diffuse = vec3(0.6);
|
|
||||||
lightNode[0]->color_specular = vec3(0.1);
|
|
||||||
lightNode[0]->attenuation = vec3(1.0, 0.0, 0.0);
|
|
||||||
|
|
||||||
|
|
||||||
textNode = createSceneNode();
|
textNode = createSceneNode();
|
||||||
|
@ -302,27 +301,23 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader = default_shader)
|
||||||
// coordinates in MV space
|
// coordinates in MV space
|
||||||
vec3 position; // MV
|
vec3 position; // MV
|
||||||
vec3 attenuation;
|
vec3 attenuation;
|
||||||
vec3 color_emissive;
|
vec3 color;
|
||||||
vec3 color_diffuse;
|
|
||||||
vec3 color_specular;
|
|
||||||
|
|
||||||
bool is_spot;
|
bool is_spot;
|
||||||
vec3 spot_target; // MV
|
vec3 spot_direction; // MV, must be normalized
|
||||||
float spot_cuttof_angle;
|
float spot_cuttof_cos;
|
||||||
|
|
||||||
void push_to_shader(Gloom::Shader* shader, uint id) {
|
void push_to_shader(Gloom::Shader* shader, uint id) {
|
||||||
#define L(x) shader->location("light[" + std::to_string(id) + "]." #x)
|
#define L(x) shader->location("light[" + std::to_string(id) + "]." #x)
|
||||||
#define V(x) glUniform3fv(L(x), 1, glm::value_ptr(x))
|
#define V(x) glUniform3fv(L(x), 1, glm::value_ptr(x))
|
||||||
glUniform1i (L(is_spot) , is_spot);
|
glUniform1i (L(is_spot) , is_spot);
|
||||||
glUniform1f (L(spot_cuttof_angle), spot_cuttof_angle);
|
glUniform1f (L(spot_cuttof_cos), spot_cuttof_cos);
|
||||||
V(position);
|
V(position);
|
||||||
V(spot_target);
|
V(spot_direction);
|
||||||
V(attenuation);
|
V(attenuation);
|
||||||
V(color_emissive);
|
V(color);
|
||||||
V(color_diffuse);
|
#undef V
|
||||||
V(color_specular);
|
#undef L
|
||||||
#undef v
|
|
||||||
#undef l
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static Light lights[N_LIGHTS];
|
static Light lights[N_LIGHTS];
|
||||||
|
@ -346,13 +341,18 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader = default_shader)
|
||||||
glUniformMatrix4fv(s->location("MV") , 1, GL_FALSE, glm::value_ptr(node->MV));
|
glUniformMatrix4fv(s->location("MV") , 1, GL_FALSE, glm::value_ptr(node->MV));
|
||||||
glUniformMatrix4fv(s->location("MVnormal"), 1, GL_FALSE, glm::value_ptr(node->MVnormal));
|
glUniformMatrix4fv(s->location("MVnormal"), 1, GL_FALSE, glm::value_ptr(node->MVnormal));
|
||||||
glUniform2fv(s->location("uvOffset") , 1, glm::value_ptr(node->uvOffset));
|
glUniform2fv(s->location("uvOffset") , 1, glm::value_ptr(node->uvOffset));
|
||||||
glUniform4fv(s->location("basecolor") , 1, glm::value_ptr(node->basecolor));
|
glUniform3fv(s->location("diffuse_color") , 1, glm::value_ptr(node->diffuse_color));
|
||||||
|
glUniform3fv(s->location("emissive_color"), 1, glm::value_ptr(node->emissive_color));
|
||||||
|
glUniform3fv(s->location("specular_color"), 1, glm::value_ptr(node->specular_color));
|
||||||
|
glUniform1f( s->location("opacity"), node->opacity);
|
||||||
glUniform1f( s->location("shininess"), node->shininess);
|
glUniform1f( s->location("shininess"), node->shininess);
|
||||||
|
glUniform1f( s->location("reflexiveness"), node->reflexiveness);
|
||||||
glUniform1f( s->location("displacementCoefficient"), node->displacementCoefficient);
|
glUniform1f( s->location("displacementCoefficient"), node->displacementCoefficient);
|
||||||
glUniform1ui(s->location("isTextured"), node->isTextured);
|
glUniform1ui(s->location("isTextured"), node->isTextured);
|
||||||
glUniform1ui(s->location("isColorMapped"), node->isColorMapped);
|
glUniform1ui(s->location("isVertexColored"), node->isVertexColored);
|
||||||
glUniform1ui(s->location("isNormalMapped"), node->isNormalMapped);
|
glUniform1ui(s->location("isNormalMapped"), node->isNormalMapped);
|
||||||
glUniform1ui(s->location("isDisplacementMapped"), node->isDisplacementMapped);
|
glUniform1ui(s->location("isDisplacementMapped"), node->isDisplacementMapped);
|
||||||
|
glUniform1ui(s->location("isReflectionMapped"), node->isReflectionMapped);
|
||||||
glUniform1ui(s->location("isIlluminated"), node->isIlluminated);
|
glUniform1ui(s->location("isIlluminated"), node->isIlluminated);
|
||||||
glUniform1ui(s->location("isInverted"), node->isInverted);
|
glUniform1ui(s->location("isInverted"), node->isInverted);
|
||||||
|
|
||||||
|
@ -368,12 +368,10 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader = default_shader)
|
||||||
uint id = node->lightID;
|
uint id = node->lightID;
|
||||||
lights[id].position = vec3(node->MV * vec4(vec3(0.0), 1.0));
|
lights[id].position = vec3(node->MV * vec4(vec3(0.0), 1.0));
|
||||||
lights[id].is_spot = node->nodeType == SPOT_LIGHT;
|
lights[id].is_spot = node->nodeType == SPOT_LIGHT;
|
||||||
lights[id].spot_target = node->rotation; // already MV space, todo: change this
|
lights[id].spot_direction = node->spot_direction; // MV space
|
||||||
lights[id].spot_cuttof_angle = glm::sin(node->spot_cuttof_angle);
|
lights[id].spot_cuttof_cos = node->spot_cuttof_cos;
|
||||||
lights[id].attenuation = node->attenuation;
|
lights[id].attenuation = node->attenuation;
|
||||||
lights[id].color_emissive = node->color_emissive;
|
lights[id].color = node->light_color;
|
||||||
lights[id].color_diffuse = node->color_diffuse;
|
|
||||||
lights[id].color_specular = node->color_specular;
|
|
||||||
lights[id].push_to_shader(s, id);
|
lights[id].push_to_shader(s, id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,14 +43,20 @@ struct SceneNode {
|
||||||
|
|
||||||
vertexArrayObjectID = cache[mesh];
|
vertexArrayObjectID = cache[mesh];
|
||||||
VAOIndexCount = mesh->indices.size();
|
VAOIndexCount = mesh->indices.size();
|
||||||
isColorMapped = ! mesh->colors.empty();
|
isVertexColored = ! mesh->colors.empty();
|
||||||
}
|
}
|
||||||
void setTexture(const PNGImage* diffuse, const PNGImage* normal=nullptr, const PNGImage* displacement=nullptr) {
|
void setTexture(
|
||||||
|
const PNGImage* diffuse,
|
||||||
|
const PNGImage* normal=nullptr,
|
||||||
|
const PNGImage* displacement=nullptr,
|
||||||
|
const PNGImage* reflection=nullptr,
|
||||||
|
bool texture_reset=true) {
|
||||||
static map<const PNGImage*, int> cache;
|
static map<const PNGImage*, int> cache;
|
||||||
assert(vertexArrayObjectID==-1);
|
if (texture_reset){
|
||||||
isTextured = false;
|
isTextured = false;
|
||||||
isNormalMapped = false;
|
isNormalMapped = false;
|
||||||
isDisplacementMapped = false;
|
isDisplacementMapped = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (diffuse) {
|
if (diffuse) {
|
||||||
if (cache.find(diffuse) == cache.end())
|
if (cache.find(diffuse) == cache.end())
|
||||||
|
@ -73,6 +79,21 @@ struct SceneNode {
|
||||||
isDisplacementMapped = true;
|
isDisplacementMapped = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void setMaterial(const Material& mat, bool recursive=false) {
|
||||||
|
if (!mat.ignore_diffuse) diffuse_color = mat.diffuse_color;
|
||||||
|
if (!mat.ignore_emissive) emissive_color = mat.emissive_color;
|
||||||
|
if (!mat.ignore_specular) specular_color = mat.specular_color;
|
||||||
|
if (!mat.ignore_specular) shininess = mat.shininess;
|
||||||
|
setTexture(
|
||||||
|
mat.diffuse_texture,
|
||||||
|
mat.normal_texture,
|
||||||
|
mat.displacement_texture,
|
||||||
|
mat.reflection_texture,
|
||||||
|
mat.texture_reset
|
||||||
|
);
|
||||||
|
if (recursive) for (SceneNode* child : children)
|
||||||
|
child->setMaterial(mat, true);
|
||||||
|
}
|
||||||
|
|
||||||
// this node
|
// this node
|
||||||
SceneNodeType nodeType;
|
SceneNodeType nodeType;
|
||||||
|
@ -80,11 +101,10 @@ struct SceneNode {
|
||||||
|
|
||||||
// light specific:
|
// light specific:
|
||||||
uint lightID = -1;
|
uint lightID = -1;
|
||||||
vec3 color_emissive = vec3(0.0);
|
vec3 light_color = vec3(1.0);
|
||||||
vec3 color_diffuse = vec3(0.0);
|
|
||||||
vec3 color_specular = vec3(0.0);
|
|
||||||
vec3 attenuation = vec3(1.0, 0.0, 0.001); // 1 / (x + y*l + z*l*l)
|
vec3 attenuation = vec3(1.0, 0.0, 0.001); // 1 / (x + y*l + z*l*l)
|
||||||
float spot_cuttof_angle = glm::radians(1.5); // radians
|
vec3 spot_direction = vec3(0.0); // in MV space, must be normalized
|
||||||
|
float spot_cuttof_cos = glm::cos(glm::radians(1.5));
|
||||||
SceneNode* targeted_by = nullptr; // spot will follow this node
|
SceneNode* targeted_by = nullptr; // spot will follow this node
|
||||||
|
|
||||||
// The node's position and rotation relative to its parent
|
// The node's position and rotation relative to its parent
|
||||||
|
@ -97,9 +117,12 @@ struct SceneNode {
|
||||||
int vertexArrayObjectID = -1;
|
int vertexArrayObjectID = -1;
|
||||||
uint VAOIndexCount = 0;
|
uint VAOIndexCount = 0;
|
||||||
|
|
||||||
// textures
|
// textures and materials
|
||||||
float shininess = 10.0; // specular power
|
float opacity = 1.0;
|
||||||
vec4 basecolor = vec4(1.0);
|
float shininess = 1.0; // specular power
|
||||||
|
vec3 diffuse_color = vec3(1.0);
|
||||||
|
vec3 emissive_color = vec3(0.5);
|
||||||
|
vec3 specular_color = vec3(0.2);
|
||||||
vec2 uvOffset = vec2(0.0, 0.0); // specular power
|
vec2 uvOffset = vec2(0.0, 0.0); // specular power
|
||||||
uint diffuseTextureID;
|
uint diffuseTextureID;
|
||||||
uint normalTextureID;
|
uint normalTextureID;
|
||||||
|
@ -108,7 +131,7 @@ struct SceneNode {
|
||||||
|
|
||||||
// shader flags
|
// shader flags
|
||||||
bool isTextured = false;
|
bool isTextured = false;
|
||||||
bool isColorMapped = false;
|
bool isVertexColored = false;
|
||||||
bool isNormalMapped = false;
|
bool isNormalMapped = false;
|
||||||
bool isDisplacementMapped = false;
|
bool isDisplacementMapped = false;
|
||||||
bool isIlluminated = true;
|
bool isIlluminated = true;
|
||||||
|
|
|
@ -51,7 +51,7 @@ uint generateBuffer(const Mesh &mesh, bool doAddTangents) {
|
||||||
glEnableVertexAttribArray(3);
|
glEnableVertexAttribArray(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doAddTangents && !mesh.textureCoordinates.empty())
|
if (doAddTangents || !mesh.textureCoordinates.empty())
|
||||||
addTangents(vaoID, mesh);
|
addTangents(vaoID, mesh);
|
||||||
|
|
||||||
return vaoID;
|
return vaoID;
|
||||||
|
|
Loading…
Reference in New Issue