在2d对象统一后渲染3d对象

时间:2018-08-07 09:33:55

标签: unity3d rendering shader

我正在制作结合了2d和3d元素的等距游戏。我想知道如何使我的玩家和敌方精灵(全部由2d元素组成)不渲染在3d元素的后面或内部。

enter image description here

所以我尝试弄弄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

更新1

enter image description here

1 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,我认为您可以尝试使用其他相机。

正确设置两个摄像机的剔除蒙版深度以及清除标志

额外相机的深度应更高,并且clearflag应设置为仅深度,而剔除遮罩仅设置要在前面渲染的图层。

您原来的相机剔除蒙版应该删除额外相机中的图层渲染。

您可以使特定图层的对象在前面呈现。

昨天Svp告诉我他想要2d和3d对象的细粒度控制绘图顺序。我以前的答案不能很好地解决这个问题,因此经过研究,有三种解决方案。

更新:

  1. 将2d对象视为3d。使用z-pos对所有对象进行排序。保持很少的3d对象z-pos始终小于或大于播放器z-pos(3d对象与播放器的z-pos偏移量需要大于固定值,从而使整个3d对象位于播放器后面。)最多选择3d对象边界。

  2. 将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]);
        }
    }
    

此后,渲染网格检查器视图如下: Mesh Render Inspector

  1. 合并2d渲染系统和3d渲染系统。处理Z缓冲区Z写操作以及许多其他方法...我相信这是一个巨大的挑战。团结应该完成这项工作,而不是我们。

希望这对您有所帮助。