From b860d962aed00ef020914371a03cfea6ad632baa Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 25 Mar 2017 19:51:58 -1000 Subject: [PATCH] Reflection shader support --- hecl/blender/hecl/hmdl/HMDLShader.py | 16 +++++ hecl/include/hecl/Backend/Backend.hpp | 7 +++ hecl/include/hecl/Backend/GLSL.hpp | 10 +-- hecl/include/hecl/Backend/HLSL.hpp | 11 ++-- hecl/include/hecl/Backend/Metal.hpp | 8 ++- hecl/include/hecl/Runtime.hpp | 17 ++++-- hecl/lib/Backend/GLSL.cpp | 86 ++++++++++++++++++++------ hecl/lib/Backend/HLSL.cpp | 82 ++++++++++++++++++++----- hecl/lib/Backend/Metal.cpp | 87 +++++++++++++++++++-------- hecl/test/main.cpp | 3 +- 10 files changed, 251 insertions(+), 76 deletions(-) diff --git a/hecl/blender/hecl/hmdl/HMDLShader.py b/hecl/blender/hecl/hmdl/HMDLShader.py index 5c53a3764..d47557052 100644 --- a/hecl/blender/hecl/hmdl/HMDLShader.py +++ b/hecl/blender/hecl/hmdl/HMDLShader.py @@ -325,6 +325,17 @@ def recursive_alpha_trace(mat_obj, mesh_obj, tex_list, node, socket=None): raise RuntimeError("HMDL is unable to process '{0}' shader nodes in '{1}'".format(node.type, mat_obj.name)) +# Trace indirect node structure +def indirect_trace(mat_obj, mesh_obj, tex_list, node): + if node.type == 'OUTPUT': + if node.inputs['Color'].is_linked: + tex_node = node.inputs['Color'].links[0].from_node + if tex_node.type != 'TEXTURE': + raise RuntimeError("HMDL *requires* that an indirect output node is directly connected to TEXTURE") + if not tex_node.texture or not hasattr(tex_node.texture, 'name'): + raise RuntimeError("HMDL texture nodes must specify a texture object") + get_texmap_idx(tex_list, tex_node.texture.name) + def shader(mat_obj, mesh_obj): @@ -342,6 +353,11 @@ def shader(mat_obj, mesh_obj): color_trace_result = recursive_color_trace(mat_obj, mesh_obj, tex_list, output_node) alpha_trace_result = recursive_alpha_trace(mat_obj, mesh_obj, tex_list, output_node) + # Trace indirect reflection texture + if 'IndirectOutput' in mat_obj.node_tree.nodes: + ind_out_node = mat_obj.node_tree.nodes['IndirectOutput'] + indirect_trace(mat_obj, mesh_obj, tex_list, ind_out_node) + # Resolve texture paths tex_paths = [get_texture_path(name) for name in tex_list] diff --git a/hecl/include/hecl/Backend/Backend.hpp b/hecl/include/hecl/Backend/Backend.hpp index fddcb816e..e31abafc6 100644 --- a/hecl/include/hecl/Backend/Backend.hpp +++ b/hecl/include/hecl/Backend/Backend.hpp @@ -55,6 +55,13 @@ struct TextureInfo bool normalize; }; +enum class ReflectionType +{ + None, + Simple, + Indirect +}; + class IBackend { public: diff --git a/hecl/include/hecl/Backend/GLSL.hpp b/hecl/include/hecl/Backend/GLSL.hpp index 09fe9d4bc..9b52d5b69 100644 --- a/hecl/include/hecl/Backend/GLSL.hpp +++ b/hecl/include/hecl/Backend/GLSL.hpp @@ -16,19 +16,21 @@ struct GLSL : ProgrammableCommon void reset(const IR& ir, Diagnostics& diag); std::string makeVert(const char* glslVer, unsigned col, unsigned uv, unsigned w, unsigned skinSlots, unsigned texMtxs, size_t extTexCount, - const TextureInfo* extTexs) const; - std::string makeFrag(const char* glslVer, bool alphaTest, + const TextureInfo* extTexs, ReflectionType reflectionType) const; + std::string makeFrag(const char* glslVer, bool alphaTest, ReflectionType reflectionType, const ShaderFunction& lighting=ShaderFunction()) const; std::string makeFrag(const char* glslVer, bool alphaTest, + ReflectionType reflectionType, const ShaderFunction& lighting, const ShaderFunction& post, size_t extTexCount, const TextureInfo* extTexs) const; private: std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const; - std::string GenerateVertToFragStruct(size_t extTexCount) const; - std::string GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const; + std::string GenerateVertToFragStruct(size_t extTexCount, bool reflectionCoords) const; + std::string GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs, bool reflectionCoords) const; std::string GenerateAlphaTest() const; + std::string GenerateReflectionExpr(ReflectionType type) const; std::string EmitVec3(const atVec4f& vec) const { diff --git a/hecl/include/hecl/Backend/HLSL.hpp b/hecl/include/hecl/Backend/HLSL.hpp index 0a150f671..a8faf75c1 100644 --- a/hecl/include/hecl/Backend/HLSL.hpp +++ b/hecl/include/hecl/Backend/HLSL.hpp @@ -13,17 +13,20 @@ struct HLSL : ProgrammableCommon void reset(const IR& ir, Diagnostics& diag); std::string makeVert(unsigned col, unsigned uv, unsigned w, unsigned skinSlots, unsigned texMtxs, size_t extTexCount, - const TextureInfo* extTexs) const; - std::string makeFrag(bool alphaTest, const ShaderFunction& lighting=ShaderFunction()) const; + const TextureInfo* extTexs, ReflectionType reflectionType) const; + std::string makeFrag(bool alphaTest, ReflectionType reflectionType, + const ShaderFunction& lighting=ShaderFunction()) const; std::string makeFrag(bool alphaTest, const ShaderFunction& lighting, + ReflectionType reflectionType, const ShaderFunction& post, size_t extTexCount, const TextureInfo* extTexs) const; private: std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const; - std::string GenerateVertToFragStruct(size_t extTexCount) const; - std::string GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const; + std::string GenerateVertToFragStruct(size_t extTexCount, ReflectionType reflectionType) const; + std::string GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs, ReflectionType reflectionType) const; std::string GenerateAlphaTest() const; + std::string GenerateReflectionExpr(ReflectionType type) const; std::string EmitVec3(const atVec4f& vec) const { diff --git a/hecl/include/hecl/Backend/Metal.hpp b/hecl/include/hecl/Backend/Metal.hpp index 97969e4fb..785215fd1 100644 --- a/hecl/include/hecl/Backend/Metal.hpp +++ b/hecl/include/hecl/Backend/Metal.hpp @@ -15,20 +15,22 @@ struct Metal : ProgrammableCommon void reset(const IR& ir, Diagnostics& diag); std::string makeVert(unsigned col, unsigned uv, unsigned w, unsigned skinSlots, unsigned texMtxs, size_t extTexCount, - const TextureInfo* extTexs) const; + const TextureInfo* extTexs, ReflectionType reflectionType) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, + ReflectionType reflectionType, const ShaderFunction& lighting=ShaderFunction()) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, - const ShaderFunction& lighting, + ReflectionType reflectionType, const ShaderFunction& lighting, const ShaderFunction& post, size_t extTexCount, const TextureInfo* extTexs) const; private: std::string GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) const; - std::string GenerateVertToFragStruct(size_t extTexCount) const; + std::string GenerateVertToFragStruct(size_t extTexCount, bool reflectionCoords) const; std::string GenerateVertUniformStruct(unsigned skinSlots) const; std::string GenerateFragOutStruct() const; std::string GenerateAlphaTest() const; + std::string GenerateReflectionExpr(ReflectionType type) const; std::string EmitVec3(const atVec4f& vec) const { diff --git a/hecl/include/hecl/Runtime.hpp b/hecl/include/hecl/Runtime.hpp index d034eb0f7..eac15de9a 100644 --- a/hecl/include/hecl/Runtime.hpp +++ b/hecl/include/hecl/Runtime.hpp @@ -49,6 +49,7 @@ class ShaderTag : public Hash uint8_t m_skinSlotCount; uint8_t m_texMtxCount; uint8_t m_primitiveType; + uint8_t m_reflectionType; bool m_depthTest:1; bool m_depthWrite:1; bool m_backfaceCulling:1; @@ -57,19 +58,22 @@ class ShaderTag : public Hash public: ShaderTag() = default; ShaderTag(const std::string& source, uint8_t c, uint8_t u, uint8_t w, uint8_t s, uint8_t t, boo::Primitive pt, - bool depthTest, bool depthWrite, bool backfaceCulling) + Backend::ReflectionType reflectionType, bool depthTest, bool depthWrite, bool backfaceCulling) : Hash(source), m_colorCount(c), m_uvCount(u), m_weightCount(w), m_skinSlotCount(s), m_texMtxCount(t), - m_primitiveType(uint8_t(pt)), m_depthTest(depthTest), m_depthWrite(depthWrite), m_backfaceCulling(backfaceCulling) + m_primitiveType(uint8_t(pt)), m_reflectionType(uint8_t(reflectionType)), + m_depthTest(depthTest), m_depthWrite(depthWrite), m_backfaceCulling(backfaceCulling) {hash ^= m_meta;} ShaderTag(const hecl::Frontend::IR& ir, uint8_t c, uint8_t u, uint8_t w, uint8_t s, uint8_t t, boo::Primitive pt, - bool depthTest, bool depthWrite, bool backfaceCulling) + Backend::ReflectionType reflectionType, bool depthTest, bool depthWrite, bool backfaceCulling) : Hash(ir.m_hash), m_colorCount(c), m_uvCount(u), m_weightCount(w), m_skinSlotCount(s), m_texMtxCount(t), - m_primitiveType(uint8_t(pt)), m_depthTest(depthTest), m_depthWrite(depthWrite), m_backfaceCulling(backfaceCulling) + m_primitiveType(uint8_t(pt)), m_reflectionType(uint8_t(reflectionType)), + m_depthTest(depthTest), m_depthWrite(depthWrite), m_backfaceCulling(backfaceCulling) {hash ^= m_meta;} ShaderTag(uint64_t hashin, uint8_t c, uint8_t u, uint8_t w, uint8_t s, uint8_t t, boo::Primitive pt, - bool depthTest, bool depthWrite, bool backfaceCulling) + Backend::ReflectionType reflectionType, bool depthTest, bool depthWrite, bool backfaceCulling) : Hash(hashin), m_colorCount(c), m_uvCount(u), m_weightCount(w), m_skinSlotCount(s), m_texMtxCount(t), - m_primitiveType(uint8_t(pt)), m_depthTest(depthTest), m_depthWrite(depthWrite), m_backfaceCulling(backfaceCulling) + m_primitiveType(uint8_t(pt)), m_reflectionType(uint8_t(reflectionType)), + m_depthTest(depthTest), m_depthWrite(depthWrite), m_backfaceCulling(backfaceCulling) {hash ^= m_meta;} ShaderTag(uint64_t comphashin, uint64_t meta) : Hash(comphashin), m_meta(meta) {} @@ -80,6 +84,7 @@ public: uint8_t getSkinSlotCount() const {return m_skinSlotCount;} uint8_t getTexMtxCount() const {return m_texMtxCount;} boo::Primitive getPrimType() const {return boo::Primitive(m_primitiveType);} + Backend::ReflectionType getReflectionType() const {return Backend::ReflectionType(m_reflectionType);} bool getDepthTest() const {return m_depthTest;} bool getDepthWrite() const {return m_depthWrite;} bool getBackfaceCulling() const {return m_backfaceCulling;} diff --git a/hecl/lib/Backend/GLSL.cpp b/hecl/lib/Backend/GLSL.cpp index 6883b875e..adcf17811 100644 --- a/hecl/lib/Backend/GLSL.cpp +++ b/hecl/lib/Backend/GLSL.cpp @@ -69,7 +69,7 @@ std::string GLSL::GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) co return retval; } -std::string GLSL::GenerateVertToFragStruct(size_t extTexCount) const +std::string GLSL::GenerateVertToFragStruct(size_t extTexCount, bool reflectionCoords) const { std::string retval = "struct VertToFrag\n" @@ -82,10 +82,14 @@ std::string GLSL::GenerateVertToFragStruct(size_t extTexCount) const if (extTexCount) retval += hecl::Format(" vec2 extTcgs[%u];\n", unsigned(extTexCount)); + if (reflectionCoords) + retval += " vec2 reflectTcgs[2];\n" + " float reflectAlpha;\n"; + return retval + "};\n"; } -std::string GLSL::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const +std::string GLSL::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs, bool reflectionCoords) const { if (skinSlots == 0) skinSlots = 1; @@ -97,7 +101,6 @@ std::string GLSL::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs "};\n", skinSlots, skinSlots); if (texMtxs) - { retval += hecl::Format("struct HECLTCGMatrix\n" "{\n" " mat4 mtx;\n" @@ -107,7 +110,15 @@ std::string GLSL::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs "{\n" " HECLTCGMatrix texMtxs[%u];\n" "};\n", texMtxs); - } + + if (reflectionCoords) + retval += "UBINDING3 uniform HECLReflectMtx\n" + "{\n" + " mat4 indMtx;\n" + " mat4 reflectMtx;\n" + " float reflectAlpha;\n" + "};\n" + "\n"; return retval; } @@ -120,6 +131,20 @@ std::string GLSL::GenerateAlphaTest() const " }\n"; } +std::string GLSL::GenerateReflectionExpr(ReflectionType type) const +{ + switch (type) + { + case ReflectionType::None: + return "vec3(0.0, 0.0, 0.0);\n"; + case ReflectionType::Simple: + return "texture(reflectionTex, vtf.reflectTcgs[1]).rgb * vtf.reflectAlpha;\n"; + case ReflectionType::Indirect: + return "texture(reflectionTex, (texture(reflectionIndTex, vtf.reflectTcgs[0]).rg - " + "vec2(0.5, 0.5)) * vec2(0.5, 0.5) + vtf.reflectTcgs[1]).rgb * vtf.reflectAlpha;\n"; + } +} + void GLSL::reset(const IR& ir, Diagnostics& diag) { /* Common programmable interpretation */ @@ -128,13 +153,13 @@ void GLSL::reset(const IR& ir, Diagnostics& diag) std::string GLSL::makeVert(const char* glslVer, unsigned col, unsigned uv, unsigned w, unsigned s, unsigned tm, size_t extTexCount, - const TextureInfo* extTexs) const + const TextureInfo* extTexs, ReflectionType reflectionType) const { extTexCount = std::min(int(extTexCount), BOO_GLSL_MAX_TEXTURE_COUNT - int(m_tcgs.size())); std::string retval = std::string(glslVer) + "\n" BOO_GLSL_BINDING_HEAD + GenerateVertInStruct(col, uv, w) + "\n" + - GenerateVertToFragStruct(extTexCount) + "\n" + - GenerateVertUniformStruct(s, tm) + + GenerateVertToFragStruct(extTexCount, reflectionType != ReflectionType::None) + "\n" + + GenerateVertUniformStruct(s, tm, reflectionType != ReflectionType::None) + "SBINDING(0) out VertToFrag vtf;\n\n" "void main()\n{\n"; @@ -185,11 +210,16 @@ std::string GLSL::makeVert(const char* glslVer, unsigned col, unsigned uv, unsig extTex.mtxIdx, EmitTexGenSource4(extTex.src, extTex.uvIdx).c_str()); } + if (reflectionType != ReflectionType::None) + retval += " vtf.reflectTcgs[0] = normalize((indMtx * vec4(v.posIn, 1.0)).xz) * vec2(0.5, 0.5) + vec2(0.5, 0.5);\n" + " vtf.reflectTcgs[1] = (reflectMtx * vec4(v.posIn, 1.0)).xy;\n" + " vtf.reflectAlpha = reflectAlpha;\n"; + return retval + "}\n"; } std::string GLSL::makeFrag(const char* glslVer, bool alphaTest, - const ShaderFunction& lighting) const + ReflectionType reflectionType, const ShaderFunction& lighting) const { std::string lightingSrc; if (lighting.m_source) @@ -204,10 +234,17 @@ std::string GLSL::makeFrag(const char* glslVer, bool alphaTest, std::string texMapDecl; for (unsigned i=0 ; i 8) @@ -437,10 +487,10 @@ struct GLSLBackendFactory : IShaderBackendFactory sources.emplace_back(m_backend.makeVert("#version 330", tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), tag.getSkinSlotCount(), tag.getTexMtxCount(), slot.texCount, - slot.texs), + slot.texs, tag.getReflectionType()), m_backend.makeFrag("#version 330", tag.getDepthWrite() && m_backend.m_blendDst == hecl::Backend::BlendFactor::InvSrcAlpha, - slot.lighting, slot.post, slot.texCount, slot.texs)); + tag.getReflectionType(), slot.lighting, slot.post, slot.texCount, slot.texs)); cachedSz += sources.back().first.size() + 1; cachedSz += sources.back().second.size() + 1; diff --git a/hecl/lib/Backend/HLSL.cpp b/hecl/lib/Backend/HLSL.cpp index 8842fc5ab..d121d4183 100644 --- a/hecl/lib/Backend/HLSL.cpp +++ b/hecl/lib/Backend/HLSL.cpp @@ -61,7 +61,7 @@ std::string HLSL::GenerateVertInStruct(unsigned col, unsigned uv, unsigned w) co return retval + "};\n"; } -std::string HLSL::GenerateVertToFragStruct(size_t extTexCount) const +std::string HLSL::GenerateVertToFragStruct(size_t extTexCount, ReflectionType reflectionType) const { std::string retval = "struct VertToFrag\n" @@ -75,10 +75,14 @@ std::string HLSL::GenerateVertToFragStruct(size_t extTexCount) const if (extTexCount) retval += hecl::Format(" float2 extTcgs[%u] : EXTUV;\n", unsigned(extTexCount)); + if (reflectionCoords) + retval += " float2 reflectTcgs[2] : REFLECTUV;\n" + " float reflectAlpha;\n"; + return retval + "};\n"; } -std::string HLSL::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs) const +std::string HLSL::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs, ReflectionType reflectionType) const { if (skinSlots == 0) skinSlots = 1; @@ -90,7 +94,6 @@ std::string HLSL::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs "};\n", skinSlots, skinSlots); if (texMtxs) - { retval += hecl::Format("struct TCGMtx\n" "{\n" " float4x4 mtx;\n" @@ -100,7 +103,16 @@ std::string HLSL::GenerateVertUniformStruct(unsigned skinSlots, unsigned texMtxs "{\n" " TCGMtx texMtxs[%u];\n" "};\n", texMtxs); - } + + if (reflectionCoords) + retval += "cbuffer HECLReflectMtx : register(b3)\n" + "{\n" + " float4x4 indMtx;\n" + " float4x4 reflectMtx;\n" + " float reflectAlpha;\n" + "};\n" + "\n"; + return retval; } @@ -112,6 +124,20 @@ std::string HLSL::GenerateAlphaTest() const " }\n"; } +std::string HLSL::GenerateReflectionExpr(ReflectionType type) const +{ + switch (type) + { + case ReflectionType::None: + return "float3(0.0, 0.0, 0.0);\n"; + case ReflectionType::Simple: + return "reflectionTex.Sample(samp, vtf.reflectTcgs[1]).rgb * vtf.reflectAlpha;\n"; + case ReflectionType::Indirect: + return "reflectionTex.Sample(samp, (reflectionIndTex.Sample(samp, vtf.reflectTcgs[0]).rg - " + "float2(0.5, 0.5)) * float2(0.5, 0.5) + vtf.reflectTcgs[1]).rgb * vtf.reflectAlpha;\n"; + } +} + void HLSL::reset(const IR& ir, Diagnostics& diag) { /* Common programmable interpretation */ @@ -120,12 +146,12 @@ void HLSL::reset(const IR& ir, Diagnostics& diag) std::string HLSL::makeVert(unsigned col, unsigned uv, unsigned w, unsigned s, unsigned tm, size_t extTexCount, - const TextureInfo* extTexs) const + const TextureInfo* extTexs, ReflectionType reflectionType) const { std::string retval = GenerateVertInStruct(col, uv, w) + "\n" + - GenerateVertToFragStruct(extTexCount) + "\n" + - GenerateVertUniformStruct(s, tm) + "\n" + + GenerateVertToFragStruct(extTexCount, reflectionType != ReflectionType::None) + "\n" + + GenerateVertUniformStruct(s, tm, reflectionType != ReflectionType::None) + "\n" + "VertToFrag main(in VertData v)\n" "{\n" " VertToFrag vtf;\n"; @@ -176,11 +202,17 @@ std::string HLSL::makeVert(unsigned col, unsigned uv, unsigned w, extTex.mtxIdx, EmitTexGenSource4(extTex.src, extTex.uvIdx).c_str()); } + if (reflectionCoords) + retval += " vtf.reflectTcgs[0] = normalize(mul(indMtx, float4(v.posIn, 1.0)).xz) * float2(0.5, 0.5) + float2(0.5, 0.5);\n" + " vtf.reflectTcgs[1] = mul(reflectMtx, float4(v.posIn, 1.0)).xy;\n" + " vtf.reflectAlpha = reflectAlpha;\n"; + return retval + " return vtf;\n" "}\n"; } -std::string HLSL::makeFrag(bool alphaTest, const ShaderFunction& lighting) const +std::string HLSL::makeFrag(bool alphaTest, ReflectionType reflectionType, + const ShaderFunction& lighting) const { std::string lightingSrc; if (lighting.m_source) @@ -194,10 +226,16 @@ std::string HLSL::makeFrag(bool alphaTest, const ShaderFunction& lighting) const std::string texMapDecl; if (m_texMapEnd) texMapDecl = hecl::Format("Texture2D texs[%u] : register(t0);\n", m_texMapEnd); - + if (reflectionType == ReflectionType::Indirect) + texMapDecl += hecl::Format("Texture2D reflectionIndTex : register(t%u);\n" + "Texture2D reflectionTex : register(t%u);\n", + m_texMapEnd, m_texMapEnd+1); + else if (reflectionType == ReflectionType::Simple) + texMapDecl += hecl::Format("Texture2D reflectionTex : register(t%u);\n", + m_texMapEnd); std::string retval = "SamplerState samp : register(s0);\n" + - GenerateVertToFragStruct(0) + + GenerateVertToFragStruct(0, reflectionType != ReflectionType::None) + texMapDecl + "\n" + lightingSrc + "\n" + (!alphaTest ? "\n[earlydepthstencil]\n" : "\n") + @@ -217,16 +255,19 @@ std::string HLSL::makeFrag(bool alphaTest, const ShaderFunction& lighting) const retval += hecl::Format(" float4 sampling%u = texs[%u].Sample(samp, vtf.tcgs[%u]);\n", sampIdx++, sampling.mapIdx, sampling.tcgIdx); + std::string reflectionExpr = GenerateReflectionExpr(reflectionType); + retval += " float4 colorOut;\n"; if (m_alphaExpr.size()) - retval += " colorOut = float4(" + m_colorExpr + ", " + m_alphaExpr + ") * mulColor;\n"; + retval += " colorOut = float4(" + m_colorExpr + " + " + reflectionExpr + ", " + m_alphaExpr + ") * mulColor;\n"; else - retval += " colorOut = float4(" + m_colorExpr + ", 1.0) * mulColor;\n"; + retval += " colorOut = float4(" + m_colorExpr + " + " + reflectionExpr + ", 1.0) * mulColor;\n"; return retval + (alphaTest ? GenerateAlphaTest() : "") + " return colorOut;\n}\n"; } -std::string HLSL::makeFrag(bool alphaTest, const ShaderFunction& lighting, +std::string HLSL::makeFrag(bool alphaTest, ReflectionType reflectionType, + const ShaderFunction& lighting, const ShaderFunction& post, size_t extTexCount, const TextureInfo* extTexs) const { @@ -250,6 +291,13 @@ std::string HLSL::makeFrag(bool alphaTest, const ShaderFunction& lighting, std::string texMapDecl; if (m_texMapEnd) texMapDecl = hecl::Format("Texture2D texs[%u] : register(t0);\n", m_texMapEnd); + if (reflectionType == ReflectionType::Indirect) + texMapDecl += hecl::Format("Texture2D reflectionIndTex : register(t%u);\n" + "Texture2D reflectionTex : register(t%u);\n", + m_texMapEnd, m_texMapEnd+1); + else if (reflectionType == ReflectionType::Simple) + texMapDecl += hecl::Format("Texture2D reflectionTex : register(t%u);\n", + m_texMapEnd); for (int i=0 ; i tex%u [[ texture(%u) ]]", i, i); - } + if (reflectionType == ReflectionType::Indirect) + texMapDecl += hecl::Format(",\ntexture2d reflectionIndTex [[ texture(%u) ]]\n" + ",\ntexture2d reflectionTex [[ texture(%u) ]]\n", + m_texMapEnd, m_texMapEnd+1); + else if (reflectionType == ReflectionType::Simple) + texMapDecl += hecl::Format(",\ntexture2d reflectionTex [[ texture(%u) ]]\n", + m_texMapEnd); std::string blockCall; for (size_t i=0 ; i tex%u [[ texture(%u) ]]", i, i); - } + if (reflectionType == ReflectionType::Indirect) + texMapDecl += hecl::Format(",\ntexture2d reflectionIndTex [[ texture(%u) ]]\n" + ",\ntexture2d reflectionTex [[ texture(%u) ]]\n", + m_texMapEnd, m_texMapEnd+1); + else if (reflectionType == ReflectionType::Simple) + texMapDecl += hecl::Format(",\ntexture2d reflectionTex [[ texture(%u) ]]\n", + m_texMapEnd); std::string extTexCall; for (int i=0 ; i(ctx). @@ -470,10 +508,11 @@ struct MetalBackendFactory : IShaderBackendFactory for (const ShaderCacheExtensions::ExtensionSlot& slot : extensionSlots) { sources.emplace_back(m_backend.makeVert(tag.getColorCount(), tag.getUvCount(), tag.getWeightCount(), - tag.getSkinSlotCount(), tag.getTexMtxCount(), slot.texCount, slot.texs), + tag.getSkinSlotCount(), tag.getTexMtxCount(), slot.texCount, slot.texs, + tag.getReflectionType()), m_backend.makeFrag(slot.blockCount, slot.blockNames, tag.getDepthWrite() && m_backend.m_blendDst == hecl::Backend::BlendFactor::InvSrcAlpha, - slot.lighting, slot.post, slot.texCount, slot.texs)); + tag.getReflectionType(), slot.lighting, slot.post, slot.texCount, slot.texs)); cachedSz += sources.back().first.size() + 1; cachedSz += sources.back().second.size() + 1; diff --git a/hecl/test/main.cpp b/hecl/test/main.cpp index c6a12ed97..2f5d5d892 100644 --- a/hecl/test/main.cpp +++ b/hecl/test/main.cpp @@ -89,7 +89,8 @@ struct HECLApplicationCallback : boo::IApplicationCallback /* Compile HECL shader */ static std::string testShader = "HECLOpaque(Texture(0, UV(0)))"; //static std::string testShader = "HECLOpaque(vec4(1.0,1.0,1.0,1.0))"; - hecl::Runtime::ShaderTag testShaderTag(testShader, 0, 1, 0, 0, 0, boo::Primitive::TriStrips, false, false, false); + hecl::Runtime::ShaderTag testShaderTag(testShader, 0, 1, 0, 0, 0, boo::Primitive::TriStrips, + hecl::Backend::ReflectionType::None, false, false, false); std::shared_ptr testShaderObj = shaderMgr.buildShader(testShaderTag, testShader, "testShader", *gfxF);