Пример #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;
        }
        public static string RenderQueueName(HDRenderQueue.RenderQueueType value)
        {
            switch (value)
            {
            case HDRenderQueue.RenderQueueType.Opaque:
                return("Default");

            case HDRenderQueue.RenderQueueType.AfterPostProcessOpaque:
                return("After Post-process");

            case HDRenderQueue.RenderQueueType.PreRefraction:
                return("Before Refraction");

            case HDRenderQueue.RenderQueueType.Transparent:
                return("Default");

            case HDRenderQueue.RenderQueueType.LowTransparent:
                return("Low Resolution");

            case HDRenderQueue.RenderQueueType.AfterPostprocessTransparent:
                return("After Post-process");

            default:
                return("None");
            }
        }
Пример #3
0
        public static bool IsValidRenderingPassValue(HDRenderQueue.RenderQueueType value, bool needAfterPostProcess)
        {
            if (!needAfterPostProcess && (value == HDRenderQueue.RenderQueueType.AfterPostProcessOpaque || value == HDRenderQueue.RenderQueueType.AfterPostprocessTransparent))
            {
                return(false);
            }

            return(true);
        }
Пример #4
0
        public static string RenderQueueName(HDRenderQueue.RenderQueueType value)
        {
            switch (value)
            {
            case HDRenderQueue.RenderQueueType.Opaque:
                return("Default");

            case HDRenderQueue.RenderQueueType.AfterPostProcessOpaque:
                return("After Post-process");

            case HDRenderQueue.RenderQueueType.PreRefraction:
                return("Before Refraction");

            case HDRenderQueue.RenderQueueType.Transparent:
                return("Default");

            case HDRenderQueue.RenderQueueType.LowTransparent:
                return("Low Resolution");

            case HDRenderQueue.RenderQueueType.AfterPostprocessTransparent:
                return("After Post-process");

            case HDRenderQueue.RenderQueueType.RaytracingOpaque:
            {
                if ((RenderPipelineManager.currentPipeline as HDRenderPipeline).rayTracingSupported)
                {
                    return("RayTracing");
                }
                return("None");
            }

            case HDRenderQueue.RenderQueueType.RaytracingTransparent:
            {
                if ((RenderPipelineManager.currentPipeline as HDRenderPipeline).rayTracingSupported)
                {
                    return("RayTracing");
                }
                return("None");
            }

            default:
                return("None");
            }
        }
Пример #5
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();
        }