Tweak fragment shader to take and return V4f instead of Colour

This commit is contained in:
Abdelrahman Said 2024-09-14 01:22:43 +01:00
parent 390ab7c3b4
commit 87f6b2b87a
8 changed files with 54 additions and 33 deletions

View File

@ -6,6 +6,7 @@
#include "typed_list.h"
#include "utils.h"
#include "vec.h"
#include <stdint.h>
#include <math.h>
typedef struct triangle_bbox TriangleBBox;
@ -51,7 +52,7 @@ void render_model(const Model *model, Render *render, ShaderID shader,
}
internal void render_triangle(const Triangle *triangle, const Model *model, ShaderID shader,
Render *render, RenderType render_type, Colour colour) {
Render *render, RenderType render_type, Colour colour) {
Image *img = &(render->img);
VertexData vertices[TRIANGLE_VERTICES];
for (u64 i = 0; i < TRIANGLE_VERTICES; ++i) {
@ -92,6 +93,8 @@ internal void fill_triangle(Render *render, ShaderID shader, VertexData vertices
V3f coords;
f32 z;
f32 zbuf;
V4f shader_colour;
Colour output_colour;
FragmentResult result;
f32 intensity = 1.0f;
@ -114,13 +117,21 @@ internal void fill_triangle(Render *render, ShaderID shader, VertexData vertices
continue;
}
result = run_fragment_shader(shader, &coords, &colour, model);
shader_colour = (V4f){.r = colour.r, .g = colour.g, .b = colour.b, .a = colour.a};
result = run_fragment_shader(shader, &coords, &shader_colour, model);
if (DISCARD_FRAGMENT(result)) {
continue;
}
output_colour = (Colour){
.r = clamp(result.colour.r, 0, UINT8_MAX),
.g = clamp(result.colour.g, 0, UINT8_MAX),
.b = clamp(result.colour.b, 0, UINT8_MAX),
.a = clamp(result.colour.a, 0, UINT8_MAX),
};
set_pixel(depth, x, y, &z);
set_pixel(img, x, y, &result.colour);
set_pixel(img, x, y, &output_colour);
}
}
}

View File

