mirror of https://github.com/AxioDL/metaforce.git
Metal extended shader support
This commit is contained in:
parent
13f0726c40
commit
c4c3e1883f
|
@ -8,6 +8,7 @@
|
||||||
#include "Shaders/CModelShaders.hpp"
|
#include "Shaders/CModelShaders.hpp"
|
||||||
#include "Graphics/CBooRenderer.hpp"
|
#include "Graphics/CBooRenderer.hpp"
|
||||||
#include "GameGlobalObjects.hpp"
|
#include "GameGlobalObjects.hpp"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,6 +27,11 @@ CModelShaders::GetShaderExtensions(boo::IGraphicsDataFactory::Platform plat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hecl::Backend::TextureInfo CModelShaders::ThermalTextures[] =
|
||||||
|
{
|
||||||
|
{hecl::Backend::TexGenSrc::Normal, 7, 0, 7, true}
|
||||||
|
};
|
||||||
|
|
||||||
CModelShaders::CModelShaders(const hecl::Runtime::FileStoreManager& storeMgr,
|
CModelShaders::CModelShaders(const hecl::Runtime::FileStoreManager& storeMgr,
|
||||||
boo::IGraphicsDataFactory* gfxFactory)
|
boo::IGraphicsDataFactory* gfxFactory)
|
||||||
: m_shaderCache(storeMgr, gfxFactory, GetShaderExtensions(gfxFactory->platform())) {}
|
: m_shaderCache(storeMgr, gfxFactory, GetShaderExtensions(gfxFactory->platform())) {}
|
||||||
|
|
|
@ -20,6 +20,7 @@ class CModelShaders
|
||||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat);
|
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat);
|
||||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat);
|
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat);
|
||||||
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat);
|
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat);
|
||||||
|
static const hecl::Backend::TextureInfo ThermalTextures[];
|
||||||
public:
|
public:
|
||||||
struct Light
|
struct Light
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,11 +64,6 @@ static const char* ThermalBlockNames[] = {HECL_GLSL_VERT_UNIFORM_BLOCK_NAME,
|
||||||
HECL_GLSL_TEXMTX_UNIFORM_BLOCK_NAME,
|
HECL_GLSL_TEXMTX_UNIFORM_BLOCK_NAME,
|
||||||
"ThermalUniform"};
|
"ThermalUniform"};
|
||||||
|
|
||||||
static const hecl::Backend::TextureInfo ThermalTextures[] =
|
|
||||||
{
|
|
||||||
{hecl::Backend::TexGenSrc::Normal, 7, 0, 7, true}
|
|
||||||
};
|
|
||||||
|
|
||||||
hecl::Runtime::ShaderCacheExtensions
|
hecl::Runtime::ShaderCacheExtensions
|
||||||
CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat)
|
CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,13 +43,34 @@ static const char* LightingMetal =
|
||||||
" return saturate(ret);\n"
|
" return saturate(ret);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
static const char* ThermalPostMetal =
|
||||||
|
"struct ThermalUniform\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 mulColor;\n"
|
||||||
|
" float4 addColor;\n"
|
||||||
|
"};\n"
|
||||||
|
"static float4 ThermalPostFunc(thread VertToFrag& vtf, constant ThermalUniform& lu, texture2d<float> tex7, float4 colorIn)\n"
|
||||||
|
"{\n"
|
||||||
|
" return tex7.sample(samp, vtf.extTcgs0).rrrr * lu.mulColor + lu.addColor;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
static const char* BlockNames[] = {"LightingUniform"};
|
static const char* BlockNames[] = {"LightingUniform"};
|
||||||
|
static const char* ThermalBlockNames[] = {"ThermalUniform"};
|
||||||
|
|
||||||
hecl::Runtime::ShaderCacheExtensions
|
hecl::Runtime::ShaderCacheExtensions
|
||||||
CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat)
|
CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat)
|
||||||
{
|
{
|
||||||
hecl::Runtime::ShaderCacheExtensions ext(plat);
|
hecl::Runtime::ShaderCacheExtensions ext(plat);
|
||||||
ext.registerExtensionSlot({LightingMetal, "LightingFunc"}, {}, 1, BlockNames);
|
|
||||||
|
/* Normal lit shading */
|
||||||
|
ext.registerExtensionSlot({LightingMetal, "LightingFunc"}, {}, 1, BlockNames, 0, nullptr,
|
||||||
|
hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original);
|
||||||
|
|
||||||
|
/* Thermal Visor shading */
|
||||||
|
ext.registerExtensionSlot({}, {ThermalPostMetal, "ThermalPostFunc"}, 1, ThermalBlockNames, 1, ThermalTextures,
|
||||||
|
hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One);
|
||||||
|
|
||||||
return ext;
|
return ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,16 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt)
|
||||||
else
|
else
|
||||||
m_uniform.m_matrix[3][2] = pt.z;
|
m_uniform.m_matrix[3][2] = pt.z;
|
||||||
|
|
||||||
|
if (clipRect.x4_left)
|
||||||
|
{
|
||||||
|
clipRect.x4_left -= 1;
|
||||||
|
clipRect.xc_width += 1;
|
||||||
|
}
|
||||||
|
if (clipRect.x8_top)
|
||||||
|
{
|
||||||
|
clipRect.x8_top -= 1;
|
||||||
|
clipRect.x10_height += 1;
|
||||||
|
}
|
||||||
if (clipRect.x4_left + clipRect.xc_width < CGraphics::g_ViewportResolution.x)
|
if (clipRect.x4_left + clipRect.xc_width < CGraphics::g_ViewportResolution.x)
|
||||||
clipRect.xc_width += 1;
|
clipRect.xc_width += 1;
|
||||||
if (clipRect.x8_top + clipRect.x10_height < CGraphics::g_ViewportResolution.y)
|
if (clipRect.x8_top + clipRect.x10_height < CGraphics::g_ViewportResolution.y)
|
||||||
|
|
|
@ -12,6 +12,7 @@ class CSpaceWarpFilter
|
||||||
{
|
{
|
||||||
friend struct CSpaceWarpFilterGLDataBindingFactory;
|
friend struct CSpaceWarpFilterGLDataBindingFactory;
|
||||||
friend struct CSpaceWarpFilterVulkanDataBindingFactory;
|
friend struct CSpaceWarpFilterVulkanDataBindingFactory;
|
||||||
|
friend struct CSpaceWarpFilterMetalDataBindingFactory;
|
||||||
|
|
||||||
struct Uniform
|
struct Uniform
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,11 +3,88 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static const char* VS =
|
||||||
|
"#include <metal_stdlib>\n"
|
||||||
|
"using namespace metal;\n"
|
||||||
|
"struct VertData\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 posIn [[ attribute(0) ]];\n"
|
||||||
|
" float4 uvIn [[ attribute(1) ]];\n"
|
||||||
|
"};\n"
|
||||||
|
"struct SpaceWarpUniform\n"
|
||||||
|
"{\n"
|
||||||
|
" float4x4 mainMtx;\n"
|
||||||
|
" float4x4 indMtx;\n"
|
||||||
|
" float4 strength;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 position [[ position ]];\n"
|
||||||
|
" float2 sceneUv;\n"
|
||||||
|
" float2 indUv;\n"
|
||||||
|
" float2 strength;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpaceWarpUniform& swu [[ buffer(2) ]])\n"
|
||||||
|
"{\n"
|
||||||
|
" VertToFrag vtf;\n"
|
||||||
|
" vtf.position = swu.mainMtx * float4(v.posIn.xy, 0.0, 1.0);\n"
|
||||||
|
" vtf.sceneUv = vtf.position.xy * float2(0.5) + float2(0.5);\n"
|
||||||
|
" vtf.sceneUv.y = -vtf.sceneUv.y;\n"
|
||||||
|
" vtf.indUv = (float3x3(swu.indMtx[0].xyz, swu.indMtx[1].xyz, swu.indMtx[2].xyz) * float3(v.uvIn.xy, 1.0)).xy;\n"
|
||||||
|
" vtf.indUv.y = -vtf.indUv.y;\n"
|
||||||
|
" vtf.strength = swu.strength.xy;\n"
|
||||||
|
" return vtf;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char* FS =
|
||||||
|
"#include <metal_stdlib>\n"
|
||||||
|
"using namespace metal;\n"
|
||||||
|
"constexpr sampler samp(address::repeat, filter::linear);\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 position [[ position ]];\n"
|
||||||
|
" float2 sceneUv;\n"
|
||||||
|
" float2 indUv;\n"
|
||||||
|
" float2 strength;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]], texture2d<float> sceneTex [[ texture(0) ]], texture2d<float> indTex [[ texture(1) ]])\n"
|
||||||
|
"{\n"
|
||||||
|
" return sceneTex.sample(samp, vtf.sceneUv + (indTex.sample(samp, vtf.indUv).xy * float2(2.0) - float2(1.0 - 1.0 / 256.0)) * vtf.strength.xy);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
URDE_DECL_SPECIALIZE_SHADER(CSpaceWarpFilter)
|
||||||
|
|
||||||
|
struct CSpaceWarpFilterMetalDataBindingFactory : TShader<CSpaceWarpFilter>::IDataBindingFactory
|
||||||
|
{
|
||||||
|
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CSpaceWarpFilter& filter)
|
||||||
|
{
|
||||||
|
boo::MetalDataFactory::Context& cctx = static_cast<boo::MetalDataFactory::Context&>(ctx);
|
||||||
|
|
||||||
|
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
|
||||||
|
boo::ITexture* texs[] = {CGraphics::g_SpareTexture, filter.m_warpTex};
|
||||||
|
return cctx.newShaderDataBinding(TShader<CSpaceWarpFilter>::m_pipeline,
|
||||||
|
TShader<CSpaceWarpFilter>::m_vtxFmt,
|
||||||
|
filter.m_vbo, nullptr, nullptr, 1, bufs,
|
||||||
|
nullptr, nullptr, nullptr, 2, texs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
TShader<CSpaceWarpFilter>::IDataBindingFactory* CSpaceWarpFilter::Initialize(boo::MetalDataFactory::Context& ctx,
|
TShader<CSpaceWarpFilter>::IDataBindingFactory* CSpaceWarpFilter::Initialize(boo::MetalDataFactory::Context& ctx,
|
||||||
boo::IShaderPipeline*& pipeOut,
|
boo::IShaderPipeline*& pipeOut,
|
||||||
boo::IVertexFormat*& vtxFmtOut)
|
boo::IVertexFormat*& vtxFmtOut)
|
||||||
{
|
{
|
||||||
return nullptr;
|
const boo::VertexElementDescriptor VtxVmt[] =
|
||||||
|
{
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::UV4}
|
||||||
|
};
|
||||||
|
vtxFmtOut = ctx.newVertexFormat(2, VtxVmt);
|
||||||
|
pipeOut = ctx.newShaderPipeline(VS, FS, vtxFmtOut, CGraphics::g_ViewportSamples, boo::BlendFactor::One,
|
||||||
|
boo::BlendFactor::Zero, boo::Primitive::TriStrips, false, false, false);
|
||||||
|
return new CSpaceWarpFilterMetalDataBindingFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ class CThermalColdFilter
|
||||||
{
|
{
|
||||||
friend struct CThermalColdFilterGLDataBindingFactory;
|
friend struct CThermalColdFilterGLDataBindingFactory;
|
||||||
friend struct CThermalColdFilterVulkanDataBindingFactory;
|
friend struct CThermalColdFilterVulkanDataBindingFactory;
|
||||||
|
friend struct CThemalColdFilterMetalDataBindingFactory;
|
||||||
|
|
||||||
struct Uniform
|
struct Uniform
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,11 +3,115 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static const char* VS =
|
||||||
|
"#include <metal_stdlib>\n"
|
||||||
|
"using namespace metal;\n"
|
||||||
|
"struct VertData\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 posIn [[ attribute(0) ]];\n"
|
||||||
|
" float4 uvIn [[ attribute(1) ]];\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"struct ThermalColdUniform\n"
|
||||||
|
"{\n"
|
||||||
|
" float4x4 shiftMtx;\n"
|
||||||
|
" float4x4 indMtx;\n"
|
||||||
|
" float4 shiftScale;\n"
|
||||||
|
" float4 colorReg0;\n"
|
||||||
|
" float4 colorReg1;\n"
|
||||||
|
" float4 colorReg2;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 position [[ position ]];\n"
|
||||||
|
" float3 indMtx0;\n"
|
||||||
|
" float3 indMtx1;\n"
|
||||||
|
" float3 indMtx2;\n"
|
||||||
|
" float4 colorReg0;\n"
|
||||||
|
" float4 colorReg1;\n"
|
||||||
|
" float4 colorReg2;\n"
|
||||||
|
" float2 sceneUv;\n"
|
||||||
|
" float2 shiftUv;\n"
|
||||||
|
" float2 shiftScale;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant ThermalColdUniform& tcu [[ buffer(2) ]])\n"
|
||||||
|
"{\n"
|
||||||
|
" VertToFrag vtf;\n"
|
||||||
|
" vtf.indMtx0 = tcu.indMtx[0].xyz;\n"
|
||||||
|
" vtf.indMtx1 = tcu.indMtx[1].xyz;\n"
|
||||||
|
" vtf.indMtx2 = tcu.indMtx[2].xyz;\n"
|
||||||
|
" vtf.colorReg0 = tcu.colorReg0;\n"
|
||||||
|
" vtf.colorReg1 = tcu.colorReg1;\n"
|
||||||
|
" vtf.colorReg2 = tcu.colorReg2;\n"
|
||||||
|
" vtf.sceneUv = v.uvIn.xy;\n"
|
||||||
|
" vtf.shiftUv = (float3x3(tcu.shiftMtx[0].xyz, tcu.shiftMtx[1].xyz, tcu.shiftMtx[2].xyz) * v.uvIn.xyz).xy;\n"
|
||||||
|
" vtf.shiftScale = tcu.shiftScale.xy;\n"
|
||||||
|
" vtf.position = float4(v.posIn.xyz, 1.0);\n"
|
||||||
|
" return vtf;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char* FS =
|
||||||
|
"#include <metal_stdlib>\n"
|
||||||
|
"using namespace metal;\n"
|
||||||
|
"constexpr sampler samp(address::repeat, filter::linear);\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 position [[ position ]];\n"
|
||||||
|
" float3 indMtx0;\n"
|
||||||
|
" float3 indMtx1;\n"
|
||||||
|
" float3 indMtx2;\n"
|
||||||
|
" float4 colorReg0;\n"
|
||||||
|
" float4 colorReg1;\n"
|
||||||
|
" float4 colorReg2;\n"
|
||||||
|
" float2 sceneUv;\n"
|
||||||
|
" float2 shiftUv;\n"
|
||||||
|
" float2 shiftScale;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"constant float4 kRGBToYPrime = {0.299, 0.587, 0.114, 0.0};\n"
|
||||||
|
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]], texture2d<float> sceneTex [[ texture(0) ]], texture2d<float> shiftTex [[ texture(1) ]])\n"
|
||||||
|
"{\n"
|
||||||
|
" float2 shiftCoordTexel = shiftTex.sample(samp, vtf.shiftUv).xy;\n"
|
||||||
|
" float2 shiftCoord = vtf.sceneUv + shiftCoordTexel * vtf.shiftScale;\n"
|
||||||
|
" float shiftScene0 = dot(sceneTex.sample(samp, shiftCoord), kRGBToYPrime);\n"
|
||||||
|
" float shiftScene1 = dot(sceneTex.sample(samp, shiftCoord + float2(vtf.shiftScale.x / 8.0, 0.0)), kRGBToYPrime);\n"
|
||||||
|
" float2 indCoord = (float3x3(vtf.indMtx0, vtf.indMtx1, vtf.indMtx2) * float3(shiftScene0 - 0.5, shiftScene1 - 0.5, 1.0)).xy;\n"
|
||||||
|
" float indScene = dot(sceneTex.sample(samp, vtf.sceneUv + indCoord), kRGBToYPrime);\n"
|
||||||
|
" return vtf.colorReg0 * indScene + vtf.colorReg1 * shiftScene0 + vtf.colorReg2;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
URDE_DECL_SPECIALIZE_SHADER(CThermalColdFilter)
|
||||||
|
|
||||||
|
struct CThemalColdFilterMetalDataBindingFactory : TShader<CThermalColdFilter>::IDataBindingFactory
|
||||||
|
{
|
||||||
|
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CThermalColdFilter& filter)
|
||||||
|
{
|
||||||
|
boo::MetalDataFactory::Context& cctx = static_cast<boo::MetalDataFactory::Context&>(ctx);
|
||||||
|
|
||||||
|
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
|
||||||
|
boo::ITexture* texs[] = {CGraphics::g_SpareTexture, filter.m_shiftTex};
|
||||||
|
return cctx.newShaderDataBinding(TShader<CThermalColdFilter>::m_pipeline,
|
||||||
|
TShader<CThermalColdFilter>::m_vtxFmt,
|
||||||
|
filter.m_vbo, nullptr, nullptr, 1, bufs,
|
||||||
|
nullptr, nullptr, nullptr, 2, texs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
TShader<CThermalColdFilter>::IDataBindingFactory* CThermalColdFilter::Initialize(boo::MetalDataFactory::Context& ctx,
|
TShader<CThermalColdFilter>::IDataBindingFactory* CThermalColdFilter::Initialize(boo::MetalDataFactory::Context& ctx,
|
||||||
boo::IShaderPipeline*& pipeOut,
|
boo::IShaderPipeline*& pipeOut,
|
||||||
boo::IVertexFormat*& vtxFmtOut)
|
boo::IVertexFormat*& vtxFmtOut)
|
||||||
{
|
{
|
||||||
return nullptr;
|
const boo::VertexElementDescriptor VtxVmt[] =
|
||||||
|
{
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::UV4}
|
||||||
|
};
|
||||||
|
vtxFmtOut = ctx.newVertexFormat(2, VtxVmt);
|
||||||
|
pipeOut = ctx.newShaderPipeline(VS, FS, vtxFmtOut, CGraphics::g_ViewportSamples, boo::BlendFactor::One,
|
||||||
|
boo::BlendFactor::Zero, boo::Primitive::TriStrips, false, false, false);
|
||||||
|
return new CThemalColdFilterMetalDataBindingFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit 3f47a0524451e46c73915e81de85e0a926a29e12
|
Subproject commit cb3e8d09fe2def4bf594d5d4f8822440dddb3ce9
|
2
kabufuda
2
kabufuda
|
@ -1 +1 @@
|
||||||
Subproject commit 99069bd069a93ab2d98dcd09b799711d2f93754c
|
Subproject commit d242e2deb63b2fc6da526e7245d4dfa487731af4
|
Loading…
Reference in New Issue