Add support for loading normals from a map

This commit is contained in:
2024-08-18 16:47:30 +01:00
parent 1adac24148
commit 2e39780272
8 changed files with 13181 additions and 45 deletions

View File

@@ -46,7 +46,8 @@ V3f run_vertex_shader(ShaderID shader, const V3f *vertex,
}
FragmentResult run_fragment_shader(ShaderID shader, V3f normal, V2f tex_coords,
const Colour *colour, const Image *texture) {
const Colour *colour, const Image *texture,
const Image *normal_map) {
if (IS_INVALID_SHADER(shader) || shader.id > g_repository.count || !colour) {
return DISCARDED_FRAGMENT;
}
@@ -58,5 +59,6 @@ FragmentResult run_fragment_shader(ShaderID shader, V3f normal, V2f tex_coords,
return DISCARDED_FRAGMENT;
}
return fragment_func(shader_obj, normal, tex_coords, colour, texture);
return fragment_func(shader_obj, normal, tex_coords, colour, texture,
normal_map);
}

View File

@@ -25,13 +25,15 @@ typedef V3f(VertexShader)(void *shader, const V3f *vertex,
const Buffer *out_buf);
typedef FragmentResult(FragmentShader)(void *shader, V3f normal, V2f tex_coords,
const Colour *colour,
const Image *texture);
const Image *texture,
const Image *normal_map);
ShaderID create_shader(void *shader, VertexShader *vertex,
FragmentShader *fragment);
V3f run_vertex_shader(ShaderID shader, const V3f *vertex,
const Buffer *out_buf);
FragmentResult run_fragment_shader(ShaderID shader, V3f normal, V2f tex_coords,
const Colour *colour, const Image *texture);
const Colour *colour, const Image *texture,
const Image *normal_map);
#endif // SHADER_H

View File

