Beispiel #1
0
        private static void Postprocess(OutlineParameters parameters, float shiftScale, bool scaleIndependent, float bufferScale, int first, int second, Material material, int iterrations, bool additionalShift, float shiftValue, ref int stencil, Rect viewport)
        {
            if (iterrations <= 0)
            {
                return;
            }

            var scalingFactor = scaleIndependent ? bufferScale : 1.0f;

            parameters.Buffer.SetGlobalInt(ComparisonHash, (int)CompareFunction.Always);

            for (var index = 1; index <= iterrations; index++)
            {
                parameters.Buffer.SetGlobalInt(RefHash, stencil);

                var shift = (additionalShift ? (float)index : 1.0f) * scalingFactor;

                parameters.Buffer.SetGlobalVector(ShiftHash, new Vector4(shift * shiftScale, 0));
                Blit(parameters, RenderTargetUtility.ComposeTarget(parameters, first), RenderTargetUtility.ComposeTarget(parameters, second), RenderTargetUtility.ComposeTarget(parameters, second), material, shiftValue, null, -1, viewport);

                parameters.Buffer.SetGlobalVector(ShiftHash, new Vector4(0, shift * shiftScale));
                Blit(parameters, RenderTargetUtility.ComposeTarget(parameters, second), RenderTargetUtility.ComposeTarget(parameters, first), RenderTargetUtility.ComposeTarget(parameters, first), material, shiftValue, null, -1, viewport);

                stencil = (stencil + 1) & 0xFF;
            }
        }
Beispiel #2
0
        private void UpdateParameters(OutlineParameters parameters, Camera camera, bool editorCamera)
        {
            UpdateSharedParameters(parameters, camera, editorCamera);

            parameters.DepthTarget = RenderTargetUtility.ComposeTarget(parameters, BuiltinRenderTextureType.CameraTarget);

            var targetTexture = camera.targetTexture == null ? camera.activeTexture : camera.targetTexture;

            if (UnityEngine.XR.XRSettings.enabled &&
                !parameters.IsEditorCamera &&
                parameters.EyeMask != StereoTargetEyeMask.None)
            {
                var descriptor = UnityEngine.XR.XRSettings.eyeTextureDesc;
                parameters.TargetWidth  = descriptor.width;
                parameters.TargetHeight = descriptor.height;
            }
            else
            {
                parameters.TargetWidth  = targetTexture != null ? targetTexture.width : camera.scaledPixelWidth;
                parameters.TargetHeight = targetTexture != null ? targetTexture.height : camera.scaledPixelHeight;
            }

            parameters.Antialiasing = editorCamera ? (targetTexture == null ? 1 : targetTexture.antiAliasing) : CameraUtility.GetMSAA(targetCamera);

            parameters.Target = RenderTargetUtility.ComposeTarget(parameters, HasCutomRenderTarget && !editorCamera ? GetRenderTarget(parameters) :
                                                                  BuiltinRenderTextureType.CameraTarget);

            Outlinable.GetAllActiveOutlinables(parameters.Camera, parameters.OutlinablesToRender);
            RendererFilteringUtility.Filter(parameters.Camera, parameters);
        }
        public static RenderTextureInfo GetTargetInfo(OutlineParameters parameters, int width, int height, int depthBuffer, bool forceNoAA, bool noFiltering)
        {
            var filterType = noFiltering ? FilterMode.Point : FilterMode.Bilinear;
            var rtFormat   = parameters.UseHDR ? GetHDRFormat() : RenderTextureFormat.ARGB32;

            if (IsUsingVR(parameters))
            {
                var descriptor = UnityEngine.XR.XRSettings.eyeTextureDesc;
                descriptor.colorFormat     = rtFormat;
                descriptor.width           = width;
                descriptor.height          = height;
                descriptor.depthBufferBits = depthBuffer;
                descriptor.msaaSamples     = forceNoAA ? 1 : Mathf.Max(parameters.Antialiasing, 1);

                var eyesCount = parameters.EyeMask == StereoTargetEyeMask.Both ? VRTextureUsage.TwoEyes : VRTextureUsage.OneEye;
                descriptor.vrUsage = eyesCount;

                return(new RenderTextureInfo(descriptor, filterType));
            }
            else
            {
                var descriptor = new RenderTextureDescriptor(width, height, rtFormat, depthBuffer);
                descriptor.dimension   = TextureDimension.Tex2D;
                descriptor.msaaSamples = forceNoAA ? 1 : Mathf.Max(parameters.Antialiasing, 1);

                return(new RenderTextureInfo(descriptor, filterType));
            }
        }
Beispiel #4
0
        private static void PrepareTargets(OutlineParameters parameters)
        {
            targets.Clear();

            foreach (var outlinable in parameters.OutlinablesToRender)
            {
                foreach (var target in outlinable.OutlineTargets)
                {
                    target.UpdateReadyToRender();
                    target.MakeIgnoreOcclusion();
                    target.UpdateRendererType();

                    var renderer = target.Renderer;
                    if (!target.ReadyToRender)
                    {
                        if ((outlinable.DrawingMode & OutlinableDrawingMode.GenericMask) == 0 || renderer == null)
                        {
                            continue;
                        }
                    }

                    targets.Add(new OutlineTargetGroup(outlinable, target));
                }
            }
        }
Beispiel #5
0
        private void SetupOutline(Camera cameraToUse, OutlineParameters parametersToUse, bool isEditor)
        {
            UpdateBuffer(cameraToUse, parametersToUse.Buffer, false);
            UpdateParameters(parametersToUse, cameraToUse, isEditor);

            parametersToUse.Buffer.Clear();
            if (renderingStrategy == OutlineRenderingStrategy.Default)
            {
                OutlineEffect.SetupOutline(parametersToUse);
                parametersToUse.BlitMesh = null;
                parametersToUse.MeshPool.ReleaseAllMeshes();
            }
            else
            {
                temporaryOutlinables.Clear();
                temporaryOutlinables.AddRange(parametersToUse.OutlinablesToRender);

                parametersToUse.OutlinablesToRender.Clear();
                parametersToUse.OutlinablesToRender.Add(null);

                foreach (var outlinable in temporaryOutlinables)
                {
                    parametersToUse.OutlinablesToRender[0] = outlinable;
                    OutlineEffect.SetupOutline(parametersToUse);
                    parametersToUse.BlitMesh = null;
                }

                parametersToUse.MeshPool.ReleaseAllMeshes();
            }
        }
Beispiel #6
0
        private static void SetupDepth(OutlineParameters parameters)
        {
            if (parameters.Depth == BuiltinRenderTextureType.None)
            {
                return;
            }

            parameters.Buffer.SetGlobalTexture(depthHash, parameters.Depth);
        }
