示例#1
0
        DrawingSettings GetDrawingSettings(Decal decal, ref RenderingData renderingData)
        {
            // Drawing Settings
            var camera          = renderingData.cameraData.camera;
            var sortingSettings = new SortingSettings(camera)
            {
                criteria = SortingCriteria.CommonOpaque
            };
            var drawingSettings = new DrawingSettings(ShaderTagId.none, sortingSettings)
            {
                perObjectData         = renderingData.perObjectData,
                mainLightIndex        = renderingData.lightData.mainLightIndex,
                enableDynamicBatching = renderingData.supportsDynamicBatching,
                enableInstancing      = true,
            };

            // Shader Tags
            for (int i = 0; i < s_ShaderTags.Length; ++i)
            {
                drawingSettings.SetShaderPassName(i, new ShaderTagId(s_ShaderTags[i]));
            }

            // Material
            drawingSettings.overrideMaterial          = decal.decalData.material;
            drawingSettings.overrideMaterialPassIndex = 0;
            return(drawingSettings);
        }
示例#2
0
        /// <summary>
        /// Get a Decal instance.
        /// </summary>
        /// <param name="positionWS">Decal position in World space.</param>
        /// <param name="rotationWS">Decal rotation in World space.</param>
        /// <param name="scaleWS">Decal scale in World space.</param>
        /// <param name="decalData">DecalData to set.</param>
        /// <param name="usePooling">If true the Decal will be taken from a DecalPooler instance.</param>
        public static Decal GetDecal(Vector3 positionWS, Quaternion rotationWS, Vector2 scaleWS, ScriptableDecal decalData, bool usePooling)
        {
            Decal decal = GetDecalInstance(decalData, usePooling);

            decal.SetActive(true);
            decal.SetTransform(positionWS, rotationWS, scaleWS);
            decal.SetData(decalData);
            return(decal);
        }
示例#3
0
        bool Culling(ScriptableRenderContext context, Decal decal, ref RenderingData renderingData, out CullingResults cullingResults)
        {
            // Setup
            var camera     = renderingData.cameraData.camera;
            var localScale = decal.transform.lossyScale;

            cullingResults = new CullingResults();

            // Never draw in Preview
            if (camera.cameraType == CameraType.Preview)
            {
                return(false);
            }

            // Test for Decal behind Camera
            var maxRadius  = Mathf.Max(Mathf.Max(localScale.x * 0.5f, localScale.y * 0.5f), localScale.z) + kErrorMargin;
            var positionVS = camera.WorldToViewportPoint(decal.transform.position);

            if (positionVS.z < -maxRadius)
            {
                return(false);
            }

            // Get Decal bounds
            var boundsScale = new Vector3(maxRadius, maxRadius, maxRadius);
            var bounds      = new Bounds(decal.transform.position, boundsScale);

            // Test against frustum planes
            var planes = GeometryUtility.CalculateFrustumPlanes(camera);

            if (!GeometryUtility.TestPlanesAABB(planes, bounds))
            {
                return(false);
            }

            /* WARNING: Calling context.Cull() here generates a segfault, for some reason.
             * NOTE: Commenting this out is bad for performance I think... We'll render everything another time per decal.
             *
             * // Get CullingParameters
             * var cullingParameters = new ScriptableCullingParameters();
             * if (!camera.TryGetCullingParameters(out cullingParameters))
             *  return false;
             *
             * // Set culling planes
             * cullingParameters.cullingPlaneCount = 6;
             * for (int i = 0; i < 6; ++i)
             * {
             *  cullingParameters.SetCullingPlane(i, decal.clipPlanes[i]);
             * }
             *
             * cullingResults = context.Cull(ref cullingParameters);
             */

            cullingResults = renderingData.cullResults; // HACK: Just return whatever is in here for now...
            return(true);
        }
示例#4
0
        void RenderDecal(ScriptableRenderContext context, Decal decal, CullingResults cullingResults, ref RenderingData renderingData)
        {
            // Create Settings
            var drawingSettings   = GetDrawingSettings(decal, ref renderingData);
            var filteringSettings = new FilteringSettings(RenderQueueRange.all, decal.decalData.layerMask);
            var renderStateBlock  = new RenderStateBlock(RenderStateMask.Nothing);

            // Draw Renderers
            context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings, ref renderStateBlock);
        }
示例#5
0
 void SetShaderUniforms(ScriptableRenderContext context, Decal decal, CommandBuffer cmd)
 {
     // Set Shader globals
     cmd.SetGlobalMatrix("decal_Projection", decal.matrix);
     cmd.SetGlobalVector("decal_Direction", decal.transform.forward);
     cmd.SetGlobalFloat("decal_DepthFalloff", decal.decalData.depthFalloff);
     cmd.SetGlobalFloat("decal_Angle", Mathf.Deg2Rad * (180 - decal.decalData.angle));
     cmd.SetGlobalFloat("decal_AngleFalloff", decal.decalData.angleFalloff);
     ExecuteCommand(context, cmd);
 }
示例#6
0
        internal static void UnregisterDecal(Decal decal)
        {
            if (!m_Decals.Contains(decal))
            {
                return;
            }

            // Untrack Decal
            m_Decals.Remove(decal);
        }
示例#7
0
        internal static void RegisterDecal(Decal decal)
        {
            if (m_Decals.Contains(decal))
            {
                return;
            }

            // Track Decal
            m_Decals.Add(decal);
        }