@@ -1,7 +1,6 @@
#include "img.h"
#include "obj.h"
#include "shader.h"
#include "utils.h"
#include "vec.h"
typedef struct shader Shader;
@@ -13,12 +12,13 @@ struct shader {
Shader perspective = {0};
Shader orthographic = {0};
ShaderID perspective_lit_textured_id = {0};
ShaderID perspective_lit_coloured_id = {0};
ShaderID perspective_albedo_id = {0};
ShaderID orthographic_lit_textured_id = {0};
ShaderID orthographic_lit_coloured_id = {0};
ShaderID orthographic_albedo_id = {0};
ShaderID phong = {0};
ShaderID perspective_lit_textured = {0};
ShaderID perspective_lit_coloured = {0};
ShaderID perspective_albedo = {0};
ShaderID orthographic_lit_textured = {0};
ShaderID orthographic_lit_coloured = {0};
ShaderID orthographic_albedo = {0};
V3f g_light_dir = {0.0f, 0.0f, 1.0f};
V3f g_eye = {0.2f, 0.1f, 0.75f};
@@ -28,18 +28,26 @@ M4x4f g_cam_matrix = mat4x4_identity;
internal V3f general_shader_vertex(void *shader, const V3f *vertex,
const Buffer *out_buf);
internal FragmentResult phong_shader_fragment(void *shader, V3f normal,
V2f tex_coords,
const Colour *colour,
const Image *texture,
const Image *normal_map);
internal FragmentResult lit_textured_shader_fragment(void *shader, V3f normal,
V2f tex_coords,
const Colour *colour,
const Image *texture);
const Image *texture,
const Image *normal_map);
internal FragmentResult lit_coloured_shader_fragment(void *shader, V3f normal,
V2f tex_coords,
const Colour *colour,
const Image *texture);
const Image *texture,
const Image *normal_map);
internal FragmentResult albedo_shader_fragment(void *shader, V3f normal,
V2f tex_coords,
const Colour *colour,
const Image *texture);
const Image *texture,
const Image *normal_map);
internal M4x4f get_projection_matrix(ProjectionType projection_type);
internal f32 get_intensity(const V3f *normal);
@@ -54,18 +62,20 @@ void load_shaders(void) {
perspective.projection = perspective_projection;
orthographic.projection = orthographic_projection;
perspective_lit_textured_id = create_shader(
&perspective, general_shader_vertex, lit_textured_shader_fragment);
perspective_lit_coloured_id = create_shader(
&perspective, general_shader_vertex, lit_coloured_shader_fragment);
perspective_albedo_id = create_shader(&perspective, general_shader_vertex,
albedo_shader_fragment);
orthographic_lit_textured_id = create_shader(
phong =
create_shader(&perspective, general_shader_vertex, phong_shader_fragment);
perspective_lit_textured = create_shader(&perspective, general_shader_vertex,
lit_textured_shader_fragment);
perspective_lit_coloured = create_shader(&perspective, general_shader_vertex,
lit_coloured_shader_fragment);
perspective_albedo = create_shader(&perspective, general_shader_vertex,
albedo_shader_fragment);
orthographic_lit_textured = create_shader(
&orthographic, general_shader_vertex, lit_textured_shader_fragment);
orthographic_lit_coloured_id = create_shader(
orthographic_lit_coloured = create_shader(
&orthographic, general_shader_vertex, lit_coloured_shader_fragment);
orthographic_albedo_id = create_shader(&orthographic, general_shader_vertex,
albedo_shader_fragment);
orthographic_albedo = create_shader(&orthographic, general_shader_vertex,
albedo_shader_fragment);
}
internal V3f general_shader_vertex(void *shader, const V3f *vertex,
@@ -82,10 +92,46 @@ internal V3f general_shader_vertex(void *shader, const V3f *vertex,
return project_vec4(vh);
}
internal FragmentResult phong_shader_fragment(void *shader, V3f normal,
V2f tex_coords,
const Colour *colour,
const Image *texture,
const Image *normal_map) {
f32 intensity = get_intensity(&normal);
if (normal_map) {
u64 nm_x = tex_coords.u * normal_map->width;
u64 nm_y = (1.0f - tex_coords.v) * normal_map->height;
Colour pixel = get_pixel(Colour, normal_map, nm_x, nm_y);
V3f norm = {.x = pixel.r, .y = pixel.g, .z = pixel.b};
normalise_v3(norm);
intensity = get_intensity(&norm);
} else {
intensity = get_intensity(&normal);
}
Colour output;
if (texture) {
u64 tx_x = tex_coords.u * texture->width;
u64 tx_y = (1.0f - tex_coords.v) * texture->height;
output = get_pixel(Colour, texture, tx_x, tx_y);
} else {
output = *colour;
}
output.r *= intensity;
output.g *= intensity;
output.b *= intensity;
return (FragmentResult){.colour = output};
}
internal FragmentResult lit_textured_shader_fragment(void *shader, V3f normal,
V2f tex_coords,
const Colour *colour,
const Image *texture) {
const Image *texture,
const Image *normal_map) {
if (!texture) {
return DISCARDED_FRAGMENT;
}
@@ -107,7 +153,8 @@ internal FragmentResult lit_textured_shader_fragment(void *shader, V3f normal,
internal FragmentResult lit_coloured_shader_fragment(void *shader, V3f normal,
V2f tex_coords,
const Colour *colour,
const Image *texture) {
const Image *texture,
const Image *normal_map) {
f32 intensity = get_intensity(&normal);
Colour output = *colour;
@@ -121,7 +168,8 @@ internal FragmentResult lit_coloured_shader_fragment(void *shader, V3f normal,
internal FragmentResult albedo_shader_fragment(void *shader, V3f normal,
V2f tex_coords,
const Colour *colour,
const Image *texture) {
const Image *texture,
const Image *normal_map) {
return (FragmentResult){.colour = *colour};
}
@@ -141,7 +189,7 @@ internal M4x4f get_projection_matrix(ProjectionType projection_type) {
internal f32 get_intensity(const V3f *normal) {
f32 intensity = dot_v3((*normal), g_light_dir);
if (intensity < 0.0f) {
intensity = 0.01f;
intensity = 0.001f;
}
return intensity;