Beispiel #1
0
        void UpdateRenderingPassValue(HDRenderQueue.RenderQueueType newValue)
        {
            HDRenderQueue.RenderQueueType renderingPass;
            switch (m_Node.surfaceType)
            {
            case SurfaceType.Opaque:
                renderingPass = HDRenderQueue.GetOpaqueEquivalent(newValue);
                break;

            case SurfaceType.Transparent:
                renderingPass = HDRenderQueue.GetTransparentEquivalent(newValue);
                break;

            default:
                throw new ArgumentException("Unknown SurfaceType");
            }

            if (Equals(m_Node.renderingPass, renderingPass))
            {
                return;
            }

            m_Node.owner.owner.RegisterCompleteObjectUndo("Rendering Pass Change");
            m_Node.renderingPass = renderingPass;
        }
Beispiel #2
0
        protected static void ResetMaterialCustomRenderQueue(Material material)
        {
            HDRenderQueue.RenderQueueType targetQueueType;
            switch (material.GetSurfaceType())
            {
            case SurfaceType.Opaque:
                targetQueueType = HDRenderQueue.GetOpaqueEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue));
                break;

            case SurfaceType.Transparent:
                targetQueueType = HDRenderQueue.GetTransparentEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue));
                break;

            default:
                throw new ArgumentException("Unknown SurfaceType");
            }

            // Decal doesn't have properties to compute the render queue
            if (material.HasProperty(kTransparentSortPriority) && material.HasProperty(kAlphaCutoffEnabled))
            {
                float sortingPriority = material.GetFloat(kTransparentSortPriority);
                bool  alphaTest       = material.GetFloat(kAlphaCutoffEnabled) > 0.5f;
                bool  decalEnable     = material.HasProperty(kEnableDecals) && material.GetFloat(kEnableDecals) > 0.0f;
                material.renderQueue = HDRenderQueue.ChangeType(targetQueueType, (int)sortingPriority, alphaTest, decalEnable);
            }
        }
        public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null)
        {
            if (sourceAssetDependencyPaths != null)
            {
                // DecalSubShader.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("3b523fb79ded88842bb5195be78e0354"));
                // HDSubShaderUtilities.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b"));
            }

            var masterNode = iMasterNode as DecalMasterNode;

            var subShader = new ShaderGenerator();

            subShader.AddShaderChunk("SubShader", true);
            subShader.AddShaderChunk("{", true);
            subShader.Indent();
            {
                // Add tags at the SubShader level
                int queue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Opaque, masterNode.drawOrder, false);
                HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.Opaque, queue);

                // Caution: Order of GenerateShaderPass matter. Only generate required pass
                if (masterNode.affectsAlbedo.isOn || masterNode.affectsNormal.isOn || masterNode.affectsMetal.isOn || masterNode.affectsAO.isOn || masterNode.affectsSmoothness.isOn)
                {
                    GenerateShaderPass(masterNode, m_PassProjector3RT, mode, subShader, sourceAssetDependencyPaths);
                    GenerateShaderPass(masterNode, m_PassProjector4RT, mode, subShader, sourceAssetDependencyPaths);
                }
                if (masterNode.affectsEmission.isOn)
                {
                    GenerateShaderPass(masterNode, m_PassProjectorEmissive, mode, subShader, sourceAssetDependencyPaths);
                }
                if (masterNode.affectsAlbedo.isOn || masterNode.affectsNormal.isOn || masterNode.affectsMetal.isOn || masterNode.affectsAO.isOn || masterNode.affectsSmoothness.isOn)
                {
                    GenerateShaderPass(masterNode, m_PassMesh3RT, mode, subShader, sourceAssetDependencyPaths);
                    GenerateShaderPass(masterNode, m_PassMesh4RT, mode, subShader, sourceAssetDependencyPaths);
                }
                if (masterNode.affectsEmission.isOn)
                {
                    GenerateShaderPass(masterNode, m_PassMeshEmissive, mode, subShader, sourceAssetDependencyPaths);
                }

                if (mode.IsPreview())
                {
                    GenerateShaderPass(masterNode, m_PassPreview, mode, subShader, sourceAssetDependencyPaths);
                }
            }
            subShader.Deindent();
            subShader.AddShaderChunk("}", true);

            if (!masterNode.OverrideEnabled)
            {
                subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Rendering.HighDefinition.DecalGUI""");
            }

            string s = subShader.GetShaderString(0);

            return(s);
        }
Beispiel #4
0
        private int GetRenderQueueOffset()
        {
            var renderQueueType         = GetRenderQueueType();
            var materialSortingPriority = GetMaterialSortingPriority();

            return(owner is VFXDecalHDRPOutput?
                   HDRenderQueue.Clamps(k_RenderQueue_AllOpaque, ChangeType(renderQueueType, 0, owner.hasAlphaClipping) + materialSortingPriority) :
                       ChangeType(renderQueueType, materialSortingPriority, owner.hasAlphaClipping));
        }
Beispiel #5
0
        void UpgradeHDUnlitMasterNode(HDUnlitMasterNode1 hdUnlitMasterNode, out Dictionary <BlockFieldDescriptor, int> blockMap)
        {
            m_MigrateFromOldSG = true;

            // Set data
            systemData.surfaceType     = (SurfaceType)hdUnlitMasterNode.m_SurfaceType;
            systemData.blendMode       = HDSubShaderUtilities.UpgradeLegacyAlphaModeToBlendMode((int)hdUnlitMasterNode.m_AlphaMode);
            systemData.renderQueueType = HDRenderQueue.MigrateRenderQueueToHDRP10(hdUnlitMasterNode.m_RenderingPass);
            // Patch rendering pass in case the master node had an old configuration
            if (systemData.renderQueueType == HDRenderQueue.RenderQueueType.Background)
            {
                systemData.renderQueueType = HDRenderQueue.RenderQueueType.Opaque;
            }
            systemData.alphaTest           = hdUnlitMasterNode.m_AlphaTest;
            systemData.sortPriority        = hdUnlitMasterNode.m_SortPriority;
            systemData.doubleSidedMode     = hdUnlitMasterNode.m_DoubleSided ? DoubleSidedMode.Enabled : DoubleSidedMode.Disabled;
            systemData.transparentZWrite   = hdUnlitMasterNode.m_ZWrite;
            systemData.transparentCullMode = hdUnlitMasterNode.m_transparentCullMode;
            systemData.zTest          = hdUnlitMasterNode.m_ZTest;
            systemData.dotsInstancing = hdUnlitMasterNode.m_DOTSInstancing;

            builtinData.transparencyFog        = hdUnlitMasterNode.m_TransparencyFog;
            builtinData.distortion             = hdUnlitMasterNode.m_Distortion;
            builtinData.distortionMode         = hdUnlitMasterNode.m_DistortionMode;
            builtinData.distortionDepthTest    = hdUnlitMasterNode.m_DistortionDepthTest;
            builtinData.alphaToMask            = hdUnlitMasterNode.m_AlphaToMask;
            builtinData.addPrecomputedVelocity = hdUnlitMasterNode.m_AddPrecomputedVelocity;

            unlitData.distortionOnly    = hdUnlitMasterNode.m_DistortionOnly;
            unlitData.enableShadowMatte = hdUnlitMasterNode.m_EnableShadowMatte;
            target.customEditorGUI      = hdUnlitMasterNode.m_OverrideEnabled ? hdUnlitMasterNode.m_ShaderGUIOverride : "";

            // Set blockmap
            blockMap = new Dictionary <BlockFieldDescriptor, int>()
            {
                { BlockFields.VertexDescription.Position, 9 },
                { BlockFields.VertexDescription.Normal, 13 },
                { BlockFields.VertexDescription.Tangent, 14 },
                { BlockFields.SurfaceDescription.BaseColor, 0 },
                { BlockFields.SurfaceDescription.Alpha, 7 },
                { BlockFields.SurfaceDescription.AlphaClipThreshold, 8 },
                { BlockFields.SurfaceDescription.Emission, 12 },
            };

            // Distortion
            if (systemData.surfaceType == SurfaceType.Transparent && builtinData.distortion)
            {
                blockMap.Add(HDBlockFields.SurfaceDescription.Distortion, 10);
                blockMap.Add(HDBlockFields.SurfaceDescription.DistortionBlur, 11);
            }

            // Shadow Matte
            if (unlitData.enableShadowMatte)
            {
                blockMap.Add(HDBlockFields.SurfaceDescription.ShadowTint, 15);
            }
        }
        public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null)
        {
            if (sourceAssetDependencyPaths != null)
            {
                // StackLitSubShader.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("9649efe3e0e8e2941a983bb0f3a034ad"));
                // HDSubShaderUtilities.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b"));
            }

            var masterNode = iMasterNode as StackLitMasterNode;

            var subShader = new ShaderGenerator();

            subShader.AddShaderChunk("SubShader", true);
            subShader.AddShaderChunk("{", true);
            subShader.Indent();
            {
                // Add tags at the SubShader level
                var renderingPass = masterNode.surfaceType == SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent;
                int queue         = HDRenderQueue.ChangeType(renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn);
                HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDLitShader, queue);

                // generate the necessary shader passes
                bool opaque      = (masterNode.surfaceType == SurfaceType.Opaque);
                bool transparent = !opaque;

                bool distortionActive = transparent && masterNode.distortion.isOn;

                GenerateShaderPassLit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths);

                GenerateShaderPassLit(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths);

                if (distortionActive)
                {
                    GenerateShaderPassLit(masterNode, m_PassDistortion, mode, subShader, sourceAssetDependencyPaths);
                }

                // Assign define here based on opaque or transparent to save some variant
                m_PassForwardOnly.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent;
                GenerateShaderPassLit(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths);
            }

            subShader.Deindent();
            subShader.AddShaderChunk("}", true);

            if (!masterNode.OverrideEnabled)
            {
                subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Rendering.HighDefinition.StackLitGUI""");
            }

            return(subShader.GetShaderString(0));
        }
Beispiel #7
0
        void ChangeSortPriority(ChangeEvent<int> evt)
        {
            m_Node.sortPriority = HDRenderQueue.ClampsTransparentRangePriority(evt.newValue);
            // Force the text to match.
            m_SortPiorityField.value = m_Node.sortPriority;
            if (Equals(m_Node.sortPriority, evt.newValue))
                return;

            m_Node.owner.owner.RegisterCompleteObjectUndo("Sort Priority Change");
        }
