aboutsummaryrefslogtreecommitdiff
path: root/src/shaders
diff options
context:
space:
mode:
authorvimene <vincent.menegaux@gmail.com>2026-01-17 00:06:31 +0100
committervimene <vincent.menegaux@gmail.com>2026-01-17 00:06:31 +0100
commit0d10b77f77459333c5549711334f417623ab1f3e (patch)
tree6584ab5d09fa72c93a70ac916bfdf401c7617157 /src/shaders
parent175c71637b6bea6dcdd0faf3d614339983809bb1 (diff)
downloadengine-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.hpp24
-rw-r--r--src/shaders/simple_shaders.cpp18
-rw-r--r--src/shaders/simple_shaders.hpp83
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