Beispiel #7
0
        private static void SetupCutout(OutlineParameters parameters, OutlineTarget target)
        {
            if (target.Renderer == null)
            {
                return;
            }

            if (target.Renderer is SpriteRenderer)
            {
                var spriteRenderer = target.Renderer as SpriteRenderer;
                var sprite         = spriteRenderer.sprite;
                if (sprite == null)
                {
                    parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetCutoutKeyword());
                    return;
                }

                parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetCutoutKeyword());
                parameters.Buffer.SetGlobalFloat(CutoutThresholdHash, target.CutoutThreshold);
                parameters.Buffer.SetGlobalTexture(CutoutTextureHash, spriteRenderer.sprite.texture);

                return;
            }

            var materialToGetTextureFrom = target.Renderer.sharedMaterial;

            if (target.CutoutDescriptionType != CutoutDescriptionType.None &&
                materialToGetTextureFrom != null &&
                materialToGetTextureFrom.HasProperty(target.CutoutTextureId))
            {
                parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetCutoutKeyword());
                parameters.Buffer.SetGlobalFloat(CutoutThresholdHash, target.CutoutThreshold);

                var offset = materialToGetTextureFrom.GetTextureOffset(target.CutoutTextureId);
                var scale  = materialToGetTextureFrom.GetTextureScale(target.CutoutTextureId);

                parameters.Buffer.SetGlobalVector(CutoutTextureSTHash, new Vector4(scale.x, scale.y, offset.x, offset.y));

                var texture = materialToGetTextureFrom.GetTexture(target.CutoutTextureId);
                if (texture == null || texture.dimension != TextureDimension.Tex2DArray)
                {
                    parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetTextureArrayCutoutKeyword());
                }
                else
                {
                    parameters.Buffer.SetGlobalFloat(TextureIndexHash, target.CutoutTextureIndex);
                    parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetTextureArrayCutoutKeyword());
                }

                parameters.Buffer.SetGlobalTexture(CutoutTextureHash, texture);
            }
            else
            {
                parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetCutoutKeyword());
            }
        }
Beispiel #8
0
        private static void SetupDilateKeyword(OutlineParameters parameters)
        {
            KeywordsUtility.GetAllDilateKeywords(keywords);
            foreach (var keyword in keywords)
            {
                parameters.Buffer.DisableShaderKeyword(keyword);
            }

            parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetDilateQualityKeyword(parameters.DilateQuality));
        }
Beispiel #9
0
        public static void Blit(OutlineParameters parameters, RenderTargetIdentifier source, RenderTargetIdentifier destination, RenderTargetIdentifier destinationDepth, Material material, CommandBuffer targetBuffer, int pass = -1)
        {
            var buffer = targetBuffer == null ? parameters.Buffer : targetBuffer;

            buffer.SetRenderTarget(destination, destinationDepth);

            buffer.SetGlobalTexture(MainTexHash, source);

            buffer.DrawMesh(parameters.BlitMesh, Matrix4x4.identity, material, 0, pass);
        }
Beispiel #10
0
        private static void SetupBlurKeyword(OutlineParameters parameters)
        {
            KeywordsUtility.GetAllBlurKeywords(keywords);
            foreach (var keyword in keywords)
            {
                parameters.Buffer.DisableShaderKeyword(keyword);
            }

            parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetBlurKeyword(parameters.BlurType));
        }
Beispiel #11
0
        public static void Draw(OutlineParameters parameters, RenderTargetIdentifier target, RenderTargetIdentifier depth, Material material, Rect?viewport = null)
        {
            parameters.Buffer.SetRenderTarget(target, depth);
            if (viewport.HasValue)
            {
                parameters.Buffer.SetViewport(viewport.Value);
            }

            parameters.Buffer.DrawMesh(parameters.BlitMesh, Matrix4x4.identity, material, 0, -1);
        }
        public static void GetTemporaryRT(OutlineParameters parameters, int id, int width, int height, int depthBuffer, bool clear, bool forceNoAA, bool noFiltering)
        {
            var info = GetTargetInfo(parameters, width, height, depthBuffer, forceNoAA, noFiltering);

            parameters.Buffer.GetTemporaryRT(id, info.Descriptor, info.FilterMode);
            parameters.Buffer.SetRenderTarget(RenderTargetUtility.ComposeTarget(parameters, id));
            if (clear)
            {
                parameters.Buffer.ClearRenderTarget(true, true, Color.clear);
            }
        }
Beispiel #13
0
        private static float ComputeEffectShift(OutlineParameters parameters)
        {
            var effectShift = GetBlurShift(parameters.BlurType, parameters.BlurIterations) * parameters.BlurShift + parameters.DilateIterations * 4.0f * parameters.DilateShift;

            if (!parameters.ScaleIndependent)
            {
                effectShift /= parameters.PrimaryBufferScale;
            }

            return(effectShift * 2.0f);
        }
Beispiel #14
0
        private static bool SetupCutout(OutlineParameters parameters, Renderer renderer)
        {
            var module = renderer.GetComponent <CutoutOutlineModule>();

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

            parameters.Buffer.SetGlobalTexture(alphaTextureHash, module.CutoutTexture);
            parameters.Buffer.SetGlobalFloat(cutoutHash, module.CutoutAlpha);

            return(true);
        }
Beispiel #15
0
        private static void GetTemporaryRT(OutlineParameters parameters, int id, int width, int height, int depthBuffer)
        {
            var rtFormat = parameters.UseHDR ? GetHDRFormat() : RenderTextureFormat.ARGB32;

            if (parameters.Antialiasing > 1)
            {
                parameters.Buffer.GetTemporaryRT(id, width, height, depthBuffer, FilterMode.Bilinear, rtFormat,
                                                 RenderTextureReadWrite.Default, parameters.Antialiasing);
            }
            else
            {
                parameters.Buffer.GetTemporaryRT(id, width, height, depthBuffer, FilterMode.Bilinear, rtFormat,
                                                 RenderTextureReadWrite.Default);
            }
        }
Beispiel #16
0
        public RenderTexture GetTarget(OutlineParameters parameters, string name)
        {
            RenderTexture result = null;

            if (!targets.TryGetValue(name, out result))
            {
                var info = RenderTargetUtility.GetTargetInfo(parameters, parameters.TargetWidth, parameters.TargetHeight, 24, false, false);
                result            = RenderTexture.GetTemporary(info.Descriptor);
                result.filterMode = info.FilterMode;

                targets.Add(name, result);

                return(result);
            }

            Shader.SetGlobalTexture(name, result);
            return(result);
        }
Beispiel #17
0
        public void UpdateSharedParameters(OutlineParameters parameters, Camera camera, bool editorCamera)
        {
            parameters.DilateQuality      = DilateQuality;
            parameters.ScaleIndependent   = scaleIndepented;
            parameters.Camera             = camera;
            parameters.IsEditorCamera     = editorCamera;
            parameters.PrimaryBufferScale = primaryRendererScale;
            parameters.BlurIterrantions   = blurIterrations;
            parameters.BlurType           = blurType;
            parameters.DilateIterrations  = dilateIterrations;
            parameters.UseInfoBuffer      = useInfoBuffer;
            parameters.BlurShift          = blurShift;
            parameters.DilateShift        = dilateShift;
            parameters.UseHDR             = camera.allowHDR && (RenderingMode == RenderingMode.HDR);
            parameters.EyeMask            = camera.stereoTargetEye;

            parameters.OutlineLayerMask = outlineLayerMask;
        }
Beispiel #18
0
        public static void Filter(Camera camera, OutlineParameters parameters)
        {
            filteredOutlinables.Clear();

            var mask = parameters.Mask.value & camera.cullingMask;

            foreach (var outlinable in parameters.OutlinablesToRender)
            {
                var layer = 1L << outlinable.OutlineLayer;
                if ((parameters.OutlineLayerMask & layer) == 0)
                {
                    continue;
                }

                var go = outlinable.gameObject;

                if (!go.activeInHierarchy)
                {
                    continue;
                }

                if (((1 << go.layer) & mask) == 0)
                {
                    continue;
                }

#if UNITY_EDITOR
                var stage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();

                if (stage != null && !stage.IsPartOfPrefabContents(outlinable.gameObject))
                {
                    continue;
                }
#endif

                filteredOutlinables.Add(outlinable);
            }

            parameters.OutlinablesToRender.Clear();
            parameters.OutlinablesToRender.AddRange(filteredOutlinables);
        }
