В этой статье предлагаются некоторые решения проблемы проникновения модели, возникающей при отображении многослойных 3D-объектов в интерфейсе.
Как показано на рисунке, когда мы хотим отобразить два или более 3D-объектов в одном интерфейсе, иногда нарушается глубина рендеринга шейдера на первом слое материала объекта или другие причины вызывают проникновение первого слоя объектов на второй слой. появился интерфейс.
Три оранжевые сферы в представлении «Сцена» изначально находились под вторым слоем желтого фона:
Но в представлении «Игра» мы обнаружили, что три оранжевые сферы на самом деле располагаются над вторым слоем желтого фона, что вызывает проблему проникновения модели:
Поскольку отображение двух вышеперечисленных слоев 3D-объектов происходит на одном интерфейсе, решить проблему, задав независимый SortingLayer для каждого интерфейса, невозможно. На этом этапе вы можете решить проблему, установив глубину рендеринга шейдера на первом слое материала объекта:
Во-первых, добавьте следующий код в Properties и SubShader в файлы шейдеров всех 3D-объектов, где значения по умолчанию могут быть изменены в соответствии с фактическими потребностями:
Properties 中:
_Stencil("Stencil ID", Float) = 2
_StencilComp("StencilComp", int) = 6
_StencilPass("StencilPass", int) = 0
SubShader 的 Pass 中:
Stencil
{
Ref[_Stencil]
Comp[_StencilComp]
Pass[_StencilPass]
}
Эффект после добавления детали следующий:
После добавления вы можете установить глубину рендеринга 3D-объекта в соответствии с этими тремя значениями перечисления. Конкретное использование и правила см. в следующей статье: Использование Stencil в Unity.
Конкретное решение: во-первых, используйте маску на интерфейсе второго слоя, чтобы заблокировать 3D-объекты на интерфейсе первого слоя. Шейдер, используемый этой маской, должен быть больше глубины рендеринга 3D-объекта первого слоя и в то же время меньше глубины рендеринга 3D-объекта второго слоя. Например, если три значения перечисления Stencil ID, StencilComp и StencilPass (это значение перечисления также иногда называется Stencil Operation), заданные первым слоем 3D-объектов, равны 2, 6 и 0 соответственно, то Маску можно установить на 2, 8, 2, чтобы 3D-объекты второго слоя можно было заблокировать, не затрагивая 3D-объекты второго слоя. Конкретный эффект заключается в следующем:
Значение перечисления глубины рендеринга шейдера первого слоя 3D-объектов:
Шейдер маски, используемый для блокировки первого слоя 3D-объектов, отображает значение перечисления глубины, где «Всегда» означает 8, а «Заменить» означает 2:
Значение перечисления глубины рендеринга шейдера 3D-объекта третьего слоя:
При загрузке 3D-объекта установите значение перечисления глубины рендеринга текущего экземпляра шейдера следующим образом: (Этот метод будет изменять только загруженный в данный момент объект и не повлияет на другие объекты, которые также используют этот файл шейдера)
local skinnedMeshArray = go.transform:GetComponentsInChildren(typeof(UnityEngine.Renderer))
if skinnedMeshArray.Length <= 0 then
return
end
for i = 0, skinnedMeshArray.Length - 1 do
local skinnedMesh = skinnedMeshArray[i]
for j = 0, skinnedMesh.materials.Length - 1 do
skinnedMesh.materials[j]:SetInt("_Stencil", 2)
skinnedMesh.materials[j]:SetInt("_StencilComp", 6)
skinnedMesh.materials[j]:SetInt("_StencilPass", 0)
end
end
Таким образом, можно добиться иерархического управления 3D-объектами, чтобы не происходило проникновения в модель. Я надеюсь, что эта статья может быть полезной для вас, выше.