'push'
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WaveHarmonic.Crest
|
||||
{
|
||||
partial class Meniscus
|
||||
{
|
||||
internal const string k_MaterialPath = "Packages/com.waveharmonic.crest/Runtime/Materials/Meniscus.mat";
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
_Material = AssetDatabase.LoadAssetAtPath<Material>(k_MaterialPath);
|
||||
}
|
||||
|
||||
[@OnChange]
|
||||
void OnChange(string path, object previous)
|
||||
{
|
||||
switch (path)
|
||||
{
|
||||
case nameof(_Enabled): SetEnabled((bool)previous, _Enabled); break;
|
||||
case nameof(_Material): SetMaterial((Material)previous, _Material); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20f5eb7691544460796ae81ca7816cbb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,88 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#if d_UnityHDRP
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering.HighDefinition;
|
||||
|
||||
namespace WaveHarmonic.Crest
|
||||
{
|
||||
partial class Meniscus
|
||||
{
|
||||
internal sealed class MeniscusRendererHDRP : MeniscusRenderer
|
||||
{
|
||||
const string k_Name = "Meniscus";
|
||||
MeniscusCustomPass _CustomPass;
|
||||
GameObject _GameObject;
|
||||
|
||||
public MeniscusRendererHDRP(WaterRenderer water, Meniscus meniscus) : base(water, meniscus)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Enable()
|
||||
{
|
||||
base.Enable();
|
||||
|
||||
_GameObject = CustomPassHelpers.CreateOrUpdate
|
||||
(
|
||||
parent: _Water.Container.transform,
|
||||
k_Name,
|
||||
hide: !_Water._Debug._ShowHiddenObjects
|
||||
);
|
||||
|
||||
CustomPassHelpers.CreateOrUpdate
|
||||
(
|
||||
_GameObject,
|
||||
ref _CustomPass,
|
||||
k_Draw,
|
||||
CustomPassInjectionPoint.BeforePostProcess,
|
||||
priority: -1
|
||||
);
|
||||
|
||||
_CustomPass._Renderer = this;
|
||||
}
|
||||
|
||||
public override void Disable()
|
||||
{
|
||||
base.Disable();
|
||||
|
||||
if (_GameObject != null)
|
||||
{
|
||||
// Will also trigger Cleanup below.
|
||||
_GameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnBeginCameraRendering(Camera camera)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void OnEndCameraRendering(Camera camera)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
sealed class MeniscusCustomPass : CustomPass
|
||||
{
|
||||
internal MeniscusRenderer _Renderer;
|
||||
|
||||
protected override void Execute(CustomPassContext context)
|
||||
{
|
||||
var camera = context.hdCamera.camera;
|
||||
|
||||
if (!_Renderer.ShouldExecute(camera))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Renderer.Execute(camera, new CommandWrapper(context.cmd));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec8f31a3e4e434fa0a8e771834d9dc16
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace WaveHarmonic.Crest
|
||||
{
|
||||
partial class Meniscus
|
||||
{
|
||||
internal sealed class MeniscusRendererBIRP : MeniscusRenderer
|
||||
{
|
||||
CommandBuffer _Commands;
|
||||
|
||||
// NOTE: This will not work for recursive rendering.
|
||||
bool _CommandsRegistered;
|
||||
|
||||
public MeniscusRendererBIRP(WaterRenderer water, Meniscus meniscus) : base(water, meniscus)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void OnBeginCameraRendering(Camera camera)
|
||||
{
|
||||
if (!ShouldExecute(camera))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Commands ??= new()
|
||||
{
|
||||
name = k_Draw,
|
||||
};
|
||||
|
||||
_Commands.Clear();
|
||||
|
||||
Execute(camera, new CommandWrapper(_Commands));
|
||||
|
||||
camera.AddCommandBuffer(CameraEvent.AfterForwardAlpha, _Commands);
|
||||
|
||||
_CommandsRegistered = true;
|
||||
}
|
||||
|
||||
public override void OnEndCameraRendering(Camera camera)
|
||||
{
|
||||
if (!_CommandsRegistered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
camera.RemoveCommandBuffer(CameraEvent.AfterForwardAlpha, _Commands);
|
||||
|
||||
_CommandsRegistered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a79d71a3e88424f27877abd4102b5af9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,118 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#if d_UnityURP
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
namespace WaveHarmonic.Crest
|
||||
{
|
||||
partial class Meniscus
|
||||
{
|
||||
internal sealed class MeniscusRendererURP : MeniscusRenderer
|
||||
{
|
||||
readonly MeniscusRenderPass _MaskRenderPass = new();
|
||||
|
||||
public MeniscusRendererURP(WaterRenderer water, Meniscus meniscus) : base(water, meniscus)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void OnBeginCameraRendering(Camera camera)
|
||||
{
|
||||
if (!ShouldExecute(camera))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_MaskRenderPass._Renderer = this;
|
||||
_MaskRenderPass.EnqueuePass(camera);
|
||||
}
|
||||
|
||||
public override void OnEndCameraRendering(Camera camera)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
sealed partial class MeniscusRenderPass : ScriptableRenderPass
|
||||
{
|
||||
const string k_Name = k_Draw;
|
||||
|
||||
internal MeniscusRenderer _Renderer;
|
||||
|
||||
bool _RequiresOpaqueTexture;
|
||||
|
||||
public MeniscusRenderPass()
|
||||
{
|
||||
renderPassEvent = RenderPassEvent.AfterRenderingTransparents;
|
||||
}
|
||||
|
||||
internal void EnqueuePass(Camera camera)
|
||||
{
|
||||
// TODO: check if we need to even enqueue a pass
|
||||
var renderer = camera.GetUniversalAdditionalCameraData().scriptableRenderer;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (renderer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
_RequiresOpaqueTexture = _Renderer._Meniscus.RequiresOpaqueTexture;
|
||||
|
||||
ConfigureInput(_RequiresOpaqueTexture ? ScriptableRenderPassInput.Color : ScriptableRenderPassInput.None);
|
||||
|
||||
// Enqueue the pass. This happens every frame.
|
||||
renderer.EnqueuePass(this);
|
||||
}
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
class PassData
|
||||
{
|
||||
public UniversalCameraData _CameraData;
|
||||
public MeniscusRenderer _Renderer;
|
||||
}
|
||||
|
||||
public override void RecordRenderGraph(UnityEngine.Rendering.RenderGraphModule.RenderGraph graph, ContextContainer frame)
|
||||
{
|
||||
using (var builder = graph.AddRasterRenderPass<PassData>(k_Name, out var data))
|
||||
{
|
||||
builder.AllowPassCulling(false);
|
||||
|
||||
var resources = frame.Get<UniversalResourceData>();
|
||||
|
||||
if (_RequiresOpaqueTexture)
|
||||
{
|
||||
builder.UseTexture(resources.cameraOpaqueTexture);
|
||||
}
|
||||
|
||||
data._CameraData = frame.Get<UniversalCameraData>();
|
||||
data._Renderer = _Renderer;
|
||||
|
||||
builder.SetRenderAttachment(resources.activeColorTexture, index: 0);
|
||||
|
||||
builder.SetRenderFunc<PassData>((data, context) =>
|
||||
{
|
||||
data._Renderer.Execute(data._CameraData.camera, new RasterCommandWrapper(context.cmd));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[System.Obsolete]
|
||||
#endif
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData data)
|
||||
{
|
||||
var buffer = CommandBufferPool.Get(k_Name);
|
||||
_Renderer.Execute(data.cameraData.camera, new CommandWrapper(buffer));
|
||||
context.ExecuteCommandBuffer(buffer);
|
||||
CommandBufferPool.Release(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6888087ee71bb4b378cf0e4f30479f93
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,234 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace WaveHarmonic.Crest
|
||||
{
|
||||
/// <summary>
|
||||
/// Renders the meniscus (waterline).
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public sealed partial class Meniscus
|
||||
{
|
||||
[@Space(10)]
|
||||
|
||||
[Tooltip("Whether the meniscus is enabled.")]
|
||||
[@GenerateAPI(Getter.Custom, Setter.Custom)]
|
||||
[@DecoratedField]
|
||||
[SerializeField]
|
||||
internal bool _Enabled = true;
|
||||
|
||||
[Tooltip("Any camera with this layer in its culling mask will render the meniscus.")]
|
||||
[@Layer]
|
||||
[@GenerateAPI]
|
||||
[SerializeField]
|
||||
int _Layer = 4; // Water
|
||||
|
||||
[Tooltip("The meniscus material.")]
|
||||
[@AttachMaterialEditor(order: 2)]
|
||||
[@MaterialField("Crest/Meniscus", name: "Meniscus", title: "Create Meniscus Material")]
|
||||
[@GenerateAPI(Setter.Custom)]
|
||||
[SerializeField]
|
||||
internal Material _Material;
|
||||
|
||||
|
||||
WaterRenderer _Water;
|
||||
|
||||
internal MeniscusRenderer Renderer { get; private set; }
|
||||
|
||||
internal bool RequiresOpaqueTexture => Enabled && Material != null && Material.IsKeywordEnabled("d_Crest_Refraction");
|
||||
|
||||
/// <summary>
|
||||
/// Disables rendering without de-allocating.
|
||||
/// </summary>
|
||||
public bool ForceRenderingOff { get; set; }
|
||||
|
||||
internal void Enable()
|
||||
{
|
||||
Initialize(_Water);
|
||||
Renderer?.Enable();
|
||||
}
|
||||
|
||||
internal void Disable()
|
||||
{
|
||||
Renderer?.Disable();
|
||||
}
|
||||
|
||||
internal void Destroy()
|
||||
{
|
||||
Renderer?.Destroy();
|
||||
Renderer = null;
|
||||
}
|
||||
|
||||
internal void OnActiveRenderPipelineTypeChanged()
|
||||
{
|
||||
Destroy();
|
||||
Initialize(_Water);
|
||||
}
|
||||
|
||||
internal void Initialize(WaterRenderer water)
|
||||
{
|
||||
_Water = water;
|
||||
|
||||
if (!Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if d_UnityHDRP
|
||||
if (RenderPipelineHelper.IsHighDefinition)
|
||||
{
|
||||
Renderer ??= new MeniscusRendererHDRP(water, this);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#if d_UnityURP
|
||||
if (RenderPipelineHelper.IsUniversal)
|
||||
{
|
||||
Renderer ??= new MeniscusRendererURP(water, this);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
// Legacy
|
||||
{
|
||||
Renderer ??= new MeniscusRendererBIRP(water, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Getters/Setters
|
||||
partial class Meniscus
|
||||
{
|
||||
bool GetEnabled()
|
||||
{
|
||||
return _Enabled && _Material != null;
|
||||
}
|
||||
|
||||
void SetEnabled(bool previous, bool current)
|
||||
{
|
||||
if (previous == current) return;
|
||||
if (_Water == null || !_Water.isActiveAndEnabled) return;
|
||||
if (_Enabled) Enable(); else Disable();
|
||||
}
|
||||
|
||||
void SetMaterial(Material previous, Material current)
|
||||
{
|
||||
if (previous == current) return;
|
||||
if (_Water == null || !_Water.isActiveAndEnabled) return;
|
||||
if (previous == null) Enable(); else if (current == null) Disable();
|
||||
}
|
||||
}
|
||||
|
||||
partial class Meniscus
|
||||
{
|
||||
internal abstract partial class MeniscusRenderer
|
||||
{
|
||||
private protected const string k_Draw = "Crest.DrawWater/Meniscus";
|
||||
|
||||
private protected readonly WaterRenderer _Water;
|
||||
internal readonly Meniscus _Meniscus;
|
||||
|
||||
static partial class ShaderIDs
|
||||
{
|
||||
public static readonly int s_HorizonNormal = Shader.PropertyToID("_Crest_HorizonNormal");
|
||||
}
|
||||
|
||||
public abstract void OnBeginCameraRendering(Camera camera);
|
||||
public abstract void OnEndCameraRendering(Camera camera);
|
||||
|
||||
public MeniscusRenderer(WaterRenderer water, Meniscus meniscus)
|
||||
{
|
||||
_Water = water;
|
||||
_Meniscus = meniscus;
|
||||
}
|
||||
|
||||
public virtual void Enable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Disable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Destroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal bool ShouldExecute(Camera camera)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (GL.wireframe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_Meniscus.ForceRenderingOff)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Meniscus is a product of the water surface.
|
||||
if (!_Water.Surface.Enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (camera.cameraType is not CameraType.Game and not CameraType.SceneView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WaterRenderer.ShouldRender(camera, _Meniscus.Layer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if d_CrestPortals
|
||||
if (_Water.Portals.Active)
|
||||
{
|
||||
// Near surface check not compatible with portals.
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
_Water.UpdatePerCameraHeight(camera);
|
||||
|
||||
// Only execute if near the surface.
|
||||
if (_Water._ViewerHeightAboveWaterPerCamera is > 2f or < -8f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void Execute<T>(Camera camera, T commands) where T : ICommandWrapper
|
||||
{
|
||||
// Project water normal onto camera plane.
|
||||
_Meniscus.Material.SetVector(ShaderIDs.s_HorizonNormal, new Vector2
|
||||
(
|
||||
Vector3.Dot(Vector3.up, camera.transform.right),
|
||||
Vector3.Dot(Vector3.up, camera.transform.up)
|
||||
));
|
||||
|
||||
#if d_CrestPortals
|
||||
if (_Water.Portals.Active && !(_Water.Underwater.UseLegacyMask && _Water._Portals.Mode == Portals.PortalMode.Tunnel))
|
||||
{
|
||||
_Water._Portals.RenderMeniscus(commands, _Meniscus.Material);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
commands.DrawFullScreenTriangle(_Meniscus.Material, pass: _Water._Underwater.UseLegacyMask ? 4 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df109675493a845f7ad07008e1c1aaaa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user