Beispiel #19
0
        private static void PrepareTargets(OutlineParameters parameters)
        {
            targets.Clear();

            foreach (var outlinable in parameters.OutlinablesToRender)
            {
                foreach (var target in outlinable.OutlineTargets)
                {
                    var renderer = target.Renderer;
                    if (renderer == null || !renderer.gameObject.activeInHierarchy || !renderer.enabled)
                    {
                        if ((outlinable.DrawingMode & OutlinableDrawingMode.MaskOnly) == 0 || renderer == null)
                        {
                            continue;
                        }
                    }

                    targets.Add(new OutlineTargetGroup(outlinable, target));
                }
            }
        }
Beispiel #20
0
 private static void SetupCull(OutlineParameters parameters, OutlineTarget target)
 {
     parameters.Buffer.SetGlobalInt(CullHash, (int)target.CullMode);
 }
Beispiel #21
0
        private static void DrawFill(OutlineParameters parameters, RenderTargetIdentifier targetSurfance)
        {
            parameters.Buffer.SetRenderTarget(targetSurfance, parameters.DepthTarget);
            if (parameters.CustomViewport.HasValue)
            {
                parameters.Buffer.SetViewport(parameters.CustomViewport.Value);
            }

            var singleMask = 1;
            var frontMask  = 2;
            var backMask   = 3;

            foreach (var outlinable in parameters.OutlinablesToRender)
            {
                if ((outlinable.DrawingMode & OutlinableDrawingMode.Normal) == 0)
                {
                    continue;
                }

                if (outlinable.ComplexMaskingEnabled)
                {
                    parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetBackKeyword(outlinable.ComplexMaskingMode));
                }

                parameters.Buffer.SetGlobalInt(ZTestHash, (int)CompareFunction.Greater);
                foreach (var target in outlinable.OutlineTargets)
                {
                    if (target.Renderer == null)
                    {
                        continue;
                    }

                    var renderer = target.Renderer;
                    if (!renderer.gameObject.activeInHierarchy || !renderer.enabled)
                    {
                        continue;
                    }

                    SetupCutout(parameters, target);
                    SetupCull(parameters, target);

                    parameters.Buffer.SetGlobalInt(FillRefHash, backMask);
                    parameters.Buffer.DrawRenderer(renderer, FillMaskMaterial, target.ShiftedSubmeshIndex);
                }

                if (outlinable.ComplexMaskingEnabled)
                {
                    parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetBackKeyword(outlinable.ComplexMaskingMode));
                }
            }

            foreach (var outlinable in parameters.OutlinablesToRender)
            {
                if ((outlinable.DrawingMode & OutlinableDrawingMode.Normal) == 0)
                {
                    continue;
                }

                parameters.Buffer.SetGlobalInt(ZTestHash, (int)CompareFunction.LessEqual);
                foreach (var target in outlinable.OutlineTargets)
                {
                    if (target.Renderer == null)
                    {
                        continue;
                    }

                    var renderer = target.Renderer;
                    if (!renderer.gameObject.activeInHierarchy || !renderer.enabled)
                    {
                        continue;
                    }

                    SetupCutout(parameters, target);
                    SetupCull(parameters, target);

                    parameters.Buffer.SetGlobalInt(FillRefHash, frontMask);
                    parameters.Buffer.DrawRenderer(renderer, FillMaskMaterial, target.ShiftedSubmeshIndex);
                }
            }

            foreach (var outlinable in parameters.OutlinablesToRender)
            {
                if ((outlinable.DrawingMode & OutlinableDrawingMode.Normal) == 0)
                {
                    continue;
                }

                if (outlinable.RenderStyle == RenderStyle.FrontBack)
                {
                    if ((outlinable.BackParameters.FillPass.Material == null || !outlinable.BackParameters.Enabled) &&
                        (outlinable.FrontParameters.FillPass.Material == null || !outlinable.FrontParameters.Enabled))
                    {
                        continue;
                    }

                    var frontMaterial = outlinable.FrontParameters.FillPass.Material;
                    parameters.Buffer.SetGlobalInt(FillRefHash, frontMask);
                    if (frontMaterial != null && outlinable.FrontParameters.Enabled)
                    {
                        foreach (var target in outlinable.OutlineTargets)
                        {
                            if (target.Renderer == null)
                            {
                                continue;
                            }

                            var renderer = target.Renderer;
                            if (!renderer.gameObject.activeInHierarchy || !renderer.enabled)
                            {
                                continue;
                            }

                            SetupCutout(parameters, target);
                            SetupCull(parameters, target);

                            parameters.Buffer.DrawRenderer(renderer, frontMaterial, target.ShiftedSubmeshIndex);
                        }
                    }

                    var backMaterial = outlinable.BackParameters.FillPass.Material;
                    parameters.Buffer.SetGlobalInt(FillRefHash, backMask);
                    if (backMaterial != null && outlinable.BackParameters.Enabled)
                    {
                        foreach (var target in outlinable.OutlineTargets)
                        {
                            if (target.Renderer == null)
                            {
                                continue;
                            }

                            var renderer = target.Renderer;
                            if (!renderer.gameObject.activeInHierarchy || !renderer.enabled)
                            {
                                continue;
                            }

                            SetupCutout(parameters, target);
                            SetupCull(parameters, target);

                            parameters.Buffer.DrawRenderer(renderer, backMaterial, target.ShiftedSubmeshIndex);
                        }
                    }
                }
                else
                {
                    if (outlinable.OutlineParameters.FillPass.Material == null)
                    {
                        continue;
                    }

                    if (!outlinable.OutlineParameters.Enabled)
                    {
                        continue;
                    }

                    parameters.Buffer.SetGlobalInt(FillRefHash, singleMask);
                    parameters.Buffer.SetGlobalInt(ZTestHash, (int)CompareFunction.Always);

                    foreach (var target in outlinable.OutlineTargets)
                    {
                        if (target.Renderer == null)
                        {
                            continue;
                        }

                        var renderer = target.Renderer;
                        if (!renderer.gameObject.activeInHierarchy || !renderer.enabled)
                        {
                            continue;
                        }

                        SetupCutout(parameters, target);
                        SetupCull(parameters, target);

                        parameters.Buffer.DrawRenderer(renderer, FillMaskMaterial, target.ShiftedSubmeshIndex);
                    }

                    parameters.Buffer.SetGlobalInt(FillRefHash, singleMask);
                    var fillMaterial = outlinable.OutlineParameters.FillPass.Material;
                    if (FillMaskMaterial != null)
                    {
                        foreach (var target in outlinable.OutlineTargets)
                        {
                            if (target.Renderer == null)
                            {
                                continue;
                            }

                            var renderer = target.Renderer;
                            if (!renderer.gameObject.activeInHierarchy || !renderer.enabled)
                            {
                                continue;
                            }

                            SetupCutout(parameters, target);
                            SetupCull(parameters, target);

                            parameters.Buffer.DrawRenderer(renderer, fillMaterial, target.ShiftedSubmeshIndex);
                        }
                    }
                }
            }
        }
