Specular Lighting
Next up is attenuation
This commit is contained in:
parent
9920dfc25b
commit
5200ba4dbe
@ -16,6 +16,7 @@ namespace charcoal
|
||||
typedef vec4 ColorRGBA;
|
||||
typedef vec3 ColorRGB;
|
||||
typedef vec2 UV;
|
||||
typedef float SpecularExponent;
|
||||
|
||||
typedef unsigned int Index;
|
||||
|
||||
@ -37,12 +38,30 @@ namespace charcoal
|
||||
Normal normal;
|
||||
};
|
||||
|
||||
struct PNSVertex
|
||||
{
|
||||
void set_position(const Position& position) { this->position = position; }
|
||||
void set_normal(const Normal& normal) { this->normal = normal; }
|
||||
void set_specular_exponent(const SpecularExponent& specular_exponent) { this->specular_exponent = specular_exponent; }
|
||||
|
||||
Position position;
|
||||
Normal normal;
|
||||
SpecularExponent specular_exponent;
|
||||
};
|
||||
|
||||
// Other Data Types
|
||||
|
||||
struct Light
|
||||
{
|
||||
Light(const Position& position, const ColorRGB& ambient, const ColorRGB& diffuse)
|
||||
: position(position), ambient(ambient), diffuse(diffuse) {}
|
||||
Light(
|
||||
const Position& position,
|
||||
const ColorRGB& ambient,
|
||||
const ColorRGB& diffuse
|
||||
)
|
||||
: position(position),
|
||||
ambient(ambient),
|
||||
diffuse(diffuse)
|
||||
{}
|
||||
|
||||
Position position;
|
||||
ColorRGB ambient;
|
||||
@ -55,7 +74,7 @@ namespace charcoal
|
||||
typedef Index BasicIndex;
|
||||
typedef Renderable<BasicVertex, BasicIndex> BasicRenderable;
|
||||
|
||||
typedef PNVertex LitVertex;
|
||||
typedef PNSVertex LitVertex;
|
||||
typedef Index LitIndex;
|
||||
typedef Renderable<LitVertex, LitIndex> LitRenderable;
|
||||
}
|
||||
|
@ -15,11 +15,14 @@ namespace charcoal
|
||||
|
||||
mat4 get_world_to_view_matrix() const { return m_projection_matrix * m_view_matrix; }
|
||||
|
||||
const vec3& get_position() const { return m_position; }
|
||||
|
||||
const mat4& get_view_matrix() const { return m_view_matrix; }
|
||||
|
||||
const mat4& get_projection_matrix() const { return m_projection_matrix; }
|
||||
|
||||
protected:
|
||||
vec3 m_position;
|
||||
mat4 m_view_matrix;
|
||||
mat4 m_projection_matrix;
|
||||
};
|
||||
|
@ -29,6 +29,5 @@ namespace charcoal
|
||||
void update_scale();
|
||||
|
||||
vec3 m_size;
|
||||
vec3 m_position;
|
||||
};
|
||||
}
|
||||
|
@ -42,7 +42,6 @@ namespace charcoal
|
||||
vec3 get_right() const { return vec3(m_right); }
|
||||
|
||||
private:
|
||||
vec3 m_position;
|
||||
vec4 m_forward;
|
||||
vec4 m_up;
|
||||
vec4 m_right;
|
||||
|
@ -23,6 +23,16 @@ namespace charcoal
|
||||
glUniform1ui(uniform_index, value);
|
||||
}
|
||||
|
||||
void uniform_float(int uniform_index, float value)
|
||||
{
|
||||
glUniform1f(uniform_index, value);
|
||||
}
|
||||
|
||||
void uniform_vec3(int uniform_index, const vec3& value)
|
||||
{
|
||||
glUniform3fv(uniform_index, 1, &value[0]);
|
||||
}
|
||||
|
||||
void uniform_matrix(int uniform_index, const mat4& matrix, bool transpose)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_index, 1, transpose ? GL_TRUE : GL_FALSE, &matrix[0][0]);
|
||||
@ -33,6 +43,7 @@ namespace charcoal
|
||||
const int position_size = 1;
|
||||
const int ambient_size = 1;
|
||||
const int diffuse_size = 1;
|
||||
const int specular_exponent_size = 1;
|
||||
int current_location = uniform_index;
|
||||
for (std::vector<Light>::size_type i = 0; i < lights.size(); ++i)
|
||||
{
|
||||
|
@ -16,6 +16,8 @@ namespace charcoal
|
||||
void clear_screen();
|
||||
void uniform_int(int uniform_index, int value);
|
||||
void uniform_uint(int uniform_index, unsigned int value);
|
||||
void uniform_float(int uniform_index, float value);
|
||||
void uniform_vec3(int uniform_index, const vec3& value);
|
||||
void uniform_matrix(int uniform_index, const mat4& matrix, bool transpose = false);
|
||||
void uniform_lights(int uniform_index, const std::vector<Light>& lights); // TODO: This may want to be moved somewhere else
|
||||
}
|
||||
|
@ -9,24 +9,27 @@ namespace charcoal
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(LitVertex), (void*)(offsetof(LitVertex, position)));
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(LitVertex), (void*)(offsetof(LitVertex, normal)));
|
||||
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(LitVertex), (void*)(offsetof(LitVertex, specular_exponent)));
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_element_buffers[0]);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
glEnableVertexAttribArray(4);
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(0 * sizeof(vec4)));
|
||||
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(1 * sizeof(vec4)));
|
||||
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(2 * sizeof(vec4)));
|
||||
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(3 * sizeof(vec4)));
|
||||
glEnableVertexAttribArray(6);
|
||||
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(0 * sizeof(vec4)));
|
||||
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(1 * sizeof(vec4)));
|
||||
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(2 * sizeof(vec4)));
|
||||
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable), (void*)(3 * sizeof(vec4)));
|
||||
|
||||
glVertexAttribDivisor(0, 0); // Send the mesh data once
|
||||
glVertexAttribDivisor(1, 0); // Send the mesh data once
|
||||
glVertexAttribDivisor(2, 1); // Send the offset data for each instance drawn
|
||||
glVertexAttribDivisor(2, 0); // Send the mesh data once
|
||||
glVertexAttribDivisor(3, 1); // Send the offset data for each instance drawn
|
||||
glVertexAttribDivisor(4, 1); // Send the offset data for each instance drawn
|
||||
glVertexAttribDivisor(5, 1); // Send the offset data for each instance drawn
|
||||
glVertexAttribDivisor(6, 1); // Send the offset data for each instance drawn
|
||||
}
|
||||
}
|
||||
}
|
@ -9,23 +9,35 @@ struct Light
|
||||
|
||||
in vec3 fragment_position;
|
||||
in vec3 fragment_normal;
|
||||
in float fragment_specular_exponent;
|
||||
|
||||
#define MAX_LIGHTS 16
|
||||
layout(location = 4) uniform Light lights[MAX_LIGHTS];
|
||||
layout(location = 52) uniform uint num_lights;
|
||||
layout(location = 68) uniform uint num_lights;
|
||||
layout(location = 69) uniform vec3 eye_position;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 hard_eye_position = vec3(0.0f, 0.0f, -5.0f);
|
||||
vec3 norm_normal = normalize(fragment_normal);
|
||||
vec3 norm_eye_vector = normalize(eye_position - fragment_position);
|
||||
|
||||
vec3 accum = vec3(0.0);
|
||||
|
||||
float diffuse_multiplier;
|
||||
float specular_multiplier;
|
||||
vec3 light_vector;
|
||||
vec3 reflected_light_vector;
|
||||
for (uint i = 0; i < MAX_LIGHTS && i < num_lights; ++i) {
|
||||
light_vector = normalize(lights[i].position - fragment_position);
|
||||
reflected_light_vector = reflect(-light_vector, norm_normal);
|
||||
diffuse_multiplier = clamp(dot(light_vector, norm_normal), 0.0, 1.0);
|
||||
specular_multiplier = pow(clamp(dot(reflected_light_vector, norm_eye_vector), 0.0, 1.0), fragment_specular_exponent);
|
||||
accum += lights[i].ambient;
|
||||
accum += diffuse_multiplier * lights[i].diffuse;
|
||||
accum += specular_multiplier * lights[i].diffuse;
|
||||
}
|
||||
frag_color = vec4(accum, 1.0);
|
||||
}
|
@ -42,7 +42,9 @@ namespace charcoal
|
||||
CHECK_GL_ERR();
|
||||
glutil::uniform_lights(4, m_lights);
|
||||
CHECK_GL_ERR();
|
||||
glutil::uniform_uint(52, (unsigned int)m_lights.size());
|
||||
glutil::uniform_uint(68, (unsigned int)m_lights.size());
|
||||
CHECK_GL_ERR();
|
||||
glutil::uniform_vec3(69, m_p_camera->get_position());
|
||||
CHECK_GL_ERR();
|
||||
for (auto iter = m_batches.begin(); iter != m_batches.end(); ++iter)
|
||||
{
|
||||
|
@ -30,7 +30,11 @@ namespace charcoal
|
||||
protected:
|
||||
void set_camera(const Camera* p_camera) { m_p_camera = p_camera; }
|
||||
|
||||
void add_light(const Position& position, const ColorRGB& ambient, const ColorRGB& diffuse)
|
||||
void add_light(
|
||||
const Position& position,
|
||||
const ColorRGB& ambient,
|
||||
const ColorRGB& diffuse
|
||||
)
|
||||
{
|
||||
m_lights.emplace_back(position, ambient, diffuse);
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
#version 430
|
||||
layout(location = 0) in vec3 vertex_position;
|
||||
layout(location = 1) in vec3 vertex_normal;
|
||||
layout(location = 2) in mat4 model_to_world;
|
||||
layout(location = 2) in float vertex_specular_exponent;
|
||||
layout(location = 3) in mat4 model_to_world;
|
||||
|
||||
layout(location = 0) uniform mat4 world_to_projection;
|
||||
|
||||
out vec3 fragment_position;
|
||||
out vec3 fragment_normal;
|
||||
out float fragment_specular_exponent;
|
||||
|
||||
void main()
|
||||
{
|
||||
@ -15,4 +17,5 @@ void main()
|
||||
gl_Position = world_to_projection * model_position;
|
||||
fragment_position = model_position.xyz;
|
||||
fragment_normal = model_normal.xyz;
|
||||
fragment_specular_exponent = vertex_specular_exponent;
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "MeshFactory.h"
|
||||
#include "Mesh.h"
|
||||
#include "BuiltinTypes.h"
|
||||
|
||||
// TODO: Consider a mesh generator for every render type (i.e. basic::meshgenerator, lit::meshgenerator, etc.)
|
||||
|
||||
@ -14,6 +15,16 @@ namespace charcoal
|
||||
// Uses MeshFactory to generate meshes for the builtin vertex types.
|
||||
namespace meshgenerator
|
||||
{
|
||||
template <typename VertexType, typename IndexType>
|
||||
Mesh<VertexType, IndexType>* apply_specular_exponent(Mesh<VertexType, IndexType>* mesh, const SpecularExponent& specular_exponent)
|
||||
{
|
||||
for (unsigned int i = 0; i < mesh->vertex_count; ++i)
|
||||
{
|
||||
mesh->vertices[i].set_specular_exponent(specular_exponent);
|
||||
}
|
||||
return mesh;
|
||||
}
|
||||
|
||||
template <typename VertexType, typename IndexType>
|
||||
Mesh<VertexType, IndexType>* gen_cube_p(const DrawMode& draw_mode, float width, float height, float depth)
|
||||
{
|
||||
|
@ -6,7 +6,12 @@
|
||||
|
||||
MyBuiltinLitScene::MyBuiltinLitScene(Application& application)
|
||||
: LitScene(application),
|
||||
m_shape(meshgenerator::gen_cube_pn<LitVertex, LitIndex>(DRAW_TRIANGLES, 2.0f, 2.0f, 2.0f), DrawMode::DRAW_TRIANGLES),
|
||||
m_shape(
|
||||
meshgenerator::apply_specular_exponent<LitVertex, LitIndex>(
|
||||
meshgenerator::gen_cube_pn<LitVertex, LitIndex>(DRAW_TRIANGLES, 2.0f, 2.0f, 2.0f),
|
||||
2
|
||||
), DrawMode::DRAW_TRIANGLES
|
||||
),
|
||||
m_camera((float)TAU_1_4, (float)m_screen_size.x / m_screen_size.y, 1.0f, 10.0f, vec3(0.0f, 0.0f, -5.0f)),
|
||||
m_batch(add_batch(&m_shape, 1))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user