예제 #1
0
        private void RenderVPassBlend(OutlineResources resources, IOutlineSettings settings)
        {
            // Setup shader parameter overrides.
            var props = resources.VPassBlendProperties;

            props.SetFloat(resources.WidthId, settings.OutlineWidth);
            props.SetColor(resources.ColorId, settings.OutlineColor);

            if (settings.OutlineMode == OutlineMode.Solid)
            {
                props.SetFloat(resources.IntensityId, SolidIntensity);
            }
            else
            {
                props.SetFloat(resources.IntensityId, settings.OutlineIntensity);
            }

            // Set source texture as _MainTex to match Blit behavior.
            _commandBuffer.SetGlobalTexture(_mainRtId, _source);

            // Set destination texture as render target.
#if UNITY_2018_2_OR_NEWER
            _commandBuffer.SetRenderTarget(_destination, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
#else
            _commandBuffer.SetRenderTarget(_destination);
#endif

            // Blit fullscreen triangle.
            _commandBuffer.DrawMesh(resources.FullscreenTriangleMesh, Matrix4x4.identity, resources.VPassBlendMaterial, 0, 0, props);
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OutlineRenderer"/> struct.
        /// </summary>
        /// <param name="cmd">A <see cref="CommandBuffer"/> to render the effect to. It should be cleared manually (if needed) before passing to this method.</param>
        /// <param name="resources">Outline resources.</param>
        /// <param name="dst">Render target.</param>
        /// <param name="depth">Depth dexture to use.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="cmd"/> is <see langword="null"/>.</exception>
        public OutlineRenderer(CommandBuffer cmd, OutlineResources resources, RenderTargetIdentifier dst, RenderTargetIdentifier depth, Vector2Int rtSize)
        {
            if (cmd is null)
            {
                throw new ArgumentNullException(nameof(cmd));
            }

            if (resources is null)
            {
                throw new ArgumentNullException(nameof(resources));
            }

            if (rtSize.x <= 0)
            {
                rtSize.x = -1;
            }

            if (rtSize.y <= 0)
            {
                rtSize.y = -1;
            }

            cmd.GetTemporaryRT(_maskRtId, rtSize.x, rtSize.y, 0, FilterMode.Bilinear, _rtFormat);
            cmd.GetTemporaryRT(_hPassRtId, rtSize.x, rtSize.y, 0, FilterMode.Bilinear, _rtFormat);

            _rt            = dst;
            _depth         = depth;
            _commandBuffer = cmd;
            _resources     = resources;
        }
 internal void SetResources(OutlineResources resources)
 {
     if (resources != _resources)
     {
         _resources = resources;
         _changed   = true;
     }
 }
예제 #4
0
        private void Awake()
        {
            OutlineResources.LogSrpNotSupported(this);
            OutlineResources.LogPpNotSupported(this);

            CreateRenderersIfNeeded();
            CreateSettingsIfNeeded();
        }
        /// <summary>
        /// Renders all layers.
        /// </summary>
        public void Render(OutlineRenderer renderer, OutlineResources resources)
        {
            UpdateSortedLayersIfNeeded();

            foreach (var layer in _sortedLayers)
            {
                layer.Render(renderer, resources);
            }
        }
예제 #6
0
        internal void Render(OutlineRenderer renderer, OutlineResources resources)
        {
            _settings.SetResources(resources);

            foreach (var kvp in _outlineObjects)
            {
                if (kvp.Key)
                {
                    renderer.RenderSingleObject(kvp.Value, _settings.OutlineMaterials);
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Renders the layers.
        /// </summary>
        public void Render(OutlineRenderer renderer, OutlineResources resources)
        {
            if (_enabled)
            {
                _settings.SetResources(resources);

                foreach (var kvp in _outlineObjects)
                {
                    if (kvp.Key && kvp.Key.activeInHierarchy)
                    {
                        renderer.Render(kvp.Value, _settings.OutlineResources, _settings);
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OutlineRenderer"/> struct.
        /// </summary>
        /// <param name="cmd">A <see cref="CommandBuffer"/> to render the effect to. It should be cleared manually (if needed) before passing to this method.</param>
        /// <param name="resources">Outline resources.</param>
        /// <param name="dst">Render target.</param>
        /// <param name="depth">Depth dexture to use.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="cmd"/> is <see langword="null"/>.</exception>
        public OutlineRenderer(CommandBuffer cmd, OutlineResources resources, RenderTargetIdentifier dst, RenderTargetIdentifier depth, Vector2Int rtSize)
        {
            if (cmd is null)
            {
                throw new ArgumentNullException(nameof(cmd));
            }

            if (resources is null)
            {
                throw new ArgumentNullException(nameof(resources));
            }

            if (rtSize.x <= 0)
            {
                rtSize.x = -1;
            }

            if (rtSize.y <= 0)
            {
                rtSize.y = -1;
            }

            if (XRSettings.enabled)
            {
                var rtDesc = XRSettings.eyeTextureDesc;

                rtDesc.shadowSamplingMode = ShadowSamplingMode.None;
                rtDesc.depthBufferBits    = 0;
                rtDesc.colorFormat        = RtFormat;

                cmd.GetTemporaryRT(resources.MaskTexId, rtDesc, FilterMode.Bilinear);
                cmd.GetTemporaryRT(resources.TempTexId, rtDesc, FilterMode.Bilinear);

                _rtDimention = rtDesc.dimension;
            }
            else
            {
                cmd.GetTemporaryRT(resources.MaskTexId, rtSize.x, rtSize.y, 0, FilterMode.Bilinear, RtFormat);
                cmd.GetTemporaryRT(resources.TempTexId, rtSize.x, rtSize.y, 0, FilterMode.Bilinear, RtFormat);

                _rtDimention = TextureDimension.Tex2D;
            }

            _rt            = dst;
            _depth         = depth;
            _commandBuffer = cmd;
            _resources     = resources;
        }
예제 #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OutlineMaterialSet"/> class.
        /// </summary>
        internal OutlineMaterialSet(OutlineResources resources, Material renderMaterial)
        {
            Debug.Assert(resources);
            Debug.Assert(resources.IsValid);
            Debug.Assert(renderMaterial);

            _outlineResources = resources;
            _renderMaterial   = renderMaterial;
            _hPassMaterial    = new Material(resources.HPassShader);
            _vPassMaterial    = new Material(resources.VPassBlendShader);

            _hPassMaterial.SetInt(WidthNameId, _width);
            _vPassMaterial.SetInt(WidthNameId, _width);
            _vPassMaterial.SetColor(ColorNameId, _color);
            _vPassMaterial.SetFloat(IntensityNameId, OutlineRenderer.SolidIntensity);
        }
예제 #10
0
        private void RenderObject(OutlineResources resources, IOutlineSettings settings, Renderer renderer)
        {
            RenderObjectClear((settings.OutlineRenderMode & OutlineRenderFlags.EnableDepthTesting) != 0);

            if (renderer && renderer.gameObject.activeInHierarchy && renderer.enabled)
            {
                // NOTE: Accessing Renderer.sharedMaterials triggers GC.Alloc. That's why we use a temporary
                // list of materials, cached with the outline resources.
                renderer.GetSharedMaterials(resources.TmpMaterials);

                for (var i = 0; i < resources.TmpMaterials.Count; ++i)
                {
                    _commandBuffer.DrawRenderer(renderer, resources.RenderMaterial, i);
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OutlineMaterialSet"/> class.
        /// </summary>
        /// <remarks>
        /// The preferred way of creating instances of <see cref="OutlineMaterialSet"/> is calling <see cref="OutlineResources.CreateMaterialSet"/> method.
        /// </remarks>
        public OutlineMaterialSet(OutlineResources resources)
        {
            if (resources == null)
            {
                throw new ArgumentNullException("resources");
            }

            _outlineResources = resources;
            _renderMaterial   = new Material(resources.RenderShader);
            _hPassMaterial    = new Material(resources.HPassShader);
            _vPassMaterial    = new Material(resources.VPassBlendShader);

            _hPassMaterial.SetInt(WidthNameId, _width);
            _vPassMaterial.SetInt(WidthNameId, _width);
            _vPassMaterial.SetColor(ColorNameId, _color);
            _vPassMaterial.SetFloat(IntensityNameId, OutlineRenderer.SolidIntensity);
        }
 internal void SetResources(OutlineResources resources)
 {
     if (resources == null)
     {
         if (_materials != null)
         {
             _materials.Dispose();
             _materials = null;
         }
     }
     else if (_materials == null || _materials.OutlineResources != resources)
     {
         _materials = resources.CreateMaterialSet();
         _materials.Reset(this);
         _changed = true;
     }
 }
예제 #13
0
        private void RenderHPass(OutlineResources resources, IOutlineSettings settings)
        {
            // Setup shader parameter overrides.
            var props = resources.HPassProperties;

            props.SetFloat(resources.WidthId, settings.OutlineWidth);

            // Set source texture as _MainTex to match Blit behavior.
            _commandBuffer.SetGlobalTexture(_mainRtId, _maskRtId);

            // Set destination texture as render target.
#if UNITY_2018_2_OR_NEWER
            _commandBuffer.SetRenderTarget(_hPassRtId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
#else
            _commandBuffer.SetRenderTarget(_hPassRtId);
#endif

            // Blit fullscreen triangle.
            _commandBuffer.DrawMesh(resources.FullscreenTriangleMesh, Matrix4x4.identity, resources.HPassMaterial, 0, 0, props);
        }
예제 #14
0
        private void RenderObject(OutlineResources resources, IOutlineSettings settings, IEnumerable <Renderer> renderers)
        {
            RenderObjectClear((settings.OutlineRenderMode & OutlineRenderFlags.EnableDepthTesting) != 0);

            // NOTE: Calling IEnumerable.GetEnumerator() triggers GC.Alloc.
            foreach (var r in renderers)
            {
                if (r && r.enabled && r.gameObject.activeInHierarchy)
                {
                    // NOTE: Accessing Renderer.sharedMaterials triggers GC.Alloc. That's why we use a temporary
                    // list of materials, cached with the outline resources.
                    r.GetSharedMaterials(resources.TmpMaterials);

                    for (var j = 0; j < resources.TmpMaterials.Count; ++j)
                    {
                        _commandBuffer.DrawRenderer(r, resources.RenderMaterial, j);
                    }
                }
            }
        }
예제 #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OutlineRenderer"/> struct.
        /// </summary>
        /// <param name="cmd">A <see cref="CommandBuffer"/> to render the effect to. It should be cleared manually (if needed) before passing to this method.</param>
        /// <param name="resources">Outline resources.</param>
        /// <param name="dst">Render target.</param>
        /// <param name="depth">Depth dexture to use.</param>
        /// <param name="rtDesc">Render texture decsriptor.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="cmd"/> is <see langword="null"/>.</exception>
        public OutlineRenderer(CommandBuffer cmd, OutlineResources resources, RenderTargetIdentifier dst, RenderTargetIdentifier depth, RenderTextureDescriptor rtDesc)
        {
            if (cmd is null)
            {
                throw new ArgumentNullException(nameof(cmd));
            }

            if (resources is null)
            {
                throw new ArgumentNullException(nameof(resources));
            }

            if (rtDesc.width <= 0)
            {
                rtDesc.width = -1;
            }

            if (rtDesc.height <= 0)
            {
                rtDesc.height = -1;
            }

            if (rtDesc.dimension == TextureDimension.None || rtDesc.dimension == TextureDimension.Unknown)
            {
                rtDesc.dimension = TextureDimension.Tex2D;
            }

            rtDesc.shadowSamplingMode = ShadowSamplingMode.None;
            rtDesc.depthBufferBits    = 0;
            rtDesc.colorFormat        = RtFormat;
            rtDesc.msaaSamples        = 1;

            cmd.GetTemporaryRT(resources.MaskTexId, rtDesc, FilterMode.Bilinear);
            cmd.GetTemporaryRT(resources.TempTexId, rtDesc, FilterMode.Bilinear);

            _rtDimention   = rtDesc.dimension;
            _rt            = dst;
            _depth         = depth;
            _commandBuffer = cmd;
            _resources     = resources;
        }
예제 #16
0
        /// <summary>
        /// Renders outline around a single object.
        /// </summary>
        /// <param name="renderer">A <see cref="Renderer"/> representing an object to be outlined.</param>
        /// <param name="resources">Outline resources.</param>
        /// <param name="settings">Outline settings.</param>
        /// <exception cref="ArgumentNullException">Thrown if any of the arguments is <see langword="null"/>.</exception>
        public void Render(Renderer renderer, OutlineResources resources, IOutlineSettings settings)
        {
            if (renderer == null)
            {
                throw new ArgumentNullException("renderers");
            }

            if (resources == null)
            {
                throw new ArgumentNullException("resources");
            }

            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            Init(resources, settings);
            RenderObject(renderer, resources.RenderMaterial);
            RenderHPass(resources, settings);
            RenderVPassBlend(resources, settings);
        }
예제 #17
0
        /// <summary>
        /// Renders outline around a single object.
        /// </summary>
        /// <param name="renderers">One or more renderers representing a single object to be outlined.</param>
        /// <param name="resources">Outline resources.</param>
        /// <param name="settings">Outline settings.</param>
        /// <exception cref="ArgumentNullException">Thrown if any of the arguments is <see langword="null"/>.</exception>
        /// <seealso cref="Render(IList{Renderer}, OutlineResources, IOutlineSettings)"/>
        /// <seealso cref="Render(Renderer, OutlineResources, IOutlineSettings)"/>
        public void Render(IEnumerable <Renderer> renderers, OutlineResources resources, IOutlineSettings settings)
        {
            if (renderers == null)
            {
                throw new ArgumentNullException("renderers");
            }

            if (resources == null)
            {
                throw new ArgumentNullException("resources");
            }

            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            Init(resources, settings);
            RenderObject(resources, settings, renderers);
            RenderHPass(resources, settings);
            RenderVPassBlend(resources, settings);
        }
예제 #18
0
 private void Init(OutlineResources resources, IOutlineSettings settings)
 {
     _commandBuffer.SetGlobalFloatArray(resources.GaussSamplesId, resources.GetGaussSamples(settings.OutlineWidth));
 }
예제 #19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OutlineRenderer"/> struct.
 /// </summary>
 /// <param name="cmd">A <see cref="CommandBuffer"/> to render the effect to. It should be cleared manually (if needed) before passing to this method.</param>
 /// <param name="resources">Outline resources.</param>
 /// <param name="renderingPath">The rendering path of target camera (<see cref="Camera.actualRenderingPath"/>).</param>
 /// <exception cref="ArgumentNullException">Thrown if <paramref name="cmd"/> is <see langword="null"/>.</exception>
 public OutlineRenderer(CommandBuffer cmd, OutlineResources resources, RenderingPath renderingPath)
     : this(cmd, resources, BuiltinRenderTextureType.CameraTarget, GetBuiltinDepth(renderingPath), Vector2Int.zero)
 {
 }
예제 #20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OutlineRenderer"/> struct.
 /// </summary>
 /// <param name="cmd">A <see cref="CommandBuffer"/> to render the effect to. It should be cleared manually (if needed) before passing to this method.</param>
 /// <param name="resources">Outline resources.</param>
 /// <param name="dst">Render target.</param>
 /// <exception cref="ArgumentNullException">Thrown if <paramref name="cmd"/> is <see langword="null"/>.</exception>
 public OutlineRenderer(CommandBuffer cmd, OutlineResources resources, RenderTargetIdentifier dst)
     : this(cmd, resources, dst, BuiltinRenderTextureType.Depth, Vector2Int.zero)
 {
 }
예제 #21
0
        private static void Blit(CommandBuffer cmdBuffer, RenderTargetIdentifier src, OutlineResources resources, int shaderPass, Material mat, MaterialPropertyBlock props)
        {
            // Set source texture as _MainTex to match Blit behavior.
            cmdBuffer.SetGlobalTexture(resources.MainTexId, src);

            if (SystemInfo.graphicsShaderLevel < 35 || resources.UseFullscreenTriangleMesh)
            {
                cmdBuffer.DrawMesh(resources.FullscreenTriangleMesh, Matrix4x4.identity, mat, 0, shaderPass, props);
            }
            else
            {
                cmdBuffer.DrawProcedural(Matrix4x4.identity, mat, shaderPass, MeshTopology.Triangles, 3, 1, props);
            }
        }
예제 #22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OutlineRenderer"/> struct.
 /// </summary>
 /// <param name="cmd">A <see cref="CommandBuffer"/> to render the effect to. It should be cleared manually (if needed) before passing to this method.</param>
 /// <param name="resources">Outline resources.</param>
 /// <exception cref="ArgumentNullException">Thrown if <paramref name="cmd"/> is <see langword="null"/>.</exception>
 public OutlineRenderer(CommandBuffer cmd, OutlineResources resources)
     : this(cmd, resources, BuiltinRenderTextureType.CameraTarget, BuiltinRenderTextureType.Depth, Vector2Int.zero)
 {
 }
예제 #23
0
 private void Awake()
 {
     OutlineResources.LogSrpNotSupported(this);
     OutlineResources.LogPpNotSupported(this);
 }
예제 #24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OutlineRenderer"/> struct.
 /// </summary>
 /// <param name="cmd">A <see cref="CommandBuffer"/> to render the effect to. It should be cleared manually (if needed) before passing to this method.</param>
 /// <param name="dst">Render target.</param>
 /// <param name="renderingPath">The rendering path of target camera (<see cref="Camera.actualRenderingPath"/>).</param>
 /// <exception cref="ArgumentNullException">Thrown if <paramref name="cmd"/> is <see langword="null"/>.</exception>
 public OutlineRenderer(CommandBuffer cmd, OutlineResources resources, RenderTargetIdentifier dst, RenderingPath renderingPath, Vector2Int rtSize)
     : this(cmd, resources, dst, GetBuiltinDepth(renderingPath), rtSize)
 {
 }
예제 #25
0
 public void Init()
 {
     _resources   = ScriptableObject.CreateInstance <OutlineResources>();
     _materialSet = _resources.CreateMaterialSet();
     Init(_materialSet);
 }
예제 #26
0
        private static void Blit(CommandBuffer cmdBuffer, RenderTargetIdentifier src, OutlineResources resources, int shaderPass, Material mat, MaterialPropertyBlock props)
        {
            // Set source texture as _MainTex to match Blit behavior.
            cmdBuffer.SetGlobalTexture(resources.MainTexId, src);

            // NOTE: SystemInfo.graphicsShaderLevel check is not enough sometimes (esp. on mobiles), so there is SystemInfo.supportsInstancing
            // check and a flag for forcing DrawMesh.
            if (SystemInfo.graphicsShaderLevel >= 35 && SystemInfo.supportsInstancing && !resources.UseFullscreenTriangleMesh)
            {
                cmdBuffer.DrawProcedural(Matrix4x4.identity, mat, shaderPass, MeshTopology.Triangles, 3, 1, props);
            }
            else
            {
                cmdBuffer.DrawMesh(resources.FullscreenTriangleMesh, Matrix4x4.identity, mat, 0, shaderPass, props);
            }
        }
 internal OutlineSettingsInstance(OutlineResources resources)
 {
     _resources = resources;
 }