Beispiel #22
0
        public static void SetupMesh(OutlineParameters parameters, float baseShift)
        {
            if (parameters.BlitMesh == null)
            {
                parameters.BlitMesh = parameters.MeshPool.AllocateMesh();
            }

            const int numberOfVertices = 8;

            var currentIndex  = 0;
            var triangleIndex = 0;
            var expectedCount = 0;

            foreach (var outlinable in parameters.OutlinablesToRender)
            {
                if (outlinable.DrawingMode != OutlinableDrawingMode.Normal)
                {
                    continue;
                }

                foreach (var target in outlinable.OutlineTargets)
                {
                    var renderer = target.Renderer;
                    if (!target.ReadyToRender)
                    {
                        continue;
                    }

                    expectedCount += numberOfVertices;
                }
            }

            if (vertices.Length < expectedCount)
            {
                Array.Resize(ref vertices, expectedCount * 2);
                Array.Resize(ref indecies, vertices.Length * 3);
            }

            foreach (var outlinable in parameters.OutlinablesToRender)
            {
                if (outlinable.DrawingMode != OutlinableDrawingMode.Normal)
                {
                    continue;
                }

                var frontParameters = outlinable.RenderStyle == RenderStyle.FrontBack ? outlinable.FrontParameters : outlinable.OutlineParameters;
                var backParameters  = outlinable.RenderStyle == RenderStyle.FrontBack ? outlinable.BackParameters : outlinable.OutlineParameters;

                var useDilateDueToSettings = parameters.UseInfoBuffer && (frontParameters.DilateShift > 0.01f || backParameters.DilateShift > 0.01f) || !parameters.UseInfoBuffer;
                var useBlurDueToSettings   = parameters.UseInfoBuffer && (frontParameters.BlurShift > 0.01f || backParameters.BlurShift > 0.01f) || !parameters.UseInfoBuffer;

                foreach (var target in outlinable.OutlineTargets)
                {
                    var renderer = target.Renderer;
                    if (!target.ReadyToRender)
                    {
                        continue;
                    }

                    var pretransformedBounds = false;
                    var bounds = new Bounds();
                    if (target.BoundsMode == BoundsMode.Manual)
                    {
                        bounds = target.Bounds;
                        var size          = bounds.size;
                        var rendererScale = renderer.transform.localScale;
                        size.x     /= rendererScale.x;
                        size.y     /= rendererScale.y;
                        size.z     /= rendererScale.z;
                        bounds.size = size;
                    }
                    else
                    {
                        if (target.BoundsMode == BoundsMode.ForceRecalculate)
                        {
                            UpdateBounds(target.Renderer, target);
                        }

                        var meshRenderer = renderer as MeshRenderer;
                        var index        = target.RendererType != RendererType.MeshRenderer || !target.RendererIsNotNull ? 0 : meshRenderer.subMeshStartIndex + target.SubmeshIndex;
                        var filter       = target.RendererType != RendererType.MeshRenderer || !target.RendererIsNotNull ? null : meshRenderer.GetComponent <MeshFilter>();
                        var mesh         = filter == null ? null : filter.sharedMesh;

                        if (mesh != null && mesh.subMeshCount > index)
                        {
                            bounds = mesh.GetSubMesh(index).bounds;
                        }
                        else if (target.RendererIsNotNull)
                        {
                            pretransformedBounds = true;
                            bounds = renderer.bounds;
                        }
                    }

                    var     scale      = 0.5f;
                    Vector4 boundsSize = bounds.size * scale;
                    boundsSize.w = 1;

                    var boundsCenter = (Vector4)bounds.center;

                    var additionalScaleToSet = Vector2.zero;
                    if (target.CanUseEdgeDilateShift && target.DilateRenderingMode == DilateRenderMode.EdgeShift)
                    {
                        additionalScaleToSet.x = Mathf.Max(target.BackEdgeDilateAmount, target.FrontEdgeDilateAmount);
                    }

                    Matrix4x4 transformMatrix       = Matrix4x4.identity;
                    Matrix4x4 normalTransformMatrix = Matrix4x4.identity;
                    if (!pretransformedBounds && (target.BoundsMode == BoundsMode.Manual || target.RendererIsNotNull && !renderer.isPartOfStaticBatch))
                    {
                        transformMatrix       = target.renderer.transform.localToWorldMatrix;
                        normalTransformMatrix = Matrix4x4.Rotate(renderer.transform.rotation);
                    }

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)currentIndex
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 2)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 1)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)currentIndex
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 3)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 2)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 2)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 3)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 4)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 2)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 4)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 5)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 1)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 2)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 5)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 1)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 5)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 6)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)currentIndex
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 7)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 4)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)currentIndex
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 4)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 3)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 5)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 4)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 7)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 5)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 7)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 6)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)currentIndex
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 6)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 7)
                    };

                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)currentIndex
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 1)
                    };
                    indecies[triangleIndex++] = new TriangleIndex()
                    {
                        Index = (ushort)(currentIndex + 6)
                    };

                    for (var index = 0; index < numberOfVertices; index++)
                    {
                        var normal  = normalTransformMatrix * normals[index];
                        var normal3 = new Vector3(normal.x, normal.y, normal.z);

                        var vert       = tempVertecies[index];
                        var scaledVert = new Vector4(vert.x * boundsSize.x, vert.y * boundsSize.y, vert.z * boundsSize.z, 1);

                        vertices[currentIndex++] = new Vertex()
                        {
                            Position       = transformMatrix * (boundsCenter + scaledVert),
                            Normal         = normal3,
                            AdditionalSize = additionalScaleToSet
                        };
                    }
                }
            }

            var flags = MeshUpdateFlags.DontNotifyMeshUsers | MeshUpdateFlags.DontRecalculateBounds | MeshUpdateFlags.DontResetBoneBounds | MeshUpdateFlags.DontValidateIndices;

            parameters.BlitMesh.SetVertexBufferParams(currentIndex, attributes: vertexParams);
            parameters.BlitMesh.SetVertexBufferData(vertices, 0, 0, currentIndex, 0, flags);
            parameters.BlitMesh.SetIndexBufferParams(triangleIndex, IndexFormat.UInt16);
            parameters.BlitMesh.SetIndexBufferData(indecies, 0, 0, triangleIndex, flags);

            parameters.BlitMesh.subMeshCount = 1;
            parameters.BlitMesh.SetSubMesh(0, new SubMeshDescriptor(0, triangleIndex, MeshTopology.Triangles), flags);
        }
