Skip to content

Commit

Permalink
Reintegrate deferred shading
Browse files Browse the repository at this point in the history
  • Loading branch information
TypeDefinition committed Apr 9, 2024
1 parent 8553cdb commit 39279eb
Show file tree
Hide file tree
Showing 31 changed files with 728 additions and 642 deletions.
20 changes: 10 additions & 10 deletions assets/shaders/forward.frag
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
// By using glBindFragDataLocation(GLuint program, GLuint colorNumber, const char * name), it is not necessary to use the layout qualifier and vice-versa.
// However, if both are used and are in conflict, the layout qualifier in the vertex shader has priority.
layout (location = 0) out vec4 out_colour;
layout (location = 1) out vec4 out_position;
layout (location = 2) out vec4 out_normal;
layout (location = 1) out vec3 out_position;
layout (location = 2) out vec3 out_normal;

// Inputs
in io_block {
Expand All @@ -35,7 +35,7 @@ uniform vec4 u_specular_colour;
uniform float u_gloss;
uniform float u_displacement_scale;

// Texture
// Textures
uniform bool u_texture_diffuse_enabled;
uniform bool u_texture_normal_enabled;
uniform bool u_texture_specular_enabled;
Expand All @@ -48,6 +48,10 @@ uniform sampler2D u_texture_specular;
uniform sampler2D u_texture_gloss;
uniform sampler2D u_texture_displacement;

// Shadow
uniform sampler2D u_texture_shadows[max_lights];
uniform samplerCube u_cubemap_shadows[max_lights];

// Light
struct light {
int mode_;
Expand All @@ -72,10 +76,6 @@ uniform int u_num_lights;
uniform vec4 u_ambient_light;
uniform light u_lights[max_lights];

// Shadow
uniform sampler2D u_texture_shadows[max_lights];
uniform samplerCube u_cubemap_shadows[max_lights];

// Includes
vec2 parallax_occlusion(const in sampler2D _texture, const in vec2 _tex_coord, float _disp_scale, const in vec3 _frag_pos, const in mat3 _inv_tbn_matrix, const in vec3 _normal);

Expand Down Expand Up @@ -184,12 +184,12 @@ void main() {
bool cast_shadow[max_lights];
get_cast_shadow(normal, cast_shadow);

const vec4 ambient = get_diffuse(tex_coord) * u_ambient_light;
const vec4 diffuse = get_diffuse(tex_coord) * get_light_diffuse(io_position, normal, cast_shadow);
const vec4 specular = get_specular(tex_coord) * get_light_specular(io_position, normal, gloss, cast_shadow);
const vec4 ambient = get_diffuse(tex_coord) * u_ambient_light;
const vec3 phong = (ambient + diffuse + specular).rgb;

out_colour = vec4(phong, 1.0f);
out_position = vec4(io_position, 1.0f);
out_normal = vec4(io_normal, 1.0f);
out_position = io_position;
out_normal = io_normal;
}
14 changes: 5 additions & 9 deletions assets/shaders/forward.vert
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,14 @@ uniform vec2 u_texture_offset;
uniform vec2 u_texture_scale;

void main() {
io_tex_coord = (v_tex_coord + vec3(u_texture_offset, 0.0f)) * vec3(u_texture_scale, 1.0f);
io_position = (u_view_matrix * v_model_matrix * vec4(v_position, 1.0f)).xyz;
io_normal = normalize(v_normal_matrix * v_normal);

/* This is the Gramm-Schmidt process. dot(Tangent, Normal) gives us the length of the projection of the tangent along the normal vector.
The product of this length by the normal itself is the component of the tangent along the normal.
Substract that from the tangent and we get a new vector which is perpendicular to the normal.
This is our new tangent. */
vec3 n = io_normal;
vec3 n = normalize(v_normal_matrix * v_normal);
vec3 t = normalize(v_normal_matrix * v_tangent);
t = normalize(t - dot(t, n) * n);
vec3 b = cross(n, t);

io_tex_coord = (v_tex_coord + vec3(u_texture_offset, 0.0f)) * vec3(u_texture_scale, 1.0f);
io_position = (u_view_matrix * v_model_matrix * vec4(v_position, 1.0f)).xyz;
io_normal = n;
io_tbn_matrix = mat3(t, b, n);

gl_Position = u_projection_matrix * u_view_matrix * v_model_matrix * vec4(v_position, 1.0f);
Expand Down
74 changes: 19 additions & 55 deletions assets/shaders/geometry.frag
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
#version 460 core

// IMPORTANT: All transforms in the fragment shader is in camera space, where the camera is at the origin.
layout (location = 0) out vec4 out_position;
layout (location = 1) out vec4 out_normal;
layout (location = 0) out vec3 out_position;
layout (location = 1) out vec3 out_normal;
layout (location = 2) out vec4 out_diffuse;
layout (location = 3) out vec4 out_specular;
layout (location = 4) out float out_gloss;

// Inputs
in io_block {
vec3 io_tex_coord;
vec3 io_position; // Vertex position in camera space.
vec3 io_normal; // Vertex normal in camera space.
mat3 io_normal_matrix;
mat3 io_tbn_matrix; // Converts from tangent space to camera space.
mat3 io_inv_tbn_matrix; // Converts from camera space to tangent space.
vec3 io_position;// Vertex position in camera space.
vec3 io_normal;// Vertex normal in camera space.
mat3 io_tbn_matrix;// Converts from tangent space to camera space.
};

// Uniforms
// Material
uniform vec4 u_diffuse_colour;
uniform vec4 u_specular_colour;
uniform float u_gloss;
uniform float u_displacement_scale;

// Textures
uniform bool u_texture_diffuse_enabled;
uniform bool u_texture_normal_enabled;
uniform bool u_texture_specular_enabled;
Expand All @@ -35,56 +34,21 @@ uniform sampler2D u_texture_specular;
uniform sampler2D u_texture_gloss;
uniform sampler2D u_texture_displacement;

vec2 parallax(const vec2 _tex_coord) {
vec3 view_direction = normalize(io_inv_tbn_matrix * io_position);
float depth = 1.0f - texture(u_texture_displacement, _tex_coord).r;
return (view_direction.xy / -view_direction.z) * depth * u_displacement_scale; // Parallax Mapping without Offset Limiting
}

vec2 parallax_occlusion(const vec2 _tex_coord) {
const vec2 max_uv_displacement = parallax(_tex_coord);
const int min_displacement_samples = 8;
const int max_displacement_samples = 32;
const float dot_product = dot(io_normal, normalize(-io_position));
const int num_samples = int(mix(max_displacement_samples, min_displacement_samples, dot_product));

float previous_layer_depth = 0.0f;
vec2 previous_uv_displacement = vec2(0.0f, 0.0f);
float previous_texture_depth = 0.0f;
for (int i = 0; i < num_samples; ++i) {
const float current_layer_depth = float(i)/float(num_samples);
const vec2 current_uv_displacement = current_layer_depth * max_uv_displacement;
const float current_texture_depth = 1.0f - texture(u_texture_displacement, _tex_coord + current_uv_displacement).r;

if (current_layer_depth > current_texture_depth) {
const float excess_depth = current_layer_depth - current_texture_depth;
const float lacking_depth = previous_texture_depth - previous_layer_depth;
return mix(previous_uv_displacement, current_uv_displacement, lacking_depth / (lacking_depth + excess_depth));
}

previous_layer_depth = current_layer_depth;
previous_uv_displacement = current_uv_displacement;
previous_texture_depth = current_texture_depth;
}

return max_uv_displacement;
}

vec2 get_tex_coord() {
return u_texture_displacement_enabled ? (io_tex_coord.xy + parallax_occlusion(io_tex_coord.xy)) : io_tex_coord.xy;
}
// Includes
vec2 parallax_occlusion(const in sampler2D _texture, const in vec2 _tex_coord, float _disp_scale, const in vec3 _frag_pos, const in mat3 _inv_tbn_matrix, const in vec3 _normal);

vec3 get_normal(const in vec2 _tex_coord) {
if (u_texture_normal_enabled) {
vec3 normal = texture(u_texture_normal, _tex_coord).rgb;
normal *= 2.0f;
normal -= vec3(1.0f, 1.0f, 1.0f);
normal = normalize(normal);
return io_tbn_matrix * normal;
const vec3 normal = 2.0f * texture(u_texture_normal, _tex_coord).rgb - vec3(1.0f, 1.0f, 1.0f); // Convert into the [-1, 1] range.
return io_tbn_matrix * normal; // Convert the normal from tangent space to camera space.
}
return io_normal;
}

float get_gloss(const in vec2 _tex_coord) {
return u_texture_gloss_enabled ? texture(u_texture_gloss, _tex_coord).r * u_gloss : u_gloss;
}

vec4 get_diffuse(const in vec2 _tex_coord) {
return u_texture_diffuse_enabled ? texture(u_texture_diffuse, _tex_coord) * u_diffuse_colour : u_diffuse_colour;
}
Expand All @@ -93,15 +57,15 @@ vec4 get_specular(const in vec2 _tex_coord) {
return u_texture_specular_enabled ? texture(u_texture_specular, _tex_coord) * u_specular_colour : u_specular_colour;
}

float get_gloss(const in vec2 _tex_coord) {
return u_texture_gloss_enabled ? texture(u_texture_gloss, _tex_coord).r * u_gloss : u_gloss;
vec2 get_tex_coord() {
return u_texture_displacement_enabled ? parallax_occlusion(u_texture_displacement, io_tex_coord.xy, u_displacement_scale, io_position, io_tbn_matrix, io_normal) : io_tex_coord.xy;
}

void main() {
const vec2 tex_coord = get_tex_coord();

out_position = vec4(io_position, 1.0f);
out_normal = vec4(get_normal(tex_coord), 1.0f);
out_position = io_position;
out_normal = get_normal(tex_coord);
out_diffuse = get_diffuse(tex_coord);
out_specular = get_specular(tex_coord);
out_gloss = get_gloss(tex_coord);
Expand Down
31 changes: 9 additions & 22 deletions assets/shaders/geometry.vert
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,25 @@ out io_block {
vec3 io_tex_coord;
vec3 io_position; // Vertex position in camera space.
vec3 io_normal; // Vertex normal in camera space.
mat3 io_normal_matrix;
mat3 io_tbn_matrix; // Converts from tangent space to camera space.
mat3 io_inv_tbn_matrix; // Converts from camera space to tangent space.
};

// Uniforms
uniform mat4 u_view_matrix;
uniform mat4 u_projection_matrix;
uniform mat4 u_view_projection_matrix;
uniform vec2 u_texture_offset;
uniform vec2 u_texture_scale;

void main() {
vec3 n = normalize(v_normal_matrix * v_normal);
vec3 t = normalize(v_normal_matrix * v_tangent);
t = normalize(t - dot(t, n) * n);
vec3 b = cross(n, t);

io_tex_coord = (v_tex_coord + vec3(u_texture_offset, 0.0f)) * vec3(u_texture_scale, 1.0f);
io_position = (u_view_matrix * v_model_matrix * vec4(v_position, 1.0f)).xyz;
io_normal = n;
io_tbn_matrix = mat3(t, b, n);

mat4 model_view_matrix = u_view_matrix * v_model_matrix;
io_position = (model_view_matrix * vec4(v_position, 1.0f)).xyz;
io_normal = normalize(v_normal_matrix * v_normal);
io_normal_matrix = v_normal_matrix;

// This is the Gramm-Schmidt process. dot(Tangent, Normal) gives us the length of the projection of the tangent along the normal vector.
// The product of this length by the normal itself is the component of the tangent along the normal.
// Substract that from the tangent and we get a new vector which is perpendicular to the normal.
// This is our new tangent (just remember to normalize it as well...).
vec3 tangent = normalize(v_tangent - dot(v_tangent, v_normal) * v_normal);
// A cross product between the tangent and the normal gives us the bitangent.
vec3 bitangent = normalize(cross(v_normal, tangent));

io_tbn_matrix[0] = normalize(v_normal_matrix * tangent);
io_tbn_matrix[1] = normalize(v_normal_matrix * bitangent);
io_tbn_matrix[2] = io_normal;
io_inv_tbn_matrix = transpose(io_tbn_matrix); // Since TBN is an orthogonal matrix, its transpose is also its inverse.

gl_Position = u_view_projection_matrix * v_model_matrix * vec4(v_position, 1.0f);
gl_Position = u_projection_matrix * u_view_matrix * v_model_matrix * vec4(v_position, 1.0f);
}
Loading

0 comments on commit 39279eb

Please sign in to comment.