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); }
/// <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); }
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); }
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); }
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); }
internal static void UnregisterDecal(Decal decal) { if (!m_Decals.Contains(decal)) { return; } // Untrack Decal m_Decals.Remove(decal); }
internal static void RegisterDecal(Decal decal) { if (m_Decals.Contains(decal)) { return; } // Track Decal m_Decals.Add(decal); }
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); }
// -------------------------------------------------- // // 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); }
/// <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); }
// -------------------------------------------------- // // 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); }
/// <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); }
// -------------------------------------------------- // // 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)); }