Beispiel #23
0
        private static int DrawOutlineables(OutlineParameters parameters, CompareFunction function, bool edgeShiftOnly, float shift, Func <Outlinable, bool> shouldRender, Func <Outlinable, Color> colorProvider, Func <Outlinable, Material> materialProvider, RenderStyle styleMask, OutlinableDrawingMode modeMask = OutlinableDrawingMode.Normal)
        {
            var drawnCount = 0;

            parameters.Buffer.SetGlobalInt(ZTestHash, (int)function);

            foreach (var targetGroup in targets)
            {
                var outlinable = targetGroup.Outlinable;
                if ((int)(outlinable.RenderStyle & styleMask) == 0)
                {
                    continue;
                }

                if ((int)(outlinable.DrawingMode & modeMask) == 0)
                {
                    continue;
                }

                parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetBackKeyword(ComplexMaskingMode.MaskingMode));
                parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetBackKeyword(ComplexMaskingMode.ObstaclesMode));
                if (function == CompareFunction.NotEqual && outlinable.ComplexMaskingEnabled)
                {
                    parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetBackKeyword(outlinable.ComplexMaskingMode));
                }

                var color = shouldRender(outlinable) ? colorProvider(outlinable) : Color.clear;

                parameters.Buffer.SetGlobalColor(ColorHash, color);
                var target = targetGroup.Target;

                var postProcessing = !target.CanUseEdgeDilateShift || target.DilateRenderingMode == DilateRenderMode.PostProcessing;
                if (edgeShiftOnly && postProcessing)
                {
                    continue;
                }

                if (!postProcessing)
                {
                    var dilateShift = 0.0f;
                    switch (function)
                    {
                    case CompareFunction.Always:
                        dilateShift = target.EdgeDilateAmount;
                        break;

                    case CompareFunction.NotEqual:
                        dilateShift = target.BackEdgeDilateAmount;
                        break;

                    case CompareFunction.LessEqual:
                        dilateShift = target.FrontEdgeDilateAmount;
                        break;
                    }

                    parameters.Buffer.SetGlobalFloat(DilateShiftHash, shift < 0.0f ? dilateShift : shift);
                }

                parameters.Buffer.SetGlobalInt(ColorMaskHash, postProcessing ? 255 : 0);

                SetupCutout(parameters, target);
                SetupCull(parameters, target);

                if (postProcessing || edgeShiftOnly)
                {
                    drawnCount++;
                }

                var materialToUse = materialProvider(outlinable);
                parameters.Buffer.DrawRenderer(target.Renderer, materialToUse, target.ShiftedSubmeshIndex);
            }

            return(drawnCount);
        }
Beispiel #24
0
        public static void SetupOutline(OutlineParameters parameters)
        {
            parameters.Buffer.SetGlobalVector(ScaleHash, parameters.Scale);

            PrepareTargets(parameters);

            Profiler.BeginSample("Setup outline");

            Profiler.BeginSample("Check materials");
            InitMaterials();
            Profiler.EndSample();

            var effectShift  = ComputeEffectShift(parameters);
            var targetWidth  = parameters.TargetWidth;
            var targetHeight = parameters.TargetHeight;

            parameters.Camera.forceIntoRenderTexture = parameters.EyeMask == StereoTargetEyeMask.None || !UnityEngine.XR.XRSettings.enabled || parameters.IsEditorCamera;

            parameters.Buffer.SetGlobalInt(SrcBlendHash, (int)BlendMode.One);
            parameters.Buffer.SetGlobalInt(DstBlendHash, (int)BlendMode.Zero);

            var outlineRef = 1;

            parameters.Buffer.SetGlobalInt(OutlineRefHash, outlineRef);

            SetupDilateKeyword(parameters);

            RenderTargetUtility.GetTemporaryRT(parameters, TargetHash, targetWidth, targetHeight, 24, true, false, false);
            var scaledWidth  = (int)(targetWidth * parameters.PrimaryBufferScale);
            var scaledHeight = (int)(targetHeight * parameters.PrimaryBufferScale);

            if (parameters.EyeMask != StereoTargetEyeMask.None)
            {
                if (scaledWidth % 2 != 0)
                {
                    scaledWidth++;
                }

                if (scaledHeight % 2 != 0)
                {
                    scaledHeight++;
                }
            }

            var scaledViewVector = parameters.MakeScaledVector(scaledWidth, scaledHeight);

            RenderTargetUtility.GetTemporaryRT(parameters, PrimaryBufferHash, scaledWidth, scaledHeight, 24, true, false, false);
            RenderTargetUtility.GetTemporaryRT(parameters, HelperBufferHash, scaledWidth, scaledHeight, 24, true, false, false);

            if (parameters.UseInfoBuffer)
            {
                var scaledInfoWidth = (int)(targetWidth * Mathf.Min(parameters.PrimaryBufferScale, parameters.InfoBufferScale));
                if (scaledInfoWidth % 2 != 0)
                {
                    scaledInfoWidth++;
                }

                var scaledInfoHeight = (int)(targetHeight * Mathf.Min(parameters.PrimaryBufferScale, parameters.InfoBufferScale));
                if (scaledInfoHeight % 2 != 0)
                {
                    scaledInfoHeight++;
                }

                RenderTargetUtility.GetTemporaryRT(parameters, InfoTargetHash, targetWidth, targetHeight, 0, false, false, false);

                RenderTargetUtility.GetTemporaryRT(parameters, PrimaryInfoBufferHash, scaledInfoWidth, scaledInfoHeight, 0, true, true, false);
                RenderTargetUtility.GetTemporaryRT(parameters, HelperInfoBufferHash, scaledInfoWidth, scaledInfoHeight, 0, true, true, false);
            }

            Profiler.BeginSample("Updating mesh");
            BlitUtility.SetupMesh(parameters, effectShift);
            Profiler.EndSample();

            parameters.Buffer.SetRenderTarget(RenderTargetUtility.ComposeTarget(parameters, TargetHash), parameters.DepthTarget);
            if (parameters.CustomViewport.HasValue)
            {
                parameters.Buffer.SetViewport(parameters.CustomViewport.Value);
            }

            DrawOutlineables(parameters, CompareFunction.LessEqual, false, 0.0f, x => true, x => Color.clear, x => ZPrepassMaterial, RenderStyle.FrontBack | RenderStyle.Single, OutlinableDrawingMode.ZOnly);

            parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetEnabledInfoBufferKeyword());

            if (parameters.UseInfoBuffer)
            {
                parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetInfoBufferStageKeyword());

                parameters.Buffer.SetRenderTarget(RenderTargetUtility.ComposeTarget(parameters, InfoTargetHash), parameters.DepthTarget);
                parameters.Buffer.ClearRenderTarget(false, true, Color.clear);
                if (parameters.CustomViewport.HasValue)
                {
                    parameters.Buffer.SetViewport(parameters.CustomViewport.Value);
                }

                DrawOutlineables(parameters, CompareFunction.Always, false, 0.0f, x => x.OutlineParameters.Enabled, x => new Color(x.OutlineParameters.DilateShift * parameters.DilateShift, x.OutlineParameters.BlurShift * parameters.BlurShift, 0, 1),
                                 x => OutlineMaterial,
                                 RenderStyle.Single,
                                 OutlinableDrawingMode.Normal);

                DrawOutlineables(parameters, CompareFunction.NotEqual, false, 0.0f, x => x.BackParameters.Enabled, x => new Color(x.BackParameters.DilateShift * parameters.DilateShift, x.BackParameters.BlurShift * parameters.BlurShift, 0, 1),
                                 x => OutlineMaterial,
                                 RenderStyle.FrontBack);

                DrawOutlineables(parameters, CompareFunction.LessEqual, false, 0.0f, x => x.FrontParameters.Enabled, x => new Color(x.FrontParameters.DilateShift * parameters.DilateShift, x.FrontParameters.BlurShift * parameters.BlurShift, 0, 1),
                                 x => OutlineMaterial,
                                 RenderStyle.FrontBack,
                                 OutlinableDrawingMode.Normal);

                DrawOutlineables(parameters, CompareFunction.LessEqual, false, 0.0f, x => true, x => new Color(0, 0, GetMaskingValueForMode(x.DrawingMode), 1),
                                 x => ObstacleMaterial,
                                 RenderStyle.Single | RenderStyle.FrontBack,
                                 OutlinableDrawingMode.Obstacle | OutlinableDrawingMode.Mask);

                parameters.Buffer.SetGlobalInt(ComparisonHash, (int)CompareFunction.Always);
                parameters.Buffer.SetGlobalInt(RefHash, 0);
                Blit(parameters,
                     RenderTargetUtility.ComposeTarget(parameters, InfoTargetHash),
                     RenderTargetUtility.ComposeTarget(parameters, PrimaryInfoBufferHash),
                     RenderTargetUtility.ComposeTarget(parameters, PrimaryInfoBufferHash),
                     BasicBlitMaterial, effectShift, null,
                     -1);

                var infoRef     = 0;
                var bufferScale = Mathf.Min(parameters.PrimaryBufferScale, parameters.InfoBufferScale);
                Postprocess(parameters, 1.0f, false, bufferScale, PrimaryInfoBufferHash, HelperInfoBufferHash, DilateMaterial,
                            (parameters.DilateQuality == DilateQuality.Base ? parameters.DilateIterations : parameters.DilateIterations * 2) + parameters.BlurIterations, false,
                            effectShift, ref infoRef,
                            new Rect(0, 0, scaledViewVector.x, scaledViewVector.y));

                parameters.Buffer.SetRenderTarget(RenderTargetUtility.ComposeTarget(parameters, InfoTargetHash), parameters.DepthTarget);
                if (parameters.CustomViewport.HasValue)
                {
                    parameters.Buffer.SetViewport(parameters.CustomViewport.Value);
                }

                DrawOutlineables(parameters, CompareFunction.Always, true, effectShift, x => x.OutlineParameters.Enabled, x => new Color(x.OutlineParameters.DilateShift * 0.5f * parameters.DilateShift, x.OutlineParameters.BlurShift * 0.5f * parameters.BlurShift, 0, 1.0f), x => EdgeDilateMaterial, RenderStyle.Single, OutlinableDrawingMode.Normal);
                DrawOutlineables(parameters, CompareFunction.NotEqual, true, effectShift, x => x.BackParameters.Enabled, x => new Color(x.BackParameters.DilateShift * 0.5f * parameters.DilateShift, x.BackParameters.BlurShift * 0.5f * parameters.BlurShift, 0, x.ComplexMaskingEnabled ? 0.0f : 0.2f), x => EdgeDilateMaterial, RenderStyle.FrontBack);
                DrawOutlineables(parameters, CompareFunction.LessEqual, true, effectShift, x => x.FrontParameters.Enabled, x => new Color(x.FrontParameters.DilateShift * 0.5f * parameters.DilateShift, x.FrontParameters.BlurShift * 0.5f * parameters.BlurShift, 0, 1.0f), x => EdgeDilateMaterial, RenderStyle.FrontBack, OutlinableDrawingMode.Normal);

                parameters.Buffer.SetGlobalTexture(InfoBufferHash, PrimaryInfoBufferHash);

                parameters.Buffer.DisableShaderKeyword(KeywordsUtility.GetInfoBufferStageKeyword());
            }

            if (parameters.UseInfoBuffer)
            {
                parameters.Buffer.EnableShaderKeyword(KeywordsUtility.GetEnabledInfoBufferKeyword());
            }

            parameters.Buffer.SetRenderTarget(RenderTargetUtility.ComposeTarget(parameters, TargetHash), parameters.DepthTarget);
            parameters.Buffer.ClearRenderTarget(false, true, Color.clear);
            if (parameters.CustomViewport.HasValue)
            {
                parameters.Buffer.SetViewport(parameters.CustomViewport.Value);
            }

            var drawnOutlinablesCount = 0;

            drawnOutlinablesCount += DrawOutlineables(parameters, CompareFunction.Always, false, 0.0f, x => x.OutlineParameters.Enabled, x => x.OutlineParameters.Color,
                                                      x => OutlineMaterial,
                                                      RenderStyle.Single, OutlinableDrawingMode.Normal);

            drawnOutlinablesCount += DrawOutlineables(parameters, CompareFunction.NotEqual, false, 0.0f, x => x.BackParameters.Enabled, x => x.BackParameters.Color,
                                                      x => OutlineMaterial,
                                                      RenderStyle.FrontBack, OutlinableDrawingMode.Normal);

            drawnOutlinablesCount += DrawOutlineables(parameters, CompareFunction.LessEqual, false, 0.0f, x => x.FrontParameters.Enabled, x => x.FrontParameters.Color,
                                                      x => OutlineMaterial,
                                                      RenderStyle.FrontBack, OutlinableDrawingMode.Normal);

            parameters.Buffer.SetGlobalInt(ComparisonHash, (int)CompareFunction.Always);

            var postProcessingRef = 0;

            if (drawnOutlinablesCount > 0)
            {
                Blit(parameters, RenderTargetUtility.ComposeTarget(parameters, TargetHash),
                     RenderTargetUtility.ComposeTarget(parameters, PrimaryBufferHash),
                     RenderTargetUtility.ComposeTarget(parameters, PrimaryBufferHash),
                     BasicBlitMaterial, effectShift, null, -1,
                     new Rect(0, 0, scaledViewVector.x, scaledViewVector.y));

                Postprocess(parameters, parameters.DilateShift, parameters.ScaleIndependent, parameters.PrimaryBufferScale, PrimaryBufferHash, HelperBufferHash, DilateMaterial, parameters.DilateIterations, false, effectShift, ref postProcessingRef,
                            new Rect(0, 0, scaledViewVector.x, scaledViewVector.y));
            }

            parameters.Buffer.SetRenderTarget(RenderTargetUtility.ComposeTarget(parameters, TargetHash), parameters.DepthTarget);
            if (drawnOutlinablesCount > 0)
            {
                parameters.Buffer.ClearRenderTarget(false, true, Color.clear);
            }

            if (parameters.CustomViewport.HasValue)
            {
                parameters.Buffer.SetViewport(parameters.CustomViewport.Value);
            }

            var drawnSimpleEdgeDilateOutlinesCount = DrawOutlineables(parameters, CompareFunction.Always, true, -1, x => x.OutlineParameters.Enabled, x => x.OutlineParameters.Color, x => EdgeDilateMaterial, RenderStyle.Single);

            drawnSimpleEdgeDilateOutlinesCount += DrawOutlineables(parameters, CompareFunction.NotEqual, true, -1, x => x.BackParameters.Enabled, x => x.BackParameters.Color, x => EdgeDilateMaterial, RenderStyle.FrontBack);
            drawnSimpleEdgeDilateOutlinesCount += DrawOutlineables(parameters, CompareFunction.LessEqual, true, -1, x => x.FrontParameters.Enabled, x => x.FrontParameters.Color, x => EdgeDilateMaterial, RenderStyle.FrontBack);

            if (drawnSimpleEdgeDilateOutlinesCount > 0)
            {
                Blit(parameters,
                     RenderTargetUtility.ComposeTarget(parameters, TargetHash),
                     RenderTargetUtility.ComposeTarget(parameters, PrimaryBufferHash),
                     RenderTargetUtility.ComposeTarget(parameters, PrimaryBufferHash),
                     PartialBlitMaterial, effectShift, null, -1,
                     new Rect(0, 0, scaledViewVector.x, scaledViewVector.y));
            }

            if (parameters.BlurIterations > 0)
            {
                SetupBlurKeyword(parameters);
                Postprocess(parameters, parameters.BlurShift, parameters.ScaleIndependent, parameters.PrimaryBufferScale, PrimaryBufferHash, HelperBufferHash, BlurMaterial, parameters.BlurIterations, false,
                            effectShift,
                            ref postProcessingRef,
                            new Rect(0, 0, scaledViewVector.x, scaledViewVector.y));
            }

            DrawOutlineables(parameters, CompareFunction.LessEqual, false, 0.0f, x => true, x => Color.clear, x => OutlineMaskMaterial, RenderStyle.FrontBack | RenderStyle.Single, OutlinableDrawingMode.GenericMask);

            parameters.Buffer.SetGlobalInt(ComparisonHash, (int)CompareFunction.NotEqual);
            parameters.Buffer.SetGlobalInt(ReadMaskHash, 255);
            parameters.Buffer.SetGlobalInt(OperationHash, (int)StencilOp.Replace);

            Blit(parameters,
                 RenderTargetUtility.ComposeTarget(parameters, PrimaryBufferHash),
                 parameters.Target,
                 parameters.DepthTarget,
                 FinalBlitMaterial,
                 effectShift, null, -1,
                 parameters.CustomViewport);

            DrawFill(parameters, parameters.Target);

            parameters.Buffer.SetGlobalFloat(EffectSizeHash, effectShift);
            BlitUtility.Draw(parameters, parameters.Target, parameters.DepthTarget, ClearStencilMaterial, parameters.CustomViewport);

            parameters.Buffer.ReleaseTemporaryRT(PrimaryBufferHash);

            parameters.Buffer.ReleaseTemporaryRT(HelperBufferHash);
            parameters.Buffer.ReleaseTemporaryRT(TargetHash);

            if (parameters.UseInfoBuffer)
            {
                parameters.Buffer.ReleaseTemporaryRT(InfoBufferHash);
                parameters.Buffer.ReleaseTemporaryRT(PrimaryInfoBufferHash);
                parameters.Buffer.ReleaseTemporaryRT(HelperInfoBufferHash);
            }

            Profiler.EndSample();
        }