@ -1,8 +1,5 @@
#include "depth_shader.h"
#include "constants.h"
#include "img.h"
#include "shader.h"
#include "utils.h"
VertexData depth_shader_vertex(void *shader, const VertexData *vert, u8 index, const Model *model) {
DepthShader *shdr = (DepthShader *)shader;
@ -15,16 +12,15 @@ VertexData depth_shader_vertex(void *shader, const VertexData *vert, u8 index, c
return shdr->vertices[index];
}
FragmentResult depth_shader_fragment(void *shader, const V3f *barycentric, const Colour *colour,
FragmentResult depth_shader_fragment(void *shader, const V3f *barycentric, const V4f *colour,
const Model *model) {
DepthShader *shdr = (DepthShader *)shader;
M3x3f pos_mat = {.rows = {shdr->vertices[0].position, shdr->vertices[1].position, shdr->vertices[2].position}};
pos_mat = mat3x3_transpose(pos_mat);
V3f position = mat3x3_mul_vec3(pos_mat, (*barycentric));
f32 channel = clamp(position.z + DEPTH_MAX, 0.0f, DEPTH_MAX);
Colour output = {.r = (u8)(channel), .g = (u8)(channel), .b = (u8)(channel), .a = 255};
V3f position = mat3x3_mul_vec3(pos_mat, (*barycentric));
V4f output = {.r = position.z, .g = position.z, .b = position.z, .a = 255};
return (FragmentResult){.colour = output};
}

View File

@ -11,7 +11,7 @@ struct depth_shader {
};
VertexData depth_shader_vertex(void *shader, const VertexData *vert, u8 index, const Model *model);
FragmentResult depth_shader_fragment(void *shader, const V3f *barycentric, const Colour *colour,
FragmentResult depth_shader_fragment(void *shader, const V3f *barycentric, const V4f *colour,
const Model *model);
#endif // !DEPTH_SHADER_H

View File

@ -1,4 +1,5 @@
#include "main_shader.h"
#include "img.h"
#include "obj.h"
#include "shader.h"
#include "utils.h"
@ -23,7 +24,7 @@ VertexData general_shader_vertex(void *shader, const VertexData *vert, u8 index,
return shdr->vertices[index];
}
FragmentResult diffuse_shader_fragment(void *shader, const V3f *barycentric, const Colour *colour,
FragmentResult diffuse_shader_fragment(void *shader, const V3f *barycentric, const V4f *colour,
const Model *model) {
Shader *shdr = (Shader *)shader;
@ -81,11 +82,12 @@ FragmentResult diffuse_shader_fragment(void *shader, const V3f *barycentric, con
}
#pragma endregion darboux_frame_tangent_normals
Colour output;
V4f output;
if (model->texture) {
u64 tx_x = uv.u * model->texture->width;
u64 tx_y = uv.v * model->texture->height;
output = get_pixel(Colour, model->texture, tx_x, tx_y);
u64 tx_x = uv.u * model->texture->width;
u64 tx_y = uv.v * model->texture->height;
Colour tx = get_pixel(Colour, model->texture, tx_x, tx_y);
output = (V4f){.r = tx.r, .g = tx.g, .b = tx.b, .a = tx.a};
} else {
output = *colour;
}
@ -102,7 +104,7 @@ FragmentResult diffuse_shader_fragment(void *shader, const V3f *barycentric, con
return (FragmentResult){.colour = output};
}
FragmentResult albedo_shader_fragment(void *shader, const V3f *barycentric, const Colour *colour,
FragmentResult albedo_shader_fragment(void *shader, const V3f *barycentric, const V4f *colour,
const Model *model) {
Shader *shdr = (Shader *)shader;
@ -110,11 +112,12 @@ FragmentResult albedo_shader_fragment(void *shader, const V3f *barycentric, cons
M2x3f uv_mat = mat3x2_transpose(uvs);
V2f uv = mat2x3_mul_vec3(uv_mat, (*barycentric));
Colour output;
V4f output;
if (model->texture) {
u64 tx_x = uv.u * model->texture->width;
u64 tx_y = uv.v * model->texture->height;
output = get_pixel(Colour, model->texture, tx_x, tx_y);
u64 tx_x = uv.u * model->texture->width;
u64 tx_y = uv.v * model->texture->height;
Colour tx = get_pixel(Colour, model->texture, tx_x, tx_y);
output = (V4f){.r = tx.r, .g = tx.g, .b = tx.b, .a = tx.a};
} else {
output = *colour;
}

View File

@ -10,8 +10,8 @@ struct shader {
};
VertexData general_shader_vertex(void *shader, const VertexData *vert, u8 index, const Model *model);
FragmentResult diffuse_shader_fragment(void *shader, const V3f *barycentric, const Colour *colour,
FragmentResult diffuse_shader_fragment(void *shader, const V3f *barycentric, const V4f *colour,
const Model *model);
FragmentResult albedo_shader_fragment(void *shader, const V3f *barycentric, const Colour *colour,
FragmentResult albedo_shader_fragment(void *shader, const V3f *barycentric, const V4f *colour,
const Model *model);
#endif // !MAIN_SHADER_H

View File

@ -41,7 +41,7 @@ VertexData run_vertex_shader(ShaderID shader, const VertexData *vert, u8 index,
return vertex_func(shader_obj, vert, index, model);
}
FragmentResult run_fragment_shader(ShaderID shader, const V3f *barycentric, const Colour *colour,
FragmentResult run_fragment_shader(ShaderID shader, const V3f *barycentric, const V4f *colour,
const Model *model) {
if (IS_INVALID_SHADER(shader) || shader.id > g_repository.count || !colour) {
return DISCARDED_FRAGMENT;

View File

@ -2,7 +2,6 @@
#define SHADER_H
#include "aliases.h"
#include "img.h"
#include "obj.h"
#include "vec.h"
@ -20,8 +19,8 @@ struct vertex_data {
typedef struct fragment_result FragmentResult;
struct fragment_result {
Colour colour;
bool discard;
V4f colour;
bool discard;
};
#define INVALID_SHADER ((ShaderID){0})
@ -30,11 +29,11 @@ struct fragment_result {
#define DISCARD_FRAGMENT(RESULT) (RESULT.discard)
typedef VertexData(VertexShader)(void *shader, const VertexData *vert, u8 index, const Model *model);
typedef FragmentResult(FragmentShader)(void *shader, const V3f *barycentric, const Colour *colour,
typedef FragmentResult(FragmentShader)(void *shader, const V3f *barycentric, const V4f *colour,
const Model *model);
ShaderID register_shader(void *shader, VertexShader *vertex, FragmentShader *fragment);
VertexData run_vertex_shader(ShaderID shader, const VertexData *vert, u8 index, const Model *model);
FragmentResult run_fragment_shader(ShaderID shader, const V3f *barycentric, const Colour *colour, const Model *model);
FragmentResult run_fragment_shader(ShaderID shader, const V3f *barycentric, const V4f *colour, const Model *model);
#endif // SHADER_H

View File

@ -55,10 +55,22 @@ typedef union f32x4 V4f;
union f32x4 {
f32 elements[4];
struct {
f32 x;
f32 y;
f32 z;
f32 w;
union {
f32 x;
f32 r;
};
union {
f32 y;
f32 g;
};
union {
f32 z;
f32 b;
};
union {
f32 w;
f32 a;
};
};
};