diff options
| author | vimene <vincent.menegaux@gmail.com> | 2026-01-17 00:06:31 +0100 |
|---|---|---|
| committer | vimene <vincent.menegaux@gmail.com> | 2026-01-17 00:06:31 +0100 |
| commit | 0d10b77f77459333c5549711334f417623ab1f3e (patch) | |
| tree | 6584ab5d09fa72c93a70ac916bfdf401c7617157 /src/shaders | |
| parent | 175c71637b6bea6dcdd0faf3d614339983809bb1 (diff) | |
| download | engine-0d10b77f77459333c5549711334f417623ab1f3e.tar.gz | |
improved software shaders
- unified terminal and graphical software renderer shaders
- added vertex shaders for software renderers
- removed VertexData
- moved shaders from frame buffers to their own class
- added FrameBufferConcept and ShadersConcept
Diffstat (limited to 'src/shaders')
| -rw-r--r-- | src/shaders/shaders.hpp | 24 | ||||
| -rw-r--r-- | src/shaders/simple_shaders.cpp | 18 | ||||
| -rw-r--r-- | src/shaders/simple_shaders.hpp | 83 |
3 files changed, 125 insertions, 0 deletions
diff --git a/src/shaders/shaders.hpp b/src/shaders/shaders.hpp new file mode 100644 index 0000000..d5e1c3a --- /dev/null +++ b/src/shaders/shaders.hpp @@ -0,0 +1,24 @@ +#ifndef SHADERS_SHADERS_HPP +#define SHADERS_SHADERS_HPP + +#include <concepts> +#include "math/vector.hpp" +#include "o3d/vertex.hpp" +#include "fb/fb.hpp" + +namespace engine::shaders { + +template<typename T> +concept ShadersConcept = + requires { + typename T::fb_type; + requires engine::fb::FrameBufferConcept<typename T::fb_type>; + } && + requires (T shaders, int x, int y, engine::math::Vector3 v3_1, engine::math::Vector3 v3_2, engine::math::Vector2 v2) { + { shaders.vertex(v3_1, v3_2, v2) } -> std::same_as<engine::o3d::Vertex>; + { shaders.fragment(x, y, v3_1, v3_2, v2) } -> std::same_as<engine::math::Vector4>; + }; + +} + +#endif // SHADERS_SHADERS_HPP diff --git a/src/shaders/simple_shaders.cpp b/src/shaders/simple_shaders.cpp new file mode 100644 index 0000000..ebbec31 --- /dev/null +++ b/src/shaders/simple_shaders.cpp @@ -0,0 +1,18 @@ +#include "shaders/simple_shaders.hpp" +#include "math/mat4.hpp" + +using namespace engine::shaders; +using engine::math::Matrix4; + +SimpleShaders::SimpleShaders(int w, int h, unsigned char* pixels) : w { w }, h { h }, pixels { pixels } { +} + +void SimpleShaders::set_view(const Matrix4& view_mat, const Matrix4& proj_mat) { + this->view_mat = view_mat; + this->proj_mat = proj_mat; +} + +void SimpleShaders::set_model(const Matrix4& model_mat) { + this->model_mat = model_mat; + final_mat = proj_mat * view_mat * model_mat; +} diff --git a/src/shaders/simple_shaders.hpp b/src/shaders/simple_shaders.hpp new file mode 100644 index 0000000..c308ab3 --- /dev/null +++ b/src/shaders/simple_shaders.hpp @@ -0,0 +1,83 @@ +#ifndef SHADERS_SIMPLE_SHADERS_HPP +#define SHADERS_SIMPLE_SHADERS_HPP + +#include <algorithm> +#include <cmath> +#include "fb/pixfb.hpp" +#include "math/vector.hpp" +#include "math/mat4.hpp" +#include "o3d/vertex.hpp" + +namespace engine::shaders { + +class SimpleShaders { + public: + using fb_type = engine::fb::PixelFrameBuffer; + + engine::math::Matrix4 model_mat, view_mat, proj_mat, final_mat; + int w, h; + unsigned char* pixels; + + SimpleShaders(int w, int h, unsigned char* pixels); + void set_view(const engine::math::Matrix4& view_mat, const engine::math::Matrix4& proj_mat); + void set_model(const engine::math::Matrix4& model_mat); + + constexpr engine::o3d::Vertex vertex(const engine::math::Vector3& vertex, const engine::math::Vector3& normal, const engine::math::Vector2& uv) const & { + return { final_mat * engine::math::Vector4 { vertex, 1.f }, (model_mat * engine::math::Vector4 { normal, 0.f }).xyz(), uv }; + } + + constexpr engine::math::Vector4 fragment(int /* x */, int /* y */, const engine::math::Vector3& /* loc */, const engine::math::Vector3& /* normal */, + const engine::math::Vector2& uv) const & { + // auto u = vd.world_loc - camera->transform.loc; + // float u_len_sq = u.length_squared(); + // u = u.normalize(); + // float attenuation = camera->transform.rot.rot({ 0.f, 0.f, -1.f }).dot(u); + // if (attenuation < .7f) attenuation = 0.f; + // else if (attenuation > .8f) attenuation = 1.f; + // else attenuation = (attenuation - .7f) / .1f; + // float light = -normal.normalize().dot(u) / u_len_sq; + // if (light < 0.f) light = 0.f; + // float final_light = .003f + light * attenuation * .8f * .997f; + // if (final_light > 1.f) final_light = 1.f; + // // gamma correction + // // TODO: improve, we shouldn't do it here + // if (final_light <= .0031308f) + // final_light = final_light * 12.92f; + // else + // final_light = 1.055f * pow(final_light, 1.f / 2.4f) - .055f; + // std::uint32_t c = (int) (final_light * 255.f); + // pixels_vector[x + y * w] = 0xff000000 | c << 16 | c << 8 | c; + float txf, tyf; + float fac_x = std::modf(uv.x * static_cast<float>(w) - .5f, &txf); + float fac_y = std::modf(uv.y * static_cast<float>(h) - .5f, &tyf); + int tx0 = std::clamp(static_cast<int>(txf) + 0, 0, w); + int tx1 = std::clamp(static_cast<int>(txf) + 1, 0, w); + int ty0 = std::clamp(static_cast<int>(tyf) + 0, 0, h); + int ty1 = std::clamp(static_cast<int>(tyf) + 1, 0, h); + float r00 = static_cast<float>(pixels[(tx0 + ty0 * w) * 4 + 0]) / 255.f; + float r10 = static_cast<float>(pixels[(tx1 + ty0 * w) * 4 + 0]) / 255.f; + float r01 = static_cast<float>(pixels[(tx0 + ty1 * w) * 4 + 0]) / 255.f; + float r11 = static_cast<float>(pixels[(tx1 + ty1 * w) * 4 + 0]) / 255.f; + float r = (1.f - fac_x) * (1.f - fac_y) * r00 + fac_x * (1.f - fac_y) * r10 + (1.f - fac_x) * fac_y * r01 + fac_x * fac_y * r11; + float g00 = static_cast<float>(pixels[(tx0 + ty0 * w) * 4 + 1]) / 255.f; + float g10 = static_cast<float>(pixels[(tx1 + ty0 * w) * 4 + 1]) / 255.f; + float g01 = static_cast<float>(pixels[(tx0 + ty1 * w) * 4 + 1]) / 255.f; + float g11 = static_cast<float>(pixels[(tx1 + ty1 * w) * 4 + 1]) / 255.f; + float g = (1.f - fac_x) * (1.f - fac_y) * g00 + fac_x * (1.f - fac_y) * g10 + (1.f - fac_x) * fac_y * g01 + fac_x * fac_y * g11; + float b00 = static_cast<float>(pixels[(tx0 + ty0 * w) * 4 + 2]) / 255.f; + float b10 = static_cast<float>(pixels[(tx1 + ty0 * w) * 4 + 2]) / 255.f; + float b01 = static_cast<float>(pixels[(tx0 + ty1 * w) * 4 + 2]) / 255.f; + float b11 = static_cast<float>(pixels[(tx1 + ty1 * w) * 4 + 2]) / 255.f; + float b = (1.f - fac_x) * (1.f - fac_y) * b00 + fac_x * (1.f - fac_y) * b10 + (1.f - fac_x) * fac_y * b01 + fac_x * fac_y * b11; + float a00 = static_cast<float>(pixels[(tx0 + ty0 * w) * 4 + 3]) / 255.f; + float a10 = static_cast<float>(pixels[(tx1 + ty0 * w) * 4 + 3]) / 255.f; + float a01 = static_cast<float>(pixels[(tx0 + ty1 * w) * 4 + 3]) / 255.f; + float a11 = static_cast<float>(pixels[(tx1 + ty1 * w) * 4 + 3]) / 255.f; + float a = (1.f - fac_x) * (1.f - fac_y) * a00 + fac_x * (1.f - fac_y) * a10 + (1.f - fac_x) * fac_y * a01 + fac_x * fac_y * a11; + return engine::math::Vector4 { r, g, b, a }; + } +}; + +} + +#endif // SHADERS_SIMPLE_SHADERS_HPP |
