Commit ceda353e authored by Tim Übelhör's avatar Tim Übelhör

New shader loading mechanism.

Specular lighting is supported.
parent 0879fe45
......@@ -16,7 +16,7 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/bin/scigl_viewer",
"args": ["${workspaceFolder}/model/cube.blend"],
"args": ["${workspaceFolder}/model/beckenkamm.dae"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
......
......@@ -59,7 +59,8 @@
"unordered_set": "cpp",
"iomanip": "cpp",
"optional": "cpp",
"string_view": "cpp"
"string_view": "cpp",
"*.fs": "cpp"
},
"python.autoComplete.extraPaths": [
"/opt/ros/kinetic/lib/python2.7/dist-packages"
......
R""(
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal_in;
layout (location = 2) in vec2 texture_coordinate_in;
uniform float dist_coeffs[8];
uniform mat4 model_matrix;
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
out vec3 world_position;
out vec3 normal;
out vec2 texture_coordinate;
// distort the real world vertices using the rational model
vec4 distort(vec4 view_pos)
{
// normalize
float z = view_pos[2];
float z_inv = 1 / z;
float x1 = view_pos[0] * z_inv;
float y1 = view_pos[1] * z_inv;
// precalculations
float x1_2 = x1*x1;
float y1_2 = y1*y1;
float x1_y1 = x1*y1;
float r2 = x1_2 + y1_2;
float r4 = r2*r2;
float r6 = r4*r2;
// rational distortion factor
float r_dist = (1 + dist_coeffs[0]*r2 +dist_coeffs[1]*r4 + dist_coeffs[4]*r6)
/ (1 + dist_coeffs[5]*r2 + dist_coeffs[6]*r4 + dist_coeffs[7]*r6);
// full (rational + tangential) distortion
float x2 = x1*r_dist + 2*dist_coeffs[2]*x1_y1 + dist_coeffs[3]*(r2 + 2*x1_2);
float y2 = y1*r_dist + 2*dist_coeffs[3]*x1_y1 + dist_coeffs[2]*(r2 + 2*y1_2);
// denormalize for projection (which is a linear operation)
return vec4(x2*z, y2*z, z, view_pos[3]);
}
// transforms the model vertices and normals to world coordinates
void main()
{
// transform to world
vec4 local_position = vec4(position, 1.0);
world_position = (model_matrix * local_position).xyz;
normal = normalize(mat3(transpose(inverse(model_matrix))) * normal_in);
texture_coordinate = texture_coordinate_in;
// distortion in view coordinates
vec4 view_pos = view_matrix * vec4(world_position, 1.0);
vec4 dist_pos = distort(view_pos);
gl_Position = projection_matrix * dist_pos;
}
)""
\ No newline at end of file
R""(
#version 330 core
in vec3 normal;
in vec3 fragment_position;
uniform float ambient_strength;
uniform vec3 light_color;
uniform vec3 light_position;
uniform vec3 object_color;
out vec4 fragment_color;
// displays the scene in a single diffuse color
void main()
{
// ambient
vec3 ambient = ambient_strength * light_color;
vec3 light_direction = normalize(light_position - fragment_position);
// diffuse
vec3 normalized_normal = normalize(normal);
float diff = max(dot(normalized_normal, light_direction), 0.0);
vec3 diffuse = diff * light_color;
vec3 result = (ambient + diffuse) * object_color;
fragment_color = vec4(result, 1.0);
}
)""
\ No newline at end of file
......@@ -41,19 +41,5 @@ public:
\param b blue element of the RGB color, ranges from 0 to 1
*/
static void set_color(const Shader &shader, float r, float g, float b);
private:
/*!
Returns the vertex shader source code.
*/
static std::string get_vertex_source();
/*!
Returns the geometry shader source code.
*/
static std::string get_geometry_source();
/*!
Returns the fragment shader source code.
*/
static std::string get_fragment_source();
};
} // namespace scigl_render
\ No newline at end of file
......@@ -11,19 +11,5 @@ class SingleTextureShader
{
public:
static Shader create_shader();
private:
/*!
Returns the vertex shader source code.
*/
static std::string get_vertex_source();
/*!
Returns the geometry shader source code.
*/
static std::string get_geometry_source();
/*!
Returns the fragment shader source code.
*/
static std::string get_fragment_source();
};
} // namespace scigl_render
\ No newline at end of file
R""(
#version 330 core
struct Material
{
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
in vec3 world_position;
in vec3 normal;
in vec2 texture_coordinate;
uniform vec3 camera_position;
uniform vec3 light_position;
uniform vec3 light_color;
uniform Material material;
uniform sampler2D texture0;
uniform float diffuse_texture_strength;
out vec4 fragment_color;
// displays a material + texture
// supports ambient, diffuse and specular lighting
void main()
{
vec3 light_direction = normalize(light_position - world_position);
// ambient
vec3 ambient = material.ambient;
// diffuse
vec3 diffuse_color = material.diffuse + diffuse_texture_strength
* texture(texture0, texture_coordinate).xyz;
float diff = max(dot(normal, light_direction), 0.0);
vec3 diffuse = diff * diffuse_color;
// specular
vec3 view_direction = normalize(camera_position - world_position);
vec3 reflection_direction = reflect(-light_direction, normal);
float spec = pow(max(dot(view_direction, reflection_direction), 0.0),
material.shininess);
vec3 specular = material.specular * spec;
// combined
vec3 result = (ambient + diffuse + specular) * light_color;
fragment_color = vec4(result, 1.0);
}
)""
\ No newline at end of file
#include <scigl_render/shader/single_color_shader.hpp>
const std::string vs_source =
#include <scigl_render/shader/distort.vs>
"";
const std::string fs_source =
#include <scigl_render/shader/single_color.fs>
"";
namespace scigl_render
{
Shader SingleColorShader::create_shader()
{
return Shader(get_vertex_source(), get_geometry_source(),
get_fragment_source());
return Shader(vs_source, "", fs_source);
}
Shader SingleColorShader::create_shader(float ambient_strength,
......@@ -34,62 +40,4 @@ void SingleColorShader::set_color(const Shader &shader, float r, float g,
shader.setVec3("object_color", color);
shader.deactivate();
}
std::string SingleColorShader::get_vertex_source()
{
return R"(
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal_in;
out vec3 normal;
out vec3 fragment_position;
uniform mat4 model_matrix;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
void main()
{
// to world coordinates
vec4 local_pos = vec4(position, 1.0);
vec4 world_pos = model_matrix * local_pos;
fragment_position = vec3(world_pos);
normal = mat3(transpose(inverse(model_matrix))) * normal_in;
// to view coordinates
vec4 view_pos = view_matrix * world_pos;
gl_Position = projection_matrix * view_pos;
}
)";
}
std::string SingleColorShader::get_geometry_source()
{
return "";
}
std::string SingleColorShader::get_fragment_source()
{
return R"(
#version 330 core
in vec3 normal;
in vec3 fragment_position;
out vec4 fragment_color;
uniform float ambient_strength;
uniform vec3 light_color;
uniform vec3 light_position;
uniform vec3 object_color;
void main()
{
// ambient
vec3 ambient = ambient_strength * light_color;
vec3 light_direction = normalize(light_position - fragment_position);
// diffuse
vec3 normalized_normal = normalize(normal);
float diff = max(dot(normalized_normal, light_direction), 0.0);
vec3 diffuse = diff * light_color;
vec3 result = (ambient + diffuse) * object_color;
fragment_color = vec4(result, 1.0);
}
)";
}
} // namespace scigl_render
\ No newline at end of file
#include <scigl_render/shader/single_texture_shader.hpp>
const std::string vs_source =
#include<scigl_render/shader/distort.vs>
"";
const std::string fs_source =
#include <scigl_render/shader/texture.fs>
"";
namespace scigl_render
{
Shader SingleTextureShader::create_shader()
{
return Shader(get_vertex_source(), get_geometry_source(),
get_fragment_source());
}
std::string SingleTextureShader::get_vertex_source()
{
return R"(#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal_in;
layout (location = 2) in vec2 texture_coordinate_in;
uniform mat4 model_matrix;
uniform mat4 view_matrix;
uniform float dist_coeffs[8];
uniform mat4 projection_matrix;
uniform vec3 light_position;
out vec2 texture_coordinate;
out vec3 normal;
out vec3 light_direction;
// distort the real world vertices using the rational model
vec4 distort(vec4 view_pos)
{
// normalize
float z = view_pos[2];
float z_inv = 1 / z;
float x1 = view_pos[0] * z_inv;
float y1 = view_pos[1] * z_inv;
// precalculations
float x1_2 = x1*x1;
float y1_2 = y1*y1;
float x1_y1 = x1*y1;
float r2 = x1_2 + y1_2;
float r4 = r2*r2;
float r6 = r4*r2;
// rational distortion factor
float r_dist = (1 + dist_coeffs[0]*r2 +dist_coeffs[1]*r4 + dist_coeffs[4]*r6)
/ (1 + dist_coeffs[5]*r2 + dist_coeffs[6]*r4 + dist_coeffs[7]*r6);
// full (rational + tangential) distortion
float x2 = x1*r_dist + 2*dist_coeffs[2]*x1_y1 + dist_coeffs[3]*(r2 + 2*x1_2);
float y2 = y1*r_dist + 2*dist_coeffs[3]*x1_y1 + dist_coeffs[2]*(r2 + 2*y1_2);
// denormalize for projection (which is a linear operation)
return vec4(x2*z, y2*z, z, view_pos[3]);
}
void main()
{
vec4 local_pos = vec4(position, 1.0);
vec4 world_pos = model_matrix * local_pos;
vec4 view_pos = view_matrix * world_pos;
vec4 dist_pos = distort(view_pos);
gl_Position = projection_matrix * dist_pos;
// lighting on world coordinates not distorted ones
normal = mat3(transpose(inverse(model_matrix))) * normal_in;
light_direction = normalize(light_position - world_pos.xyz);
texture_coordinate = texture_coordinate_in;
})";
}
std::string SingleTextureShader::get_geometry_source()
{
return "";
}
std::string SingleTextureShader::get_fragment_source()
{
return R"(#version 330 core
struct Material
{
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
in vec2 texture_coordinate;
in vec3 normal;
in vec3 light_direction;
out vec4 fragment_color;
uniform Material material;
uniform sampler2D texture0;
uniform float diffuse_texture_strength;
uniform vec3 light_color;
void main()
{
// ambient
vec3 ambient = light_color * material.ambient;
// diffuse
vec3 diffuse_color = (material.diffuse)
+ diffuse_texture_strength * texture(texture0, texture_coordinate).xyz;
vec3 normalized_normal = normalize(normal);
float diff = max(dot(normalized_normal, light_direction), 0.0);
vec3 diffuse = light_color * (diff * diffuse_color);
// specular not used yet
vec3 result = ambient + diffuse;
fragment_color = vec4(result, 1.0);
})";
return Shader(vs_source, "", fs_source);
}
} // namespace scigl_render
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment