Skip to content
Snippets Groups Projects
Commit ceda353e authored by Tim Übelhör's avatar Tim Übelhör
Browse files

New shader loading mechanism.

Specular lighting is supported.
parent 0879fe45
No related branches found
No related tags found
No related merge requests found
......@@ -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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment