mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-07-13 02:05:51 +00:00
Convert CSpaceWarpFilter; fix up CXRayBlurFilter
This commit is contained in:
parent
3799759ca7
commit
63f7f225cc
@ -70,4 +70,6 @@ runtime_add_hsh(Graphics
|
||||
Shaders/CRadarPaintShader.cpp
|
||||
Shaders/CRandomStaticFilter.cpp
|
||||
Shaders/CScanLinesFilter.cpp
|
||||
Shaders/CSpaceWarpFilter.cpp
|
||||
Shaders/CXRayBlurFilter.cpp
|
||||
)
|
||||
|
@ -25,6 +25,13 @@ public:
|
||||
TwoLayersOutlines2 = 8 /* Fill bit2/3, Outline bit0/1 */
|
||||
};
|
||||
|
||||
struct RGBA8 {
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
};
|
||||
|
||||
private:
|
||||
ETexelFormat x0_fmt;
|
||||
u16 x4_w;
|
||||
|
@ -12,13 +12,6 @@ namespace urde {
|
||||
namespace {
|
||||
logvisor::Module Log("urde::CTextureBoo");
|
||||
|
||||
struct RGBA8 {
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
};
|
||||
|
||||
/* GX uses this upsampling technique to extract full 8-bit range */
|
||||
constexpr u8 Convert3To8(u8 v) {
|
||||
/* Swizzle bits: 00000123 -> 12312312 */
|
||||
|
@ -1,58 +1,71 @@
|
||||
#include "Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp"
|
||||
|
||||
#include "Runtime/Graphics/CBooRenderer.hpp"
|
||||
#include "Runtime/Graphics/CTexture.hpp"
|
||||
#include "Runtime/Graphics/CGraphics.hpp"
|
||||
|
||||
#define WARP_RAMP_RES 32
|
||||
#include "CSpaceWarpFilter.cpp.hshhead"
|
||||
|
||||
namespace urde {
|
||||
using namespace hsh::pipeline;
|
||||
|
||||
void CSpaceWarpFilter::GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& ctx) {
|
||||
std::array<std::array<std::array<u8, 4>, WARP_RAMP_RES + 1>, WARP_RAMP_RES + 1> data{};
|
||||
const float halfRes = WARP_RAMP_RES / 2.f;
|
||||
for (int y = 0; y < WARP_RAMP_RES + 1; ++y) {
|
||||
for (int x = 0; x < WARP_RAMP_RES + 1; ++x) {
|
||||
struct CSpaceWarpFilterPipeline
|
||||
: pipeline<topology<hsh::TriangleStrip>,
|
||||
color_attachment<hsh::One, hsh::Zero, hsh::Add, hsh::One, hsh::Zero, hsh::Add,
|
||||
hsh::ColorComponentFlags(hsh::CC_Red | hsh::CC_Green | hsh::CC_Blue)>,
|
||||
depth_write<false>> {
|
||||
CSpaceWarpFilterPipeline(hsh::vertex_buffer<CSpaceWarpFilter::Vert> vbo,
|
||||
hsh::uniform_buffer<CSpaceWarpFilter::Uniform> ubo, hsh::render_texture2d sceneTex,
|
||||
hsh::texture2d indTex) {
|
||||
this->position = ubo->m_matrix * hsh::float4(vbo->m_pos, 0.f, 1.f);
|
||||
hsh::float2 sceneUv = vbo->m_pos * hsh::float2(0.5f) + hsh::float2(0.5f);
|
||||
sceneUv.y = 1.f - sceneUv.y;
|
||||
hsh::float2 indUv = (hsh::float3x3(ubo->m_indXf[0].xyz(), ubo->m_indXf[1].xyz(), ubo->m_indXf[2].xyz()) *
|
||||
hsh::float3(vbo->m_uv, 1.f))
|
||||
.xy();
|
||||
indUv.y = 1.f - indUv.y;
|
||||
hsh::float2 indUvSample = indTex.sample<float>(indUv).xy() * hsh::float2(2.f) - hsh::float2(1.f - 1.f / 256.f);
|
||||
this->color_out[0] = hsh::float4(sceneTex.sample<float>(sceneUv + indUvSample + ubo->m_strength.xy()).xyz(), 1.f);
|
||||
}
|
||||
};
|
||||
|
||||
void CSpaceWarpFilter::GenerateWarpRampTex() {
|
||||
constexpr int skWarpRampSize = 32;
|
||||
m_warpTex =
|
||||
hsh::create_texture2d({skWarpRampSize, skWarpRampSize}, hsh::RGBA8_UNORM, 1, [&](void* data, std::size_t size) {
|
||||
auto* buf = static_cast<CTexture::RGBA8*>(data);
|
||||
const float halfRes = skWarpRampSize / 2.f;
|
||||
for (int y = 0; y < skWarpRampSize + 1; ++y) {
|
||||
for (int x = 0; x < skWarpRampSize + 1; ++x) {
|
||||
zeus::CVector2f vec((x - halfRes) / halfRes, (y - halfRes) / halfRes);
|
||||
const float mag = vec.magnitude();
|
||||
if (mag < 1.f && vec.canBeNormalized()) {
|
||||
vec.normalize();
|
||||
vec *= zeus::CVector2f(std::sqrt(mag));
|
||||
}
|
||||
data[y][x][3] = zeus::clamp(0, int((((vec.x() / 2.f + 0.5f) - x / float(WARP_RAMP_RES)) + 0.5f) * 255), 255);
|
||||
data[y][x][2] = zeus::clamp(0, int((((vec.y() / 2.f + 0.5f) - y / float(WARP_RAMP_RES)) + 0.5f) * 255), 255);
|
||||
data[y][x][0] = data[y][x][1] = data[y][x][2];
|
||||
auto& pixel = buf[y * skWarpRampSize + x];
|
||||
pixel.a = zeus::clamp(0, int((((vec.x() / 2.f + 0.5f) - x / float(skWarpRampSize)) + 0.5f) * 255), 255);
|
||||
pixel.r = pixel.g = pixel.b =
|
||||
zeus::clamp(0, int((((vec.y() / 2.f + 0.5f) - y / float(skWarpRampSize)) + 0.5f) * 255), 255);
|
||||
}
|
||||
}
|
||||
m_warpTex =
|
||||
ctx.newStaticTexture(WARP_RAMP_RES + 1, WARP_RAMP_RES + 1, 1, boo::TextureFormat::RGBA8,
|
||||
boo::TextureClampMode::Repeat, data.data(), (WARP_RAMP_RES + 1) * (WARP_RAMP_RES + 1) * 4)
|
||||
.get();
|
||||
});
|
||||
}
|
||||
|
||||
CSpaceWarpFilter::CSpaceWarpFilter() {
|
||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
GenerateWarpRampTex(ctx);
|
||||
GenerateWarpRampTex();
|
||||
|
||||
const std::array<Vert, 4> verts{{
|
||||
constexpr std::array<Vert, 4> verts{{
|
||||
{{-1.f, -1.f}, {0.f, 0.f}},
|
||||
{{-1.f, 1.f}, {0.f, 1.f}},
|
||||
{{1.f, -1.f}, {1.f, 0.f}},
|
||||
{{1.f, 1.f}, {1.f, 1.f}},
|
||||
}};
|
||||
m_vbo = hsh::create_vertex_buffer(verts);
|
||||
m_uniBuf = hsh::create_dynamic_uniform_buffer<Uniform>();
|
||||
|
||||
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 32, verts.size());
|
||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
|
||||
|
||||
const std::array<boo::ObjToken<boo::IGraphicsBuffer>, 1> bufs{m_uniBuf.get()};
|
||||
constexpr std::array<boo::PipelineStage, 1> stages{boo::PipelineStage::Vertex};
|
||||
const std::array<boo::ObjToken<boo::ITexture>, 2> texs{
|
||||
CGraphics::g_SpareTexture.get(),
|
||||
m_warpTex.get(),
|
||||
};
|
||||
m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(),
|
||||
stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr);
|
||||
return true;
|
||||
} BooTrace);
|
||||
m_dataBind.hsh_bind(
|
||||
CSpaceWarpFilterPipeline(m_vbo.get(), m_uniBuf.get(), CGraphics::g_SpareTexture.get_color(0), m_warpTex.get()));
|
||||
}
|
||||
|
||||
void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) {
|
||||
@ -117,15 +130,15 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) {
|
||||
m_uniform.m_matrix[1][1] = clipRect.x10_height / vp.y();
|
||||
m_uniform.m_matrix[3][0] = pt.x() + (1.f / vp.x());
|
||||
m_uniform.m_matrix[3][1] = pt.y() + (1.f / vp.y());
|
||||
if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::OpenGL) {
|
||||
m_uniform.m_matrix[3][2] = pt.z() * 2.f - 1.f;
|
||||
} else if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::Vulkan) {
|
||||
m_uniform.m_matrix[1][1] *= -1.f;
|
||||
m_uniform.m_matrix[3][1] *= -1.f;
|
||||
// if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::OpenGL) {
|
||||
// m_uniform.m_matrix[3][2] = pt.z() * 2.f - 1.f;
|
||||
// } else if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::Vulkan) {
|
||||
// m_uniform.m_matrix[1][1] *= -1.f;
|
||||
// m_uniform.m_matrix[3][1] *= -1.f;
|
||||
// m_uniform.m_matrix[3][2] = pt.z();
|
||||
// } else {
|
||||
m_uniform.m_matrix[3][2] = pt.z();
|
||||
} else {
|
||||
m_uniform.m_matrix[3][2] = pt.z();
|
||||
}
|
||||
// }
|
||||
|
||||
if (clipRect.x4_left) {
|
||||
clipRect.x4_left -= 1;
|
||||
@ -145,13 +158,12 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) {
|
||||
clipRect.x8_top = g_Viewport.xc_height - clipRect.x10_height - clipRect.x8_top;
|
||||
CGraphics::ResolveSpareTexture(clipRect);
|
||||
|
||||
m_uniform.m_strength.x() =
|
||||
m_uniform.m_strength.x =
|
||||
m_uniform.m_matrix[0][0] * m_strength * 0.5f * (clipRect.x10_height / float(clipRect.xc_width));
|
||||
m_uniform.m_strength.y() = m_uniform.m_matrix[1][1] * m_strength * 0.5f;
|
||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
m_uniform.m_strength.y = m_uniform.m_matrix[1][1] * m_strength * 0.5f;
|
||||
m_uniBuf.load(m_uniform);
|
||||
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
m_dataBind.draw(0, 4);
|
||||
}
|
||||
|
||||
} // namespace urde
|
||||
|
@ -9,6 +9,7 @@
|
||||
namespace urde {
|
||||
|
||||
class CSpaceWarpFilter {
|
||||
public:
|
||||
struct Uniform {
|
||||
hsh::float4x4 m_matrix;
|
||||
hsh::float4x4 m_indXf;
|
||||
@ -18,6 +19,8 @@ class CSpaceWarpFilter {
|
||||
hsh::float2 m_pos;
|
||||
hsh::float2 m_uv;
|
||||
};
|
||||
|
||||
private:
|
||||
std::array<std::array<std::array<u8, 4>, 8>, 4> m_shiftTexture{};
|
||||
hsh::owner<hsh::texture2d> m_warpTex;
|
||||
hsh::owner<hsh::vertex_buffer<Vert>> m_vbo;
|
||||
|
@ -4,41 +4,52 @@
|
||||
#include "Runtime/Graphics/CGraphics.hpp"
|
||||
#include "Runtime/Graphics/CTexture.hpp"
|
||||
|
||||
#include "zeus/CVector2f.hpp"
|
||||
|
||||
#include "CXRayBlurFilter.cpp.hshhead"
|
||||
|
||||
namespace urde {
|
||||
using namespace hsh::pipeline;
|
||||
|
||||
struct CXRayBlurFilterPipeline : pipeline<color_attachment<>> {
|
||||
struct CXRayBlurFilterPipeline
|
||||
: pipeline<topology<hsh::TriangleStrip>,
|
||||
color_attachment<hsh::One, hsh::Zero, hsh::Add, hsh::One, hsh::Zero, hsh::Add,
|
||||
hsh::ColorComponentFlags(hsh::CC_Red | hsh::CC_Green | hsh::CC_Blue)>,
|
||||
depth_write<false>> {
|
||||
CXRayBlurFilterPipeline(hsh::vertex_buffer<CXRayBlurFilter::Vert> vbo,
|
||||
hsh::uniform_buffer<CXRayBlurFilter::Uniform> ubo,
|
||||
hsh::render_texture2d sceneTex, hsh::texture2d paletteTex) {
|
||||
hsh::float2 uv0 = (ubo->m_uv[0] * hsh::float4(vbo->m_uv, 0.0, 1.0)).xy();
|
||||
hsh::float2 uv1 = (ubo->m_uv[1] * hsh::float4(vbo->m_uv, 0.0, 1.0)).xy();
|
||||
hsh::float2 uv2 = (ubo->m_uv[2] * hsh::float4(vbo->m_uv, 0.0, 1.0)).xy();
|
||||
hsh::float2 uv3 = (ubo->m_uv[3] * hsh::float4(vbo->m_uv, 0.0, 1.0)).xy();
|
||||
hsh::float2 uv4 = (ubo->m_uv[4] * hsh::float4(vbo->m_uv, 0.0, 1.0)).xy();
|
||||
hsh::float2 uv5 = (ubo->m_uv[5] * hsh::float4(vbo->m_uv, 0.0, 1.0)).xy();
|
||||
hsh::float2 uv6 = (ubo->m_uv[6] * hsh::float4(vbo->m_uv, 0.0, 1.0)).xy();
|
||||
hsh::float2 uv7 = (ubo->m_uv[7] * hsh::float4(vbo->m_uv, 0.0, 1.0)).xy();
|
||||
position = hsh::float4(vbo->m_pos, 1.0);
|
||||
hsh::uniform_buffer<CXRayBlurFilter::Uniform> ubo, hsh::render_texture2d sceneTex,
|
||||
hsh::texture2d paletteTex) {
|
||||
hsh::float2 uv0 = (ubo->m_uv[0] * hsh::float4(vbo->m_uv, 0.f, 1.f)).xy();
|
||||
hsh::float2 uv1 = (ubo->m_uv[1] * hsh::float4(vbo->m_uv, 0.f, 1.f)).xy();
|
||||
hsh::float2 uv2 = (ubo->m_uv[2] * hsh::float4(vbo->m_uv, 0.f, 1.f)).xy();
|
||||
hsh::float2 uv3 = (ubo->m_uv[3] * hsh::float4(vbo->m_uv, 0.f, 1.f)).xy();
|
||||
hsh::float2 uv4 = (ubo->m_uv[4] * hsh::float4(vbo->m_uv, 0.f, 1.f)).xy();
|
||||
hsh::float2 uv5 = (ubo->m_uv[5] * hsh::float4(vbo->m_uv, 0.f, 1.f)).xy();
|
||||
hsh::float2 uv6 = (ubo->m_uv[6] * hsh::float4(vbo->m_uv, 0.f, 1.f)).xy();
|
||||
hsh::float2 uv7 = (ubo->m_uv[7] * hsh::float4(vbo->m_uv, 0.f, 1.f)).xy();
|
||||
position = hsh::float4(vbo->m_pos, 0.f, 1.f);
|
||||
|
||||
hsh::float4 colorSample = paletteTex.sample(hsh::float2(hsh::dot(sceneTex.sample(uv0), kRGBToYPrime) * 0.98 + 0.01, 0.5)) * 0.125;
|
||||
colorSample += paletteTex.sample(hsh::float2(hsh::dot(sceneTex.sample(uv1), kRGBToYPrime) * 0.98 + 0.01, 0.5)) * 0.125;
|
||||
colorSample += paletteTex.sample(hsh::float2(hsh::dot(sceneTex.sample(uv2), kRGBToYPrime) * 0.98 + 0.01, 0.5)) * 0.125;
|
||||
colorSample += paletteTex.sample(hsh::float2(hsh::dot(sceneTex.sample(uv3), kRGBToYPrime) * 0.98 + 0.01, 0.5)) * 0.125;
|
||||
colorSample += paletteTex.sample(hsh::float2(hsh::dot(sceneTex.sample(uv4), kRGBToYPrime) * 0.98 + 0.01, 0.5)) * 0.125;
|
||||
colorSample += paletteTex.sample(hsh::float2(hsh::dot(sceneTex.sample(uv5), kRGBToYPrime) * 0.98 + 0.01, 0.5)) * 0.125;
|
||||
colorSample += paletteTex.sample(hsh::float2(hsh::dot(sceneTex.sample(uv6), kRGBToYPrime) * 0.98 + 0.01, 0.5)) * 0.125;
|
||||
colorSample += paletteTex.sample(hsh::float2(hsh::dot(sceneTex.sample(uv7), kRGBToYPrime) * 0.98 + 0.01, 0.5)) * 0.125;
|
||||
hsh::float4 kRGBToYPrime{0.257f, 0.504f, 0.098f, 0.f};
|
||||
hsh::float2 uvSample = hsh::float2(hsh::dot(sceneTex.sample<float>(uv0), kRGBToYPrime) * 0.98f + 0.01f, 0.5f);
|
||||
hsh::float4 colorSample = paletteTex.sample<float>(uvSample) * 0.125f;
|
||||
uvSample = hsh::float2(hsh::dot(sceneTex.sample<float>(uv1), kRGBToYPrime) * 0.98f + 0.01f, 0.5f);
|
||||
colorSample += paletteTex.sample<float>(uvSample) * 0.125f;
|
||||
uvSample = hsh::float2(hsh::dot(sceneTex.sample<float>(uv2), kRGBToYPrime) * 0.98f + 0.01f, 0.5f);
|
||||
colorSample += paletteTex.sample<float>(uvSample) * 0.125f;
|
||||
uvSample = hsh::float2(hsh::dot(sceneTex.sample<float>(uv3), kRGBToYPrime) * 0.98f + 0.01f, 0.5f);
|
||||
colorSample += paletteTex.sample<float>(uvSample) * 0.125f;
|
||||
uvSample = hsh::float2(hsh::dot(sceneTex.sample<float>(uv4), kRGBToYPrime) * 0.98f + 0.01f, 0.5f);
|
||||
colorSample += paletteTex.sample<float>(uvSample) * 0.125f;
|
||||
uvSample = hsh::float2(hsh::dot(sceneTex.sample<float>(uv5), kRGBToYPrime) * 0.98f + 0.01f, 0.5f);
|
||||
colorSample += paletteTex.sample<float>(uvSample) * 0.125f;
|
||||
uvSample = hsh::float2(hsh::dot(sceneTex.sample<float>(uv6), kRGBToYPrime) * 0.98f + 0.01f, 0.5f);
|
||||
colorSample += paletteTex.sample<float>(uvSample) * 0.125f;
|
||||
uvSample = hsh::float2(hsh::dot(sceneTex.sample<float>(uv7), kRGBToYPrime) * 0.98f + 0.01f, 0.5f);
|
||||
colorSample += paletteTex.sample<float>(uvSample) * 0.125f;
|
||||
color_out[0] = colorSample;
|
||||
}
|
||||
};
|
||||
|
||||
CXRayBlurFilter::CXRayBlurFilter(TLockedToken<CTexture>& tex) : m_paletteTex(tex) {
|
||||
const std::array<Vert, 4> verts{{
|
||||
constexpr std::array<Vert, 4> verts{{
|
||||
{{-1.f, -1.f}, {0.f, 0.f}},
|
||||
{{-1.f, 1.f}, {0.f, 1.f}},
|
||||
{{1.f, -1.f}, {1.f, 0.f}},
|
||||
@ -46,8 +57,9 @@ CXRayBlurFilter::CXRayBlurFilter(TLockedToken<CTexture>& tex) : m_paletteTex(tex
|
||||
}};
|
||||
m_vbo = hsh::create_vertex_buffer<Vert, 4>(verts);
|
||||
m_uniBuf = hsh::create_dynamic_uniform_buffer<Uniform>();
|
||||
m_dataBind = hsh_binding(CXRayBlurFilterPipeline(m_vbo.get(), m_uniBuf.get(), CGraphics::g_SpareTexture.get_color(0),
|
||||
m_paletteTex->GetPaletteTexture()));
|
||||
hsh::texture2d paletteTex = m_paletteTex->GetPaletteTexture();
|
||||
m_dataBind.hsh_bind(
|
||||
CXRayBlurFilterPipeline(m_vbo.get(), m_uniBuf.get(), CGraphics::g_SpareTexture.get_color(0), paletteTex));
|
||||
}
|
||||
|
||||
void CXRayBlurFilter::draw(float amount) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user