diff options
Diffstat (limited to 'engine/src/renderer/opengl/glsl')
-rw-r--r-- | engine/src/renderer/opengl/glsl/fragment.glsl | 73 | ||||
-rw-r--r-- | engine/src/renderer/opengl/glsl/light.glsl | 133 | ||||
-rw-r--r-- | engine/src/renderer/opengl/glsl/vertex.glsl | 24 | ||||
-rw-r--r-- | engine/src/renderer/opengl/glsl/vertex_data.glsl | 11 |
4 files changed, 241 insertions, 0 deletions
diff --git a/engine/src/renderer/opengl/glsl/fragment.glsl b/engine/src/renderer/opengl/glsl/fragment.glsl new file mode 100644 index 0000000..5bf5ff2 --- /dev/null +++ b/engine/src/renderer/opengl/glsl/fragment.glsl @@ -0,0 +1,73 @@ +#version 330 core + +#preinclude "light.glsl" +#preinclude "vertex_data.glsl" + +#define MAX_LIGHT_CNT 64 + +out vec4 FragColor; + +in VertexData vertex_data; + +uniform vec3 view_pos; +uniform sampler2D input_texture; +uniform Material material; + +uniform PointLight point_lights[MAX_LIGHT_CNT]; +uniform int point_light_cnt; + +uniform DirectionalLight directional_lights[MAX_LIGHT_CNT]; +uniform int directional_light_cnt; + +void main() +{ + vec3 ambient_light = calc_ambient_light(material, vertex_data.texture_coords); + + vec3 directional_light_sum = vec3(0.0, 0.0, 0.0); + + for (int dl_index = 0; dl_index < directional_light_cnt; dl_index++) { + CalculatedLight calculated_dir_light; + + calc_light( + // Negated since we want the light to point from the light direction + normalize(-directional_lights[dl_index].direction), + directional_lights[dl_index].phong, + vertex_data, + view_pos, + material, + calculated_dir_light + ); + + directional_light_sum += + calculated_dir_light.diffuse + calculated_dir_light.specular; + } + + vec3 point_light_sum = vec3(0.0, 0.0, 0.0); + + for (int pl_index = 0; pl_index < point_light_cnt; pl_index++) { + vec3 light_direction = + normalize(point_lights[pl_index].position - vertex_data.world_space_pos); + + CalculatedLight calculated_point_light; + + calc_light( + light_direction, + point_lights[pl_index].phong, + vertex_data, + view_pos, + material, + calculated_point_light + ); + + float attenuation = + calc_attenuation(point_lights[pl_index], vertex_data.world_space_pos); + + calculated_point_light.diffuse *= attenuation; + calculated_point_light.specular *= attenuation; + + point_light_sum += + calculated_point_light.diffuse + calculated_point_light.specular; + } + + FragColor = vec4((ambient_light + directional_light_sum + point_light_sum), 1.0); +} diff --git a/engine/src/renderer/opengl/glsl/light.glsl b/engine/src/renderer/opengl/glsl/light.glsl new file mode 100644 index 0000000..1bc23a4 --- /dev/null +++ b/engine/src/renderer/opengl/glsl/light.glsl @@ -0,0 +1,133 @@ +#version 330 core + +#ifndef LIGHT_GLSL +#define LIGHT_GLSL + +#preinclude "vertex_data.glsl" + +struct Material +{ + vec3 ambient; + vec3 diffuse; + vec3 specular; + sampler2D ambient_map; + sampler2D diffuse_map; + sampler2D specular_map; + float shininess; +}; + +struct LightPhong +{ + vec3 diffuse; + vec3 specular; +}; + +struct AttenuationProperties +{ + float constant; + float linear; + float quadratic; +}; + +struct PointLight +{ + LightPhong phong; + vec3 position; + AttenuationProperties attenuation_props; +}; + +struct DirectionalLight +{ + LightPhong phong; + vec3 direction; +}; + +struct CalculatedLight +{ + vec3 diffuse; + vec3 specular; +}; + +vec3 calc_ambient_light(in Material material, in vec2 texture_coords) +{ + return vec3(texture(material.ambient_map, texture_coords)) * material.ambient; +} + +vec3 calc_diffuse_light( + in Material material, + in LightPhong light_phong, + in vec3 light_dir, + in vec3 norm, + in vec2 texture_coords +) +{ + float diff = max(dot(norm, light_dir), 0.0); + + return light_phong.diffuse * ( + diff * (vec3(texture(material.diffuse_map, texture_coords)) * material.diffuse) + ); +} + +vec3 calc_specular_light( + in Material material, + in LightPhong light_phong, + in vec3 light_dir, + in vec3 norm, + in vec3 view_pos, + in vec3 frag_pos, + in vec2 texture_coords +) +{ + vec3 view_direction = normalize(view_pos - frag_pos); + + vec3 reflect_direction = reflect(-light_dir, norm); + + float spec = + pow(max(dot(view_direction, reflect_direction), 0.0), material.shininess); + + return light_phong.specular * ( + spec * (vec3(texture(material.specular_map, texture_coords)) * material.specular) + ); +} + +float calc_attenuation(in PointLight point_light, in vec3 position) +{ + float light_distance = length(point_light.position - position); + + return 1.0 / (point_light.attenuation_props.constant + + point_light.attenuation_props.linear + * light_distance + point_light.attenuation_props.quadratic + * pow(light_distance, 2)); +} + +void calc_light( + in vec3 light_direction, + in LightPhong light_phong, + in VertexData vertex_data, + in vec3 view_pos, + in Material material, + out CalculatedLight calculated_light +) +{ + vec3 norm = normalize(vertex_data.world_space_normal); + + calculated_light.diffuse = calc_diffuse_light( + material, + light_phong, + light_direction, + norm, + vertex_data.texture_coords + ); + + calculated_light.specular = calc_specular_light( + material, + light_phong, + light_direction, + norm, + view_pos, + vertex_data.world_space_pos, + vertex_data.texture_coords + ); +} + +#endif diff --git a/engine/src/renderer/opengl/glsl/vertex.glsl b/engine/src/renderer/opengl/glsl/vertex.glsl new file mode 100644 index 0000000..b57caa6 --- /dev/null +++ b/engine/src/renderer/opengl/glsl/vertex.glsl @@ -0,0 +1,24 @@ +#version 330 core + +#preinclude "vertex_data.glsl" + +layout (location = 0) in vec3 pos; +layout (location = 1) in vec2 texture_coords; +layout (location = 2) in vec3 normal; + +out VertexData vertex_data; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + gl_Position = projection * view * model * vec4(pos, 1.0); + + vertex_data.world_space_pos = vec3(model * vec4(pos, 1.0)); + vertex_data.texture_coords = texture_coords; + + // TODO: Do this using CPU for performance increase + vertex_data.world_space_normal = mat3(transpose(inverse(model))) * normal; +} diff --git a/engine/src/renderer/opengl/glsl/vertex_data.glsl b/engine/src/renderer/opengl/glsl/vertex_data.glsl new file mode 100644 index 0000000..486d445 --- /dev/null +++ b/engine/src/renderer/opengl/glsl/vertex_data.glsl @@ -0,0 +1,11 @@ +#ifndef VERTEX_DATA_GLSL +#define VERTEX_DATA_GLSL + +struct VertexData +{ + vec2 texture_coords; + vec3 world_space_pos; + vec3 world_space_normal; +}; + +#endif |