#ifndef SHADERS_SIMPLE_SHADERS_HPP #define SHADERS_SIMPLE_SHADERS_HPP #include #include #include #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; std::vector 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(w) - .5f, &txf); float fac_y = std::modf(uv.y * static_cast(h) - .5f, &tyf); int tx0 = std::clamp(static_cast(txf) + 0, 0, w); int tx1 = std::clamp(static_cast(txf) + 1, 0, w); int ty0 = std::clamp(static_cast(tyf) + 0, 0, h); int ty1 = std::clamp(static_cast(tyf) + 1, 0, h); return ((1.f - fac_x) * (1.f - fac_y)) * pixels[tx0 + ty0 * w] + (fac_x * (1.f - fac_y)) * pixels[tx1 + ty0 * w] + ((1.f - fac_x) * fac_y ) * pixels[tx0 + ty1 * w] + (fac_x * fac_y ) * pixels[tx1 + ty1 * w]; } }; } #endif // SHADERS_SIMPLE_SHADERS_HPP