Files
Fishing2/Packages/com.waveharmonic.crest/Editor/Scripts/Previews.cs
2026-01-31 00:32:49 +08:00

307 lines
10 KiB
C#

// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace WaveHarmonic.Crest.Editor
{
//
// Lod
//
abstract class LodPreview : TexturePreview
{
protected abstract Lod Lod { get; }
protected abstract bool VisualizeNegatives { get; }
protected virtual bool ForceAlpha => false;
public override GUIContent GetPreviewTitle() => new(Lod.Name);
protected RenderTexture _TemporaryTexture;
protected override Texture OriginalTexture
{
get
{
var water = (WaterRenderer)target;
if ((!Application.isPlaying && !water.runInEditMode) || !water.isActiveAndEnabled)
{
return null;
}
if (!Lod.Enabled)
{
return null;
}
var texture = Lod.DataTexture;
if (texture == null)
{
return null;
}
return texture;
}
}
protected override Texture ModifiedTexture => _TemporaryTexture;
public override void OnPreviewSettings()
{
base.OnPreviewSettings();
// OnPreviewSettings is called after OnPreviewGUI so release here.
RenderTexture.ReleaseTemporary(_TemporaryTexture);
_TemporaryTexture = null;
}
public override void OnPreviewGUI(Rect rect, GUIStyle background)
{
var texture = (RenderTexture)OriginalTexture;
var descriptor = texture.descriptor;
_TemporaryTexture = RenderTexture.GetTemporary(descriptor);
_TemporaryTexture.name = texture.name;
Graphics.CopyTexture(texture, _TemporaryTexture);
if (VisualizeNegatives)
{
var wrapper = new PropertyWrapperComputeStandalone(EditorHelpers.VisualizeNegativeValuesShader, 1);
wrapper.SetTexture(ShaderIDs.s_Target, _TemporaryTexture);
wrapper.Dispatch
(
Lod.Resolution / Lod.k_ThreadGroupSizeX,
Lod.Resolution / Lod.k_ThreadGroupSizeY,
Lod.Slices
);
}
ModifyTexture();
if (ForceAlpha)
{
// Set alpha to one otherwise it shows nothing when set to RGB.
if (WaterResources.Instance.Compute._Clear != null)
{
var compute = WaterResources.Instance._ComputeLibrary._ClearCompute;
var wrapper = new PropertyWrapperComputeStandalone(compute._Shader, compute._KernelClearTarget);
compute.SetVariantForFormat(wrapper, _TemporaryTexture.graphicsFormat);
wrapper.SetTexture(ShaderIDs.s_Target, _TemporaryTexture);
wrapper.SetVector(ShaderIDs.s_ClearMask, Color.black);
wrapper.SetVector(ShaderIDs.s_ClearColor, Color.black);
wrapper.Dispatch
(
Lod.Resolution / Lod.k_ThreadGroupSizeX,
Lod.Resolution / Lod.k_ThreadGroupSizeY,
Lod.Slices
);
}
}
base.OnPreviewGUI(rect, background);
}
protected virtual void ModifyTexture()
{
}
public override void Cleanup()
{
base.Cleanup();
RenderTexture.ReleaseTemporary(_TemporaryTexture);
}
// FIXME: Without constructor Unity complains:
// WaveHarmonic.Crest.Editor.LodPreview does not contain a default constructor, it
// will not be registered as a preview handler. Use the Initialize function to set
// up your object instead.
public LodPreview() { }
}
[CustomPreview(typeof(WaterRenderer))]
sealed class AbsorptionLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._AbsorptionLod;
protected override bool VisualizeNegatives => false;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class AlbedoLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._AlbedoLod;
protected override bool VisualizeNegatives => false;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class AnimatedWavesLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._AnimatedWavesLod;
protected override bool VisualizeNegatives => true;
protected override bool ForceAlpha => true;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class ClipLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._ClipLod;
protected override bool VisualizeNegatives => false;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class DepthLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._DepthLod;
protected override bool VisualizeNegatives => true;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class DynamicWavesLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._DynamicWavesLod;
// Negatives do not visualize well, and obscure positives too much.
protected override bool VisualizeNegatives => false;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class FlowLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._FlowLod;
protected override bool VisualizeNegatives => true;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class FoamLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._FoamLod;
protected override bool VisualizeNegatives => false;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class LevelLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._LevelLod;
protected override bool VisualizeNegatives => true;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class ScatteringLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._ScatteringLod;
protected override bool VisualizeNegatives => false;
protected override bool ForceAlpha => true;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class ShadowLodPreview : LodPreview
{
protected override Lod Lod => (target as WaterRenderer)._ShadowLod;
protected override bool VisualizeNegatives => false;
}
//
// LodInput
//
// Adding abstract causes exception:
// does not contain a default constructor, it will not be registered as a preview
// handler. Use the Initialize function to set up your object instead.
class ShapeWavesPreview : TexturePreview
{
public override GUIContent GetPreviewTitle() => new($"{target.GetType().Name}: Wave Buffer");
protected override Texture OriginalTexture => (target as ShapeWaves).WaveBuffer;
}
[CustomPreview(typeof(ShapeFFT))]
sealed class ShapeFFTPreview : ShapeWavesPreview
{
}
[CustomPreview(typeof(ShapeGerstner))]
sealed class ShapeGerstnerPreview : ShapeWavesPreview
{
}
[CustomPreview(typeof(DepthProbe))]
sealed class DepthProbePreview : TexturePreview
{
public override GUIContent GetPreviewTitle() => new("Depth Probe");
protected override Texture OriginalTexture => (target as DepthProbe).Texture;
}
#if CREST_DEBUG
[CustomPreview(typeof(DepthProbe))]
sealed class DepthProbeCameraPreview : TexturePreview
{
public override GUIContent GetPreviewTitle() => new("Depth Probe: Camera");
protected override Texture OriginalTexture
{
get
{
var target = this.target as DepthProbe;
if (target._Camera == null) return null;
return target._Camera.targetTexture;
}
}
}
#endif
//
// Other
//
#if CREST_DEBUG
[CustomPreview(typeof(WaterRenderer))]
sealed class WaterLevelDepthPreview : TexturePreview
{
public override GUIContent GetPreviewTitle() => new("Water Level Screen-Space Depth");
protected override Texture OriginalTexture => (target as WaterRenderer).Surface.WaterLevelDepthTexture;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class WaterLinePreview : TexturePreview
{
public override GUIContent GetPreviewTitle() => new("Pre-Computed Displacement");
protected override Texture OriginalTexture => (target as WaterRenderer).Surface.HeightRT;
}
[CustomPreview(typeof(WaterRenderer))]
sealed class WaterVolumeMaskPreview : TexturePreview
{
public override GUIContent GetPreviewTitle() => new("Water Volume Mask");
protected override Texture OriginalTexture
{
get
{
var target = this.target as WaterRenderer;
return target._Mask?.ColorT != null && target._Mask?.ColorT.width > 0
? target._Mask.ColorT
: null;
}
}
}
#endif
[CustomPreview(typeof(WaterRenderer))]
sealed class ReflectionPreview : TexturePreview
{
static readonly PropertyInfo s_DefaultReflection = typeof(RenderSettings).GetProperty("defaultReflection", BindingFlags.NonPublic | BindingFlags.Static);
public override GUIContent GetPreviewTitle() => new("Water Reflections");
protected override Texture OriginalTexture => (target as WaterRenderer)._Reflections._Enabled
? (target as WaterRenderer)._Reflections.ColorTexture
: s_DefaultReflection?.GetValue(null) as Texture;
}
#if CREST_DEBUG
[CustomPreview(typeof(WaterRenderer))]
sealed class ReflectionDepthPreview : TexturePreview
{
public override GUIContent GetPreviewTitle() => new("Water Reflections (Depth)");
protected override Texture OriginalTexture => (target as WaterRenderer)._Reflections.DepthTexture;
}
#endif
}