diff options
| author | Tilka <tilkax@gmail.com> | 2024-10-12 19:49:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-12 19:49:48 +0100 |
| commit | d43c6dc555fea0b0ec84d05779a62dc876b70bf4 (patch) | |
| tree | f7e24ca237cdda8cde7e611ee52806fdea96292a /Source/Core | |
| parent | 35ec2e97a8ea90730cb33eceec701f81597f98f7 (diff) | |
| parent | 937bb2aa2e12b635ba328af8de7c9a5d5963d084 (diff) | |
Merge pull request #13074 from Pokechu22/normal-cache
Cache normals in addition to binormals and tangents
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/State.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/SWVertexLoader.cpp | 12 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/ConstantManager.h | 1 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/ShaderGenCommon.h | 2 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/UberShaderVertex.cpp | 42 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderARM64.cpp | 7 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderBase.cpp | 10 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderManager.cpp | 1 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderManager.h | 4 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderX64.cpp | 8 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoader_Normal.cpp | 4 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexManagerBase.cpp | 15 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexManagerBase.h | 2 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VertexShaderGen.cpp | 67 |
14 files changed, 111 insertions, 66 deletions
diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index fe20d74ea4..f9964c0fa8 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -98,7 +98,7 @@ static size_t s_state_writes_in_queue; static std::condition_variable s_state_write_queue_is_empty; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 168; // Last changed in PR 12639 +constexpr u32 STATE_VERSION = 169; // Last changed in PR 13074 // Increase this if the StateExtendedHeader definition changes constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217 diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp index cfb05d096b..2e6e748a38 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp @@ -81,9 +81,7 @@ void SWVertexLoader::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_ // transform this vertex so that it can be used for rasterization (outVertex) OutputVertexData* outVertex = m_setup_unit.GetVertex(); TransformUnit::TransformPosition(&m_vertex, outVertex); - outVertex->normal = {}; - if (VertexLoaderManager::g_current_components & VB_HAS_NORMAL) - TransformUnit::TransformNormal(&m_vertex, outVertex); + TransformUnit::TransformNormal(&m_vertex, outVertex); TransformUnit::TransformColor(&m_vertex, outVertex); TransformUnit::TransformTexCoord(&m_vertex, outVertex); @@ -209,6 +207,14 @@ void SWVertexLoader::ParseVertex(const PortableVertexDeclaration& vdec, int inde { ReadVertexAttribute<float>(&m_vertex.normal[i][0], src, vdec.normals[i], 0, 3, false); } + if (!vdec.normals[0].enable) + { + auto& system = Core::System::GetInstance(); + auto& vertex_shader_manager = system.GetVertexShaderManager(); + m_vertex.normal[0][0] = vertex_shader_manager.constants.cached_normal[0]; + m_vertex.normal[0][1] = vertex_shader_manager.constants.cached_normal[1]; + m_vertex.normal[0][2] = vertex_shader_manager.constants.cached_normal[2]; + } if (!vdec.normals[1].enable) { auto& system = Core::System::GetInstance(); diff --git a/Source/Core/VideoCommon/ConstantManager.h b/Source/Core/VideoCommon/ConstantManager.h index b8c65aaefb..14c8732580 100644 --- a/Source/Core/VideoCommon/ConstantManager.h +++ b/Source/Core/VideoCommon/ConstantManager.h @@ -93,6 +93,7 @@ struct alignas(16) VertexShaderConstants // .x - texMtxInfo, .y - postMtxInfo, [0..1].z = color, [0..1].w = alpha std::array<uint4, 8> xfmem_pack1; + float4 cached_normal; float4 cached_tangent; float4 cached_binormal; // For UberShader vertex loader diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index 6ec00331e6..4723cbfc79 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -283,6 +283,7 @@ void WriteSwitch(ShaderCode& out, APIType ApiType, std::string_view variable, #define I_POSTTRANSFORMMATRICES "cpostmtx" #define I_PIXELCENTERCORRECTION "cpixelcenter" #define I_VIEWPORT_SIZE "cviewport" +#define I_CACHED_NORMAL "cnormal" #define I_CACHED_TANGENT "ctangent" #define I_CACHED_BINORMAL "cbinormal" @@ -306,6 +307,7 @@ static const char s_shader_uniforms[] = "\tuint components;\n" "\tfloat4 " I_PIXELCENTERCORRECTION ";\n" "\tfloat2 " I_VIEWPORT_SIZE ";\n" "\tuint4 xfmem_pack1[8];\n" + "\tfloat4 " I_CACHED_NORMAL ";\n" "\tfloat4 " I_CACHED_TANGENT ";\n" "\tfloat4 " I_CACHED_BINORMAL ";\n" "\tuint vertex_stride;\n" diff --git a/Source/Core/VideoCommon/UberShaderVertex.cpp b/Source/Core/VideoCommon/UberShaderVertex.cpp index eceda62e48..a6c0502dfe 100644 --- a/Source/Core/VideoCommon/UberShaderVertex.cpp +++ b/Source/Core/VideoCommon/UberShaderVertex.cpp @@ -251,47 +251,53 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{ "o.pos = float4(dot(" I_PROJECTION "[0], pos), dot(" I_PROJECTION "[1], pos), dot(" I_PROJECTION "[2], pos), dot(" I_PROJECTION "[3], pos));\n" "\n" - "// The scale of the transform matrix is used to control the size of the emboss map\n" - "// effect by changing the scale of the transformed binormals (which only get used by\n" - "// emboss map texgens). By normalising the first transformed normal (which is used\n" - "// by lighting calculations and needs to be unit length), the same transform matrix\n" - "// can do double duty, scaling for emboss mapping, and not scaling for lighting.\n" - "float3 _normal = float3(0.0, 0.0, 0.0);\n" + "float3 _rawnormal;\n" + "float3 _rawtangent;\n" + "float3 _rawbinormal;\n" "if ((components & {}u) != 0u) // VB_HAS_NORMAL\n" "{{\n", Common::ToUnderlying(VB_HAS_NORMAL)); LoadVertexAttribute(out, host_config, 2, "rawnormal", "float3", "float3"); - out.Write(" _normal = normalize(float3(dot(N0, rawnormal), dot(N1, rawnormal), dot(N2, " - "rawnormal)));\n" + out.Write(" _rawnormal = rawnormal;\n" + "}}\n" + "else\n" + "{{\n" + " _rawnormal = " I_CACHED_NORMAL ".xyz;\n" "}}\n" "\n" - "float3 _tangent = float3(0.0, 0.0, 0.0);\n" "if ((components & {}u) != 0u) // VB_HAS_TANGENT\n" "{{\n", Common::ToUnderlying(VB_HAS_TANGENT)); LoadVertexAttribute(out, host_config, 2, "rawtangent", "float3", "float3"); - out.Write(" _tangent = float3(dot(N0, rawtangent), dot(N1, rawtangent), dot(N2, rawtangent));\n" + out.Write(" _rawtangent = rawtangent;\n" "}}\n" "else\n" "{{\n" - " _tangent = float3(dot(N0, " I_CACHED_TANGENT ".xyz), dot(N1, " I_CACHED_TANGENT - ".xyz), dot(N2, " I_CACHED_TANGENT ".xyz));\n" + " _rawtangent = " I_CACHED_TANGENT ".xyz;\n" "}}\n" "\n" - "float3 _binormal = float3(0.0, 0.0, 0.0);\n" "if ((components & {}u) != 0u) // VB_HAS_BINORMAL\n" "{{\n", Common::ToUnderlying(VB_HAS_BINORMAL)); LoadVertexAttribute(out, host_config, 2, "rawbinormal", "float3", "float3"); - out.Write(" _binormal = float3(dot(N0, rawbinormal), dot(N1, rawbinormal), dot(N2, " - "rawbinormal));\n" + out.Write(" _rawbinormal = rawbinormal;\n" "}}\n" "else\n" "{{\n" - " _binormal = float3(dot(N0, " I_CACHED_BINORMAL ".xyz), dot(N1, " I_CACHED_BINORMAL - ".xyz), dot(N2, " I_CACHED_BINORMAL ".xyz));\n" + " _rawbinormal = " I_CACHED_BINORMAL ".xyz;\n" "}}\n" - "\n"); + "\n" + "// The scale of the transform matrix is used to control the size of the emboss map\n" + "// effect by changing the scale of the transformed binormals (which only get used by\n" + "// emboss map texgens). By normalising the first transformed normal (which is used\n" + "// by lighting calculations and needs to be unit length), the same transform matrix\n" + "// can do double duty, scaling for emboss mapping, and not scaling for lighting.\n" + "float3 _normal = normalize(float3(dot(N0, _rawnormal), dot(N1, _rawnormal), dot(N2, " + "_rawnormal)));\n" + "float3 _tangent = float3(dot(N0, _rawtangent), dot(N1, _rawtangent), dot(N2, " + "_rawtangent));\n" + "float3 _binormal = float3(dot(N0, _rawbinormal), dot(N1, _rawbinormal), dot(N2, " + "_rawbinormal));\n"); // Hardware Lighting out.Write("// xfmem.numColorChans controls the number of color channels available to TEV,\n" diff --git a/Source/Core/VideoCommon/VertexLoaderARM64.cpp b/Source/Core/VideoCommon/VertexLoaderARM64.cpp index 9fd8c0c29c..9e0075f9a2 100644 --- a/Source/Core/VideoCommon/VertexLoaderARM64.cpp +++ b/Source/Core/VideoCommon/VertexLoaderARM64.cpp @@ -164,6 +164,13 @@ void VertexLoaderARM64::ReadVertex(VertexComponentFormat attribute, ComponentFor m_float_emit.STR(128, coords, EncodeRegTo64(scratch2_reg), ArithOption(remaining_reg, true)); SetJumpTarget(dont_store); } + else if (native_format == &m_native_vtx_decl.normals[0]) + { + FixupBranch dont_store = CBNZ(remaining_reg); + MOVP2R(EncodeRegTo64(scratch2_reg), VertexLoaderManager::normal_cache.data()); + m_float_emit.STR(128, IndexType::Unsigned, coords, EncodeRegTo64(scratch2_reg), 0); + SetJumpTarget(dont_store); + } else if (native_format == &m_native_vtx_decl.normals[1]) { FixupBranch dont_store = CBNZ(remaining_reg); diff --git a/Source/Core/VideoCommon/VertexLoaderBase.cpp b/Source/Core/VideoCommon/VertexLoaderBase.cpp index 3284a2ccdb..a3597b53e5 100644 --- a/Source/Core/VideoCommon/VertexLoaderBase.cpp +++ b/Source/Core/VideoCommon/VertexLoaderBase.cpp @@ -68,6 +68,7 @@ public: VertexLoaderManager::position_matrix_index_cache; const std::array<std::array<float, 4>, 3> old_position_cache = VertexLoaderManager::position_cache; + const std::array<float, 4> old_normal_cache = VertexLoaderManager::normal_cache; const std::array<float, 4> old_tangent_cache = VertexLoaderManager::tangent_cache; const std::array<float, 4> old_binormal_cache = VertexLoaderManager::binormal_cache; @@ -77,12 +78,14 @@ public: VertexLoaderManager::position_matrix_index_cache; const std::array<std::array<float, 4>, 3> a_position_cache = VertexLoaderManager::position_cache; + const std::array<float, 4> a_normal_cache = VertexLoaderManager::normal_cache; const std::array<float, 4> a_tangent_cache = VertexLoaderManager::tangent_cache; const std::array<float, 4> a_binormal_cache = VertexLoaderManager::binormal_cache; // Reset state before running b VertexLoaderManager::position_matrix_index_cache = old_position_matrix_index_cache; VertexLoaderManager::position_cache = old_position_cache; + VertexLoaderManager::normal_cache = old_normal_cache; VertexLoaderManager::tangent_cache = old_tangent_cache; VertexLoaderManager::binormal_cache = old_binormal_cache; @@ -92,6 +95,7 @@ public: VertexLoaderManager::position_matrix_index_cache; const std::array<std::array<float, 4>, 3> b_position_cache = VertexLoaderManager::position_cache; + const std::array<float, 4> b_normal_cache = VertexLoaderManager::normal_cache; const std::array<float, 4> b_tangent_cache = VertexLoaderManager::tangent_cache; const std::array<float, 4> b_binormal_cache = VertexLoaderManager::binormal_cache; @@ -141,6 +145,12 @@ public: // The last element is allowed to be garbage for SIMD overwrites ASSERT_MSG(VIDEO, + std::equal(a_normal_cache.begin(), a_normal_cache.begin() + 3, + b_normal_cache.begin(), b_normal_cache.begin() + 3, bit_equal), + "Expected matching normal caches after loading (a: {}; b: {})", + fmt::join(a_normal_cache, ", "), fmt::join(b_normal_cache, ", ")); + + ASSERT_MSG(VIDEO, std::equal(a_tangent_cache.begin(), a_tangent_cache.begin() + 3, b_tangent_cache.begin(), b_tangent_cache.begin() + 3, bit_equal), "Expected matching tangent caches after loading (a: {}; b: {})", diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index 0c48bf32a8..4ef11a1283 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -40,6 +40,7 @@ namespace VertexLoaderManager std::array<u32, 3> position_matrix_index_cache; // 3 vertices, 4 floats each to allow SIMD overwrite alignas(sizeof(std::array<float, 4>)) std::array<std::array<float, 4>, 3> position_cache; +alignas(sizeof(std::array<float, 4>)) std::array<float, 4> normal_cache; alignas(sizeof(std::array<float, 4>)) std::array<float, 4> tangent_cache; alignas(sizeof(std::array<float, 4>)) std::array<float, 4> binormal_cache; diff --git a/Source/Core/VideoCommon/VertexLoaderManager.h b/Source/Core/VideoCommon/VertexLoaderManager.h index ce8b6a22d1..0e1caa6fa1 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.h +++ b/Source/Core/VideoCommon/VertexLoaderManager.h @@ -62,6 +62,10 @@ void UpdateVertexArrayPointers(); // These arrays are in reverse order. extern std::array<std::array<float, 4>, 3> position_cache; extern std::array<u32, 3> position_matrix_index_cache; +// Needed for the game "LIT", which has text that has lighting enabled, but doesn't have normal +// vectors. The normals from the last drawn object are used instead. +// See https://bugs.dolphin-emu.org/issues/13635 +extern std::array<float, 4> normal_cache; // Store the tangent and binormal vectors for games that use emboss texgens when the vertex format // doesn't include them (e.g. RS2 and RS3). These too are 4 floats each for SIMD overwrites. extern std::array<float, 4> tangent_cache; diff --git a/Source/Core/VideoCommon/VertexLoaderX64.cpp b/Source/Core/VideoCommon/VertexLoaderX64.cpp index 9934570b55..aa8ad2bd67 100644 --- a/Source/Core/VideoCommon/VertexLoaderX64.cpp +++ b/Source/Core/VideoCommon/VertexLoaderX64.cpp @@ -137,6 +137,14 @@ void VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute, MOVUPS(MPIC(VertexLoaderManager::position_cache.data(), scratch3, SCALE_4), coords); SetJumpTarget(dont_store); } + else if (native_format == &m_native_vtx_decl.normals[0]) + { + TEST(32, R(remaining_reg), R(remaining_reg)); + FixupBranch dont_store = J_CC(CC_NZ); + // For similar reasons, the cached normal is 4 floats each + MOVUPS(MPIC(VertexLoaderManager::normal_cache.data()), coords); + SetJumpTarget(dont_store); + } else if (native_format == &m_native_vtx_decl.normals[1]) { TEST(32, R(remaining_reg), R(remaining_reg)); diff --git a/Source/Core/VideoCommon/VertexLoader_Normal.cpp b/Source/Core/VideoCommon/VertexLoader_Normal.cpp index b91c7fe127..50e0dbbd63 100644 --- a/Source/Core/VideoCommon/VertexLoader_Normal.cpp +++ b/Source/Core/VideoCommon/VertexLoader_Normal.cpp @@ -49,7 +49,9 @@ void ReadIndirect(VertexLoader* loader, const T* data) const float value = FracAdjust(Common::FromBigEndian(data[i])); if (loader->m_remaining == 0) { - if (i >= 3 && i < 6) + if (i < 3) + VertexLoaderManager::normal_cache[i] = value; + else if (i >= 3 && i < 6) VertexLoaderManager::tangent_cache[i - 3] = value; else if (i >= 6 && i < 9) VertexLoaderManager::binormal_cache[i - 6] = value; diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 02edb56d35..0e69c4fdd0 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -558,7 +558,7 @@ void VertexManagerBase::Flush() pixel_shader_manager.constants.time_ms = seconds_elapsed * 1000; } - CalculateBinormals(VertexLoaderManager::GetCurrentVertexFormat()); + CalculateNormals(VertexLoaderManager::GetCurrentVertexFormat()); // Calculate ZSlope for zfreeze const auto used_textures = UsedTextures(); std::vector<std::string> texture_names; @@ -699,6 +699,7 @@ void VertexManagerBase::DoState(PointerWrap& p) } p.Do(m_zslope); + p.Do(VertexLoaderManager::normal_cache); p.Do(VertexLoaderManager::tangent_cache); p.Do(VertexLoaderManager::binormal_cache); } @@ -769,7 +770,7 @@ void VertexManagerBase::CalculateZSlope(NativeVertexFormat* format) m_zslope.dirty = true; } -void VertexManagerBase::CalculateBinormals(NativeVertexFormat* format) +void VertexManagerBase::CalculateNormals(NativeVertexFormat* format) { const PortableVertexDeclaration vert_decl = format->GetVertexDeclaration(); @@ -794,6 +795,16 @@ void VertexManagerBase::CalculateBinormals(NativeVertexFormat* format) vertex_shader_manager.constants.cached_binormal = VertexLoaderManager::binormal_cache; vertex_shader_manager.dirty = true; } + + if (vert_decl.normals[0].enable) + return; + + VertexLoaderManager::normal_cache[3] = 0; + if (vertex_shader_manager.constants.cached_normal != VertexLoaderManager::normal_cache) + { + vertex_shader_manager.constants.cached_normal = VertexLoaderManager::normal_cache; + vertex_shader_manager.dirty = true; + } } void VertexManagerBase::UpdatePipelineConfig() diff --git a/Source/Core/VideoCommon/VertexManagerBase.h b/Source/Core/VideoCommon/VertexManagerBase.h index 648e26be59..715dbee692 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.h +++ b/Source/Core/VideoCommon/VertexManagerBase.h @@ -192,7 +192,7 @@ protected: u32 GetRemainingIndices(OpcodeDecoder::Primitive primitive) const; void CalculateZSlope(NativeVertexFormat* format); - void CalculateBinormals(NativeVertexFormat* format); + void CalculateNormals(NativeVertexFormat* format); BitSet32 UsedTextures() const; diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 9f854f2d9e..4a46834c14 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -312,56 +312,43 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho out.Write("int posidx = int(posmtx.r);\n" "float4 P0 = " I_TRANSFORMMATRICES "[posidx];\n" "float4 P1 = " I_TRANSFORMMATRICES "[posidx + 1];\n" - "float4 P2 = " I_TRANSFORMMATRICES "[posidx + 2];\n"); - if ((uid_data->components & VB_HAS_NORMAL) != 0) - { - out.Write("int normidx = posidx & 31;\n" - "float3 N0 = " I_NORMALMATRICES "[normidx].xyz;\n" - "float3 N1 = " I_NORMALMATRICES "[normidx + 1].xyz;\n" - "float3 N2 = " I_NORMALMATRICES "[normidx + 2].xyz;\n"); - } + "float4 P2 = " I_TRANSFORMMATRICES "[posidx + 2];\n" + "int normidx = posidx & 31;\n" + "float3 N0 = " I_NORMALMATRICES "[normidx].xyz;\n" + "float3 N1 = " I_NORMALMATRICES "[normidx + 1].xyz;\n" + "float3 N2 = " I_NORMALMATRICES "[normidx + 2].xyz;\n"); } else { // One shared matrix out.Write("float4 P0 = " I_POSNORMALMATRIX "[0];\n" "float4 P1 = " I_POSNORMALMATRIX "[1];\n" - "float4 P2 = " I_POSNORMALMATRIX "[2];\n"); - if ((uid_data->components & VB_HAS_NORMAL) != 0) - { - out.Write("float3 N0 = " I_POSNORMALMATRIX "[3].xyz;\n" - "float3 N1 = " I_POSNORMALMATRIX "[4].xyz;\n" - "float3 N2 = " I_POSNORMALMATRIX "[5].xyz;\n"); - } + "float4 P2 = " I_POSNORMALMATRIX "[2];\n" + "float3 N0 = " I_POSNORMALMATRIX "[3].xyz;\n" + "float3 N1 = " I_POSNORMALMATRIX "[4].xyz;\n" + "float3 N2 = " I_POSNORMALMATRIX "[5].xyz;\n"); } out.Write("// Multiply the position vector by the position matrix\n" "float4 pos = float4(dot(P0, rawpos), dot(P1, rawpos), dot(P2, rawpos), 1.0);\n"); - if ((uid_data->components & VB_HAS_NORMAL) != 0) - { - if ((uid_data->components & VB_HAS_TANGENT) == 0) - out.Write("float3 rawtangent = " I_CACHED_TANGENT ".xyz;\n"); - if ((uid_data->components & VB_HAS_BINORMAL) == 0) - out.Write("float3 rawbinormal = " I_CACHED_BINORMAL ".xyz;\n"); - - // The scale of the transform matrix is used to control the size of the emboss map effect, by - // changing the scale of the transformed binormals (which only get used by emboss map texgens). - // By normalising the first transformed normal (which is used by lighting calculations and needs - // to be unit length), the same transform matrix can do double duty, scaling for emboss mapping, - // and not scaling for lighting. - out.Write("float3 _normal = normalize(float3(dot(N0, rawnormal), dot(N1, rawnormal), dot(N2, " - "rawnormal)));\n" - "float3 _tangent = float3(dot(N0, rawtangent), dot(N1, rawtangent), dot(N2, " - "rawtangent));\n" - "float3 _binormal = float3(dot(N0, rawbinormal), dot(N1, rawbinormal), dot(N2, " - "rawbinormal));\n"); - } - else - { - out.Write("float3 _normal = float3(0.0, 0.0, 0.0);\n"); - out.Write("float3 _binormal = float3(0.0, 0.0, 0.0);\n"); - out.Write("float3 _tangent = float3(0.0, 0.0, 0.0);\n"); - } + if ((uid_data->components & VB_HAS_NORMAL) == 0) + out.Write("float3 rawnormal = " I_CACHED_NORMAL ".xyz;\n"); + if ((uid_data->components & VB_HAS_TANGENT) == 0) + out.Write("float3 rawtangent = " I_CACHED_TANGENT ".xyz;\n"); + if ((uid_data->components & VB_HAS_BINORMAL) == 0) + out.Write("float3 rawbinormal = " I_CACHED_BINORMAL ".xyz;\n"); + + // The scale of the transform matrix is used to control the size of the emboss map effect, by + // changing the scale of the transformed binormals (which only get used by emboss map texgens). + // By normalising the first transformed normal (which is used by lighting calculations and needs + // to be unit length), the same transform matrix can do double duty, scaling for emboss mapping, + // and not scaling for lighting. + out.Write("float3 _normal = normalize(float3(dot(N0, rawnormal), dot(N1, rawnormal), dot(N2, " + "rawnormal)));\n" + "float3 _tangent = float3(dot(N0, rawtangent), dot(N1, rawtangent), dot(N2, " + "rawtangent));\n" + "float3 _binormal = float3(dot(N0, rawbinormal), dot(N1, rawbinormal), dot(N2, " + "rawbinormal));\n"); out.Write("o.pos = float4(dot(" I_PROJECTION "[0], pos), dot(" I_PROJECTION "[1], pos), dot(" I_PROJECTION "[2], pos), dot(" I_PROJECTION "[3], pos));\n"); |
