我正在制作结合了2d和3d元素的等距游戏。我想知道如何使我的玩家和敌方精灵(全部由2d元素组成)不渲染在3d元素的后面或内部。
所以我尝试弄弄renderQueue并将这些岩石等材质的渲染队列设置得很高,以便将它们绘制在2d元素后面。
但是,通过搜索,我发现实际上我需要设置对象的ztest来更正此问题。这让我有些困惑,我不确定该怎么做,因为我还没有真正使用过着色器。我找不到任何像样的参考文献来确切解释如何进行此工作,只是假设具有this之类的先验知识。我尝试下载unity着色器并打开默认的精灵1,但不确定在哪里更改ztest或标记以解决此问题。
这是统一的标准精灵着色器:
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
#ifndef UNITY_SPRITES_INCLUDED
#define UNITY_SPRITES_INCLUDED
#include "UnityCG.cginc"
#ifdef UNITY_INSTANCING_ENABLED
UNITY_INSTANCING_BUFFER_START(PerDrawSprite)
// SpriteRenderer.Color while Non-Batched/Instanced.
UNITY_DEFINE_INSTANCED_PROP(fixed4, unity_SpriteRendererColorArray)
// this could be smaller but that's how bit each entry is regardless of type
UNITY_DEFINE_INSTANCED_PROP(fixed2, unity_SpriteFlipArray)
UNITY_INSTANCING_BUFFER_END(PerDrawSprite)
#define _RendererColor UNITY_ACCESS_INSTANCED_PROP(PerDrawSprite, unity_SpriteRendererColorArray)
#define _Flip UNITY_ACCESS_INSTANCED_PROP(PerDrawSprite, unity_SpriteFlipArray)
#endif // instancing
CBUFFER_START(UnityPerDrawSprite)
#ifndef UNITY_INSTANCING_ENABLED
fixed4 _RendererColor;
fixed2 _Flip;
#endif
float _EnableExternalAlpha;
CBUFFER_END
// Material Color.
fixed4 _Color;
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
inline float4 UnityFlipSprite(in float3 pos, in fixed2 flip)
{
return float4(pos.xy * flip, pos.z, 1.0);
}
v2f SpriteVert(appdata_t IN)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID (IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.vertex = UnityFlipSprite(IN.vertex, _Flip);
OUT.vertex = UnityObjectToClipPos(OUT.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color * _RendererColor;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
return OUT;
}
sampler2D _MainTex;
sampler2D _AlphaTex;
fixed4 SampleSpriteTexture (float2 uv)
{
fixed4 color = tex2D (_MainTex, uv);
#if ETC1_EXTERNAL_ALPHA
fixed4 alpha = tex2D (_AlphaTex, uv);
color.a = lerp (color.a, alpha.r, _EnableExternalAlpha);
#endif
return color;
}
fixed4 SpriteFrag(v2f IN) : SV_Target
{
fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
c.rgb *= c.a;
return c;
}
#endif // UNITY_SPRITES_INCLUDED
答案 0 :(得分:1)
如果我正确理解了您的问题,我认为您可以尝试使用其他相机。
正确设置两个摄像机的剔除蒙版和深度以及清除标志。
额外相机的深度应更高,并且clearflag应设置为仅深度,而剔除遮罩仅设置要在前面渲染的图层。
您原来的相机剔除蒙版应该删除额外相机中的图层渲染。
您可以使特定图层的对象在前面呈现。
昨天Svp告诉我他想要2d和3d对象的细粒度控制绘图顺序。我以前的答案不能很好地解决这个问题,因此经过研究,有三种解决方案。
更新:
将2d对象视为3d。使用z-pos对所有对象进行排序。保持很少的3d对象z-pos始终小于或大于播放器z-pos(3d对象与播放器的z-pos偏移量需要大于固定值,从而使整个3d对象位于播放器后面。)最多选择3d对象边界。
将3d对象视为2d。 3d对象网格渲染使用2d sprite-default着色器。 在图层控制3d对象渲染中使用2d排序图层和顺序。但是,我们需要自定义网格渲染检查器使用来自here by uvivagabond的跟随代码副本。
using System;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Reflection;
using UnityEngine.Rendering;
[CanEditMultipleObjects ()]
[CustomEditor (typeof(MeshRenderer))]
public class MeshRendererSortingLayersEditor : Editor
{
public override void OnInspectorGUI ()
{
#region Get Serialized Property
SerializedProperty sortingLayerID = serializedObject.FindProperty (propertyPath: "m_SortingLayerID");
SerializedProperty sortingOrder = serializedObject.FindProperty ("m_SortingOrder");
SerializedProperty castShadows = serializedObject.FindProperty ("m_CastShadows");
SerializedProperty receiveShadows = serializedObject.FindProperty ("m_ReceiveShadows");
SerializedProperty motionVectors = serializedObject.FindProperty ("m_MotionVectors");
SerializedProperty materials = serializedObject.FindProperty ("m_Materials");
SerializedProperty lightProbes = serializedObject.FindProperty ("m_LightProbeUsage");
SerializedProperty reflectionProbes = serializedObject.FindProperty ("m_ReflectionProbeUsage");
SerializedProperty anchorProbes = serializedObject.FindProperty ("m_ProbeAnchor");
#endregion
#region Draw Properties
AddPropertyField (castShadows);
AddPropertyField (receiveShadows);
AddPropertyField (motionVectors);
AddPropertyField (materials);
AddPopup (ref lightProbes, "Light Probes", typeof(LightProbeUsage));
AddPopup (ref reflectionProbes, "Reflection Probes", typeof(ReflectionProbeUsage));
AddPropertyField (anchorProbes, "Anchor Override");
#endregion
GUIStyle style = new GUIStyle (GUI.skin.label);
style.richText = true;
EditorGUILayout.Space ();
EditorGUILayout.LabelField ("<b><color=#EE4035FF>SortingLayers Options:</color></b>", style);
#region SortingLayer
Rect firstHoriz = EditorGUILayout.BeginHorizontal ();
EditorGUI.BeginChangeCheck ();
// EditorGUI.PropertyField (mat, new GUIContent ("Materials"));
EditorGUI.BeginProperty (firstHoriz, GUIContent.none, sortingLayerID);
string[] layerNames = GetSortingLayerNames ();
int[] layerID = GetSortingLayerUniqueIDs ();
int selected = -1;
int sID = sortingLayerID.intValue;
for (int i = 0; i < layerID.Length; i++)
if (sID == layerID [i])
selected = i;
if (selected == -1)
for (int i = 0; i < layerID.Length; i++)
if (layerID [i] == 0)
selected = i;
selected = EditorGUILayout.Popup ("Sorting Layer", selected, layerNames);
sortingLayerID.intValue = layerID [selected];
EditorGUI.EndProperty ();
EditorGUILayout.EndHorizontal ();
#endregion
#region OrderInLayer
EditorGUILayout.BeginHorizontal ();
EditorGUI.BeginChangeCheck ();
EditorGUILayout.PropertyField (sortingOrder, new GUIContent ("Order in Layer"));
EditorGUILayout.EndHorizontal ();
serializedObject.ApplyModifiedProperties ();
#endregion
}
void AddPropertyField (SerializedProperty ourSerializedProperty)
{
Rect ourRect = EditorGUILayout.BeginHorizontal ();
EditorGUI.BeginProperty (ourRect, GUIContent.none, ourSerializedProperty);
EditorGUI.BeginChangeCheck ();
EditorGUILayout.PropertyField (property: ourSerializedProperty, includeChildren: true); //I set includeChildren:true to display material children
EditorGUI.EndProperty ();
EditorGUILayout.EndHorizontal ();
}
void AddPropertyField (SerializedProperty ourSerializedProperty, string name)
{
Rect ourRect = EditorGUILayout.BeginHorizontal ();
EditorGUI.BeginProperty (ourRect, GUIContent.none, ourSerializedProperty);
EditorGUI.BeginChangeCheck ();
EditorGUILayout.PropertyField (ourSerializedProperty, new GUIContent (name), true);
EditorGUI.EndProperty ();
EditorGUILayout.EndHorizontal ();
}
void AddPopup (ref SerializedProperty ourSerializedProperty, string nameOfLabel, Type typeOfEnum)
{
Rect ourRect = EditorGUILayout.BeginHorizontal ();
EditorGUI.BeginProperty (ourRect, GUIContent.none, ourSerializedProperty);
EditorGUI.BeginChangeCheck ();
int actualSelected = 1;
int selectionFromInspector = ourSerializedProperty.intValue;
string[] enumNamesList = System.Enum.GetNames (typeOfEnum);
actualSelected = EditorGUILayout.Popup (nameOfLabel, selectionFromInspector, enumNamesList);
ourSerializedProperty.intValue = actualSelected;
EditorGUI.EndProperty ();
EditorGUILayout.EndHorizontal ();
}
public string[] GetSortingLayerNames ()
{
Type internalEditorUtilityType = typeof(InternalEditorUtility);
PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty ("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
return (string[])sortingLayersProperty.GetValue (null, new object[0]);
}
public int[] GetSortingLayerUniqueIDs ()
{
Type internalEditorUtilityType = typeof(InternalEditorUtility);
PropertyInfo sortingLayerUniqueIDsProperty = internalEditorUtilityType.GetProperty ("sortingLayerUniqueIDs", BindingFlags.Static | BindingFlags.NonPublic);
return (int[])sortingLayerUniqueIDsProperty.GetValue (null, new object[0]);
}
}
希望这对您有所帮助。