| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Serialization;
- #if MATHEMATICS
- using Unity.Mathematics;
- #endif
- #if VFX_GRAPH
- using UnityEngine.VFX;
- #endif
- namespace sc.modeling.water.common.runtime
- {
- public static class VFX
- {
- public const string DEFAULT_EFFECT_GUID = "e4f6c7bafe287f84fa437a2c93276b5a";
-
- private const int MAX_EMITTERS = 16384;
- private static readonly Vector3 BOUNDS_PADDING = Vector3.one * 2f;
- #if MATHEMATICS
- public struct Emitter
- {
- /// <summary>
- /// Position in local-space of VFX Graph
- /// </summary>
- public float3 position;
- /// <summary>
- /// Velocity vector in local-space
- /// </summary>
- public float3 velocity;
- }
- [Serializable]
- public class PointCache
- {
- [SerializeField]
- public Texture2D positions;
- [SerializeField]
- public Texture2D velocities;
-
- public Bounds volumeBounds;
-
- private const string BoundsCenter = "Bounds Center";
- private static int BoundsCenterID = Shader.PropertyToID(BoundsCenter);
-
- private const string BoundsSize = "Bounds Size";
- private static int BoundsSizeID = Shader.PropertyToID(BoundsSize);
-
- private const string EmitterPositionsName = "Emitter Positions";
- private static int EmitterPositionsID = Shader.PropertyToID(EmitterPositionsName);
-
- private const string EmitterVelocitesName = "Emitter Velocity";
- private static int EmitterVelocitesID = Shader.PropertyToID(EmitterVelocitesName);
- public void SetData(List<Emitter> emitters, Bounds bounds)
- {
- if (emitters.Count == 0)
- {
- positions = Texture2D.blackTexture;
- velocities = Texture2D.blackTexture;
- return;
- }
-
- this.volumeBounds = bounds;
-
- if (emitters.Count-1 >= MAX_EMITTERS)
- {
- throw new Exception($"Maximum amount of particle emitters exceeded ({MAX_EMITTERS}). Change the spawning criteria so fewer emitters are created. Such as increasing distances, or using multiple components for different sections of the river.");
- }
-
- var emitterCount = math.clamp(emitters.Count, 1, MAX_EMITTERS);
- if (positions == null || positions.width != emitterCount)
- {
- positions = new Texture2D(emitterCount, 1, TextureFormat.RGBAFloat, false, true);
- positions.wrapMode = TextureWrapMode.Repeat;
- positions.name = $"Emitter Positions";
- }
- if (velocities == null || velocities.width != emitterCount)
- {
- velocities = new Texture2D(emitterCount, 1, TextureFormat.RGBAFloat, false, true);
- velocities.wrapMode = TextureWrapMode.Repeat;
- velocities.name = $"Emitter Velocity";
- }
-
- for (int i = 0; i < emitterCount; i++)
- {
- positions.SetPixel(i, 0, new Color(emitters[i].position.x, emitters[i].position.y, emitters[i].position.z, 1f));
- velocities.SetPixel(i, 0, new Color(emitters[i].velocity.x, emitters[i].velocity.y, emitters[i].velocity.z, 1f));
- }
-
- positions.Apply(false);
- velocities.Apply(false);
- }
-
- #if VFX_GRAPH
- public void ApplyToEffect(VisualEffect effect, bool clear = false)
- {
- if (effect && effect.visualEffectAsset)
- {
- if (effect.HasTexture(EmitterPositionsID))
- {
- //Note: A bug introduces in 2022.3 requires resetting the override state before a texture assignment.
-
- effect.ResetOverride(EmitterPositionsID);
- effect.SetTexture(EmitterPositionsID, clear || positions == null ? Texture2D.blackTexture : positions);
- effect.ResetOverride(EmitterVelocitesID);
- effect.SetTexture(EmitterVelocitesID, clear || velocities == null ? Texture2D.blackTexture : velocities);
-
- effect.ResetOverride(BoundsCenter);
- effect.SetVector3(BoundsCenterID, volumeBounds.center);
-
- effect.ResetOverride(BoundsSize);
- effect.SetVector3(BoundsSizeID, volumeBounds.size + BOUNDS_PADDING);
- }
- else
- {
- throw new Exception($"Failed to generate emitters. The VFX Graph \"{effect.visualEffectAsset.name}\" rendering output or point cache input is missing. " +
- $"This graph was constructed for the Universal Render Pipeline, it was likely imported without URP being installed. If you believe this is in error, open up the graph and recompile it.");
- }
- }
- }
- #endif
- #if VFX_GRAPH
- public static bool IsValidTargetEffect(VisualEffect effect)
- {
- if (effect && effect.visualEffectAsset)
- {
- /*
- List<VFXExposedProperty> props = new List<VFXExposedProperty>();
- targetEffect.visualEffectAsset.GetExposedProperties(props);
-
- Debug.Log($"Exposed properties: {props.Count}");
- foreach (var prop in props)
- {
- Debug.Log(prop.name);
- }
- */
-
- return effect.HasTexture(EmitterPositionsID);
- }
-
- return false;
- }
- #endif
- }
- #endif
- #if VFX_GRAPH
- public static void SetSortingOrder(VisualEffect effect, int sortingOrder)
- {
- if (effect)
- {
- Renderer vfxRenderer = effect.GetComponent<Renderer>();
- vfxRenderer.sortingOrder = sortingOrder;
- }
- }
- #endif
- }
- }
|