#include "Runtime/Graphics/Shaders/CElementGenShaders.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Graphics/CBooRenderer.hpp" #include "Runtime/Particle/CElementGen.hpp" enum class BlendMode { Regular, Additive, Subtract, }; #include "CElementGenShaders.cpp.hshhead" namespace urde { using namespace hsh::pipeline; template struct BlendModeAttachmentExt { using type = BlendAttachment; }; template struct BlendModeAttachmentExt { using type = AdditiveAttachment; }; template struct BlendModeAttachmentExt { using type = SubtractAttachment; }; template using BlendModeAttachment = typename BlendModeAttachmentExt::type; template struct CElementGenShadersTexPipeline : pipeline, BlendModeAttachment, depth_compare, depth_write> { CElementGenShadersTexPipeline(hsh::vertex_buffer vbo, hsh::uniform_buffer uniBuf, hsh::texture2d tex) { this->position = uniBuf->mvp * vbo->pos[this->vertex_id]; this->color_out[0] = vbo->color * uniBuf->moduColor * tex.sample(vbo->uvs[this->vertex_id]); if constexpr (RedToAlpha) { this->color_out[0].w = this->color_out[0].x; } } }; template struct CElementGenShadersTexPipeline; template struct CElementGenShadersTexPipeline; template struct CElementGenShadersTexPipeline; template struct CElementGenShadersIndTexPipeline : pipeline, BlendModeAttachment, depth_compare, depth_write> { CElementGenShadersIndTexPipeline(hsh::vertex_buffer vbo, hsh::uniform_buffer 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(vbo->texrTindUVs[this->vertex_id].xy()); hsh::float2 tindTexel = tindTex.sample(vbo->texrTindUVs[this->vertex_id].zw()).xy(); hsh::float4 sceneTexel = sceneTex.sample(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; template struct CElementGenShadersIndTexPipeline; template struct CElementGenShadersNoTexPipeline : pipeline, BlendModeAttachment, depth_compare, depth_write> { CElementGenShadersNoTexPipeline(hsh::vertex_buffer vbo, hsh::uniform_buffer uniBuf) { this->position = uniBuf->mvp * vbo->pos[this->vertex_id]; this->color_out[0] = vbo->color * uniBuf->moduColor; } }; template struct CElementGenShadersNoTexPipeline; template struct CElementGenShadersNoTexPipeline; template struct CElementGenShadersNoTexPipeline; CElementGenShaders::EShaderClass CElementGenShaders::GetShaderClass(CElementGen& gen) { const auto* desc = gen.x1c_genDesc.GetObj(); if (desc->x54_x40_TEXR) { if (desc->x58_x44_TIND) { return EShaderClass::IndTex; } return EShaderClass::Tex; } return EShaderClass::NoTex; } 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; } 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( CElementGenShadersTexPipelineIsThermalVisorHotPass(), gen.x26c_28_zTest, gen.x26c_27_ZBUF, CElementGen::sMoveRedToAlphaBuffer>(instBuf, uniBuf, tex)); break; } 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( CElementGenShadersIndTexPipelineIsThermalVisorHotPass(), gen.x26c_28_zTest, gen.x26c_27_ZBUF, desc->x45_30_x32_24_CIND>(instBuf, uniBuf, texrTex, tindTex, sceneTex)); break; } case EShaderClass::NoTex: { m_shaderBind.hsh_notex_bind( CElementGenShadersNoTexPipelineIsThermalVisorHotPass(), gen.x26c_28_zTest, gen.x26c_27_ZBUF>( instBuf, uniBuf)); break; } } return m_shaderBind; } } // namespace urde