mirror of https://github.com/AxioDL/metaforce.git
hsh pipelines for ThermalCold, ThermalHot, ElemenGen
Plus various fixes
This commit is contained in:
parent
485e0afb43
commit
6c56f6452e
|
@ -577,7 +577,8 @@ void CBooRenderer::ReallyRenderFogVolume(const zeus::CColor& color, const zeus::
|
|||
}
|
||||
|
||||
void CBooRenderer::GenerateFogVolumeRampTex() {
|
||||
x1b8_fogVolumeRamp = hsh::create_texture2d({FOGVOL_RAMP_RES, FOGVOL_RAMP_RES}, hsh::R16_UNORM, 1, [&](u16* data, std::size_t size) {
|
||||
x1b8_fogVolumeRamp = hsh::create_texture2d({FOGVOL_RAMP_RES, FOGVOL_RAMP_RES}, hsh::R16_UNORM, 1, [&](void* data, std::size_t size) {
|
||||
auto* out = static_cast<u16*>(data);
|
||||
for (size_t y = 0; y < FOGVOL_RAMP_RES; ++y) {
|
||||
for (size_t x = 0; x < FOGVOL_RAMP_RES; ++x) {
|
||||
const int tmp = int(y << 16 | x << 8 | 0x7f);
|
||||
|
@ -586,19 +587,20 @@ void CBooRenderer::GenerateFogVolumeRampTex() {
|
|||
(-150.0 / (tmp / double(0xffffff) * (FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) *
|
||||
3.0 / (FOGVOL_FAR - FOGVOL_NEAR),
|
||||
1.0);
|
||||
data[x + y * FOGVOL_RAMP_RES] = u16((a * a + a) / 2.0 * 65535);
|
||||
out[x + y * FOGVOL_RAMP_RES] = u16((a * a + a) / 2.0 * 65535);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CBooRenderer::GenerateSphereRampTex() {
|
||||
x220_sphereRamp = hsh::create_texture2d({SPHERE_RAMP_RES, SPHERE_RAMP_RES}, hsh::R8_UNORM, 1, [&](u8* data, std::size_t size) {
|
||||
x220_sphereRamp = hsh::create_texture2d({SPHERE_RAMP_RES, SPHERE_RAMP_RES}, hsh::R8_UNORM, 1, [&](void* data, std::size_t size) {
|
||||
auto* out = static_cast<u8*>(data);
|
||||
constexpr float halfRes = SPHERE_RAMP_RES / 2.f;
|
||||
for (size_t y = 0; y < SPHERE_RAMP_RES; ++y) {
|
||||
for (size_t x = 0; x < SPHERE_RAMP_RES; ++x) {
|
||||
const zeus::CVector2f vec((float(x) - halfRes) / halfRes, (float(y) - halfRes) / halfRes);
|
||||
data[x + y * SPHERE_RAMP_RES] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255;
|
||||
out[x + y * SPHERE_RAMP_RES] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -647,8 +649,9 @@ hsh::texture2d CBooRenderer::GetColorTexture(const zeus::CColor& color) {
|
|||
return search->second;
|
||||
}
|
||||
|
||||
m_colorTextures.emplace(color, hsh::create_texture2d({1, 1}, hsh::RGBA8_UNORM, 1, [&](zeus::Comp8* data, std::size_t size) {
|
||||
color.toRGBA8(data[0], data[1], data[2], data[3]);
|
||||
m_colorTextures.emplace(color, hsh::create_texture2d({1, 1}, hsh::RGBA8_UNORM, 1, [&](void* data, std::size_t size) {
|
||||
auto* out = static_cast<zeus::Comp8*>(data);
|
||||
color.toRGBA8(out[0], out[1], out[2], out[3]);
|
||||
}));
|
||||
return m_colorTextures[color].get();
|
||||
}
|
||||
|
@ -690,7 +693,7 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac)
|
|||
|
||||
GenerateFogVolumeRampTex();
|
||||
GenerateSphereRampTex();
|
||||
m_ballShadowId = hsh::create_render_texture2d({m_ballShadowIdW, m_ballShadowIdH}, hsh::RGBA8_UNORM, 1, 0);
|
||||
m_ballShadowId = hsh::create_render_texture2d({skBallShadowIdSize, skBallShadowIdSize}, hsh::RGBA8_UNORM, 1, 0);
|
||||
x14c_reflectionTex = hsh::create_render_texture2d({256, 256}, hsh::RGBA8_UNORM, 1, 0);
|
||||
GenerateScanLinesVBO();
|
||||
|
||||
|
|
|
@ -289,15 +289,15 @@ public:
|
|||
void ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const CModel* model,
|
||||
const CSkinnedModel* sModel);
|
||||
|
||||
auto GetThermoPalette() const { return x288_thermoPalette.get(); }
|
||||
auto GetFogRampTex() const { return x1b8_fogVolumeRamp.get(); }
|
||||
auto GetRandomStaticEntropyTex() const { return m_staticEntropy->GetBooTexture(); }
|
||||
hsh::texture2d GetThermoPalette() const { return x288_thermoPalette; }
|
||||
hsh::texture2d GetFogRampTex() const { return x1b8_fogVolumeRamp.get(); }
|
||||
hsh::texture2d GetRandomStaticEntropyTex() const { return m_staticEntropy->GetBooTexture(); }
|
||||
auto GetScanLinesEvenVBO() const { return m_scanLinesEvenVBO.get(); }
|
||||
auto GetScanLinesOddVBO() const { return m_scanLinesOddVBO.get(); }
|
||||
|
||||
auto GetClearTexture() const { return m_clearTexture.get(); }
|
||||
auto GetBlackTexture() const { return m_blackTexture.get(); }
|
||||
auto GetWhiteTexture() const { return m_whiteTexture.get(); }
|
||||
hsh::texture2d GetClearTexture() const { return m_clearTexture.get(); }
|
||||
hsh::texture2d GetBlackTexture() const { return m_blackTexture.get(); }
|
||||
hsh::texture2d GetWhiteTexture() const { return m_whiteTexture.get(); }
|
||||
|
||||
hsh::texture2d GetColorTexture(const zeus::CColor& color);
|
||||
|
||||
|
|
|
@ -59,4 +59,7 @@ runtime_add_hsh(Graphics
|
|||
Shaders/CColoredStripShader.cpp
|
||||
Shaders/CDecalShaders.cpp
|
||||
Shaders/CEnergyBarShader.cpp
|
||||
Shaders/CThermalColdFilter.cpp
|
||||
Shaders/CThermalHotFilter.cpp
|
||||
Shaders/CElementGenShaders.cpp
|
||||
)
|
||||
|
|
|
@ -12,12 +12,7 @@ CRainSplashGenerator::CRainSplashGenerator(const zeus::CVector3f& scale, u32 max
|
|||
: x14_scale(scale), x2c_minZ(minZ) {
|
||||
x30_alpha = std::min(1.f, alpha);
|
||||
x44_genRate = std::min(maxSplashes, genRate);
|
||||
x0_rainSplashes.reserve(maxSplashes);
|
||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
for (u32 i = 0; i < maxSplashes; ++i)
|
||||
x0_rainSplashes.emplace_back(ctx);
|
||||
return true;
|
||||
} BooTrace);
|
||||
x0_rainSplashes.resize(maxSplashes);
|
||||
}
|
||||
|
||||
void CRainSplashGenerator::SSplashLine::Draw(float alpha, float dt, const zeus::CVector3f& pos) {
|
||||
|
@ -73,13 +68,11 @@ void CRainSplashGenerator::Draw(const zeus::CTransform& xf) {
|
|||
DoDraw(xf);
|
||||
}
|
||||
|
||||
CRainSplashGenerator::SSplashLine::SSplashLine(boo::IGraphicsDataFactory::Context& ctx)
|
||||
: m_renderer(ctx, CLineRenderer::EPrimitiveMode::LineStrip, 3, nullptr, false) {}
|
||||
CRainSplashGenerator::SSplashLine::SSplashLine()
|
||||
: m_renderer(CLineRenderer::EPrimitiveMode::LineStrip, 3, hsh::texture2d{}, false, hsh::LEqual) {}
|
||||
|
||||
CRainSplashGenerator::SRainSplash::SRainSplash(boo::IGraphicsDataFactory::Context& ctx) {
|
||||
for (size_t i = 0; i < x0_lines.capacity(); ++i) {
|
||||
x0_lines.emplace_back(ctx);
|
||||
}
|
||||
CRainSplashGenerator::SRainSplash::SRainSplash() {
|
||||
x0_lines.resize(x0_lines.capacity());
|
||||
}
|
||||
|
||||
void CRainSplashGenerator::SSplashLine::Update(float dt, CStateManager& mgr) {
|
||||
|
@ -158,8 +151,7 @@ u32 CRainSplashGenerator::GetNextBestPt(u32 pt, const std::vector<std::pair<zeus
|
|||
const auto idx = u32(rand.Range(0, int(vn.size() - 1)));
|
||||
const auto& vert = vn[idx];
|
||||
const float distSq = (refVert.first - vert.first).magSquared();
|
||||
if (distSq > maxDist && vert.second.dot(zeus::skUp) >= 0.f &&
|
||||
(vert.first.z() <= 0.f || vert.first.z() > minZ)) {
|
||||
if (distSq > maxDist && vert.second.dot(zeus::skUp) >= 0.f && (vert.first.z() <= 0.f || vert.first.z() > minZ)) {
|
||||
nextPt = idx;
|
||||
maxDist = distSq;
|
||||
}
|
||||
|
|
|
@ -32,20 +32,20 @@ void CSkinnedModel::Calculate(const CPoseAsTransforms& pose, const CModelFlags&
|
|||
const std::optional<CVertexMorphEffect>& morphEffect,
|
||||
const float* morphMagnitudes) {
|
||||
if (morphEffect || g_PointGenFunc) {
|
||||
if (auto vertBuf = m_modelInst->UpdateUniformData(drawFlags, nullptr, nullptr)) {
|
||||
if (auto* vertBuf = m_modelInst->UpdateUniformData(drawFlags, nullptr, nullptr)) {
|
||||
x10_skinRules->TransformVerticesCPU(m_vertWorkspace, pose, *x4_model);
|
||||
if (morphEffect)
|
||||
morphEffect->MorphVertices(m_vertWorkspace, morphMagnitudes, x10_skinRules, pose);
|
||||
if (g_PointGenFunc)
|
||||
g_PointGenFunc(g_PointGenCtx, m_vertWorkspace);
|
||||
x4_model->ApplyVerticesCPU(vertBuf, m_vertWorkspace);
|
||||
x4_model->ApplyVerticesCPU(*vertBuf, m_vertWorkspace);
|
||||
m_modifiedVBO = true;
|
||||
}
|
||||
} else {
|
||||
if (auto vertBuf =
|
||||
if (auto* vertBuf =
|
||||
m_modelInst->UpdateUniformData(drawFlags, x10_skinRules.GetObj(), &pose)) {
|
||||
if (m_modifiedVBO) {
|
||||
x4_model->RestoreVerticesCPU(vertBuf);
|
||||
x4_model->RestoreVerticesCPU(*vertBuf);
|
||||
m_modifiedVBO = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@ struct CAABoxShaderPipeline
|
|||
this->color_out[0] = uniBuf->m_color;
|
||||
}
|
||||
};
|
||||
template struct CAABoxShaderPipeline<ERglCullMode::None, ERglEnum::Always, true, ERglBlendMode::Blend,
|
||||
template struct CAABoxShaderPipeline<ERglCullMode::None, ERglEnum::LEqual, true, ERglBlendMode::Blend,
|
||||
ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear, true>;
|
||||
|
||||
constexpr size_t VertexCount = 34;
|
||||
|
||||
CAABoxShader::CAABoxShader(const zeus::CAABox& aabb) {
|
||||
const std::array<Vert, 34> verts{{
|
||||
const std::array<Vert, VertexCount> verts{{
|
||||
{{aabb.max.x(), aabb.max.y(), aabb.min.z()}}, {{aabb.max.x(), aabb.min.y(), aabb.min.z()}},
|
||||
{{aabb.max.x(), aabb.max.y(), aabb.max.z()}}, {{aabb.max.x(), aabb.min.y(), aabb.max.z()}},
|
||||
{{aabb.max.x(), aabb.min.y(), aabb.max.z()}},
|
||||
|
@ -62,7 +64,7 @@ void CAABoxShader::draw(const zeus::CColor& color) {
|
|||
m_uniform.m_color = color;
|
||||
m_uniBuf.load(m_uniform);
|
||||
|
||||
m_dataBind.draw(0, 34);
|
||||
m_dataBind.draw(0, VertexCount);
|
||||
}
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -7,6 +7,8 @@ namespace urde {
|
|||
|
||||
class CCameraBlurFilter {
|
||||
friend struct CCameraBlurFilterPipeline;
|
||||
|
||||
public:
|
||||
struct Vert {
|
||||
hsh::float2 m_pos;
|
||||
hsh::float2 m_uv;
|
||||
|
@ -16,6 +18,7 @@ class CCameraBlurFilter {
|
|||
float m_opacity = 1.f;
|
||||
};
|
||||
|
||||
private:
|
||||
hsh::dynamic_owner<hsh::vertex_buffer<Vert>> m_vbo;
|
||||
hsh::dynamic_owner<hsh::uniform_buffer<Uniform>> m_uniBuf;
|
||||
hsh::binding m_dataBind;
|
||||
|
|
|
@ -31,7 +31,7 @@ template struct CDecalShaderTexPipeline<false, false>;
|
|||
template <bool Additive>
|
||||
struct CDecalShaderNoTexPipeline : pipeline<std::conditional_t<Additive, AdditiveAttachment<>, BlendAttachment<>>,
|
||||
depth_compare<hsh::LEqual>, depth_write<!Additive>> {
|
||||
CDecalShaderNoTexPipeline(hsh::vertex_buffer<SParticleInstanceTex> vbo,
|
||||
CDecalShaderNoTexPipeline(hsh::vertex_buffer<SParticleInstanceNoTex> vbo,
|
||||
hsh::uniform_buffer<SParticleUniforms> uniBuf) {
|
||||
this->position = uniBuf->mvp * vbo->pos[this->vertex_id];
|
||||
this->color_out[0] = vbo->color * uniBuf->moduColor;
|
||||
|
|
|
@ -1,274 +1,133 @@
|
|||
#include "Runtime/Graphics/Shaders/CElementGenShaders.hpp"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include "Runtime/GameGlobalObjects.hpp"
|
||||
#include "Runtime/Graphics/CBooRenderer.hpp"
|
||||
#include "Runtime/Particle/CElementGen.hpp"
|
||||
|
||||
#include <hecl/Pipeline.hpp>
|
||||
enum class BlendMode {
|
||||
Regular,
|
||||
Additive,
|
||||
Subtract,
|
||||
};
|
||||
|
||||
#include "CElementGenShaders.cpp.hshhead"
|
||||
|
||||
namespace urde {
|
||||
using namespace hsh::pipeline;
|
||||
|
||||
void CElementGenShaders::Initialize() {
|
||||
m_texZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexZTestZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexZTestZWrite{})};
|
||||
m_texNoZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexNoZTestZWriteAWrite{})};
|
||||
m_texZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteAWrite{})};
|
||||
m_texNoZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteAWrite{})};
|
||||
m_texAdditiveZTest = {hecl::conv->convert(Shader_CElementGenShaderTexAdditiveZTest{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexAdditiveZTestAWrite{})};
|
||||
m_texAdditiveNoZTest = {hecl::conv->convert(Shader_CElementGenShaderTexAdditiveNoZTest{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexAdditiveNoZTestAWrite{})};
|
||||
m_texRedToAlphaZTest = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTest{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestAWrite{})};
|
||||
m_texRedToAlphaNoZTest = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTest{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestAWrite{})};
|
||||
m_texZTestNoZWriteSub = {hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteSub{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteSubAWrite{})};
|
||||
m_texNoZTestNoZWriteSub = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteSub{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteSubAWrite{})};
|
||||
m_texRedToAlphaZTestSub = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestSub{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestSubAWrite{})};
|
||||
m_texRedToAlphaNoZTestSub = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestSub{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestSubAWrite{})};
|
||||
template <BlendMode Mode, bool AlphaWrite>
|
||||
struct BlendModeAttachmentExt {
|
||||
using type = BlendAttachment<AlphaWrite>;
|
||||
};
|
||||
template <bool AlphaWrite>
|
||||
struct BlendModeAttachmentExt<BlendMode::Additive, AlphaWrite> {
|
||||
using type = AdditiveAttachment<AlphaWrite>;
|
||||
};
|
||||
template <bool AlphaWrite>
|
||||
struct BlendModeAttachmentExt<BlendMode::Subtract, AlphaWrite> {
|
||||
using type = SubtractAttachment<AlphaWrite>;
|
||||
};
|
||||
template <BlendMode Mode, bool AlphaWrite>
|
||||
using BlendModeAttachment = typename BlendModeAttachmentExt<Mode, AlphaWrite>::type;
|
||||
|
||||
m_indTexZWrite = {hecl::conv->convert(Shader_CElementGenShaderIndTexZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderIndTexZWriteAWrite{})};
|
||||
m_indTexNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderIndTexNoZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderIndTexNoZWriteAWrite{})};
|
||||
m_indTexAdditive = {hecl::conv->convert(Shader_CElementGenShaderIndTexAdditive{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderIndTexAdditiveAWrite{})};
|
||||
template <BlendMode Mode, bool AlphaWrite, bool ZTest, bool ZWrite, bool RedToAlpha>
|
||||
struct CElementGenShadersTexPipeline : pipeline<topology<hsh::TriangleStrip>, BlendModeAttachment<Mode, AlphaWrite>,
|
||||
depth_compare<ZTest ? hsh::LEqual : hsh::Always>, depth_write<ZWrite>> {
|
||||
CElementGenShadersTexPipeline(hsh::vertex_buffer<SParticleInstanceTex> vbo,
|
||||
hsh::uniform_buffer<SParticleUniforms> uniBuf, hsh::texture2d tex) {
|
||||
this->position = uniBuf->mvp * vbo->pos[this->vertex_id];
|
||||
this->color_out[0] = vbo->color * uniBuf->moduColor * tex.sample<float>(vbo->uvs[this->vertex_id]);
|
||||
if constexpr (RedToAlpha) {
|
||||
this->color_out[0].w = this->color_out[0].x;
|
||||
}
|
||||
}
|
||||
};
|
||||
template struct CElementGenShadersTexPipeline<BlendMode::Regular, true, true, true, false>;
|
||||
template struct CElementGenShadersTexPipeline<BlendMode::Additive, true, true, true, true>;
|
||||
template struct CElementGenShadersTexPipeline<BlendMode::Subtract, true, true, true, true>;
|
||||
|
||||
m_cindTexZWrite = {hecl::conv->convert(Shader_CElementGenShaderCindTexZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderCindTexZWriteAWrite{})};
|
||||
m_cindTexNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderCindTexNoZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderCindTexNoZWriteAWrite{})};
|
||||
m_cindTexAdditive = {hecl::conv->convert(Shader_CElementGenShaderCindTexAdditive{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderCindTexAdditiveAWrite{})};
|
||||
template <BlendMode Mode, bool AlphaWrite, bool ZTest, bool ZWrite, bool ColoredIndirect>
|
||||
struct CElementGenShadersIndTexPipeline
|
||||
: pipeline<topology<hsh::TriangleStrip>, BlendModeAttachment<Mode, AlphaWrite>,
|
||||
depth_compare<ZTest ? hsh::LEqual : hsh::Always>, depth_write<ZWrite>> {
|
||||
CElementGenShadersIndTexPipeline(hsh::vertex_buffer<SParticleInstanceIndTex> vbo,
|
||||
hsh::uniform_buffer<SParticleUniforms> uniBuf, hsh::texture2d texrTex,
|
||||
hsh::texture2d tindTex, hsh::render_texture2d sceneTex) {
|
||||
this->position = uniBuf->mvp * vbo->pos[this->vertex_id];
|
||||
hsh::float4 texrTexel = texrTex.sample<float>(vbo->texrTindUVs[this->vertex_id].xy());
|
||||
hsh::float2 tindTexel = tindTex.sample<float>(vbo->texrTindUVs[this->vertex_id].zw()).xy();
|
||||
hsh::float4 sceneTexel = sceneTex.sample<float>(hsh::lerp(vbo->sceneUVs.xy(), vbo->sceneUVs.zw(), tindTexel));
|
||||
if constexpr (ColoredIndirect) {
|
||||
this->color_out[0] = vbo->color * hsh::float4(sceneTexel.xyz(), 1.f) * texrTexel;
|
||||
} else {
|
||||
this->color_out[0] = vbo->color * hsh::float4(sceneTexel.xyz(), 1.f) + texrTexel;
|
||||
this->color_out[0].w *= texrTexel.x;
|
||||
}
|
||||
}
|
||||
};
|
||||
template struct CElementGenShadersIndTexPipeline<BlendMode::Regular, true, true, true, true>;
|
||||
template struct CElementGenShadersIndTexPipeline<BlendMode::Additive, true, true, true, false>;
|
||||
|
||||
m_noTexZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexZTestZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderNoTexZTestZWriteAWrite{})};
|
||||
m_noTexNoZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestZWriteAWrite{})};
|
||||
m_noTexZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexZTestNoZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderNoTexZTestNoZWriteAWrite{})};
|
||||
m_noTexNoZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestNoZWrite{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestNoZWriteAWrite{})};
|
||||
m_noTexAdditiveZTest = {hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveZTest{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveZTestAWrite{})};
|
||||
m_noTexAdditiveNoZTest = {hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveNoZTest{}),
|
||||
hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveNoZTestAWrite{})};
|
||||
}
|
||||
|
||||
void CElementGenShaders::Shutdown() {
|
||||
for (auto& s : m_texZTestZWrite) s.reset();
|
||||
for (auto& s : m_texNoZTestZWrite) s.reset();
|
||||
for (auto& s : m_texZTestNoZWrite) s.reset();
|
||||
for (auto& s : m_texNoZTestNoZWrite) s.reset();
|
||||
for (auto& s : m_texAdditiveZTest) s.reset();
|
||||
for (auto& s : m_texAdditiveNoZTest) s.reset();
|
||||
for (auto& s : m_texRedToAlphaZTest) s.reset();
|
||||
for (auto& s : m_texRedToAlphaNoZTest) s.reset();
|
||||
for (auto& s : m_texZTestNoZWriteSub) s.reset();
|
||||
for (auto& s : m_texNoZTestNoZWriteSub) s.reset();
|
||||
for (auto& s : m_texRedToAlphaZTestSub) s.reset();
|
||||
for (auto& s : m_texRedToAlphaNoZTestSub) s.reset();
|
||||
|
||||
for (auto& s : m_indTexZWrite) s.reset();
|
||||
for (auto& s : m_indTexNoZWrite) s.reset();
|
||||
for (auto& s : m_indTexAdditive) s.reset();
|
||||
|
||||
for (auto& s : m_cindTexZWrite) s.reset();
|
||||
for (auto& s : m_cindTexNoZWrite) s.reset();
|
||||
for (auto& s : m_cindTexAdditive) s.reset();
|
||||
|
||||
for (auto& s : m_noTexZTestZWrite) s.reset();
|
||||
for (auto& s : m_noTexNoZTestZWrite) s.reset();
|
||||
for (auto& s : m_noTexZTestNoZWrite) s.reset();
|
||||
for (auto& s : m_noTexNoZTestNoZWrite) s.reset();
|
||||
for (auto& s : m_noTexAdditiveZTest) s.reset();
|
||||
for (auto& s : m_noTexAdditiveNoZTest) s.reset();
|
||||
}
|
||||
template <BlendMode Mode, bool AlphaWrite, bool ZTest, bool ZWrite>
|
||||
struct CElementGenShadersNoTexPipeline
|
||||
: pipeline<topology<hsh::TriangleStrip>, BlendModeAttachment<Mode, AlphaWrite>,
|
||||
depth_compare<ZTest ? hsh::LEqual : hsh::Always>, depth_write<ZWrite>> {
|
||||
CElementGenShadersNoTexPipeline(hsh::vertex_buffer<SParticleInstanceNoTex> vbo,
|
||||
hsh::uniform_buffer<SParticleUniforms> uniBuf) {
|
||||
this->position = uniBuf->mvp * vbo->pos[this->vertex_id];
|
||||
this->color_out[0] = vbo->color * uniBuf->moduColor;
|
||||
}
|
||||
};
|
||||
template struct CElementGenShadersNoTexPipeline<BlendMode::Regular, true, true, true>;
|
||||
template struct CElementGenShadersNoTexPipeline<BlendMode::Additive, true, true, true>;
|
||||
template struct CElementGenShadersNoTexPipeline<BlendMode::Subtract, true, true, true>;
|
||||
|
||||
CElementGenShaders::EShaderClass CElementGenShaders::GetShaderClass(CElementGen& gen) {
|
||||
CGenDescription* desc = gen.x1c_genDesc.GetObj();
|
||||
|
||||
if (desc->x54_x40_TEXR) {
|
||||
if (desc->x58_x44_TIND)
|
||||
return EShaderClass::IndTex;
|
||||
else
|
||||
return EShaderClass::Tex;
|
||||
} else
|
||||
return EShaderClass::NoTex;
|
||||
}
|
||||
|
||||
void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CElementGen& gen) {
|
||||
CGenDescription* desc = gen.x1c_genDesc.GetObj();
|
||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* regPipeline = nullptr;
|
||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* regPipelineSub = nullptr;
|
||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* redToAlphaPipeline = nullptr;
|
||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* redToAlphaPipelineSub = nullptr;
|
||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* regPipelinePmus = nullptr;
|
||||
std::array<boo::ObjToken<boo::IShaderPipeline>, 2>* redToAlphaPipelinePmus = nullptr;
|
||||
|
||||
const auto* desc = gen.x1c_genDesc.GetObj();
|
||||
if (desc->x54_x40_TEXR) {
|
||||
if (desc->x58_x44_TIND) {
|
||||
if (desc->x45_30_x32_24_CIND) {
|
||||
if (gen.x26c_26_AAPH)
|
||||
regPipeline = &m_cindTexAdditive;
|
||||
else {
|
||||
if (gen.x26c_27_ZBUF)
|
||||
regPipeline = &m_cindTexZWrite;
|
||||
else
|
||||
regPipeline = &m_cindTexNoZWrite;
|
||||
}
|
||||
} else {
|
||||
if (gen.x26c_26_AAPH)
|
||||
regPipeline = &m_indTexAdditive;
|
||||
else {
|
||||
if (gen.x26c_27_ZBUF)
|
||||
regPipeline = &m_indTexZWrite;
|
||||
else
|
||||
regPipeline = &m_indTexNoZWrite;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (gen.x26c_28_zTest) {
|
||||
redToAlphaPipeline = &m_texRedToAlphaZTest;
|
||||
regPipelineSub = &m_texZTestNoZWriteSub;
|
||||
redToAlphaPipelineSub = &m_texRedToAlphaZTestSub;
|
||||
} else {
|
||||
redToAlphaPipeline = &m_texRedToAlphaNoZTest;
|
||||
regPipelineSub = &m_texNoZTestNoZWriteSub;
|
||||
redToAlphaPipelineSub = &m_texRedToAlphaNoZTestSub;
|
||||
}
|
||||
|
||||
if (gen.x26c_26_AAPH) {
|
||||
if (gen.x26c_28_zTest)
|
||||
regPipeline = &m_texAdditiveZTest;
|
||||
else
|
||||
regPipeline = &m_texAdditiveNoZTest;
|
||||
} else {
|
||||
if (gen.x26c_28_zTest) {
|
||||
if (gen.x26c_27_ZBUF)
|
||||
regPipeline = &m_texZTestZWrite;
|
||||
else
|
||||
regPipeline = &m_texZTestNoZWrite;
|
||||
} else {
|
||||
if (gen.x26c_27_ZBUF)
|
||||
regPipeline = &m_texNoZTestZWrite;
|
||||
else
|
||||
regPipeline = &m_texNoZTestNoZWrite;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (gen.x26c_26_AAPH) {
|
||||
if (gen.x26c_28_zTest)
|
||||
regPipeline = &m_noTexAdditiveZTest;
|
||||
else
|
||||
regPipeline = &m_noTexAdditiveNoZTest;
|
||||
} else {
|
||||
if (gen.x26c_28_zTest) {
|
||||
if (gen.x26c_27_ZBUF)
|
||||
regPipeline = &m_noTexZTestZWrite;
|
||||
else
|
||||
regPipeline = &m_noTexZTestNoZWrite;
|
||||
} else {
|
||||
if (gen.x26c_27_ZBUF)
|
||||
regPipeline = &m_noTexNoZTestZWrite;
|
||||
else
|
||||
regPipeline = &m_noTexNoZTestNoZWrite;
|
||||
}
|
||||
return EShaderClass::IndTex;
|
||||
}
|
||||
return EShaderClass::Tex;
|
||||
}
|
||||
return EShaderClass::NoTex;
|
||||
}
|
||||
|
||||
if (desc->x45_24_x31_26_PMUS) {
|
||||
if (desc->x54_x40_TEXR) {
|
||||
redToAlphaPipelinePmus = &m_texRedToAlphaZTest;
|
||||
if (desc->x44_31_x31_25_PMAB)
|
||||
regPipelinePmus = &m_texAdditiveZTest;
|
||||
else
|
||||
regPipelinePmus = &m_texZTestZWrite;
|
||||
} else {
|
||||
if (desc->x44_31_x31_25_PMAB)
|
||||
regPipelinePmus = &m_noTexAdditiveZTest;
|
||||
else
|
||||
regPipelinePmus = &m_noTexZTestZWrite;
|
||||
}
|
||||
hsh::binding& CElementGenShaders::BuildShaderDataBinding(CElementGen& gen, bool pmus) {
|
||||
const auto& desc = gen.x1c_genDesc;
|
||||
BlendMode mode = BlendMode::Regular;
|
||||
if (CElementGen::g_subtractBlend) {
|
||||
mode = BlendMode::Subtract;
|
||||
} else if (gen.x26c_26_AAPH) {
|
||||
mode = BlendMode::Additive;
|
||||
}
|
||||
|
||||
const CUVElement* const texr = desc->x54_x40_TEXR.get();
|
||||
const CUVElement* const tind = desc->x58_x44_TIND.get();
|
||||
int texCount = 0;
|
||||
std::array<boo::ObjToken<boo::ITexture>, 3> textures;
|
||||
|
||||
if (texr) {
|
||||
textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||
texCount = 1;
|
||||
if (gen.m_instBuf) {
|
||||
if (tind) {
|
||||
textures[1] = CGraphics::g_SpareTexture.get();
|
||||
textures[2] = tind->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||
texCount = 3;
|
||||
}
|
||||
}
|
||||
hsh::vertex_buffer_typeless instBuf = pmus ? gen.m_instBufPmus.get() : gen.m_instBuf.get();
|
||||
hsh::uniform_buffer_typeless uniBuf = pmus ? gen.m_uniformBufPmus.get() : gen.m_uniformBuf.get();
|
||||
switch (GetShaderClass(gen)) {
|
||||
case EShaderClass::Tex: {
|
||||
hsh::texture2d tex = desc->x54_x40_TEXR->GetValueTexture(0)->GetBooTexture();
|
||||
m_shaderBind.hsh_tex_bind(
|
||||
CElementGenShadersTexPipeline<mode, g_Renderer->IsThermalVisorHotPass(), gen.x26c_28_zTest, gen.x26c_27_ZBUF,
|
||||
CElementGen::sMoveRedToAlphaBuffer>(instBuf, uniBuf, tex));
|
||||
break;
|
||||
}
|
||||
|
||||
if (gen.m_instBuf) {
|
||||
const std::array<boo::ObjToken<boo::IGraphicsBuffer>, 1> uniforms{gen.m_uniformBuf.get()};
|
||||
|
||||
if (regPipeline != nullptr) {
|
||||
for (size_t i = 0; i < gen.m_normalDataBind.size(); ++i) {
|
||||
gen.m_normalDataBind[i] =
|
||||
ctx.newShaderDataBinding((*regPipeline)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(),
|
||||
uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
if (regPipelineSub != nullptr) {
|
||||
for (size_t i = 0; i < gen.m_normalSubDataBind.size(); ++i) {
|
||||
gen.m_normalSubDataBind[i] =
|
||||
ctx.newShaderDataBinding((*regPipelineSub)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(),
|
||||
uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
if (redToAlphaPipeline != nullptr) {
|
||||
for (size_t i = 0; i < gen.m_redToAlphaDataBind.size(); ++i) {
|
||||
gen.m_redToAlphaDataBind[i] =
|
||||
ctx.newShaderDataBinding((*redToAlphaPipeline)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(),
|
||||
uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
if (redToAlphaPipelineSub != nullptr) {
|
||||
for (size_t i = 0; i < gen.m_redToAlphaSubDataBind.size(); ++i) {
|
||||
gen.m_redToAlphaSubDataBind[i] = ctx.newShaderDataBinding(
|
||||
(*redToAlphaPipelineSub)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), uniforms.data(),
|
||||
nullptr, texCount, textures.data(), nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
case EShaderClass::IndTex: {
|
||||
hsh::texture2d texrTex = desc->x54_x40_TEXR->GetValueTexture(0)->GetBooTexture();
|
||||
hsh::texture2d tindTex = desc->x58_x44_TIND->GetValueTexture(0)->GetBooTexture();
|
||||
hsh::render_texture2d sceneTex = CGraphics::g_SpareTexture.get_color(0);
|
||||
m_shaderBind.hsh_indtex_bind(
|
||||
CElementGenShadersIndTexPipeline<mode, g_Renderer->IsThermalVisorHotPass(), gen.x26c_28_zTest, gen.x26c_27_ZBUF,
|
||||
desc->x45_30_x32_24_CIND>(instBuf, uniBuf, texrTex, tindTex, sceneTex));
|
||||
break;
|
||||
}
|
||||
|
||||
if (gen.m_instBufPmus) {
|
||||
const std::array<boo::ObjToken<boo::IGraphicsBuffer>, 1> uniforms{gen.m_uniformBufPmus.get()};
|
||||
texCount = std::min(texCount, 1);
|
||||
|
||||
if (regPipelinePmus != nullptr) {
|
||||
for (size_t i = 0; i < gen.m_normalDataBindPmus.size(); ++i) {
|
||||
gen.m_normalDataBindPmus[i] =
|
||||
ctx.newShaderDataBinding((*regPipelinePmus)[i], nullptr, gen.m_instBufPmus.get(), nullptr, uniforms.size(),
|
||||
uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
if (redToAlphaPipelinePmus != nullptr) {
|
||||
for (size_t i = 0; i < gen.m_redToAlphaDataBindPmus.size(); ++i) {
|
||||
gen.m_redToAlphaDataBindPmus[i] = ctx.newShaderDataBinding(
|
||||
(*redToAlphaPipelinePmus)[i], nullptr, gen.m_instBufPmus.get(), nullptr, uniforms.size(), uniforms.data(),
|
||||
nullptr, texCount, textures.data(), nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
case EShaderClass::NoTex: {
|
||||
m_shaderBind.hsh_notex_bind(
|
||||
CElementGenShadersNoTexPipeline<mode, g_Renderer->IsThermalVisorHotPass(), gen.x26c_28_zTest, gen.x26c_27_ZBUF>(
|
||||
instBuf, uniBuf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m_shaderBind;
|
||||
}
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -8,11 +8,12 @@ class CElementGen;
|
|||
|
||||
class CElementGenShaders {
|
||||
hsh::binding m_shaderBind;
|
||||
|
||||
public:
|
||||
enum class EShaderClass { Tex, IndTex, NoTex };
|
||||
|
||||
static EShaderClass GetShaderClass(CElementGen& gen);
|
||||
hsh::binding& BuildShaderDataBinding(CElementGen& gen);
|
||||
hsh::binding& BuildShaderDataBinding(CElementGen& gen, bool pmus);
|
||||
};
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -4,31 +4,54 @@
|
|||
#include "Runtime/Graphics/CBooRenderer.hpp"
|
||||
#include "Runtime/Graphics/CGraphics.hpp"
|
||||
|
||||
#include "zeus/CVector2f.hpp"
|
||||
#include "CThermalColdFilter.cpp.hshhead"
|
||||
|
||||
namespace urde {
|
||||
using namespace hsh::pipeline;
|
||||
|
||||
struct CThermalColdFilterPipeline : pipeline<topology<hsh::TriangleStrip>,
|
||||
ERglBlendModeAttachment<ERglBlendMode::Blend, ERglBlendFactor::One,
|
||||
ERglBlendFactor::Zero, ERglLogicOp::Clear, true>,
|
||||
depth_write<false>> {
|
||||
CThermalColdFilterPipeline(hsh::vertex_buffer<CThermalColdFilter::Vert> vbo,
|
||||
hsh::uniform_buffer<CThermalColdFilter::Uniform> ubo, hsh::render_texture2d sceneTex,
|
||||
hsh::texture2d noiseTex) {
|
||||
static hsh::float4 kRGBToYPrime = {0.257f, 0.504f, 0.098f, 0.f};
|
||||
|
||||
this->position = hsh::float4(vbo->m_pos, 0.f, 1.f);
|
||||
hsh::float4 noiseTexel = noiseTex.read<float>(Lookup8BPP(vbo->m_uvNoise, ubo->m_randOff));
|
||||
hsh::float2 indCoord = (hsh::float3x3(ubo->m_indMtx[0].xyz(), ubo->m_indMtx[1].xyz(), ubo->m_indMtx[2].xyz()) *
|
||||
hsh::float3(noiseTexel.x - 0.5f, noiseTexel.w - 0.5f, 1.f))
|
||||
.xy();
|
||||
hsh::float2 sceneUv = vbo->m_uv + indCoord;
|
||||
sceneUv.y = 1.f - sceneUv.y;
|
||||
float indScene = hsh::dot(sceneTex.sample<float>(sceneUv), kRGBToYPrime) + 16.f / 255.f;
|
||||
this->color_out[0] = ubo->m_colorRegs[0] * indScene + ubo->m_colorRegs[2] - ubo->m_colorRegs[1] * noiseTexel.x;
|
||||
this->color_out[0].w = ubo->m_colorRegs[1].x + ubo->m_colorRegs[1].w * noiseTexel.x + ubo->m_colorRegs[2].w;
|
||||
}
|
||||
|
||||
static constexpr hsh::uint2 Lookup8BPP(hsh::float2 uv, float randOff) {
|
||||
int bx = int(uv.x) >> 3;
|
||||
int rx = int(uv.x) & 0x7;
|
||||
int by = int(uv.y) >> 2;
|
||||
int ry = int(uv.y) & 0x3;
|
||||
int bidx = by * 128 + bx;
|
||||
int addr = bidx * 32 + ry * 8 + rx + int(randOff);
|
||||
return hsh::uint2(addr & 0x3ff, addr >> 10);
|
||||
}
|
||||
};
|
||||
|
||||
CThermalColdFilter::CThermalColdFilter() {
|
||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
const std::array<Vert, 4> verts{{
|
||||
{{-1.f, -1.f}, {0.f, 0.f}, {0.f, 0.f}},
|
||||
{{-1.f, 1.f}, {0.f, 1.f}, {0.f, 448.f}},
|
||||
{{1.f, -1.f}, {1.f, 0.f}, {640.f, 0.f}},
|
||||
{{1.f, 1.f}, {1.f, 1.f}, {640.f, 448.f}},
|
||||
}};
|
||||
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 48, 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(),
|
||||
g_Renderer->GetRandomStaticEntropyTex(),
|
||||
};
|
||||
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);
|
||||
const std::array<Vert, 4> verts{{
|
||||
{{-1.f, -1.f}, {0.f, 0.f}, {0.f, 0.f}},
|
||||
{{-1.f, 1.f}, {0.f, 1.f}, {0.f, 448.f}},
|
||||
{{1.f, -1.f}, {1.f, 0.f}, {640.f, 0.f}},
|
||||
{{1.f, 1.f}, {1.f, 1.f}, {640.f, 448.f}},
|
||||
}};
|
||||
m_vbo = hsh::create_vertex_buffer(verts);
|
||||
m_uniBuf = hsh::create_dynamic_uniform_buffer<Uniform>();
|
||||
m_dataBind.hsh_bind(CThermalColdFilterPipeline(m_vbo.get(), m_uniBuf.get(), CGraphics::g_SpareTexture.get_color(0),
|
||||
g_Renderer->GetRandomStaticEntropyTex()));
|
||||
|
||||
setNoiseOffset(0);
|
||||
setScale(0.f);
|
||||
|
@ -38,9 +61,8 @@ void CThermalColdFilter::draw() {
|
|||
SCOPED_GRAPHICS_DEBUG_GROUP("CThermalColdFilter::draw", zeus::skMagenta);
|
||||
|
||||
CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport);
|
||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
m_uniBuf.load(m_uniform);
|
||||
m_dataBind.draw(0, 4);
|
||||
}
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -8,20 +8,23 @@
|
|||
namespace urde {
|
||||
|
||||
class CThermalColdFilter {
|
||||
public:
|
||||
struct Uniform {
|
||||
zeus::CMatrix4f m_indMtx;
|
||||
std::array<zeus::CColor, 3> m_colorRegs;
|
||||
hsh::float4x4 m_indMtx;
|
||||
std::array<hsh::float4, 3> m_colorRegs;
|
||||
float m_randOff = 0.f;
|
||||
};
|
||||
struct Vert {
|
||||
zeus::CVector2f m_pos;
|
||||
zeus::CVector2f m_uv;
|
||||
zeus::CVector2f m_uvNoise;
|
||||
hsh::float2 m_pos;
|
||||
hsh::float2 m_uv;
|
||||
hsh::float2 m_uvNoise;
|
||||
};
|
||||
|
||||
private:
|
||||
hsh::owner<hsh::vertex_buffer<Vert>> m_vbo;
|
||||
hsh::dynamic_owner<hsh::uniform_buffer<Uniform>> m_uniBuf;
|
||||
hsh::binding m_dataBind;
|
||||
Uniform m_uniform;
|
||||
Uniform m_uniform{};
|
||||
|
||||
public:
|
||||
CThermalColdFilter();
|
||||
|
|
|
@ -4,42 +4,49 @@
|
|||
#include "Runtime/Graphics/CBooRenderer.hpp"
|
||||
#include "Runtime/Graphics/CGraphics.hpp"
|
||||
|
||||
#include "zeus/CVector2f.hpp"
|
||||
#include "CThermalHotFilter.cpp.hshhead"
|
||||
|
||||
namespace urde {
|
||||
using namespace hsh::pipeline;
|
||||
|
||||
struct CThermalHotFilterPipeline
|
||||
: pipeline<ERglBlendModeAttachment<ERglBlendMode::Blend, ERglBlendFactor::DstAlpha, ERglBlendFactor::InvDstAlpha,
|
||||
ERglLogicOp::Clear, true>,
|
||||
depth_write<false>> {
|
||||
CThermalHotFilterPipeline(hsh::vertex_buffer<CThermalHotFilter::Vert> vbo,
|
||||
hsh::uniform_buffer<CThermalHotFilter::Uniform> ubo, hsh::render_texture2d sceneTex,
|
||||
hsh::texture2d paletteTex) {
|
||||
static hsh::float4 kRGBToYPrime = {0.257f, 0.504f, 0.098f, 0.f};
|
||||
|
||||
this->position = hsh::float4(vbo->m_pos, 0.f, 1.f);
|
||||
|
||||
hsh::float2 sceneUv = vbo->m_uv;
|
||||
sceneUv.y = 1.f - sceneUv.y;
|
||||
float sceneSample = hsh::dot(sceneTex.sample<float>(sceneUv), kRGBToYPrime) + 16.f / 255.f;
|
||||
hsh::float4 colorSample = paletteTex.sample<float>(hsh::float2(sceneSample / 16.f, 0.5f));
|
||||
this->color_out[0] = hsh::float4(colorSample.xyz(), 0.f);
|
||||
}
|
||||
};
|
||||
|
||||
CThermalHotFilter::CThermalHotFilter() {
|
||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
const std::array<Vert, 4> verts{{
|
||||
{{-1.0, -1.0}, {0.0, 0.0}},
|
||||
{{-1.0, 1.0}, {0.0, 1.0}},
|
||||
{{1.0, -1.0}, {1.0, 0.0}},
|
||||
{{1.0, 1.0}, {1.0, 1.0}},
|
||||
}};
|
||||
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(),
|
||||
g_Renderer->GetThermoPalette(),
|
||||
};
|
||||
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);
|
||||
const std::array<Vert, 4> verts{{
|
||||
{{-1.0, -1.0}, {0.0, 0.0}},
|
||||
{{-1.0, 1.0}, {0.0, 1.0}},
|
||||
{{1.0, -1.0}, {1.0, 0.0}},
|
||||
{{1.0, 1.0}, {1.0, 1.0}},
|
||||
}};
|
||||
m_vbo = hsh::create_vertex_buffer(verts);
|
||||
m_uniBuf = hsh::create_dynamic_uniform_buffer<Uniform>();
|
||||
m_dataBind.hsh_bind(CThermalHotFilterPipeline(m_vbo.get(), m_uniBuf.get(), CGraphics::g_SpareTexture.get_color(0),
|
||||
g_Renderer->GetThermoPalette()));
|
||||
}
|
||||
|
||||
void CThermalHotFilter::draw() {
|
||||
SCOPED_GRAPHICS_DEBUG_GROUP("CThermalHotFilter::draw", zeus::skMagenta);
|
||||
|
||||
CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport);
|
||||
|
||||
// m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
m_uniBuf.load(m_uniform);
|
||||
m_dataBind.draw(0, 4);
|
||||
}
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -2,22 +2,26 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "hsh/hsh.h"
|
||||
#include "zeus/CColor.hpp"
|
||||
|
||||
namespace urde {
|
||||
|
||||
class CThermalHotFilter {
|
||||
public:
|
||||
struct Uniform {
|
||||
std::array<zeus::CColor, 3> m_colorRegs;
|
||||
std::array<hsh::float4, 3> m_colorRegs;
|
||||
};
|
||||
struct Vert {
|
||||
zeus::CVector2f m_pos;
|
||||
zeus::CVector2f m_uv;
|
||||
hsh::float2 m_pos;
|
||||
hsh::float2 m_uv;
|
||||
};
|
||||
|
||||
private:
|
||||
hsh::owner<hsh::vertex_buffer<Vert>> m_vbo;
|
||||
hsh::dynamic_owner<hsh::uniform_buffer<Uniform>> m_uniBuf;
|
||||
hsh::binding m_dataBind;
|
||||
Uniform m_uniform;
|
||||
Uniform m_uniform{};
|
||||
|
||||
public:
|
||||
CThermalHotFilter();
|
||||
|
|
|
@ -200,8 +200,8 @@ void CGuiFrame::ProcessUserInput(const CFinalInput& input) const {
|
|||
|
||||
bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDrawParms& parms) {
|
||||
if (const auto& kbm = input.GetKBM()) {
|
||||
zeus::CVector2f point(kbm->m_mouseCoord.norm[0] * 2.f - 1.f,
|
||||
kbm->m_mouseCoord.norm[1] * 2.f - 1.f);
|
||||
zeus::CVector2f point(kbm->m_mouseCoord.x * 2.f - 1.f,
|
||||
kbm->m_mouseCoord.y * 2.f - 1.f);
|
||||
CGuiWidget* hit = BestCursorHit(point, parms);
|
||||
if (hit != m_lastMouseOverWidget) {
|
||||
if (m_inMouseDown && m_mouseDownWidget != hit) {
|
||||
|
@ -220,14 +220,14 @@ bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDraw
|
|||
m_lastMouseOverWidget = hit;
|
||||
}
|
||||
if (hit && hit->m_lastScroll) {
|
||||
boo::SScrollDelta delta = kbm->m_accumScroll - *hit->m_lastScroll;
|
||||
auto delta = kbm->m_accumScroll - *hit->m_lastScroll;
|
||||
hit->m_lastScroll.emplace(kbm->m_accumScroll);
|
||||
if (!delta.isZero()) {
|
||||
if (delta.x != 0.0 || delta.y != 0.0) {
|
||||
hit->m_integerScroll += delta;
|
||||
if (m_mouseScrollCb)
|
||||
m_mouseScrollCb(hit, delta, int(hit->m_integerScroll.delta[0]), int(hit->m_integerScroll.delta[1]));
|
||||
hit->m_integerScroll.delta[0] -= std::trunc(hit->m_integerScroll.delta[0]);
|
||||
hit->m_integerScroll.delta[1] -= std::trunc(hit->m_integerScroll.delta[1]);
|
||||
m_mouseScrollCb(hit, delta, int(hit->m_integerScroll.x), int(hit->m_integerScroll.y));
|
||||
hit->m_integerScroll.x -= std::trunc(hit->m_integerScroll.x);
|
||||
hit->m_integerScroll.y -= std::trunc(hit->m_integerScroll.y);
|
||||
}
|
||||
}
|
||||
if (!m_inMouseDown && kbm->m_mouseButtons[size_t(boo2::MouseButton::Primary)]) {
|
||||
|
|
|
@ -213,22 +213,28 @@ CElementGen::CElementGen(TToken<CGenDescription> gen, EModelOrientationType orie
|
|||
if (!x26c_31_LINE) {
|
||||
switch (m_shaderClass) {
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceTex>(maxInsts); break;
|
||||
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceTex>(maxInsts);
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::IndTex:
|
||||
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceIndTex>(maxInsts); break;
|
||||
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceIndTex>(maxInsts);
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceNoTex>(maxInsts); break;
|
||||
m_instBuf = hsh::create_dynamic_vertex_buffer<SParticleInstanceNoTex>(maxInsts);
|
||||
break;
|
||||
}
|
||||
m_uniformBuf = hsh::create_dynamic_uniform_buffer<SParticleUniforms>();
|
||||
}
|
||||
if (desc->x45_24_x31_26_PMUS) {
|
||||
switch (m_shaderClass) {
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceTex>(maxInsts); break;
|
||||
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceTex>(maxInsts);
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::IndTex:
|
||||
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceIndTex>(maxInsts); break;
|
||||
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceIndTex>(maxInsts);
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceNoTex>(maxInsts); break;
|
||||
m_instBufPmus = hsh::create_dynamic_vertex_buffer<SParticleInstanceNoTex>(maxInsts);
|
||||
break;
|
||||
}
|
||||
m_uniformBufPmus = hsh::create_dynamic_uniform_buffer<SParticleUniforms>();
|
||||
}
|
||||
|
@ -907,14 +913,6 @@ void CElementGen::RenderModels(const CActorLights* actorLights) {
|
|||
}
|
||||
|
||||
m_uniformBufPmus.load({CGraphics::GetPerspectiveProjectionMatrix(true), {1.f, 1.f, 1.f, 1.f}});
|
||||
|
||||
// TODO: Implement in builder
|
||||
#if 0
|
||||
if (moveRedToAlphaBuffer)
|
||||
CGraphics::SetShaderDataBinding(m_redToAlphaDataBindPmus[g_Renderer->IsThermalVisorHotPass()]);
|
||||
else
|
||||
CGraphics::SetShaderDataBinding(m_normalDataBindPmus[g_Renderer->IsThermalVisorHotPass()]);
|
||||
#endif
|
||||
}
|
||||
|
||||
zeus::CTransform orient = zeus::CTransform();
|
||||
|
@ -1064,11 +1062,11 @@ void CElementGen::RenderModels(const CActorLights* actorLights) {
|
|||
switch (m_shaderClass) {
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
m_instBufPmus.load<SParticleInstanceTex>(g_instTexData);
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instTexData.size());
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this, true).draw_instanced(0, 4, g_instTexData.size());
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
m_instBufPmus.load<SParticleInstanceNoTex>(g_instNoTexData);
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instNoTexData.size());
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this, true).draw_instanced(0, 4, g_instNoTexData.size());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1194,12 +1192,12 @@ void CElementGen::RenderParticles() {
|
|||
return;
|
||||
}
|
||||
|
||||
CRealElement* size = desc->x4c_x38_SIZE.get();
|
||||
if (size && size->IsConstant()) {
|
||||
CRealElement* sizeElem = desc->x4c_x38_SIZE.get();
|
||||
if (sizeElem && sizeElem->IsConstant()) {
|
||||
float sizeVal;
|
||||
size->GetValue(0, sizeVal);
|
||||
sizeElem->GetValue(0, sizeVal);
|
||||
if (sizeVal == 0.f) {
|
||||
size->GetValue(1, sizeVal);
|
||||
sizeElem->GetValue(1, sizeVal);
|
||||
if (sizeVal == 0.f)
|
||||
return;
|
||||
}
|
||||
|
@ -1263,22 +1261,6 @@ void CElementGen::RenderParticles() {
|
|||
if (sMoveRedToAlphaBuffer && x26c_26_AAPH)
|
||||
moveRedToAlphaBuffer = true;
|
||||
|
||||
// TODO: Implement in builder
|
||||
#if 0
|
||||
if (g_subtractBlend) {
|
||||
// FIXME should there be NoTex specializations for RedToAlpha?
|
||||
if (moveRedToAlphaBuffer && desc->x54_x40_TEXR)
|
||||
CGraphics::SetShaderDataBinding(m_redToAlphaSubDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
||||
else
|
||||
CGraphics::SetShaderDataBinding(m_normalSubDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
||||
} else {
|
||||
if (moveRedToAlphaBuffer && desc->x54_x40_TEXR)
|
||||
CGraphics::SetShaderDataBinding(m_redToAlphaDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
||||
else
|
||||
CGraphics::SetShaderDataBinding(m_normalDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
||||
}
|
||||
#endif
|
||||
|
||||
int mbspVal = std::max(1, x270_MBSP);
|
||||
|
||||
CParticleGlobals::instance()->SetEmitterTime(x74_curFrame);
|
||||
|
@ -1490,11 +1472,11 @@ void CElementGen::RenderParticles() {
|
|||
switch (m_shaderClass) {
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
m_instBuf.load<SParticleInstanceTex>(g_instTexData);
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instTexData.size());
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instTexData.size());
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
m_instBuf.load<SParticleInstanceNoTex>(g_instNoTexData);
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instNoTexData.size());
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instNoTexData.size());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1604,11 +1586,11 @@ void CElementGen::RenderParticles() {
|
|||
switch (m_shaderClass) {
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
m_instBuf.load<SParticleInstanceTex>(g_instTexData);
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instTexData.size());
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instTexData.size());
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
m_instBuf.load<SParticleInstanceNoTex>(g_instNoTexData);
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instNoTexData.size());
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instNoTexData.size());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1681,12 +1663,6 @@ void CElementGen::RenderParticlesIndirectTexture() {
|
|||
g_instIndTexData.clear();
|
||||
g_instIndTexData.reserve(x30_particles.size());
|
||||
|
||||
// TODO: move to builder
|
||||
#if 0
|
||||
if (!x30_particles.empty())
|
||||
CGraphics::SetShaderDataBinding(m_normalDataBind[g_Renderer->IsThermalVisorHotPass()]);
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < x30_particles.size(); ++i) {
|
||||
const int partIdx = desc->x44_28_x30_28_SORT ? sortItems[i].x0_partIdx : int(i);
|
||||
CParticle& particle = x30_particles[partIdx];
|
||||
|
@ -1743,9 +1719,9 @@ void CElementGen::RenderParticlesIndirectTexture() {
|
|||
inst.texrTindUVs[1] = zeus::CVector4f{uvs.xMin, uvs.yMax, uvsInd.xMin, uvsInd.yMax};
|
||||
inst.texrTindUVs[2] = zeus::CVector4f{uvs.xMax, uvs.yMin, uvsInd.xMax, uvsInd.yMin};
|
||||
inst.texrTindUVs[3] = zeus::CVector4f{uvs.xMin, uvs.yMin, uvsInd.xMin, uvsInd.yMin};
|
||||
inst.sceneUVs = zeus::CVector4f{clipRect.x18_uvXMin, 1.f - clipRect.x24_uvYMax, clipRect.x1c_uvXMax,
|
||||
1.f - clipRect.x20_uvYMin};
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this).draw_instanced(0, 4, g_instIndTexData.size() - 1);
|
||||
inst.sceneUVs =
|
||||
zeus::CVector4f{clipRect.x18_uvXMin, 1.f - clipRect.x24_uvYMax, clipRect.x1c_uvXMax, 1.f - clipRect.x20_uvYMin};
|
||||
m_shaderBuilder.BuildShaderDataBinding(*this, false).draw_instanced(0, 4, g_instIndTexData.size() - 1);
|
||||
}
|
||||
|
||||
if (!g_instIndTexData.empty()) {
|
||||
|
|
Loading…
Reference in New Issue