Beispiel #8
0
        private RenderQueueType GetRenderQueueType()
        {
            RenderQueueType renderQueueType;

            if (owner.isBlendModeOpaque)
            {
                renderQueueType = HDRenderQueue.ConvertFromOpaqueRenderQueue(opaqueRenderQueue);
            }
            else
            {
                renderQueueType = HDRenderQueue.ConvertFromTransparentRenderQueue(transparentRenderQueue);
            }
            return(renderQueueType);
        }
        public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null)
        {
            if (sourceAssetDependencyPaths != null)
            {
                // HDUnlitSubShader.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("1c44ec077faa54145a89357de68e5d26"));
                // HDSubShaderUtilities.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b"));
            }

            var masterNode = iMasterNode as HDUnlitMasterNode;

            var subShader = new ShaderGenerator();

            subShader.AddShaderChunk("SubShader", true);
            subShader.AddShaderChunk("{", true);
            subShader.Indent();
            {
                // Add tags at the SubShader level
                int queue = HDRenderQueue.ChangeType(masterNode.renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn);
                HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDUnlitShader, queue);

                // For preview only we generate the passes that are enabled
                bool opaque           = (masterNode.surfaceType == SurfaceType.Opaque);
                bool transparent      = !opaque;
                bool distortionActive = transparent && masterNode.distortion.isOn;

                GenerateShaderPassUnlit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassUnlit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassUnlit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths);

                GenerateShaderPassUnlit(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassUnlit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths);

                if (distortionActive)
                {
                    GenerateShaderPassUnlit(masterNode, m_PassDistortion, mode, subShader, sourceAssetDependencyPaths);
                }

                GenerateShaderPassUnlit(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths);
            }
            subShader.Deindent();
            subShader.AddShaderChunk("}", true);

            subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.HDUnlitGUI""");

            return(subShader.GetShaderString(0));
        }
        void AddTags(ShaderGenerator generator, string pipeline, HDRenderTypeTags renderType, PBRMasterNode masterNode)
        {
            var    type  = masterNode.surfaceType == ShaderGraph.SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent;
            string queue = HDRenderQueue.GetShaderTagValue(HDRenderQueue.ChangeType(type, 0, true));
            ShaderStringBuilder builder = new ShaderStringBuilder();

            builder.AppendLine("Tags");
            using (builder.BlockScope())
            {
                builder.AppendLine("\"RenderPipeline\"=\"{0}\"", pipeline);
                builder.AppendLine("\"RenderType\"=\"{0}\"", renderType);
                builder.AppendLine("\"Queue\"=\"{0}\"", queue);
            }

            generator.AddShaderChunk(builder.ToString());
        }
        public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null)
        {
            if (sourceAssetDependencyPaths != null)
            {
                // UnlitSubShader.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("a32a2cf536cae8e478ca1bbb7b9c493b"));
                // HDSubShaderUtilities.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b"));
            }

            var masterNode = iMasterNode as UnlitMasterNode;
            var subShader  = new ShaderGenerator();

            subShader.AddShaderChunk("SubShader", true);
            subShader.AddShaderChunk("{", true);
            subShader.Indent();
            {
                var renderingPass = masterNode.surfaceType == ShaderGraph.SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent;
                int queue         = HDRenderQueue.ChangeType(renderingPass, 0, true);
                HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDUnlitShader, queue);

                // generate the necessary shader passes
                bool opaque = (masterNode.surfaceType == ShaderGraph.SurfaceType.Opaque);

                GenerateShaderPassUnlit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassUnlit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassUnlit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths);

                if (opaque)
                {
                    GenerateShaderPassUnlit(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths);
                    GenerateShaderPassUnlit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths);
                }

                GenerateShaderPassUnlit(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths);
            }
            subShader.Deindent();
            subShader.AddShaderChunk("}", true);

            if (!masterNode.OverrideEnabled)
            {
                subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Rendering.HighDefinition.UnlitUI""");
            }

            return(subShader.GetShaderString(0));
        }
        public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null)
        {
            if (sourceAssetDependencyPaths != null)
            {
                // FabricSubShader.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("059cc3132f0336e40886300f3d2d7f12"));
                // HDSubShaderUtilities.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b"));
            }

            var masterNode = iMasterNode as FabricMasterNode;

            var subShader = new ShaderGenerator();

            subShader.AddShaderChunk("SubShader", true);
            subShader.AddShaderChunk("{", true);
            subShader.Indent();
            {
                // generate the necessary shader passes
                bool opaque      = (masterNode.surfaceType == SurfaceType.Opaque);
                bool transparent = !opaque;

                // Add tags at the SubShader level
                var renderingPass = masterNode.surfaceType == SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent;
                int queue         = HDRenderQueue.ChangeType(renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn);
                HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDLitShader, queue);

                GenerateShaderPassLit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths);

                GenerateShaderPassLit(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths);

                // Assign define here based on opaque or transparent to save some variant
                m_PassForwardOnly.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent;
                GenerateShaderPassLit(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths);
            }
            subShader.Deindent();
            subShader.AddShaderChunk("}", true);
            subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.FabricGUI""");

            return(subShader.GetShaderString(0));
        }
        public override string GetRenderQueueStr()
        {
            RenderQueueType renderQueueType;
            string          prefix = string.Empty;

            if (owner.isBlendModeOpaque)
            {
                prefix          = "Geometry";
                renderQueueType = HDRenderQueue.ConvertFromOpaqueRenderQueue(opaqueRenderQueue);
            }
            else
            {
                prefix          = "Transparent";
                renderQueueType = HDRenderQueue.ConvertFromTransparentRenderQueue(transparentRenderQueue);
            }

            int renderQueue = HDRenderQueue.ChangeType(renderQueueType, 0, owner.useAlphaClipping) - (int)(owner.isBlendModeOpaque ? Priority.Opaque : Priority.Transparent);

            return(prefix + renderQueue.ToString("+#;-#;+0"));
        }
Beispiel #14
0
        protected static void ResetMaterialCustomRenderQueue(Material material)
        {
            HDRenderQueue.RenderQueueType targetQueueType;
            switch (material.GetSurfaceType())
            {
            case SurfaceType.Opaque:
                targetQueueType = HDRenderQueue.GetOpaqueEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue));
                break;

            case SurfaceType.Transparent:
                targetQueueType = HDRenderQueue.GetTransparentEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue));
                break;

            default:
                throw new ArgumentException("Unknown SurfaceType");
            }

            float sortingPriority = material.GetFloat(kTransparentSortPriority);
            bool  alphaTest       = material.GetFloat(kAlphaCutoffEnabled) > 0.5f;

            material.renderQueue = HDRenderQueue.ChangeType(targetQueueType, (int)sortingPriority, alphaTest);
        }
Beispiel #15
0
        public static void ResetMaterialCustomRenderQueue(this Material material)
        {
            // using GetOpaqueEquivalent / GetTransparentEquivalent allow to handle the case when we switch surfaceType
            HDRenderQueue.RenderQueueType targetQueueType;
            switch (material.GetSurfaceType())
            {
            case SurfaceType.Opaque:
                targetQueueType = HDRenderQueue.GetOpaqueEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue));
                break;

            case SurfaceType.Transparent:
                targetQueueType = HDRenderQueue.GetTransparentEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue));
                break;

            default:
                throw new ArgumentException("Unknown SurfaceType");
            }

            float sortingPriority = material.HasProperty(kTransparentSortPriority) ? material.GetFloat(kTransparentSortPriority) : 0.0f;
            bool  alphaTest       = material.HasProperty(kAlphaCutoffEnabled) && material.GetFloat(kAlphaCutoffEnabled) > 0.0f;
            bool  decalEnable     = material.HasProperty(kEnableDecals) && material.GetFloat(kEnableDecals) > 0.0f;

            material.renderQueue = HDRenderQueue.ChangeType(targetQueueType, (int)sortingPriority, alphaTest, decalEnable);
        }
Beispiel #16
0
        private int GetRenderQueueOffset()
        {
            var renderQueueType = GetRenderQueueType();

            return(HDRenderQueue.ChangeType(renderQueueType, GetMaterialOffset(), owner.hasAlphaClipping));
        }
Beispiel #17
0
        public HDUnlitSettingsView(HDUnlitMasterNode node)
        {
            m_Node = node;
            PropertySheet ps = new PropertySheet();

            int indentLevel = 0;

            ps.Add(new PropertyRow(CreateLabel("Surface Type", indentLevel)), (row) =>
            {
                row.Add(new EnumField(SurfaceType.Opaque), (field) =>
                {
                    field.value = m_Node.surfaceType;
                    field.RegisterValueChangedCallback(ChangeSurfaceType);
                });
            });

            ++indentLevel;
            switch (m_Node.surfaceType)
            {
            case SurfaceType.Opaque:
                ps.Add(new PropertyRow(CreateLabel("Rendering Pass", indentLevel)), (row) =>
                {
                    var valueList = HDSubShaderUtilities.GetRenderingPassList(true, true);

                    row.Add(new PopupField <HDRenderQueue.RenderQueueType>(valueList, HDRenderQueue.RenderQueueType.Opaque, HDSubShaderUtilities.RenderQueueName, HDSubShaderUtilities.RenderQueueName), (field) =>
                    {
                        field.value = HDRenderQueue.GetOpaqueEquivalent(m_Node.renderingPass);
                        field.RegisterValueChangedCallback(ChangeRenderingPass);
                    });
                });
                break;

            case SurfaceType.Transparent:
                ps.Add(new PropertyRow(CreateLabel("Rendering Pass", indentLevel)), (row) =>
                {
                    Enum defaultValue;
                    switch (m_Node.renderingPass) // Migration
                    {
                    default:                      //when deserializing without issue, we still need to init the default to something even if not used.
                    case HDRenderQueue.RenderQueueType.Transparent:
                        defaultValue = HDRenderQueue.TransparentRenderQueue.Default;
                        break;

                    case HDRenderQueue.RenderQueueType.PreRefraction:
                        defaultValue = HDRenderQueue.TransparentRenderQueue.BeforeRefraction;
                        break;
                    }

                    var valueList = HDSubShaderUtilities.GetRenderingPassList(false, true);

                    row.Add(new PopupField <HDRenderQueue.RenderQueueType>(valueList, HDRenderQueue.RenderQueueType.Transparent, HDSubShaderUtilities.RenderQueueName, HDSubShaderUtilities.RenderQueueName), (field) =>
                    {
                        field.value = HDRenderQueue.GetTransparentEquivalent(m_Node.renderingPass);
                        field.RegisterValueChangedCallback(ChangeRenderingPass);
                    });
                });
                break;

            default:
                throw new ArgumentException("Unknown SurfaceType");
            }
            --indentLevel;

            if (m_Node.surfaceType == SurfaceType.Transparent)
            {
                ++indentLevel;
                ps.Add(new PropertyRow(CreateLabel("Blending Mode", indentLevel)), (row) =>
                {
                    row.Add(new EnumField(HDUnlitMasterNode.AlphaModeLit.Additive), (field) =>
                    {
                        field.value = GetAlphaModeLit(m_Node.alphaMode);
                        field.RegisterValueChangedCallback(ChangeBlendMode);
                    });
                });

                m_SortPiorityField = new IntegerField();
                ps.Add(new PropertyRow(CreateLabel("Sorting Priority", indentLevel)), (row) =>
                {
                    row.Add(m_SortPiorityField, (field) =>
                    {
                        field.value = m_Node.sortPriority;
                        field.RegisterValueChangedCallback(ChangeSortPriority);
                    });
                });

                ps.Add(new PropertyRow(CreateLabel("Receive Fog", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.transparencyFog.isOn;
                        toggle.OnToggleChanged(ChangeTransparencyFog);
                    });
                });

                ps.Add(new PropertyRow(CreateLabel("Distortion", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.distortion.isOn;
                        toggle.OnToggleChanged(ChangeDistortion);
                    });
                });

                if (m_Node.distortion.isOn)
                {
                    ++indentLevel;
                    ps.Add(new PropertyRow(CreateLabel("Mode", indentLevel)), (row) =>
                    {
                        row.Add(new EnumField(DistortionMode.Add), (field) =>
                        {
                            field.value = m_Node.distortionMode;
                            field.RegisterValueChangedCallback(ChangeDistortionMode);
                        });
                    });
                    ps.Add(new PropertyRow(CreateLabel("Distortion Only", indentLevel)), (row) =>
                    {
                        row.Add(new Toggle(), (toggle) =>
                        {
                            toggle.value = m_Node.distortionOnly.isOn;
                            toggle.OnToggleChanged(ChangeDistortionOnly);
                        });
                    });
                    ps.Add(new PropertyRow(CreateLabel("Depth Test", indentLevel)), (row) =>
                    {
                        row.Add(new Toggle(), (toggle) =>
                        {
                            toggle.value = m_Node.distortionDepthTest.isOn;
                            toggle.OnToggleChanged(ChangeDistortionDepthTest);
                        });
                    });
                    --indentLevel;
                }

                --indentLevel;
            }

            ps.Add(new PropertyRow(new Label("Double-Sided")), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.doubleSided.isOn;
                    toggle.OnToggleChanged(ChangeDoubleSided);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("Alpha Clipping", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.alphaTest.isOn;
                    toggle.OnToggleChanged(ChangeAlphaTest);
                });
            });

            Add(ps);
        }
        public HDLitSettingsView(HDLitMasterNode node) : base(node)
        {
            m_Node = node;
            PropertySheet ps = new PropertySheet();

            int indentLevel = 0;

            ps.Add(new PropertyRow(CreateLabel("Surface Type", indentLevel)), (row) =>
            {
                row.Add(new EnumField(SurfaceType.Opaque), (field) =>
                {
                    field.value = m_Node.surfaceType;
                    field.RegisterValueChangedCallback(ChangeSurfaceType);
                });
            });

            ++indentLevel;
            switch (m_Node.surfaceType)
            {
            case SurfaceType.Opaque:
                ps.Add(new PropertyRow(CreateLabel("Rendering Pass", indentLevel)), (row) =>
                {
                    var valueList = HDSubShaderUtilities.GetRenderingPassList(true, false);

                    row.Add(new PopupField <HDRenderQueue.RenderQueueType>(valueList, HDRenderQueue.RenderQueueType.Opaque, HDSubShaderUtilities.RenderQueueName, HDSubShaderUtilities.RenderQueueName), (field) =>
                    {
                        field.value = HDRenderQueue.GetOpaqueEquivalent(m_Node.renderingPass);
                        field.RegisterValueChangedCallback(ChangeRenderingPass);
                    });
                });
                break;

            case SurfaceType.Transparent:
                ps.Add(new PropertyRow(CreateLabel("Rendering Pass", indentLevel)), (row) =>
                {
                    Enum defaultValue;
                    switch (m_Node.renderingPass) // Migration
                    {
                    default:                      //when deserializing without issue, we still need to init the default to something even if not used.
                    case HDRenderQueue.RenderQueueType.Transparent:
                        defaultValue = HDRenderQueue.TransparentRenderQueue.Default;
                        break;

                    case HDRenderQueue.RenderQueueType.PreRefraction:
                        defaultValue = HDRenderQueue.TransparentRenderQueue.BeforeRefraction;
                        break;
                    }

                    var valueList = HDSubShaderUtilities.GetRenderingPassList(false, false);

                    row.Add(new PopupField <HDRenderQueue.RenderQueueType>(valueList, HDRenderQueue.RenderQueueType.Transparent, HDSubShaderUtilities.RenderQueueName, HDSubShaderUtilities.RenderQueueName), (field) =>
                    {
                        field.value = HDRenderQueue.GetTransparentEquivalent(m_Node.renderingPass);
                        field.RegisterValueChangedCallback(ChangeRenderingPass);
                    });
                });
                break;

            default:
                throw new ArgumentException("Unknown SurfaceType");
            }
            --indentLevel;

            if (m_Node.surfaceType == SurfaceType.Transparent)
            {
                ++indentLevel;

                if (!m_Node.HasRefraction())
                {
                    ps.Add(new PropertyRow(CreateLabel("Blending Mode", indentLevel)), (row) =>
                    {
                        row.Add(new EnumField(HDLitMasterNode.AlphaModeLit.Additive), (field) =>
                        {
                            field.value = GetAlphaModeLit(m_Node.alphaMode);
                            field.RegisterValueChangedCallback(ChangeBlendMode);
                        });
                    });

                    ++indentLevel;
                    ps.Add(new PropertyRow(CreateLabel("Preserve Specular Lighting", indentLevel)), (row) =>
                    {
                        row.Add(new Toggle(), (toggle) =>
                        {
                            toggle.value = m_Node.blendPreserveSpecular.isOn;
                            toggle.OnToggleChanged(ChangeBlendPreserveSpecular);
                        });
                    });
                    --indentLevel;
                }

                m_SortPriorityField = new IntegerField();
                ps.Add(new PropertyRow(CreateLabel("Sorting Priority", indentLevel)), (row) =>
                {
                    row.Add(m_SortPriorityField, (field) =>
                    {
                        field.value = m_Node.sortPriority;
                        field.RegisterValueChangedCallback(ChangeSortPriority);
                    });
                });

                ps.Add(new PropertyRow(CreateLabel("Receive Fog", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.transparencyFog.isOn;
                        toggle.OnToggleChanged(ChangeTransparencyFog);
                    });
                });

                ps.Add(new PropertyRow(CreateLabel("Back Then Front Rendering", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.backThenFrontRendering.isOn;
                        toggle.OnToggleChanged(ChangeBackThenFrontRendering);
                    });
                });

                ps.Add(new PropertyRow(CreateLabel("Transparent Depth Prepass", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.alphaTestDepthPrepass.isOn;
                        toggle.OnToggleChanged(ChangeAlphaTestPrepass);
                    });
                });

                ps.Add(new PropertyRow(CreateLabel("Transparent Depth Postpass", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.alphaTestDepthPostpass.isOn;
                        toggle.OnToggleChanged(ChangeAlphaTestPostpass);
                    });
                });

                ps.Add(new PropertyRow(CreateLabel("Transparent Writes Motion Vector", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.transparentWritesMotionVec.isOn;
                        toggle.OnToggleChanged(ChangeTransparentWritesMotionVec);
                    });
                });

                if (m_Node.renderingPass != HDRenderQueue.RenderQueueType.PreRefraction)
                {
                    ps.Add(new PropertyRow(CreateLabel("Refraction Model", indentLevel)), (row) =>
                    {
                        row.Add(new EnumField(ScreenSpaceRefraction.RefractionModel.None), (field) =>
                        {
                            field.value = m_Node.refractionModel;
                            field.RegisterValueChangedCallback(ChangeRefractionModel);
                        });
                    });
                }

                ps.Add(new PropertyRow(CreateLabel("Distortion", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.distortion.isOn;
                        toggle.OnToggleChanged(ChangeDistortion);
                    });
                });

                if (m_Node.distortion.isOn)
                {
                    ++indentLevel;
                    ps.Add(new PropertyRow(CreateLabel("Distortion Blend Mode", indentLevel)), (row) =>
                    {
                        row.Add(new EnumField(DistortionMode.Add), (field) =>
                        {
                            field.value = m_Node.distortionMode;
                            field.RegisterValueChangedCallback(ChangeDistortionMode);
                        });
                    });
                    ps.Add(new PropertyRow(CreateLabel("Distortion Depth Test", indentLevel)), (row) =>
                    {
                        row.Add(new Toggle(), (toggle) =>
                        {
                            toggle.value = m_Node.distortionDepthTest.isOn;
                            toggle.OnToggleChanged(ChangeDistortionDepthTest);
                        });
                    });
                    --indentLevel;
                }

                ps.Add(new PropertyRow(CreateLabel("Depth Write", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.zWrite.isOn;
                        toggle.OnToggleChanged(ChangeZWrite);
                    });
                });

                if (m_Node.doubleSidedMode == DoubleSidedMode.Disabled)
                {
                    ps.Add(new PropertyRow(CreateLabel("Cull Mode", indentLevel)), (row) =>
                    {
                        row.Add(new EnumField(m_Node.transparentCullMode), (e) =>
                        {
                            e.value = m_Node.transparentCullMode;
                            e.RegisterValueChangedCallback(ChangeTransparentCullMode);
                        });
                    });
                }

                ps.Add(new PropertyRow(CreateLabel("Depth Test", indentLevel)), (row) =>
                {
                    row.Add(new EnumField(m_Node.zTest), (e) =>
                    {
                        e.value = m_Node.zTest;
                        e.RegisterValueChangedCallback(ChangeZTest);
                    });
                });

                --indentLevel;
            }

            ps.Add(new PropertyRow(CreateLabel("Double-Sided", indentLevel)), (row) =>
            {
                row.Add(new EnumField(DoubleSidedMode.Disabled), (field) =>
                {
                    field.value = m_Node.doubleSidedMode;
                    field.RegisterValueChangedCallback(ChangeDoubleSidedMode);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("Fragment Normal Space", indentLevel)), (row) =>
            {
                row.Add(new EnumField(NormalDropOffSpace.Tangent), (field) =>
                {
                    field.value = m_Node.normalDropOffSpace;
                    field.RegisterValueChangedCallback(ChangeSpaceOfNormalDropOffMode);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("Alpha Clipping", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.alphaTest.isOn;
                    toggle.OnToggleChanged(ChangeAlphaTest);
                });
            });

            if (m_Node.alphaTest.isOn)
            {
                ++indentLevel;
                ps.Add(new PropertyRow(CreateLabel("Use Shadow Threshold", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.alphaTestShadow.isOn;
                        toggle.OnToggleChanged(ChangeAlphaTestShadow);
                    });
                });
                --indentLevel;
            }

            ps.Add(new PropertyRow(CreateLabel("Material Type", indentLevel)), (row) =>
            {
                row.Add(new EnumField(HDLitMasterNode.MaterialType.Standard), (field) =>
                {
                    field.value = m_Node.materialType;
                    field.RegisterValueChangedCallback(ChangeMaterialType);
                });
            });

            ++indentLevel;
            if (m_Node.materialType == HDLitMasterNode.MaterialType.SubsurfaceScattering)
            {
                ps.Add(new PropertyRow(CreateLabel("Transmission", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.sssTransmission.isOn;
                        toggle.OnToggleChanged(ChangeSSSTransmission);
                    });
                });
            }

            if (m_Node.materialType == HDLitMasterNode.MaterialType.SpecularColor)
            {
                ps.Add(new PropertyRow(CreateLabel("Energy Conserving Specular", indentLevel)), (row) =>
                {
                    row.Add(new Toggle(), (toggle) =>
                    {
                        toggle.value = m_Node.energyConservingSpecular.isOn;
                        toggle.OnToggleChanged(ChangeEnergyConservingSpecular);
                    });
                });
            }
            --indentLevel;

            ps.Add(new PropertyRow(CreateLabel("Receive Decals", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.receiveDecals.isOn;
                    toggle.OnToggleChanged(ChangeDecal);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("Receive SSR", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.receiveSSR.isOn;
                    toggle.OnToggleChanged(ChangeSSR);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("Add Precomputed Velocity", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.addPrecomputedVelocity.isOn;
                    toggle.OnToggleChanged(ChangeAddPrecomputedVelocity);
                });
            });


            ps.Add(new PropertyRow(CreateLabel("Geometric Specular AA", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.specularAA.isOn;
                    toggle.OnToggleChanged(ChangeSpecularAA);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("Specular Occlusion Mode", indentLevel)), (row) =>
            {
                row.Add(new EnumField(SpecularOcclusionMode.Off), (field) =>
                {
                    field.value = m_Node.specularOcclusionMode;
                    field.RegisterValueChangedCallback(ChangeSpecularOcclusionMode);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("Override Baked GI", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.overrideBakedGI.isOn;
                    toggle.OnToggleChanged(ChangeoverrideBakedGI);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("Depth Offset", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.depthOffset.isOn;
                    toggle.OnToggleChanged(ChangeDepthOffset);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("DOTS instancing", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.dotsInstancing.isOn;
                    toggle.OnToggleChanged(ChangeDotsInstancing);
                });
            });

            ps.Add(new PropertyRow(CreateLabel("Support LOD CrossFade", indentLevel)), (row) =>
            {
                row.Add(new Toggle(), (toggle) =>
                {
                    toggle.value = m_Node.supportLodCrossFade.isOn;
                    toggle.OnToggleChanged(ChangeSupportLODCrossFade);
                });
            });

            Add(ps);
            Add(GetShaderGUIOverridePropertySheet());
        }
        void SurfaceTypePopup()
        {
            if (surfaceType == null)
            {
                return;
            }

            Material material        = m_MaterialEditor.target as Material;
            var      mode            = (SurfaceType)surfaceType.floatValue;
            var      renderQueueType = HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue);
            bool     alphaTest       = material.HasProperty(kAlphaCutoffEnabled) && material.GetFloat(kAlphaCutoffEnabled) > 0.0f;

            EditorGUI.showMixedValue = surfaceType.hasMixedValue;
            var newMode = (SurfaceType)EditorGUILayout.Popup(StylesBaseUnlit.surfaceTypeText, (int)mode, StylesBaseUnlit.surfaceTypeNames);

            if (newMode != mode) //EditorGUI.EndChangeCheck is called even if value remain the same after the popup. Prefer not to use it here
            {
                m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type");
                surfaceType.floatValue = (float)newMode;
                HDRenderQueue.RenderQueueType targetQueueType;
                switch (newMode)
                {
                case SurfaceType.Opaque:
                    targetQueueType = HDRenderQueue.GetOpaqueEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue));
                    break;

                case SurfaceType.Transparent:
                    targetQueueType = HDRenderQueue.GetTransparentEquivalent(HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue));
                    break;

                default:
                    throw new ArgumentException("Unknown SurfaceType");
                }
                material.renderQueue = HDRenderQueue.ChangeType(targetQueueType, (int)transparentSortPriority.floatValue, alphaTest);
            }
            EditorGUI.showMixedValue = false;

            bool isMixedRenderQueue = surfaceType.hasMixedValue || m_MaterialEditor.targets.Select(m => HDRenderQueue.GetTypeByRenderQueueValue(((Material)m).renderQueue)).Distinct().Count() > 1;

            EditorGUI.showMixedValue = isMixedRenderQueue;
            ++EditorGUI.indentLevel;
            switch (mode)
            {
            case SurfaceType.Opaque:
                //GetOpaqueEquivalent: prevent issue when switching surface type
                HDRenderQueue.OpaqueRenderQueue renderQueueOpaqueType = HDRenderQueue.ConvertToOpaqueRenderQueue(HDRenderQueue.GetOpaqueEquivalent(renderQueueType));
                var newRenderQueueOpaqueType = (HDRenderQueue.OpaqueRenderQueue)EditorGUILayout.Popup(StylesBaseUnlit.renderingPassText, (int)renderQueueOpaqueType, StylesBaseUnlit.opaqueRenderingPassNames);
                if (newRenderQueueOpaqueType != renderQueueOpaqueType)     //EditorGUI.EndChangeCheck is called even if value remain the same after the popup. Prefer not to use it here
                {
                    m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Pass");
                    renderQueueType      = HDRenderQueue.ConvertFromOpaqueRenderQueue(newRenderQueueOpaqueType);
                    material.renderQueue = HDRenderQueue.ChangeType(renderQueueType, alphaTest: alphaTest);
                }
                break;

            case SurfaceType.Transparent:
                //GetTransparentEquivalent: prevent issue when switching surface type
                HDRenderQueue.TransparentRenderQueue renderQueueTransparentType = HDRenderQueue.ConvertToTransparentRenderQueue(HDRenderQueue.GetTransparentEquivalent(renderQueueType));
                var names = StylesBaseUnlit.transparentRenderingPassNames;
                if (!showPreRefractionPass)
                {
                    names = names.Skip(1).ToArray();
                    --renderQueueTransparentType;         //keep index sync with displayed value
                }
                var newRenderQueueTransparentType = (HDRenderQueue.TransparentRenderQueue)EditorGUILayout.Popup(StylesBaseUnlit.renderingPassText, (int)renderQueueTransparentType, names);
                if (newRenderQueueTransparentType != renderQueueTransparentType)     //EditorGUI.EndChangeCheck is called even if value remain the same after the popup. Prefer not to use it here
                {
                    if (!showPreRefractionPass)
                    {
                        ++newRenderQueueTransparentType;        //keep index sync with displayed value
                    }
                    m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Pass");
                    renderQueueType      = HDRenderQueue.ConvertFromTransparentRenderQueue(newRenderQueueTransparentType);
                    material.renderQueue = HDRenderQueue.ChangeType(renderQueueType, offset: (int)transparentSortPriority.floatValue);
                }
                break;

            default:
                throw new ArgumentException("Unknown SurfaceType");
            }
            --EditorGUI.indentLevel;
            EditorGUI.showMixedValue = false;
        }
Beispiel #20
0
        public static void SetupBaseUnlitKeywords(this Material material)
        {
            bool alphaTestEnable = material.HasProperty(kAlphaCutoffEnabled) && material.GetFloat(kAlphaCutoffEnabled) > 0.0f;

            CoreUtils.SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);

            // Setup alpha to mask using the _AlphaToMaskInspectorValue that we configure in the material UI
            float alphaToMaskEnabled = material.HasProperty("_AlphaToMaskInspectorValue") && material.GetFloat("_AlphaToMaskInspectorValue") > 0.0 ? 1 : 0;

            material.SetFloat(kAlphaToMask, alphaTestEnable ? alphaToMaskEnabled : 0);

            bool alphaToMaskEnable = alphaTestEnable && material.HasProperty(kAlphaToMask) && material.GetFloat(kAlphaToMask) > 0.0f;

            CoreUtils.SetKeyword(material, "_ALPHATOMASK_ON", alphaToMaskEnable);

            SurfaceType surfaceType = material.GetSurfaceType();

            CoreUtils.SetKeyword(material, "_SURFACE_TYPE_TRANSPARENT", surfaceType == SurfaceType.Transparent);

            bool enableBlendModePreserveSpecularLighting = (surfaceType == SurfaceType.Transparent) && material.HasProperty(kEnableBlendModePreserveSpecularLighting) && material.GetFloat(kEnableBlendModePreserveSpecularLighting) > 0.0f;

            CoreUtils.SetKeyword(material, "_BLENDMODE_PRESERVE_SPECULAR_LIGHTING", enableBlendModePreserveSpecularLighting);

            bool transparentWritesMotionVec = (surfaceType == SurfaceType.Transparent) && material.HasProperty(kTransparentWritingMotionVec) && material.GetInt(kTransparentWritingMotionVec) > 0;

            CoreUtils.SetKeyword(material, "_TRANSPARENT_WRITES_MOTION_VEC", transparentWritesMotionVec);

            // These need to always been set either with opaque or transparent! So a users can switch to opaque and remove the keyword correctly
            CoreUtils.SetKeyword(material, "_BLENDMODE_ALPHA", false);
            CoreUtils.SetKeyword(material, "_BLENDMODE_ADD", false);
            CoreUtils.SetKeyword(material, "_BLENDMODE_PRE_MULTIPLY", false);

            HDRenderQueue.RenderQueueType renderQueueType = HDRenderQueue.GetTypeByRenderQueueValue(material.renderQueue);
            bool needOffScreenBlendFactor = renderQueueType == HDRenderQueue.RenderQueueType.AfterPostprocessTransparent || renderQueueType == HDRenderQueue.RenderQueueType.LowTransparent;

            // Alpha tested materials always have a prepass where we perform the clip.
            // Then during Gbuffer pass we don't perform the clip test, so we need to use depth equal in this case.
            if (alphaTestEnable)
            {
                material.SetInt(kZTestGBuffer, (int)UnityEngine.Rendering.CompareFunction.Equal);
            }
            else
            {
                material.SetInt(kZTestGBuffer, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
            }

            // If the material use the kZTestDepthEqualForOpaque it mean it require depth equal test for opaque but transparent are not affected
            if (material.HasProperty(kZTestDepthEqualForOpaque))
            {
                if (surfaceType == SurfaceType.Opaque)
                {
                    // When the material is after post process, we need to use LEssEqual because there is no depth prepass for unlit opaque
                    if (HDRenderQueue.k_RenderQueue_AfterPostProcessOpaque.Contains(material.renderQueue))
                    {
                        material.SetInt(kZTestDepthEqualForOpaque, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
                    }
                    else
                    {
                        material.SetInt(kZTestDepthEqualForOpaque, (int)UnityEngine.Rendering.CompareFunction.Equal);
                    }
                }
                else
                {
                    material.SetInt(kZTestDepthEqualForOpaque, (int)material.GetTransparentZTest());
                }
            }

            if (surfaceType == SurfaceType.Opaque)
            {
                material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                // Caution:  we need to setup One for src and Zero for Dst for all element as users could switch from transparent to Opaque and keep remaining value.
                // Unity will disable Blending based on these default value.
                // Note that for after postprocess we setup 0 in opacity inside the shaders, so we correctly end with 0 in opacity for the compositing pass
                material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt(kZWrite, 1);
            }
            else
            {
                material.SetOverrideTag("RenderType", "Transparent");
                material.SetInt(kZWrite, material.GetTransparentZWrite() ? 1 : 0);

                if (material.HasProperty(kBlendMode))
                {
                    BlendMode blendMode = material.GetBlendMode();

                    CoreUtils.SetKeyword(material, "_BLENDMODE_ALPHA", BlendMode.Alpha == blendMode);
                    CoreUtils.SetKeyword(material, "_BLENDMODE_ADD", BlendMode.Additive == blendMode);
                    CoreUtils.SetKeyword(material, "_BLENDMODE_PRE_MULTIPLY", BlendMode.Premultiply == blendMode);

                    // When doing off-screen transparency accumulation, we change blend factors as described here: https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch23.html
                    switch (blendMode)
                    {
                    // Alpha
                    // color: src * src_a + dst * (1 - src_a)
                    // src * src_a is done in the shader as it allow to reduce precision issue when using _BLENDMODE_PRESERVE_SPECULAR_LIGHTING (See Material.hlsl)
                    case BlendMode.Alpha:
                        material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                        material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                        if (needOffScreenBlendFactor)
                        {
                            material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                            material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                        }
                        else
                        {
                            material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                            material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                        }
                        break;

                    // Additive
                    // color: src * src_a + dst
                    // src * src_a is done in the shader
                    case BlendMode.Additive:
                        material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                        material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
                        if (needOffScreenBlendFactor)
                        {
                            material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                            material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.One);
                        }
                        else
                        {
                            material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                            material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.One);
                        }
                        break;

                    // PremultipliedAlpha
                    // color: src * src_a + dst * (1 - src_a)
                    // src is supposed to have been multiplied by alpha in the texture on artists side.
                    case BlendMode.Premultiply:
                        material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                        material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                        if (needOffScreenBlendFactor)
                        {
                            material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                            material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                        }
                        else
                        {
                            material.SetInt("_AlphaSrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                            material.SetInt("_AlphaDstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                        }
                        break;
                    }
                }
            }

            bool fogEnabled = material.HasProperty(kEnableFogOnTransparent) && material.GetFloat(kEnableFogOnTransparent) > 0.0f && surfaceType == SurfaceType.Transparent;

            CoreUtils.SetKeyword(material, "_ENABLE_FOG_ON_TRANSPARENT", fogEnabled);

            if (material.HasProperty(kDistortionEnable) && material.HasProperty(kDistortionBlendMode))
            {
                bool distortionDepthTest = material.GetFloat(kDistortionDepthTest) > 0.0f;
                if (material.HasProperty(kZTestModeDistortion))
                {
                    if (distortionDepthTest)
                    {
                        material.SetInt(kZTestModeDistortion, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
                    }
                    else
                    {
                        material.SetInt(kZTestModeDistortion, (int)UnityEngine.Rendering.CompareFunction.Always);
                    }
                }

                var distortionBlendMode = material.GetInt(kDistortionBlendMode);
                switch (distortionBlendMode)
                {
                default:
                case 0:     // Add
                    material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                    material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.One);

                    material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                    material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.One);
                    material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add);
                    break;

                case 1:     // Multiply
                    material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
                    material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);

                    material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.DstAlpha);
                    material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                    material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add);
                    break;

                case 2:     // Replace
                    material.SetInt("_DistortionSrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                    material.SetInt("_DistortionDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);

                    material.SetInt("_DistortionBlurSrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                    material.SetInt("_DistortionBlurDstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                    material.SetInt("_DistortionBlurBlendOp", (int)UnityEngine.Rendering.BlendOp.Add);
                    break;
                }
            }

            CullMode doubleSidedOffMode = (surfaceType == SurfaceType.Transparent) ? material.GetTransparentCullMode() : material.GetOpaqueCullMode();

            bool isBackFaceEnable  = material.HasProperty(kTransparentBackfaceEnable) && material.GetFloat(kTransparentBackfaceEnable) > 0.0f && surfaceType == SurfaceType.Transparent;
            bool doubleSidedEnable = material.HasProperty(kDoubleSidedEnable) && material.GetFloat(kDoubleSidedEnable) > 0.0f;

            // Disable culling if double sided
            material.SetInt("_CullMode", doubleSidedEnable ? (int)UnityEngine.Rendering.CullMode.Off : (int)doubleSidedOffMode);

            // We have a separate cullmode (_CullModeForward) for Forward in case we use backface then frontface rendering, need to configure it
            if (isBackFaceEnable)
            {
                material.SetInt("_CullModeForward", (int)UnityEngine.Rendering.CullMode.Back);
            }
            else
            {
                material.SetInt("_CullModeForward", (int)(doubleSidedEnable ? UnityEngine.Rendering.CullMode.Off : doubleSidedOffMode));
            }

            CoreUtils.SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable);

            // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect
            // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color.
            // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color.
            if (material.HasProperty(kEmissionColor))
            {
                material.SetColor(kEmissionColor, Color.white); // kEmissionColor must always be white to allow our own material to control the GI (this allow to fallback from builtin unity to our system).
                                                                // as it happen with old material that it isn't the case, we force it.
                MaterialEditor.FixupEmissiveFlag(material);
            }

            // Commented out for now because unfortunately we used the hard coded property names used by the GI system for our own parameters
            // So we need a way to work around that before we activate this.
            material.SetupMainTexForAlphaTestGI("_EmissiveColorMap", "_EmissiveColor");

            // depth offset for ShaderGraphs (they don't have the displacement mode property)
            if (!material.HasProperty(kDisplacementMode) && material.HasProperty(kDepthOffsetEnable))
            {
                // Depth offset is only enabled if per pixel displacement is
                bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f);
                CoreUtils.SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable);
            }

            // DoubleSidedGI has to be synced with our double sided toggle
            var serializedObject = new SerializedObject(material);
            var doubleSidedGIppt = serializedObject.FindProperty("m_DoubleSidedGI");

            doubleSidedGIppt.boolValue = doubleSidedEnable;
            serializedObject.ApplyModifiedProperties();
        }
Beispiel #21
0
        void UpgradeHDLitMasterNode(HDLitMasterNode1 hdLitMasterNode, out Dictionary <BlockFieldDescriptor, int> blockMap)
        {
            // Set data
            systemData.surfaceType     = (SurfaceType)hdLitMasterNode.m_SurfaceType;
            systemData.blendMode       = HDSubShaderUtilities.UpgradeLegacyAlphaModeToBlendMode((int)hdLitMasterNode.m_AlphaMode);
            systemData.renderQueueType = HDRenderQueue.MigrateRenderQueueToHDRP10(hdLitMasterNode.m_RenderingPass);
            if (systemData.renderQueueType == HDRenderQueue.RenderQueueType.PreRefraction && !hdLitMasterNode.m_DrawBeforeRefraction)
            {
                systemData.renderQueueType = HDRenderQueue.RenderQueueType.Transparent;
            }
            // Patch rendering pass in case the master node had an old configuration
            if (systemData.renderQueueType == HDRenderQueue.RenderQueueType.Background)
            {
                systemData.renderQueueType = HDRenderQueue.RenderQueueType.Opaque;
            }
            systemData.alphaTest           = hdLitMasterNode.m_AlphaTest;
            systemData.sortPriority        = hdLitMasterNode.m_SortPriority;
            systemData.doubleSidedMode     = hdLitMasterNode.m_DoubleSidedMode;
            systemData.transparentZWrite   = hdLitMasterNode.m_ZWrite;
            systemData.transparentCullMode = hdLitMasterNode.m_transparentCullMode;
            systemData.zTest                   = hdLitMasterNode.m_ZTest;
            systemData.dotsInstancing          = hdLitMasterNode.m_DOTSInstancing;
            systemData.materialNeedsUpdateHash = hdLitMasterNode.m_MaterialNeedsUpdateHash;

            builtinData.transparentDepthPrepass  = hdLitMasterNode.m_AlphaTestDepthPrepass;
            builtinData.transparentDepthPostpass = hdLitMasterNode.m_AlphaTestDepthPostpass;
            builtinData.supportLodCrossFade      = hdLitMasterNode.m_SupportLodCrossFade;
            builtinData.transparencyFog          = hdLitMasterNode.m_TransparencyFog;
            builtinData.distortion                 = hdLitMasterNode.m_Distortion;
            builtinData.distortionMode             = hdLitMasterNode.m_DistortionMode;
            builtinData.distortionDepthTest        = hdLitMasterNode.m_DistortionDepthTest;
            builtinData.transparentWritesMotionVec = hdLitMasterNode.m_TransparentWritesMotionVec;
            builtinData.addPrecomputedVelocity     = hdLitMasterNode.m_AddPrecomputedVelocity;
            builtinData.depthOffset                = hdLitMasterNode.m_depthOffset;
            builtinData.alphaToMask                = hdLitMasterNode.m_AlphaToMask;

            builtinData.alphaTestShadow        = hdLitMasterNode.m_AlphaTestShadow;
            builtinData.backThenFrontRendering = hdLitMasterNode.m_BackThenFrontRendering;
            lightingData.normalDropOffSpace    = hdLitMasterNode.m_NormalDropOffSpace;
            lightingData.blendPreserveSpecular = hdLitMasterNode.m_BlendPreserveSpecular;
            lightingData.receiveDecals         = hdLitMasterNode.m_ReceiveDecals;
            lightingData.receiveSSR            = hdLitMasterNode.m_ReceivesSSR;
            lightingData.receiveSSRTransparent = hdLitMasterNode.m_ReceivesSSRTransparent;
            lightingData.specularAA            = hdLitMasterNode.m_SpecularAA;
            lightingData.specularOcclusionMode = hdLitMasterNode.m_SpecularOcclusionMode;
            lightingData.overrideBakedGI       = hdLitMasterNode.m_overrideBakedGI;
            HDLitData.MaterialType materialType = (HDLitData.MaterialType)hdLitMasterNode.m_MaterialType;

            litData.clearCoat = UpgradeCoatMask(hdLitMasterNode);
            litData.energyConservingSpecular = hdLitMasterNode.m_EnergyConservingSpecular;
            litData.rayTracing      = hdLitMasterNode.m_RayTracing;
            litData.refractionModel = hdLitMasterNode.m_RefractionModel;
            litData.materialType    = materialType;
            litData.sssTransmission = hdLitMasterNode.m_SSSTransmission;

            target.customEditorGUI = hdLitMasterNode.m_OverrideEnabled ? hdLitMasterNode.m_ShaderGUIOverride : "";

            // Handle mapping of Normal block specifically
            BlockFieldDescriptor normalBlock;
            BlockFieldDescriptor tangentBlock;

            switch (lightingData.normalDropOffSpace)
            {
            case NormalDropOffSpace.Object:
                normalBlock  = BlockFields.SurfaceDescription.NormalOS;
                tangentBlock = HDBlockFields.SurfaceDescription.TangentOS;
                break;

            case NormalDropOffSpace.World:
                normalBlock  = BlockFields.SurfaceDescription.NormalWS;
                tangentBlock = HDBlockFields.SurfaceDescription.TangentWS;
                break;

            default:
                normalBlock  = BlockFields.SurfaceDescription.NormalTS;
                tangentBlock = HDBlockFields.SurfaceDescription.TangentTS;
                break;
            }

            // Convert SlotMask to BlockMap entries
            var blockMapLookup = new Dictionary <HDLitMasterNode1.SlotMask, BlockFieldDescriptor>()
            {
                { HDLitMasterNode1.SlotMask.Albedo, BlockFields.SurfaceDescription.BaseColor },
                { HDLitMasterNode1.SlotMask.Normal, normalBlock },
                { HDLitMasterNode1.SlotMask.BentNormal, HDBlockFields.SurfaceDescription.BentNormal },
                { HDLitMasterNode1.SlotMask.Tangent, tangentBlock },
                { HDLitMasterNode1.SlotMask.Anisotropy, HDBlockFields.SurfaceDescription.Anisotropy },
                { HDLitMasterNode1.SlotMask.SubsurfaceMask, HDBlockFields.SurfaceDescription.SubsurfaceMask },
                { HDLitMasterNode1.SlotMask.Thickness, HDBlockFields.SurfaceDescription.Thickness },
                { HDLitMasterNode1.SlotMask.DiffusionProfile, HDBlockFields.SurfaceDescription.DiffusionProfileHash },
                { HDLitMasterNode1.SlotMask.IridescenceMask, HDBlockFields.SurfaceDescription.IridescenceMask },
                { HDLitMasterNode1.SlotMask.IridescenceLayerThickness, HDBlockFields.SurfaceDescription.IridescenceThickness },
                { HDLitMasterNode1.SlotMask.Specular, BlockFields.SurfaceDescription.Specular },
                { HDLitMasterNode1.SlotMask.CoatMask, BlockFields.SurfaceDescription.CoatMask },
                { HDLitMasterNode1.SlotMask.Metallic, BlockFields.SurfaceDescription.Metallic },
                { HDLitMasterNode1.SlotMask.Smoothness, BlockFields.SurfaceDescription.Smoothness },
                { HDLitMasterNode1.SlotMask.Occlusion, BlockFields.SurfaceDescription.Occlusion },
                { HDLitMasterNode1.SlotMask.SpecularOcclusion, HDBlockFields.SurfaceDescription.SpecularOcclusion },
                { HDLitMasterNode1.SlotMask.Emission, BlockFields.SurfaceDescription.Emission },
                { HDLitMasterNode1.SlotMask.Alpha, BlockFields.SurfaceDescription.Alpha },
                { HDLitMasterNode1.SlotMask.AlphaThreshold, BlockFields.SurfaceDescription.AlphaClipThreshold },
                { HDLitMasterNode1.SlotMask.AlphaThresholdDepthPrepass, HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPrepass },
                { HDLitMasterNode1.SlotMask.AlphaThresholdDepthPostpass, HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPostpass },
                { HDLitMasterNode1.SlotMask.AlphaThresholdShadow, HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow },
            };

            // Legacy master node slots have additional slot conditions, test them here
            bool AdditionalSlotMaskTests(HDLitMasterNode1.SlotMask slotMask)
            {
                switch (slotMask)
                {
                case HDLitMasterNode1.SlotMask.Thickness:
                    return(litData.sssTransmission || litData.materialType == HDLitData.MaterialType.Translucent);

                case HDLitMasterNode1.SlotMask.SpecularOcclusion:
                    return(lightingData.specularOcclusionMode == SpecularOcclusionMode.Custom);

                case HDLitMasterNode1.SlotMask.AlphaThreshold:
                    return(systemData.alphaTest);

                case HDLitMasterNode1.SlotMask.AlphaThresholdDepthPrepass:
                    return(systemData.surfaceType == SurfaceType.Transparent && systemData.alphaTest && builtinData.transparentDepthPrepass);

                case HDLitMasterNode1.SlotMask.AlphaThresholdDepthPostpass:
                    return(systemData.surfaceType == SurfaceType.Transparent && systemData.alphaTest && builtinData.transparentDepthPostpass);

                case HDLitMasterNode1.SlotMask.AlphaThresholdShadow:
                    return(systemData.alphaTest && builtinData.alphaTestShadow);

                default:
                    return(true);
                }
            }

            bool UpgradeCoatMask(HDLitMasterNode1 masterNode)
            {
                var coatMaskSlotId = HDLitMasterNode1.CoatMaskSlotId;

                var node         = masterNode as AbstractMaterialNode;
                var coatMaskSlot = node.FindSlot <Vector1MaterialSlot>(coatMaskSlotId);

                if (coatMaskSlot == null)
                {
                    return(false);
                }

                coatMaskSlot.owner = node;
                return(coatMaskSlot.isConnected || coatMaskSlot.value > 0.0f);
            }

            // Set blockmap
            blockMap = new Dictionary <BlockFieldDescriptor, int>();

            // First handle vertex blocks. We ran out of SlotMask bits for VertexNormal and VertexTangent
            // so do all Vertex blocks here to maintain correct block order (Position is not in blockMapLookup)
            blockMap.Add(BlockFields.VertexDescription.Position, HDLitMasterNode1.PositionSlotId);
            blockMap.Add(BlockFields.VertexDescription.Normal, HDLitMasterNode1.VertexNormalSlotID);
            blockMap.Add(BlockFields.VertexDescription.Tangent, HDLitMasterNode1.VertexTangentSlotID);

            // Now handle the SlotMask cases
            foreach (HDLitMasterNode1.SlotMask slotMask in Enum.GetValues(typeof(HDLitMasterNode1.SlotMask)))
            {
                if (hdLitMasterNode.MaterialTypeUsesSlotMask(slotMask))
                {
                    if (!blockMapLookup.TryGetValue(slotMask, out var blockFieldDescriptor))
                    {
                        continue;
                    }

                    if (!AdditionalSlotMaskTests(slotMask))
                    {
                        continue;
                    }

                    var slotId = Mathf.Log((int)slotMask, 2);
                    blockMap.Add(blockFieldDescriptor, (int)slotId);
                }
            }

            // Specular AA
            if (lightingData.specularAA)
            {
                blockMap.Add(HDBlockFields.SurfaceDescription.SpecularAAScreenSpaceVariance, HDLitMasterNode1.SpecularAAScreenSpaceVarianceSlotId);
                blockMap.Add(HDBlockFields.SurfaceDescription.SpecularAAThreshold, HDLitMasterNode1.SpecularAAThresholdSlotId);
            }

            // Refraction
            bool hasRefraction = (systemData.surfaceType == SurfaceType.Transparent && systemData.renderQueueType != HDRenderQueue.RenderQueueType.PreRefraction && litData.refractionModel != ScreenSpaceRefraction.RefractionModel.None);

            if (hasRefraction)
            {
                if (!blockMap.TryGetValue(HDBlockFields.SurfaceDescription.Thickness, out _))
                {
                    blockMap.Add(HDBlockFields.SurfaceDescription.Thickness, HDLitMasterNode1.ThicknessSlotId);
                }

                blockMap.Add(HDBlockFields.SurfaceDescription.RefractionIndex, HDLitMasterNode1.RefractionIndexSlotId);
                blockMap.Add(HDBlockFields.SurfaceDescription.RefractionColor, HDLitMasterNode1.RefractionColorSlotId);
                blockMap.Add(HDBlockFields.SurfaceDescription.RefractionDistance, HDLitMasterNode1.RefractionDistanceSlotId);
            }

            // Distortion
            bool hasDistortion = (systemData.surfaceType == SurfaceType.Transparent && builtinData.distortion);

            if (hasDistortion)
            {
                blockMap.Add(HDBlockFields.SurfaceDescription.Distortion, HDLitMasterNode1.DistortionSlotId);
                blockMap.Add(HDBlockFields.SurfaceDescription.DistortionBlur, HDLitMasterNode1.DistortionBlurSlotId);
            }

            // Override Baked GI
            if (lightingData.overrideBakedGI)
            {
                blockMap.Add(HDBlockFields.SurfaceDescription.BakedGI, HDLitMasterNode1.LightingSlotId);
                blockMap.Add(HDBlockFields.SurfaceDescription.BakedBackGI, HDLitMasterNode1.BackLightingSlotId);
            }

            // Depth Offset (Removed from SlotMask because of missing bits)
            if (builtinData.depthOffset)
            {
                blockMap.Add(HDBlockFields.SurfaceDescription.DepthOffset, HDLitMasterNode1.DepthOffsetSlotId);
            }
        }
        /// <summary>
        /// Renders the properties in the block.
        /// </summary>
        public override void OnGUI()
        {
            if (refractionModel != null)
            {
                materialEditor.ShaderProperty(refractionModel, Styles.refractionModelText);
                var mode = (ScreenSpaceRefraction.RefractionModel)refractionModel.floatValue;
                switch (mode)
                {
                case ScreenSpaceRefraction.RefractionModel.Box:
                case ScreenSpaceRefraction.RefractionModel.Sphere:
                {
                    if (ior != null)
                    {
                        materialEditor.ShaderProperty(ior, Styles.refractionIorText);
                    }

                    if (thicknessMap[0] != null)
                    {
                        if (thicknessMap[0].textureValue == null)
                        {
                            materialEditor.TexturePropertySingleLine(Styles.refractionThicknessText, thicknessMap[0], thickness[0]);
                        }
                        else
                        {
                            materialEditor.TexturePropertySingleLine(Styles.refractionThicknessMapText, thicknessMap[0]);
                            // Display the remap of texture values.
                            materialEditor.MinMaxShaderProperty(thicknessRemap[0], 0.0f, 1.0f, Styles.refractionThicknessRemappingText);
                        }
                    }

                    if (transmittanceColorMap != null)
                    {
                        materialEditor.TexturePropertySingleLine(Styles.transmittanceColorText, transmittanceColorMap, transmittanceColor);
                        ++EditorGUI.indentLevel;
                        materialEditor.ShaderProperty(atDistance, Styles.atDistanceText);
                        atDistance.floatValue = Mathf.Max(atDistance.floatValue, 0);
                        --EditorGUI.indentLevel;
                    }
                }
                break;

                case ScreenSpaceRefraction.RefractionModel.Thin:
                {
                    if (ior != null)
                    {
                        materialEditor.ShaderProperty(ior, Styles.refractionIorText);
                    }
                    if (transmittanceColorMap != null)
                    {
                        materialEditor.TexturePropertySingleLine(Styles.transmittanceColorText, transmittanceColorMap, transmittanceColor);
                    }
                }
                break;

                default:
                    break;
                }

                if (refractionModel.floatValue != 0 && blendMode != null)
                {
                    if (blendMode.floatValue != (int)BlendMode.Alpha)
                    {
                        EditorGUILayout.HelpBox(Styles.refractionBlendModeWarning, MessageType.Warning);
                    }

                    // Check for multi-selection render queue different values
                    if (materials.Length == 1 || materials.All(m => m.renderQueue == materials[0].renderQueue))
                    {
                        var renderQueueType = HDRenderQueue.GetTypeByRenderQueueValue(materials[0].renderQueue);

                        if (renderQueueType == HDRenderQueue.RenderQueueType.PreRefraction)
                        {
                            EditorGUILayout.HelpBox(Styles.refractionRenderingPassWarning, MessageType.Warning);
                        }
                    }
                }
            }
        }
Beispiel #23
0
        public override void Convert(Material srcMaterial, Material dstMaterial)
        {
            dstMaterial.hideFlags = HideFlags.DontUnloadUnusedAsset;

            base.Convert(srcMaterial, dstMaterial);

            // ---------- Mask Map ----------

            // Metallic
            bool    hasMetallic = false;
            Texture metallicMap = TextureCombiner.TextureFromColor(Color.black);

            if ((srcMaterial.shader.name == Standard) || (srcMaterial.shader.name == Standard_Rough))
            {
                hasMetallic = srcMaterial.GetTexture("_MetallicGlossMap") != null;
                if (hasMetallic)
                {
                    metallicMap = TextureCombiner.GetTextureSafe(srcMaterial, "_MetallicGlossMap", Color.white);
                }
                else
                {
                    metallicMap = TextureCombiner.TextureFromColor(Color.white);
                }

                // Convert _Metallic value from Gamma to Linear, or set to 1 if a map is used
                float metallicValue = Mathf.Pow(srcMaterial.GetFloat("_Metallic"), 2.2f);
                dstMaterial.SetFloat("_Metallic", hasMetallic? 1f : metallicValue);
            }

            // Occlusion
            bool    hasOcclusion = srcMaterial.GetTexture("_OcclusionMap") != null;
            Texture occlusionMap = Texture2D.whiteTexture;

            if (hasOcclusion)
            {
                occlusionMap = TextureCombiner.GetTextureSafe(srcMaterial, "_OcclusionMap", Color.white);
            }

            dstMaterial.SetFloat("_AORemapMin", 1f - srcMaterial.GetFloat("_OcclusionStrength"));

            // Detail Mask
            bool    hasDetailMask = srcMaterial.GetTexture("_DetailMask") != null;
            Texture detailMaskMap = Texture2D.whiteTexture;

            if (hasDetailMask)
            {
                detailMaskMap = TextureCombiner.GetTextureSafe(srcMaterial, "_DetailMask", Color.white);
            }

            // Smoothness
            bool      hasSmoothness = false;
            Texture2D smoothnessMap = TextureCombiner.TextureFromColor(Color.white);

            dstMaterial.SetFloat("_SmoothnessRemapMax", srcMaterial.GetFloat("_Glossiness"));

            if (srcMaterial.shader.name == Standard_Rough)
            {
                hasSmoothness = srcMaterial.GetTexture("_SpecGlossMap") != null;

                if (hasSmoothness)
                {
                    smoothnessMap = (Texture2D)TextureCombiner.GetTextureSafe(srcMaterial, "_SpecGlossMap", Color.grey);
                }
            }
            else
            {
                string smoothnessTextureChannel = "_MainTex";

                if (srcMaterial.GetFloat("_SmoothnessTextureChannel") == 0)
                {
                    if (srcMaterial.shader.name == Standard)
                    {
                        smoothnessTextureChannel = "_MetallicGlossMap";
                    }
                    if (srcMaterial.shader.name == Standard_Spec)
                    {
                        smoothnessTextureChannel = "_SpecGlossMap";
                    }
                }

                smoothnessMap = (Texture2D)srcMaterial.GetTexture(smoothnessTextureChannel);
                if (smoothnessMap != null)
                {
                    hasSmoothness = true;

                    dstMaterial.SetFloat("_SmoothnessRemapMax", srcMaterial.GetFloat("_GlossMapScale"));

                    if (!TextureCombiner.TextureHasAlpha(smoothnessMap))
                    {
                        smoothnessMap = TextureCombiner.TextureFromColor(Color.white);
                    }
                }
                else
                {
                    smoothnessMap = TextureCombiner.TextureFromColor(Color.white);
                }
            }


            // Build the mask map
            if (hasMetallic || hasOcclusion || hasDetailMask || hasSmoothness)
            {
                Texture2D maskMap;

                TextureCombiner maskMapCombiner = new TextureCombiner(
                    metallicMap, 0,                                                         // R: Metallic from red
                    occlusionMap, 1,                                                        // G: Occlusion from green
                    detailMaskMap, 3,                                                       // B: Detail Mask from alpha
                    smoothnessMap, (srcMaterial.shader.name == Standard_Rough) ? -4 : 3     // A: Smoothness Texture from inverse greyscale for roughness setup, or alpha
                    );

                string maskMapPath = AssetDatabase.GetAssetPath(srcMaterial);
                maskMapPath = maskMapPath.Remove(maskMapPath.Length - 4) + "_MaskMap.png";
                maskMap     = maskMapCombiner.Combine(maskMapPath);
                dstMaterial.SetTexture("_MaskMap", maskMap);
            }

            // Specular Setup Specific
            if (srcMaterial.shader.name == Standard_Spec)
            {
                // if there is a specular map, change the specular color to white
                if (srcMaterial.GetTexture("_SpecGlossMap") != null)
                {
                    dstMaterial.SetColor("_SpecularColor", Color.white);
                }
            }

            // ---------- Height Map ----------
            bool hasHeightMap = srcMaterial.GetTexture("_ParallaxMap") != null;

            if (hasHeightMap) // Enable Parallax Occlusion Mapping
            {
                dstMaterial.SetFloat("_DisplacementMode", 2);
                dstMaterial.SetFloat("_HeightPoMAmplitude", srcMaterial.GetFloat("_Parallax") * 2f);
            }

            // ---------- Detail Map ----------
            bool hasDetailAlbedo = srcMaterial.GetTexture("_DetailAlbedoMap") != null;
            bool hasDetailNormal = srcMaterial.GetTexture("_DetailNormalMap") != null;

            if (hasDetailAlbedo || hasDetailNormal)
            {
                Texture2D       detailMap;
                TextureCombiner detailCombiner = new TextureCombiner(
                    TextureCombiner.GetTextureSafe(srcMaterial, "_DetailAlbedoMap", Color.grey), 4,     // Albedo (overlay)
                    TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 1,     // Normal Y
                    TextureCombiner.midGrey, 1,                                                         // Smoothness
                    TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 0      // Normal X
                    );
                string detailMapPath = AssetDatabase.GetAssetPath(srcMaterial);
                detailMapPath = detailMapPath.Remove(detailMapPath.Length - 4) + "_DetailMap.png";
                detailMap     = detailCombiner.Combine(detailMapPath);
                dstMaterial.SetTexture("_DetailMap", detailMap);
            }


            // Blend Mode
            int previousBlendMode = srcMaterial.GetInt("_Mode");

            switch (previousBlendMode)
            {
            case 0:     // Opaque
                dstMaterial.SetFloat("_SurfaceType", 0);
                dstMaterial.SetFloat("_BlendMode", 0);
                dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
                dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
                dstMaterial.renderQueue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Opaque, 0, false, true);
                break;

            case 1:     // Cutout
                dstMaterial.SetFloat("_SurfaceType", 0);
                dstMaterial.SetFloat("_BlendMode", 0);
                dstMaterial.SetFloat("_AlphaCutoffEnable", 1);
                dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
                dstMaterial.renderQueue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Opaque, 0, true, true);
                break;

            case 2:     // Fade -> Alpha with depth prepass + Disable preserve specular
                dstMaterial.SetFloat("_SurfaceType", 1);
                dstMaterial.SetFloat("_BlendMode", 0);
                dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
                dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 0);
                dstMaterial.SetFloat("_TransparentDepthPrepassEnable", 1);
                dstMaterial.renderQueue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Transparent, 0, false, true);
                break;

            case 3:     // Transparent -> Alpha
                dstMaterial.SetFloat("_SurfaceType", 1);
                dstMaterial.SetFloat("_BlendMode", 0);
                dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
                dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
                dstMaterial.renderQueue = HDRenderQueue.ChangeType(HDRenderQueue.RenderQueueType.Transparent, 0, false, true);
                break;
            }

            Color hdrEmission = srcMaterial.GetColor("_EmissionColor");

            // Get the _EMISSION keyword of the Standard shader
            if (!srcMaterial.IsKeywordEnabled("_EMISSION"))
            {
                hdrEmission = Color.black;
            }

            // Emission toggle of Particle Standard Surface
            if (srcMaterial.HasProperty("_EmissionEnabled"))
            {
                if (srcMaterial.GetFloat("_EmissionEnabled") == 0)
                {
                    hdrEmission = Color.black;
                }
            }

            dstMaterial.SetColor("_EmissiveColor", hdrEmission);

            HDShaderUtils.ResetMaterialKeywords(dstMaterial);
        }
Beispiel #24
0
        public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null)
        {
            if (sourceAssetDependencyPaths != null)
            {
                // HairSubShader.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("c3f20efb64673e0488a2c8e986a453fa"));
                // HDSubShaderUtilities.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b"));
            }

            var masterNode = iMasterNode as HairMasterNode;

            var subShader = new ShaderGenerator();

            subShader.AddShaderChunk("SubShader", true);
            subShader.AddShaderChunk("{", true);
            subShader.Indent();
            {
                // Add tags at the SubShader level
                var renderingPass = masterNode.surfaceType == SurfaceType.Opaque ? HDRenderQueue.RenderQueueType.Opaque : HDRenderQueue.RenderQueueType.Transparent;
                int queue         = HDRenderQueue.ChangeType(renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn);
                HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDLitShader, queue);

                // generate the necessary shader passes
                bool opaque      = (masterNode.surfaceType == SurfaceType.Opaque);
                bool transparent = !opaque;

                bool transparentBackfaceActive      = transparent && masterNode.backThenFrontRendering.isOn;
                bool transparentDepthPrepassActive  = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPrepass.isOn;
                bool transparentDepthPostpassActive = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPostpass.isOn;

                GenerateShaderPassHair(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassHair(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassHair(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths);

                GenerateShaderPassHair(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassHair(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths);

                if (transparentBackfaceActive)
                {
                    GenerateShaderPassHair(masterNode, m_PassTransparentBackface, mode, subShader, sourceAssetDependencyPaths);
                }

                if (transparentDepthPrepassActive)
                {
                    GenerateShaderPassHair(masterNode, m_PassTransparentDepthPrepass, mode, subShader, sourceAssetDependencyPaths);
                }

                // Assign define here based on opaque or transparent to save some variant
                m_PassForwardOnly.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent;
                GenerateShaderPassHair(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths);

                if (transparentDepthPostpassActive)
                {
                    GenerateShaderPassHair(masterNode, m_PassTransparentDepthPostpass, mode, subShader, sourceAssetDependencyPaths);
                }
            }
            subShader.Deindent();
            subShader.AddShaderChunk("}", true);
            subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.HairGUI""");

            return(subShader.GetShaderString(0));
        }
        public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null)
        {
            if (sourceAssetDependencyPaths != null)
            {
                // HDLitSubShader.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("bac1a9627cfec924fa2ea9c65af8eeca"));
                // HDSubShaderUtilities.cs
                sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b"));
            }

            var masterNode = iMasterNode as HDLitMasterNode;

            var subShader = new ShaderGenerator();

            subShader.AddShaderChunk("SubShader", false);
            subShader.AddShaderChunk("{", false);
            subShader.Indent();
            {
                //Handle data migration here as we need to have a renderingPass already set with accurate data at this point.
                if (masterNode.renderingPass == HDRenderQueue.RenderQueueType.Unknown)
                {
                    switch (masterNode.surfaceType)
                    {
                    case SurfaceType.Opaque:
                        masterNode.renderingPass = HDRenderQueue.RenderQueueType.Opaque;
                        break;

                    case SurfaceType.Transparent:
#pragma warning disable CS0618 // Type or member is obsolete
                        if (masterNode.m_DrawBeforeRefraction)
                        {
                            masterNode.m_DrawBeforeRefraction = false;
#pragma warning restore CS0618 // Type or member is obsolete
                            masterNode.renderingPass = HDRenderQueue.RenderQueueType.PreRefraction;
                        }
                        else
                        {
                            masterNode.renderingPass = HDRenderQueue.RenderQueueType.Transparent;
                        }
                        break;

                    default:
                        throw new System.ArgumentException("Unknown SurfaceType");
                    }
                }

                // Add tags at the SubShader level
                int queue = HDRenderQueue.ChangeType(masterNode.renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn);
                HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDLitShader, queue);

                // generate the necessary shader passes
                bool opaque      = (masterNode.surfaceType == SurfaceType.Opaque);
                bool transparent = !opaque;

                bool distortionActive               = transparent && masterNode.distortion.isOn;
                bool transparentBackfaceActive      = transparent && masterNode.backThenFrontRendering.isOn;
                bool transparentDepthPrepassActive  = transparent && masterNode.alphaTestDepthPrepass.isOn;
                bool transparentDepthPostpassActive = transparent && masterNode.alphaTestDepthPostpass.isOn;

                GenerateShaderPassLit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths);

                GenerateShaderPassLit(masterNode, m_PassDepthOnly, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_PassGBuffer, mode, subShader, sourceAssetDependencyPaths);
                GenerateShaderPassLit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths);

                if (distortionActive)
                {
                    GenerateShaderPassLit(masterNode, m_PassDistortion, mode, subShader, sourceAssetDependencyPaths);
                }

                if (transparentBackfaceActive)
                {
                    GenerateShaderPassLit(masterNode, m_PassTransparentBackface, mode, subShader, sourceAssetDependencyPaths);
                }

                // Assign define here based on opaque or transparent to save some variant
                m_PassForward.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent;
                GenerateShaderPassLit(masterNode, m_PassForward, mode, subShader, sourceAssetDependencyPaths);

                if (transparentDepthPrepassActive)
                {
                    GenerateShaderPassLit(masterNode, m_PassTransparentDepthPrepass, mode, subShader, sourceAssetDependencyPaths);
                }

                if (transparentDepthPostpassActive)
                {
                    GenerateShaderPassLit(masterNode, m_PassTransparentDepthPostpass, mode, subShader, sourceAssetDependencyPaths);
                }
            }
            subShader.Deindent();
            subShader.AddShaderChunk("}", false);

