SplashVFX.cs 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // River Modeler
  2. // Staggart Creations (http://staggart.xyz)
  3. // Copyright protected under Unity Asset Store EULA
  4. // Copying or referencing source code for the production of new asset store content is strictly prohibited.
  5. using System.Collections.Generic;
  6. using sc.modeling.water.common.runtime;
  7. using UnityEngine;
  8. using Random = UnityEngine.Random;
  9. #if MATHEMATICS
  10. using Unity.Mathematics;
  11. #endif
  12. namespace sc.modeling.river.runtime
  13. {
  14. [AddComponentMenu("Water/River/River Splash VFX")]
  15. [HelpURL("https://staggart.xyz/river-modeler-docs/?section=splash-vfx")]
  16. public class SplashVFX : RiverVFX
  17. {
  18. [Range(0f,1f)]
  19. [Tooltip("Threshold to meet for the foam vertex color")]
  20. public float foamThreshold = 0.2f;
  21. [Tooltip("Emitters will only be created if the surface angle falls within this range")]
  22. public Vector2 minMaxSlopeAngle = new Vector2(0f, 5f);
  23. [Range(0f, 100f)]
  24. public float spawnChance = 100f;
  25. //Analyze the mesh's vertex colors to detect foam
  26. public override void GenerateEmitters()
  27. {
  28. #if VFX_GRAPH && MATHEMATICS
  29. if (!river || !targetEffect || !river.meshFilter) return;
  30. emitters = new List<VFX.Emitter>();
  31. Vector3 min = Vector3.one * float.MaxValue;
  32. Vector3 max = Vector3.one * float.MinValue;
  33. Vector3[] vertices = river.meshFilter.sharedMesh.vertices;
  34. Vector3[] normals = river.meshFilter.sharedMesh.normals;
  35. var pCount = vertices.Length;
  36. Color[] colors = river.meshFilter.sharedMesh.colors;
  37. if (confines == Confines.Bounds) bounds = new Bounds(this.transform.position, boundsSize);
  38. for (int i = 0; i < pCount; i++)
  39. {
  40. float3 worldPos = river.meshFilter.transform.TransformPoint(vertices[i]);
  41. if (confines == Confines.Bounds)
  42. {
  43. if (bounds.Contains(worldPos) == false) continue;
  44. }
  45. vertices[i] = targetEffect.transform.InverseTransformPoint(worldPos);
  46. //Ensure opacity also subtracts from foam
  47. var weight = colors[i][(int)river.settings.foam.vertexColorChannel];
  48. weight -= colors[i][(int)river.settings.transparency.vertexColorChannel];
  49. float slopeMask = 0f;
  50. #if MATHEMATICS
  51. float angle = ((float)math.acos(math.dot(normals[i], Vector3.up)) * Mathf.Rad2Deg);
  52. if (angle > minMaxSlopeAngle.x && angle < minMaxSlopeAngle.y) slopeMask = 1f;
  53. #endif
  54. //Random.InitState(i + (int)Time.time);
  55. if (slopeMask > 0 && weight >= foamThreshold && (Random.value * 100 < spawnChance))
  56. {
  57. VFX.Emitter emitter = new VFX.Emitter();
  58. emitter.position = vertices[i];
  59. min = Vector3.Min(emitter.position, min);
  60. max = Vector3.Max(emitter.position, max);
  61. emitters.Add(emitter);
  62. }
  63. }
  64. particleBounds = new Bounds();
  65. particleBounds.SetMinMax(min, max);
  66. ApplyEmitters();
  67. #endif
  68. }
  69. }
  70. }