Beispiel #25
0
        public static void Draw(OutlineParameters parameters, RenderTargetIdentifier target, RenderTargetIdentifier depth, Material material)
        {
            parameters.Buffer.SetRenderTarget(target, depth);

            parameters.Buffer.DrawMesh(parameters.BlitMesh, Matrix4x4.identity, material, 0, -1);
        }
Beispiel #26
0
        public static void SetupMesh(OutlineParameters parameters, float baseShift)
        {
            if (parameters.BlitMesh == null)
            {
                parameters.BlitMesh = parameters.MeshPool.AllocateMesh();
            }

            parameters.BlitMesh.Clear(true);

            addedNormals.Clear();
            addedVertices.Clear();
            addedTriangles.Clear();

            var otherStages = new Vector4(1, 0, 0);
            var dilateStage = new Vector4(0, 1, 0);
            var blurStage   = new Vector4(0, 0, 1);
            var allStages   = dilateStage + blurStage + otherStages;

            firstUV.Clear();
            secondUV.Clear();
            thirdUV.Clear();
            fourthUV.Clear();
            centers.Clear();
            size.Clear();
            stages.Clear();
            additionalScale.Clear();

            var minusBoundsX = -1;
            var plusBoundsX  = 1;
            var minusBoundsY = -1;
            var plusBoundsY  = 1;
            var minusBoundsZ = -1;
            var plusBoundsZ  = 1;

            vertices[0] = new Vector3(minusBoundsX, minusBoundsY, minusBoundsZ);
            vertices[1] = new Vector3(plusBoundsX, minusBoundsY, minusBoundsZ);
            vertices[2] = new Vector3(plusBoundsX, plusBoundsY, minusBoundsZ);
            vertices[3] = new Vector3(minusBoundsX, plusBoundsY, minusBoundsZ);
            vertices[4] = new Vector3(minusBoundsX, plusBoundsY, plusBoundsZ);
            vertices[5] = new Vector3(plusBoundsX, plusBoundsY, plusBoundsZ);
            vertices[6] = new Vector3(plusBoundsX, minusBoundsY, plusBoundsZ);
            vertices[7] = new Vector3(minusBoundsX, minusBoundsY, plusBoundsZ);

            var       currentIndex     = 0;
            const int numberOfVertices = 8;
            var       addedCount       = 0;

            foreach (var outlinable in parameters.OutlinablesToRender)
            {
                if (outlinable.DrawingMode != OutlinableDrawingMode.Normal)
                {
                    continue;
                }

                var frontParameters = outlinable.RenderStyle == RenderStyle.FrontBack ? outlinable.FrontParameters : outlinable.OutlineParameters;
                var backParameters  = outlinable.RenderStyle == RenderStyle.FrontBack ? outlinable.BackParameters : outlinable.OutlineParameters;

                var useDilateDueToSettings = parameters.UseInfoBuffer && (frontParameters.DilateShift > 0.01f || backParameters.DilateShift > 0.01f) || !parameters.UseInfoBuffer;
                var useBlurDueToSettings   = parameters.UseInfoBuffer && (frontParameters.BlurShift > 0.01f || backParameters.BlurShift > 0.01f) || !parameters.UseInfoBuffer;

                foreach (var target in outlinable.OutlineTargets)
                {
                    var renderer = target.Renderer;
                    if (renderer == null || !renderer.enabled || !renderer.gameObject.activeInHierarchy)
                    {
                        continue;
                    }

                    Profiler.BeginSample("Getting mesh bounds");

                    if (target.ForceRecalculateBounds)
                    {
                        UpdateBounds(target.Renderer);
                    }

#if UNITY_2019_3_OR_NEWER
                    var meshRenderer = renderer as MeshRenderer;
                    var index        = meshRenderer == null ? 0 : meshRenderer.subMeshStartIndex + target.SubmeshIndex;
                    var filter       = meshRenderer == null ? null : meshRenderer.GetComponent <MeshFilter>();
                    var mesh         = filter == null ? null : filter.sharedMesh;

                    var bounds = new Bounds();
                    if (meshRenderer != null && mesh != null && mesh.subMeshCount > index)
                    {
                        bounds = mesh.GetSubMesh(index).bounds;
                    }
                    else if (renderer != null)
                    {
                        bounds = renderer.bounds;
                    }
#else
                    var bounds = renderer.bounds;
#endif

                    Profiler.EndSample();

                    var scale        = 0.5f;
                    var boundsSize   = bounds.size * scale;
                    var boundsCenter = bounds.center;

                    var stagesToSet = otherStages;
                    if ((!target.CanUseEdgeDilateShift || target.DilateRenderingMode == DilateRenderMode.PostProcessing) && useDilateDueToSettings)
                    {
                        stagesToSet += dilateStage;
                    }

                    if (useBlurDueToSettings)
                    {
                        stagesToSet += blurStage;
                    }

                    var additionalScaleToSet = Vector2.zero;
                    if (target.CanUseEdgeDilateShift && target.DilateRenderingMode == DilateRenderMode.EdgeShift)
                    {
                        additionalScaleToSet.x = Mathf.Max(target.BackEdgeDilateAmount, target.FrontEdgeDilateAmount);
                    }

                    Profiler.BeginSample("Setting vertex values");

#if UNITY_2019_3_OR_NEWER
                    if (meshRenderer != null && !meshRenderer.isPartOfStaticBatch)
                    {
                        var transformMatrix = meshRenderer.transform.localToWorldMatrix;

                        matrix[0] = matrix[1] = matrix[2] = matrix[3] = matrix[4] = matrix[5] = matrix[6] = matrix[7] = transformMatrix.GetColumn(0);
                        firstUV.AddRange(matrix);
                        matrix[0] = matrix[1] = matrix[2] = matrix[3] = matrix[4] = matrix[5] = matrix[6] = matrix[7] = transformMatrix.GetColumn(1);
                        secondUV.AddRange(matrix);
                        matrix[0] = matrix[1] = matrix[2] = matrix[3] = matrix[4] = matrix[5] = matrix[6] = matrix[7] = transformMatrix.GetColumn(2);
                        thirdUV.AddRange(matrix);
                        matrix[0] = matrix[1] = matrix[2] = matrix[3] = matrix[4] = matrix[5] = matrix[6] = matrix[7] = transformMatrix.GetColumn(3);
                        fourthUV.AddRange(matrix);

                        tempVector3[0] = tempVector3[1] = tempVector3[2] = tempVector3[3] = tempVector3[4] = tempVector3[5] = tempVector3[6] = tempVector3[7] = boundsCenter;
                        centers.AddRange(tempVector3);

                        tempVector3[0] = tempVector3[1] = tempVector3[2] = tempVector3[3] = tempVector3[4] = tempVector3[5] = tempVector3[6] = tempVector3[7] = boundsSize;
                        size.AddRange(tempVector3);

                        tempVector3[0] = tempVector3[1] = tempVector3[2] = tempVector3[3] = tempVector3[4] = tempVector3[5] = tempVector3[6] = tempVector3[7] = stagesToSet;
                        stages.AddRange(tempVector3);

                        tempVector2[0] = tempVector2[1] = tempVector2[2] = tempVector2[3] = tempVector2[4] = tempVector2[5] = tempVector2[6] = tempVector2[7] = additionalScaleToSet;
                        additionalScale.AddRange(tempVector2);
                    }
                    else
#endif
                    {
                        matrix[0] = matrix[1] = matrix[2] = matrix[3] = matrix[4] = matrix[5] = matrix[6] = matrix[7] = new Vector4(1, 0, 0, 0);
                        firstUV.AddRange(matrix);
                        matrix[0] = matrix[1] = matrix[2] = matrix[3] = matrix[4] = matrix[5] = matrix[6] = matrix[7] = new Vector4(0, 1, 0, 0);
                        secondUV.AddRange(matrix);
                        matrix[0] = matrix[1] = matrix[2] = matrix[3] = matrix[4] = matrix[5] = matrix[6] = matrix[7] = new Vector4(0, 0, 1, 0);
                        thirdUV.AddRange(matrix);
                        matrix[0] = matrix[1] = matrix[2] = matrix[3] = matrix[4] = matrix[5] = matrix[6] = matrix[7] = new Vector4(0, 0, 0, 1);
                        fourthUV.AddRange(matrix);

                        tempVector3[0] = tempVector3[1] = tempVector3[2] = tempVector3[3] = tempVector3[4] = tempVector3[5] = tempVector3[6] = tempVector3[7] = boundsCenter;
                        centers.AddRange(tempVector3);

                        tempVector3[0] = tempVector3[1] = tempVector3[2] = tempVector3[3] = tempVector3[4] = tempVector3[5] = tempVector3[6] = tempVector3[7] = boundsSize;
                        size.AddRange(tempVector3);

                        tempVector3[0] = tempVector3[1] = tempVector3[2] = tempVector3[3] = tempVector3[4] = tempVector3[5] = tempVector3[6] = tempVector3[7] = stagesToSet;
                        stages.AddRange(tempVector3);

                        tempVector2[0] = tempVector2[1] = tempVector2[2] = tempVector2[3] = tempVector2[4] = tempVector2[5] = tempVector2[6] = tempVector2[7] = additionalScaleToSet;
                        additionalScale.AddRange(tempVector2);
                    }


                    Profiler.EndSample();

                    addedVertices.AddRange(vertices);
                    addedNormals.AddRange(normals);

                    trianglesToAdd[0]                      =
                        trianglesToAdd[3]                  =
                            trianglesToAdd[18]             =
                                trianglesToAdd[21]         =
                                    trianglesToAdd[30]     =
                                        trianglesToAdd[33] = currentIndex;

                    trianglesToAdd[2]              =
                        trianglesToAdd[12]         =
                            trianglesToAdd[15]     =
                                trianglesToAdd[34] = 1 + currentIndex;

                    trianglesToAdd[1]                  =
                        trianglesToAdd[5]              =
                            trianglesToAdd[6]          =
                                trianglesToAdd[9]      =
                                    trianglesToAdd[13] = 2 + currentIndex;

                    trianglesToAdd[4]          =
                        trianglesToAdd[7]      =
                            trianglesToAdd[23] = 3 + currentIndex;

                    trianglesToAdd[8]                  =
                        trianglesToAdd[10]             =
                            trianglesToAdd[20]         =
                                trianglesToAdd[22]     =
                                    trianglesToAdd[25] = 4 + currentIndex;

                    trianglesToAdd[11]                 =
                        trianglesToAdd[14]             =
                            trianglesToAdd[16]         =
                                trianglesToAdd[24]     =
                                    trianglesToAdd[27] = 5 + currentIndex;

                    trianglesToAdd[17]             =
                        trianglesToAdd[29]         =
                            trianglesToAdd[31]     =
                                trianglesToAdd[35] = 6 + currentIndex;

                    trianglesToAdd[19]             =
                        trianglesToAdd[26]         =
                            trianglesToAdd[28]     =
                                trianglesToAdd[32] = 7 + currentIndex;

                    currentIndex += numberOfVertices;

                    addedTriangles.AddRange(trianglesToAdd);
                    addedCount++;
                }
            }

            if (addedCount == 0)
            {
                return;
            }

            Profiler.BeginSample("Setting mesh values");

            parameters.BlitMesh.SetVertices(addedVertices);

            parameters.BlitMesh.SetUVs(0, firstUV);
            parameters.BlitMesh.SetUVs(1, secondUV);
            parameters.BlitMesh.SetUVs(2, thirdUV);
            parameters.BlitMesh.SetUVs(3, fourthUV);
            parameters.BlitMesh.SetUVs(4, centers);
            parameters.BlitMesh.SetUVs(5, size);
            parameters.BlitMesh.SetUVs(6, stages);
            parameters.BlitMesh.SetUVs(7, additionalScale);

            parameters.BlitMesh.SetTriangles(addedTriangles, 0, false);
            parameters.BlitMesh.SetNormals(addedNormals);

            Profiler.EndSample();
        }
 public static RenderTargetIdentifier ComposeTarget(OutlineParameters parameters, RenderTargetIdentifier target)
 {
     return(new RenderTargetIdentifier(target, 0, CubemapFace.Unknown, GetDepthSliceForEye(parameters.EyeMask)));
 }
Beispiel #28
0
 private static void Blit(OutlineParameters parameters, RenderTargetIdentifier source, RenderTargetIdentifier destination, RenderTargetIdentifier destinationDepth, Material material, float effectSize, CommandBuffer buffer, int pass = -1, Rect?viewport = null)
 {
     parameters.Buffer.SetGlobalFloat(EffectSizeHash, effectSize);
     BlitUtility.Blit(parameters, source, destination, destinationDepth, material, buffer, pass, viewport);
 }
 public static bool IsUsingVR(OutlineParameters parameters)
 {
     return(UnityEngine.XR.XRSettings.enabled &&
            !parameters.IsEditorCamera &&
            parameters.EyeMask != StereoTargetEyeMask.None);
 }
Beispiel #30
0
 public RenderTargetIdentifier GetRenderTarget(OutlineParameters parameters)
 {
     return(TargetsHolder.Instance.GetTarget(parameters, renderTargetName));
 }