#if ENABLE_RAYTRACING
            if (mode == GenerationMode.ForReals)
            {
                subShader.AddShaderChunk("SubShader", false);
                subShader.AddShaderChunk("{", false);
                subShader.Indent();
                {
                    GenerateShaderPassLit(masterNode, m_PassRaytracingIndirect, mode, subShader, sourceAssetDependencyPaths);
                    GenerateShaderPassLit(masterNode, m_PassRaytracingVisibility, mode, subShader, sourceAssetDependencyPaths);
                    GenerateShaderPassLit(masterNode, m_PassRaytracingForward, mode, subShader, sourceAssetDependencyPaths);
                }
                subShader.Deindent();
                subShader.AddShaderChunk("}", false);
            }
#endif
            subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.HDLitGUI""");

            return(subShader.GetShaderString(0));
        }
        protected virtual void BaseMaterialPropertiesGUI()
        {
            SurfaceTypePopup();
            if (surfaceTypeValue == SurfaceType.Transparent)
            {
                EditorGUI.indentLevel++;

                if (blendMode != null && showBlendModePopup)
                {
                    BlendModePopup();
                }

                EditorGUI.indentLevel++;
                if (enableBlendModePreserveSpecularLighting != null && blendMode != null && showBlendModePopup)
                {
                    m_MaterialEditor.ShaderProperty(enableBlendModePreserveSpecularLighting, StylesBaseUnlit.enableBlendModePreserveSpecularLightingText);
                }
                EditorGUI.indentLevel--;

                if (transparentSortPriority != null)
                {
                    EditorGUI.BeginChangeCheck();
                    m_MaterialEditor.ShaderProperty(transparentSortPriority, StylesBaseUnlit.transparentSortPriorityText);
                    if (EditorGUI.EndChangeCheck())
                    {
                        transparentSortPriority.floatValue = HDRenderQueue.ClampsTransparentRangePriority((int)transparentSortPriority.floatValue);
                    }
                }

                if (enableFogOnTransparent != null)
                {
                    m_MaterialEditor.ShaderProperty(enableFogOnTransparent, StylesBaseUnlit.enableTransparentFogText);
                }

                if (transparentBackfaceEnable != null)
                {
                    m_MaterialEditor.ShaderProperty(transparentBackfaceEnable, StylesBaseUnlit.transparentBackfaceEnableText);
                }

                if (transparentDepthPrepassEnable != null)
                {
                    m_MaterialEditor.ShaderProperty(transparentDepthPrepassEnable, StylesBaseUnlit.transparentDepthPrepassEnableText);
                }

                if (transparentDepthPostpassEnable != null)
                {
                    m_MaterialEditor.ShaderProperty(transparentDepthPostpassEnable, StylesBaseUnlit.transparentDepthPostpassEnableText);
                }

                EditorGUI.indentLevel--;
            }

            // This function must finish with double sided option (see LitUI.cs)
            if (doubleSidedEnable != null)
            {
                m_MaterialEditor.ShaderProperty(doubleSidedEnable, StylesBaseUnlit.doubleSidedEnableText);
            }

            if (alphaCutoffEnable != null)
            {
                m_MaterialEditor.ShaderProperty(alphaCutoffEnable, StylesBaseUnlit.alphaCutoffEnableText);
            }

            if (alphaCutoffEnable != null && alphaCutoffEnable.floatValue == 1.0f)
            {
                EditorGUI.indentLevel++;
                m_MaterialEditor.ShaderProperty(alphaCutoff, StylesBaseUnlit.alphaCutoffText);

                if (useShadowThreshold != null)
                {
                    m_MaterialEditor.ShaderProperty(useShadowThreshold, StylesBaseUnlit.useShadowThresholdText);
                }

                if (alphaCutoffShadow != null && useShadowThreshold != null && useShadowThreshold.floatValue == 1.0f)
                {
                    EditorGUI.indentLevel++;
                    m_MaterialEditor.ShaderProperty(alphaCutoffShadow, StylesBaseUnlit.alphaCutoffShadowText);
                    EditorGUI.indentLevel--;
                }

                // With transparent object and few specific materials like Hair, we need more control on the cutoff to apply
                // This allow to get a better sorting (with prepass), better shadow (better silhouettes fidelity) etc...
                if (surfaceTypeValue == SurfaceType.Transparent)
                {
                    if (transparentDepthPrepassEnable != null && transparentDepthPrepassEnable.floatValue == 1.0f)
                    {
                        m_MaterialEditor.ShaderProperty(alphaCutoffPrepass, StylesBaseUnlit.alphaCutoffPrepassText);
                    }

                    if (transparentDepthPostpassEnable != null && transparentDepthPostpassEnable.floatValue == 1.0f)
                    {
                        m_MaterialEditor.ShaderProperty(alphaCutoffPostpass, StylesBaseUnlit.alphaCutoffPostpassText);
                    }
                }
                EditorGUI.indentLevel--;
            }
        }