示例#8
0
        bool Culling(ScriptableRenderContext context, Decal decal, ref RenderingData renderingData, out CullingResults cullingResults)
        {
            // Setup
            var camera     = renderingData.cameraData.camera;
            var localScale = decal.transform.lossyScale;

            cullingResults = new CullingResults();

            // Never draw in Preview
            if (camera.cameraType == CameraType.Preview)
            {
                return(false);
            }

            // Test for Decal behind Camera
            var maxRadius  = Mathf.Max(Mathf.Max(localScale.x * 0.5f, localScale.y * 0.5f), localScale.z) + kErrorMargin;
            var positionVS = camera.WorldToViewportPoint(decal.transform.position);

            if (positionVS.z < -maxRadius)
            {
                return(false);
            }

            // Get Decal bounds
            var boundsScale = new Vector3(maxRadius, maxRadius, maxRadius);
            var bounds      = new Bounds(decal.transform.position, boundsScale);

            // Test against frustum planes
            var planes = GeometryUtility.CalculateFrustumPlanes(camera);

            if (!GeometryUtility.TestPlanesAABB(planes, bounds))
            {
                return(false);
            }

            // Get CullingParameters
            var cullingParameters = new ScriptableCullingParameters();

            if (!camera.TryGetCullingParameters(out cullingParameters))
            {
                return(false);
            }

            // Set culling planes
            cullingParameters.cullingPlaneCount = 6;
            for (int i = 0; i < 6; ++i)
            {
                cullingParameters.SetCullingPlane(i, decal.clipPlanes[i]);
            }

            // Culling Results
            cullingResults = context.Cull(ref cullingParameters);
            return(true);
        }
示例#9
0
        // -------------------------------------------------- //
        //                   PUBLIC METHODS                   //
        // -------------------------------------------------- //

        /// <summary>
        /// Try to get a Decal instance from pools.
        /// </summary>
        /// <param name="decalData">DecalData to get an instance of.</param>
        /// <param name="decal">Decal instance out.</param>
        public bool TryGetInstance(ScriptableDecal decalData, out Decal decal)
        {
            DecalPool pool = GetPool(decalData);

            ValidatePool(pool);
            for (int i = 0; i < pool.decals.Length; i++)
            {
                if (!pool.decals[i].gameObject.activeSelf)
                {
                    decal             = pool.decals[i];
                    pool.initTimes[i] = Time.realtimeSinceStartup;
                    return(true);
                }
            }
            decal = null;
            return(false);
        }
示例#10
0
        /// <summary>
        /// Remove existing Decal. If Pooling is enabled on DecalData, Decal will be returned to Pool.
        /// </summary>
        /// <param name="decal">Decal to remove.</param>
        public static void RemoveDecal(Decal decal)
        {
            // Test for pooling enabled
            var key = decal.decalData;

            if (key.poolingEnabled)
            {
                // Try to return Decal to Pool
                if (HasDecalPool(key))
                {
                    PoolingSystem.ReturnInstance <Decal>(key, decal);
                    return;
                }
            }

            // Destroy decal
            DestroyGameObject(decal.gameObject);
        }
示例#11
0
        // -------------------------------------------------- //
        //                  INTERNAL METHODS                  //
        // -------------------------------------------------- //

        // Initialize a new DecalPool
        private DecalPool InitializePool(ScriptableDecal decalData)
        {
            Decal[] decals   = new Decal[decalData.maxInstances];
            float[] initTime = new float[decalData.maxInstances];
            for (int i = 0; i < decals.Length; i++)
            {
                Decal decal = DecalSystem.CreateDecalDirect(decalData);
                decal.transform.localScale = this.transform.InverseTransformVector(Vector3.one);
                decal.transform.SetParent(this.transform);
                decals[i] = decal;
                decal.gameObject.SetActive(false);
            }

            DecalPool pool = new DecalPool(decalData, decals, initTime);

            pools.Add(pool);
            return(pool);
        }
示例#12
0
        /// <summary>
        /// Get a direction vector from a Decal to the nearest Collider face.
        /// </summary>
        /// <param name="decal">Decal to use as vector source.</param>
        /// <param name="hitPoint">The location of the hit on the Collider face.</param>
        public static Vector3 GetDirectionToNearestFace(Decal decal, out Vector3 hitPoint)
        {
            Vector3 nearestVector   = Vector3.zero;
            float   nearestDistance = Mathf.Infinity;

            hitPoint = Vector3.zero;

            for (int i = 0; i < 1000; i++)
            {
                Vector3    direction = RandomSphericalDistributionVector();
                RaycastHit hit;
                if (Physics.Raycast(decal.transform.position, direction, out hit, 1000))
                {
                    float distance = Vector3.Distance(hit.point, decal.transform.position);
                    if (distance < nearestDistance)
                    {
                        nearestVector   = direction;
                        nearestDistance = distance;
                        hitPoint        = hit.point;
                    }
                }
            }
            return(nearestVector);
        }
示例#13
0
        // -------------------------------------------------- //
        //                   GEOMETRY UTILS                   //
        // -------------------------------------------------- //

        /// <summary>
        /// Get a direction vector from a Decal to the nearest Collider face.
        /// </summary>
        /// <param name="decal">Decal to use as vector source.</param>
        public static Vector3 GetDirectionToNearestFace(Decal decal)
        {
            Vector3 hitPoint = Vector3.zero;

            return(GetDirectionToNearestFace(decal, out hitPoint));
        }