先修复一下,错误的场景 删除不必要的钓场资产 修复into场景 update:更新meta文件,修复报错 update:修复资源 修复第一章节建造 修复建造第三章 update:删除多余内容 update:更新README.md update:还原图标 update:更新README update:更新配置
1037 lines
53 KiB
C#
1037 lines
53 KiB
C#
// WaterCausticsModules
|
|
// Copyright (c) 2021 Masataka Hakozaki
|
|
|
|
#if WCE_URP
|
|
using System.Collections.Generic;
|
|
using MH.WaterCausticsModules.Effect;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.Universal;
|
|
using UnityEngine.Serialization;
|
|
|
|
#if UNITY_EDITOR
|
|
using System.IO;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine.SceneManagement;
|
|
#endif
|
|
|
|
namespace MH.WaterCausticsModules {
|
|
|
|
namespace Effect {
|
|
// ----------------------------------------------------------- Enum
|
|
public enum TexChannel { RGB, R, G, B, A }
|
|
public enum Method { AtOnce = 0, EachMesh = 1 }
|
|
public enum NormalSrc { DepthTex = 0, NormalTex = 1 }
|
|
public enum DebugMode { Normal = 1, Depth, Facing, Caustics, LightArea }
|
|
public enum ListUsage { Ignore = 0, Valid = 1 }
|
|
}
|
|
|
|
[ExecuteAlways]
|
|
[DisallowMultipleComponent]
|
|
[HelpURL (Constant.URL_MANUAL)]
|
|
[AddComponentMenu ("WaterCausticsModules/WaterCausticsEffect")]
|
|
public class WaterCausticsEffect : MonoBehaviour {
|
|
// ----------------------------------------------------------- Constant
|
|
private Vector3 [] _texChannelVec = { new Vector3 (0, 1, 2), Vector3.zero, Vector3.one, Vector3.one * 2, Vector3.one * 3 };
|
|
|
|
static internal readonly RenderPassEvent SYS_OPAQUE_TEX_EVENT = RenderPassEvent.AfterRenderingSkybox; // URP OpaqueTex描画タイミング
|
|
static internal readonly RenderPassEvent RENDER_EVENT = SYS_OPAQUE_TEX_EVENT; // EachMesh描画タイミング
|
|
static internal readonly int RENDER_EVENT_ADJ = -1; // EachMesh描画タイミング
|
|
|
|
// ----------------------------------------------------------- SerializeField
|
|
[SerializeField] private Method m_method = Method.AtOnce;
|
|
[SerializeField] private NormalSrc m_normalSrc = NormalSrc.NormalTex; // for AtOnceMethod only
|
|
[SerializeField] private bool m_debugInfo = false;
|
|
[SerializeField] private DebugMode m_debugMode = DebugMode.Normal;
|
|
[SerializeField] private uint m_renderLayerMask = 1; // for AtOnceMethod only
|
|
[SerializeField] private LayerMask m_layerMask = ~0;
|
|
[FormerlySerializedAs ("m_clipOutsideVolume")] [SerializeField] private bool m_clipOutside = true;
|
|
[SerializeField] private bool m_useImageMask = true;
|
|
[SerializeField] private Texture m_imageMaskTexture;
|
|
[SerializeField] private Texture m_texture;
|
|
[SerializeField] private TexChannel m_textureChannel;
|
|
[SerializeField, Range (-180f, 180f)] private float m_textureRotation = 15f;
|
|
[SerializeField] private Vector2 m_texRotSinCos = new Vector2 (0, 1);
|
|
[SerializeField] private bool m_useRandomTiling;
|
|
[SerializeField, Range (0, 1000)] private int m_tilingSeed = 0;
|
|
[SerializeField, Range (0f, 0.2f)] private float m_tilingRotation = 0.02f;
|
|
[SerializeField, Range (0.75f, 0.999f)] private float m_tilingHardness = 0.85f;
|
|
[SerializeField, Min (0.0001f)] private float m_scale = 1f;
|
|
[FormerlySerializedAs ("m_waterSurfaceY")] [SerializeField] private float m_surfaceY = 2f;
|
|
[FormerlySerializedAs ("m_waterSurfaceAttenOffset")] [SerializeField, Min (0f)] private float m_surfFadeStart;
|
|
[FormerlySerializedAs ("m_waterSurfaceAttenWide")] [SerializeField, Min (0f)] private float m_surfFadeEnd = 0.5f;
|
|
[FormerlySerializedAs ("m_useDepthAtten")] [SerializeField] private bool m_useDepthFade = false;
|
|
[SerializeField, Min (0f)] private float m_depthFadeStart = 0f;
|
|
[FormerlySerializedAs ("m_depthAttenDepth")] [SerializeField, Min (0f)] private float m_depthFadeEnd = 50f;
|
|
[SerializeField] private bool m_useDistanceFade = false;
|
|
[SerializeField, Min (0f)] private float m_distanceFadeStart = 30f;
|
|
[SerializeField, Min (0f)] private float m_distanceFadeEnd = 100f;
|
|
[SerializeField, Min (0f)] private float m_intensity = 5f;
|
|
[FormerlySerializedAs ("m_adjustMainLit")] [SerializeField, Range (0f, 10f)] private float m_mainLit = 1f;
|
|
[FormerlySerializedAs ("m_adjustAddLit")] [SerializeField, Range (0f, 10f)] private float m_addLit = 1f;
|
|
[SerializeField] float m_colorShiftU; // Legacy
|
|
[SerializeField] float m_colorShiftV; // Legacy
|
|
[SerializeField, Range (0f, 5f)] float m_colorShift = 0.6f;
|
|
[SerializeField, Range (-180f, 180f)] float m_colorShiftDir = 120f;
|
|
[SerializeField, Range (0f, 2f)] private float m_litSaturation = 0.2f;
|
|
[FormerlySerializedAs ("m_multiplyOpaqueColor")] [SerializeField] private bool m_useMultiply; // Legacy
|
|
[FormerlySerializedAs ("m_multiplyOpaqueIntensity")] [SerializeField, Range (0f, 1f)] private float m_multiply = 1f;
|
|
[FormerlySerializedAs ("m_normalAttenIntensity")] [SerializeField, Range (0f, 1f)] private float m_normalAtten = 1f;
|
|
[FormerlySerializedAs ("m_normalAttenPower")] [SerializeField, Range (1f, 8f)] private float m_normalAttenRate = 1.5f;
|
|
[SerializeField, Range (0f, 1f)] private float m_transparentBackside = 0f;
|
|
[SerializeField, Range (0f, 1f)] private float m_backsideShadow = 0f;
|
|
[SerializeField] private bool m_receiveShadows = true;
|
|
[SerializeField, Range (0f, 1f)] private float m_shadowIntensity = 1f;
|
|
[FormerlySerializedAs ("m_useMainLight")] [SerializeField] private int m_version = Constant.WCE_VERSION_INT;
|
|
[SerializeField] private bool m_useMainLit = true;
|
|
[FormerlySerializedAs ("m_useAdditionalLights")] [SerializeField] private bool m_useAddLit = true;
|
|
[FormerlySerializedAs ("m_syncWithShaderFunctions")] [SerializeField] private bool m_useCustomFunc = false;
|
|
[SerializeField] private RenderPassEvent m_renderEvent = RENDER_EVENT;
|
|
[SerializeField] private int m_renderEventAdjust = RENDER_EVENT_ADJ;
|
|
[SerializeField, Range (0, 255)] private int m_stencilRef = 0;
|
|
[SerializeField, Range (0, 255)] private int m_stencilReadMask = 255;
|
|
[SerializeField, Range (0, 255)] private int m_stencilWriteMask = 255;
|
|
[SerializeField] private CompareFunction m_stencilComp = CompareFunction.Always;
|
|
[SerializeField] private StencilOp m_stencilPass = StencilOp.Keep;
|
|
[SerializeField] private StencilOp m_stencilFail = StencilOp.Keep;
|
|
[SerializeField] private StencilOp m_stencilZFail = StencilOp.Keep;
|
|
[SerializeField] private CullMode m_cullMode = CullMode.Off;
|
|
[SerializeField] private bool m_zWriteMode = false;
|
|
[SerializeField] private CompareFunction m_zTestMode = CompareFunction.Equal;
|
|
[SerializeField] private float m_depthOffsetFactor = 0;
|
|
[SerializeField] private float m_depthOffsetUnits = 0;
|
|
[SerializeField] private Shader m_shader;
|
|
[SerializeField] private Texture m_noTexture;
|
|
|
|
// ----------------------------------------------------------- private property
|
|
private RenderPassEvent eventAdjusted => (RenderPassEvent) Mathf.Clamp ((int) m_renderEvent + m_renderEventAdjust, 0, 1000);
|
|
private bool existOpaqueTex => (eventAdjusted > SYS_OPAQUE_TEX_EVENT);
|
|
private bool useBlendMultiply => (m_multiply == 1f || (m_multiply > 0f && !existOpaqueTex));
|
|
private float multiplyByTex => (m_multiply < 1f && existOpaqueTex) ? m_multiply : 0f;
|
|
private float multiplyRaw => m_multiply;
|
|
private Vector2 calcColorShiftVec () => dirToVec (m_colorShiftDir) * m_colorShift * 0.01f;
|
|
private float finalMainLit => m_intensity * m_mainLit * (m_useMainLit ? 1f : 0f);
|
|
private float finalAddLit => m_intensity * m_addLit * (m_useAddLit ? 1f : 0f);
|
|
private bool isIntensityZero => (finalMainLit + finalAddLit == 0f);
|
|
private bool useClipOutside => (m_method == Method.AtOnce || m_clipOutside);
|
|
|
|
// ----------------------------------------------------------- Public property
|
|
private void setValAndNeedSetMat<T> (ref T prop, T val) {
|
|
prop = val;
|
|
_needUpdateMat = true;
|
|
}
|
|
public Method method {
|
|
get => m_method;
|
|
set => setValAndNeedSetMat (ref m_method, value);
|
|
}
|
|
public NormalSrc normalSrc {
|
|
get => m_normalSrc;
|
|
set => setValAndNeedSetMat (ref m_normalSrc, value);
|
|
}
|
|
public bool debugInfo {
|
|
get => m_debugInfo;
|
|
set => setValAndNeedSetMat (ref m_debugInfo, value);
|
|
}
|
|
public DebugMode debugMode {
|
|
get => m_debugMode;
|
|
set => setValAndNeedSetMat (ref m_debugMode, value);
|
|
}
|
|
public uint renderingLayerMask {
|
|
get => m_renderLayerMask;
|
|
set => setValAndNeedSetMat (ref m_renderLayerMask, value);
|
|
}
|
|
public LayerMask layerMask {
|
|
get => m_layerMask;
|
|
set => m_layerMask = value;
|
|
}
|
|
public bool clipOutside {
|
|
get => m_clipOutside;
|
|
set => setValAndNeedSetMat (ref m_clipOutside, value);
|
|
}
|
|
public Texture texture {
|
|
get => m_texture;
|
|
set => setValAndNeedSetMat (ref m_texture, value);
|
|
}
|
|
public TexChannel textureChannel {
|
|
get => m_textureChannel;
|
|
set => setValAndNeedSetMat (ref m_textureChannel, value);
|
|
}
|
|
public float textureRotation {
|
|
get => m_textureRotation;
|
|
set {
|
|
float rad = value * Mathf.Deg2Rad;
|
|
m_texRotSinCos = new Vector2 (Mathf.Sin (rad), Mathf.Cos (rad));
|
|
setValAndNeedSetMat (ref m_textureRotation, value);
|
|
}
|
|
}
|
|
public bool useRandomTiling {
|
|
get => m_useRandomTiling;
|
|
set => setValAndNeedSetMat (ref m_useRandomTiling, value);
|
|
}
|
|
public int tilingSeed {
|
|
get => m_tilingSeed;
|
|
set => setValAndNeedSetMat (ref m_tilingSeed, Mathf.Max (0, value));
|
|
}
|
|
public float tilingRotation {
|
|
get => m_tilingRotation;
|
|
set => setValAndNeedSetMat (ref m_tilingRotation, Mathf.Clamp (value, 0f, 1f));
|
|
}
|
|
public float tilingHardness {
|
|
get => m_tilingHardness;
|
|
set => setValAndNeedSetMat (ref m_tilingHardness, Mathf.Clamp (value, 0.001f, 0.999f));
|
|
}
|
|
public float intensity {
|
|
get => m_intensity;
|
|
set => setValAndNeedSetMat (ref m_intensity, Mathf.Max (0f, value));
|
|
}
|
|
public float mainLightIntensity {
|
|
get => m_mainLit;
|
|
set => setValAndNeedSetMat (ref m_mainLit, Mathf.Max (0f, value));
|
|
}
|
|
public float additionalLightsIntensity {
|
|
get => m_addLit;
|
|
set => setValAndNeedSetMat (ref m_addLit, Mathf.Max (0f, value));
|
|
}
|
|
public float scale {
|
|
get => m_scale;
|
|
set => setValAndNeedSetMat (ref m_scale, Mathf.Max (0.0001f, value));
|
|
}
|
|
public float colorShift {
|
|
get => m_colorShift;
|
|
set => setValAndNeedSetMat (ref m_colorShift, Mathf.Max (0f, value));
|
|
}
|
|
public float colorShiftDirection {
|
|
get => m_colorShiftDir;
|
|
set => setValAndNeedSetMat (ref m_colorShiftDir, wrapAngle180 (value));
|
|
}
|
|
public float surfaceY {
|
|
get => m_surfaceY;
|
|
set => setValAndNeedSetMat (ref m_surfaceY, value);
|
|
}
|
|
public float surfaceFadeStart {
|
|
get => m_surfFadeStart;
|
|
set => setValAndNeedSetMat (ref m_surfFadeStart, Mathf.Max (0f, value));
|
|
}
|
|
public float surfaceFadeEnd {
|
|
get => m_surfFadeEnd;
|
|
set => setValAndNeedSetMat (ref m_surfFadeEnd, Mathf.Max (0f, value));
|
|
}
|
|
|
|
public bool useDepthFade {
|
|
get => m_useDepthFade;
|
|
set => setValAndNeedSetMat (ref m_useDepthFade, value);
|
|
}
|
|
public float depthAttenStart {
|
|
get => m_depthFadeStart;
|
|
set => setValAndNeedSetMat (ref m_depthFadeStart, Mathf.Max (0f, value));
|
|
}
|
|
public float depthAttenEnd {
|
|
get => m_depthFadeEnd;
|
|
set => setValAndNeedSetMat (ref m_depthFadeEnd, Mathf.Max (0f, value));
|
|
}
|
|
public bool useDistanceAtten {
|
|
get => m_useDistanceFade;
|
|
set => setValAndNeedSetMat (ref m_useDistanceFade, value);
|
|
}
|
|
public float distanceAttenStart {
|
|
get => m_distanceFadeStart;
|
|
set => setValAndNeedSetMat (ref m_distanceFadeStart, Mathf.Max (0f, value));
|
|
}
|
|
public float distanceAttenEnd {
|
|
get => m_distanceFadeEnd;
|
|
set => setValAndNeedSetMat (ref m_distanceFadeEnd, Mathf.Max (0f, value));
|
|
}
|
|
public float lightSaturation {
|
|
get => m_litSaturation;
|
|
set => setValAndNeedSetMat (ref m_litSaturation, Mathf.Max (0f, value));
|
|
}
|
|
public bool receiveShadows {
|
|
get => m_receiveShadows;
|
|
set => setValAndNeedSetMat (ref m_receiveShadows, value);
|
|
}
|
|
public float shadowIntensity {
|
|
get => m_shadowIntensity;
|
|
set => setValAndNeedSetMat (ref m_shadowIntensity, value);
|
|
}
|
|
public bool useMainLight {
|
|
get => m_useMainLit;
|
|
set => setValAndNeedSetMat (ref m_useMainLit, value);
|
|
}
|
|
public bool useAdditionalLights {
|
|
get => m_useAddLit;
|
|
set => setValAndNeedSetMat (ref m_useAddLit, value);
|
|
}
|
|
public float multiplyWithBaseColor {
|
|
get => m_multiply;
|
|
set => setValAndNeedSetMat (ref m_multiply, Mathf.Clamp (value, 0f, 1f));
|
|
}
|
|
public float normalAttenRate {
|
|
get => m_normalAttenRate;
|
|
set => setValAndNeedSetMat (ref m_normalAttenRate, Mathf.Clamp (value, 1f, 8f));
|
|
}
|
|
public float normalAtten {
|
|
get => m_normalAtten;
|
|
set => setValAndNeedSetMat (ref m_normalAtten, Mathf.Clamp (value, 0f, 1f));
|
|
}
|
|
public float TransparentBack {
|
|
get => m_transparentBackside;
|
|
set => setValAndNeedSetMat (ref m_transparentBackside, Mathf.Clamp (value, 0f, 1f));
|
|
}
|
|
public float backsideShadow {
|
|
get => m_backsideShadow;
|
|
set => setValAndNeedSetMat (ref m_backsideShadow, Mathf.Clamp (value, 0f, 1f));
|
|
}
|
|
public int stencilRef {
|
|
get => m_stencilRef;
|
|
set => setValAndNeedSetMat (ref m_stencilRef, Mathf.Clamp (value, 0, 255));
|
|
}
|
|
public int stencilReadMask {
|
|
get => m_stencilReadMask;
|
|
set => setValAndNeedSetMat (ref m_stencilReadMask, Mathf.Clamp (value, 0, 255));
|
|
}
|
|
public int stencilWriteMask {
|
|
get => m_stencilWriteMask;
|
|
set => setValAndNeedSetMat (ref m_stencilWriteMask, Mathf.Clamp (value, 0, 255));
|
|
}
|
|
public CompareFunction stencilComp {
|
|
get => m_stencilComp;
|
|
set => setValAndNeedSetMat (ref m_stencilComp, value);
|
|
}
|
|
|
|
public StencilOp stencilPass {
|
|
get => m_stencilPass;
|
|
set => setValAndNeedSetMat (ref m_stencilPass, value);
|
|
}
|
|
public StencilOp stencilFail {
|
|
get => m_stencilFail;
|
|
set => setValAndNeedSetMat (ref m_stencilFail, value);
|
|
}
|
|
public StencilOp stencilZFail {
|
|
get => m_stencilZFail;
|
|
set => setValAndNeedSetMat (ref m_stencilZFail, value);
|
|
}
|
|
public CullMode cullMode {
|
|
get => m_cullMode;
|
|
set => setValAndNeedSetMat (ref m_cullMode, value);
|
|
}
|
|
public bool zWriteMode {
|
|
get => m_zWriteMode;
|
|
set => setValAndNeedSetMat (ref m_zWriteMode, value);
|
|
}
|
|
public CompareFunction zTestMode {
|
|
get => m_zTestMode;
|
|
set => setValAndNeedSetMat (ref m_zTestMode, value);
|
|
}
|
|
public float depthOffsetFactor {
|
|
get => m_depthOffsetFactor;
|
|
set => setValAndNeedSetMat (ref m_depthOffsetFactor, value);
|
|
}
|
|
public float depthOffsetUnits {
|
|
get => m_depthOffsetUnits;
|
|
set => setValAndNeedSetMat (ref m_depthOffsetUnits, value);
|
|
}
|
|
public bool useImageMask {
|
|
get => m_useImageMask;
|
|
set => setValAndNeedSetMat (ref m_useImageMask, value);
|
|
}
|
|
public Texture imageMaskTexture {
|
|
get => m_imageMaskTexture;
|
|
set => setValAndNeedSetMat (ref m_imageMaskTexture, value);
|
|
}
|
|
public bool supportCustomFunction {
|
|
get => m_useCustomFunc;
|
|
set => m_useCustomFunc = value;
|
|
}
|
|
public RenderPassEvent renderEvent {
|
|
get => m_renderEvent;
|
|
set => setValAndNeedSetMat (ref m_renderEvent, value);
|
|
}
|
|
public int renderEventAdjust {
|
|
get => m_renderEventAdjust;
|
|
set => setValAndNeedSetMat (ref m_renderEventAdjust, value);
|
|
}
|
|
|
|
public void ForceApplyChanges () {
|
|
#if UNITY_EDITOR
|
|
if (!isActiveAndEnabled) return;
|
|
#endif
|
|
_needUpdateMat = false;
|
|
updateMaterialValues ();
|
|
}
|
|
|
|
// ----------------------------------------------------------- Tools
|
|
static private float round2Dec (float val) => (float) (System.Math.Round (val * 100f) * 0.01); // 小数点2位で丸め
|
|
static private float round2Dec5 (float val) => (float) (System.Math.Round (val * 20f) * 0.05); // 小数点2位を0か5で丸め
|
|
static private float wrapAngle180 (float angle) => Mathf.Repeat (angle + 180f, 360f) - 180f;
|
|
static private Vector2 dirToVec (float dir) => new Vector2 (Mathf.Sin (dir * Mathf.Deg2Rad), Mathf.Cos (-dir * Mathf.Deg2Rad));
|
|
static private float vecToDir (Vector2 v) => round2Dec5 (wrapAngle180 (Mathf.Atan2 (v.x, v.y) * Mathf.Rad2Deg));
|
|
|
|
// ----------------------------------------------------------- Editor
|
|
#if UNITY_EDITOR
|
|
internal void OnInspectorChanged () {
|
|
if (isActiveAndEnabled)
|
|
updateMaterialValues ();
|
|
}
|
|
|
|
private void onUndoCallback () {
|
|
if (isActiveAndEnabled)
|
|
updateMaterialValues ();
|
|
}
|
|
|
|
[ContextMenu ("Open Asset Manual")]
|
|
private void OpenManualURL () {
|
|
Application.OpenURL (Constant.URL_MANUAL);
|
|
}
|
|
#endif
|
|
|
|
// ----------------------------------------------------------- Init
|
|
private void Reset () {
|
|
// ※ Awakeの後に呼ばれる (Editorのみ Undo登録/SetDirty不要)
|
|
#if UNITY_EDITOR
|
|
addFeatureIfNeedManage ();
|
|
#endif
|
|
m_scale = Mathf.Clamp (Mathf.Max (transform.lossyScale.x, transform.lossyScale.z), 0.3f, 3f);
|
|
m_useImageMask = (m_imageMaskTexture != null);
|
|
}
|
|
|
|
internal void VersionCheck () {
|
|
#if UNITY_EDITOR
|
|
if (m_version < Constant.WCE_VERSION_INT) EditorUtility.SetDirty (this);
|
|
#endif
|
|
const int VER_20000 = 20000;
|
|
if (m_version < VER_20000) {
|
|
// -- Ver1.2.2以前に作成されている場合、データをv2用にアップデート
|
|
m_useMainLit = (m_version > 0); // m_version は元 m_useMainLight
|
|
m_method = Method.EachMesh;
|
|
if (m_useMultiply == true && m_multiply > 0f && m_multiply < 1f) {
|
|
m_renderEvent = RenderPassEvent.BeforeRenderingTransparents;
|
|
m_renderEventAdjust = 0;
|
|
}
|
|
if (m_useMultiply == false)
|
|
m_multiply = 0f;
|
|
textureRotation = 0f;
|
|
var v = new Vector2 (m_colorShiftU, m_colorShiftV);
|
|
m_colorShift = round2Dec5 (v.magnitude);
|
|
m_colorShiftDir = vecToDir (v);
|
|
if (m_surfFadeStart != 0f) {
|
|
m_surfFadeEnd = m_surfFadeEnd + m_surfFadeStart;
|
|
m_surfFadeStart = Mathf.Abs (m_surfFadeStart);
|
|
m_surfFadeEnd = Mathf.Max (m_surfFadeEnd, m_surfFadeStart);
|
|
}
|
|
m_version = VER_20000; // ※最後に設定
|
|
}
|
|
if (m_version < Constant.WCE_VERSION_INT)
|
|
m_version = Constant.WCE_VERSION_INT;
|
|
}
|
|
|
|
private void Awake () {
|
|
VersionCheck ();
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
private void OnEnable () {
|
|
#if UNITY_EDITOR
|
|
Undo.undoRedoPerformed += onUndoCallback;
|
|
#endif
|
|
onEnableForPass ();
|
|
_needUpdateMat = true;
|
|
}
|
|
|
|
private void OnDisable () {
|
|
#if UNITY_EDITOR
|
|
Undo.undoRedoPerformed -= onUndoCallback;
|
|
#endif
|
|
onDisableForPass ();
|
|
onDisableForCF ();
|
|
}
|
|
|
|
private void OnDestroy () {
|
|
onDestroyForAtOnce ();
|
|
destroy (ref __mat);
|
|
}
|
|
|
|
private void destroy<T> (ref T o) where T : Object {
|
|
if (o == null) return;
|
|
destroy (o);
|
|
o = null;
|
|
}
|
|
|
|
private void destroy (Object o) {
|
|
if (o == null) return;
|
|
if (Application.isPlaying)
|
|
Destroy (o);
|
|
else
|
|
DestroyImmediate (o);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------- Update
|
|
private bool _needUpdateMat;
|
|
|
|
private void Update () {
|
|
updateForCF ();
|
|
}
|
|
|
|
private void LateUpdate () {
|
|
// --- 設定変更時のみの設定
|
|
if (_needUpdateMat || !Application.isPlaying) {
|
|
_needUpdateMat = false;
|
|
updateMaterialValues ();
|
|
}
|
|
|
|
// --- 毎フレームの設定
|
|
if (m_method == Method.EachMesh) {
|
|
// Each Mesh 方式
|
|
if ((m_clipOutside || (m_useImageMask && m_imageMaskTexture)))
|
|
getMat ().SetMatrix (pID._WCE_WorldToObjMatrix, transform.worldToLocalMatrix);
|
|
}
|
|
|
|
// --- Sync with Custom Function
|
|
lateUpdateForCF ();
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------- Property ID
|
|
private class pID {
|
|
readonly internal static int _WCE_CausticsTex = Shader.PropertyToID ("_WCE_CausticsTex");
|
|
readonly internal static int _WCE_TexChannels = Shader.PropertyToID ("_WCE_TexChannels");
|
|
readonly internal static int _WCE_TexRotateSinCos = Shader.PropertyToID ("_WCE_TexRotateSinCos");
|
|
readonly internal static int _WCE_TilingSeed = Shader.PropertyToID ("_WCE_TilingSeed");
|
|
readonly internal static int _WCE_TilingRot = Shader.PropertyToID ("_WCE_TilingRot");
|
|
readonly internal static int _WCE_TilingHard = Shader.PropertyToID ("_WCE_TilingHard");
|
|
readonly internal static int _WCE_IntensityMainLit = Shader.PropertyToID ("_WCE_IntensityMainLit");
|
|
readonly internal static int _WCE_IntensityAddLit = Shader.PropertyToID ("_WCE_IntensityAddLit");
|
|
readonly internal static int _WCE_Density = Shader.PropertyToID ("_WCE_Density");
|
|
readonly internal static int _WCE_ColorShift = Shader.PropertyToID ("_WCE_ColorShift");
|
|
readonly internal static int _WCE_SurfaceY = Shader.PropertyToID ("_WCE_SurfaceY");
|
|
readonly internal static int _WCE_SurfFadeStart = Shader.PropertyToID ("_WCE_SurfFadeStart");
|
|
readonly internal static int _WCE_SurfFadeCoef = Shader.PropertyToID ("_WCE_SurfFadeCoef");
|
|
readonly internal static int _WCE_DepthFadeStart = Shader.PropertyToID ("_WCE_DepthFadeStart");
|
|
readonly internal static int _WCE_DepthFadeCoef = Shader.PropertyToID ("_WCE_DepthFadeCoef");
|
|
readonly internal static int _WCE_DistanceFadeStart = Shader.PropertyToID ("_WCE_DistanceFadeStart");
|
|
readonly internal static int _WCE_DistanceFadeCoef = Shader.PropertyToID ("_WCE_DistanceFadeCoef");
|
|
readonly internal static int _WCE_LitSaturation = Shader.PropertyToID ("_WCE_LitSaturation");
|
|
readonly internal static int _WCE_MultiplyByTex = Shader.PropertyToID ("_WCE_MultiplyByTex");
|
|
readonly internal static int _WCE_NormalAtten = Shader.PropertyToID ("_WCE_NormalAtten");
|
|
readonly internal static int _WCE_NormalAttenRate = Shader.PropertyToID ("_WCE_NormalAttenRate");
|
|
readonly internal static int _WCE_TransparentBack = Shader.PropertyToID ("_WCE_TransparentBack");
|
|
readonly internal static int _WCE_BacksideShadow = Shader.PropertyToID ("_WCE_BacksideShadow");
|
|
readonly internal static int _WCE_ShadowIntensity = Shader.PropertyToID ("_WCE_ShadowIntensity");
|
|
readonly internal static int _WCE_ImageMaskTex = Shader.PropertyToID ("_WCE_ImageMaskTex");
|
|
readonly internal static int _WCE_WorldToObjMatrix = Shader.PropertyToID ("_WCE_WorldToObjMatrix");
|
|
readonly internal static int _WCE_ClipOutside = Shader.PropertyToID ("_WCE_ClipOutside");
|
|
readonly internal static int _WCE_UseImageMask = Shader.PropertyToID ("_WCE_UseImageMask");
|
|
|
|
readonly internal static int _StencilRef = Shader.PropertyToID ("_StencilRef");
|
|
readonly internal static int _StencilReadMask = Shader.PropertyToID ("_StencilReadMask");
|
|
readonly internal static int _StencilWriteMask = Shader.PropertyToID ("_StencilWriteMask");
|
|
readonly internal static int _StencilComp = Shader.PropertyToID ("_StencilComp");
|
|
readonly internal static int _StencilPass = Shader.PropertyToID ("_StencilPass");
|
|
readonly internal static int _StencilFail = Shader.PropertyToID ("_StencilFail");
|
|
readonly internal static int _StencilZFail = Shader.PropertyToID ("_StencilZFail");
|
|
readonly internal static int _CullMode = Shader.PropertyToID ("_CullMode");
|
|
readonly internal static int _ZWrite = Shader.PropertyToID ("_ZWrite");
|
|
readonly internal static int _ZTest = Shader.PropertyToID ("_ZTest");
|
|
readonly internal static int _OffsetFactor = Shader.PropertyToID ("_OffsetFactor");
|
|
readonly internal static int _OffsetUnits = Shader.PropertyToID ("_OffsetUnits");
|
|
readonly internal static int _BlendSrcFactor = Shader.PropertyToID ("_BlendSrcFactor");
|
|
readonly internal static int _BlendDstFactor = Shader.PropertyToID ("_BlendDstFactor");
|
|
|
|
readonly internal static int _WCECF_TexChannels = Shader.PropertyToID ("_WCECF_TexChannels");
|
|
readonly internal static int _WCECF_TexRotateSinCos = Shader.PropertyToID ("_WCECF_TexRotateSinCos");
|
|
readonly internal static int _WCECF_TilingSeed = Shader.PropertyToID ("_WCECF_TilingSeed");
|
|
readonly internal static int _WCECF_TilingRot = Shader.PropertyToID ("_WCECF_TilingRot");
|
|
readonly internal static int _WCECF_TilingHard = Shader.PropertyToID ("_WCECF_TilingHard");
|
|
readonly internal static int _WCECF_IntensityMainLit = Shader.PropertyToID ("_WCECF_IntensityMainLit");
|
|
readonly internal static int _WCECF_Density = Shader.PropertyToID ("_WCECF_Density");
|
|
readonly internal static int _WCECF_ColorShift = Shader.PropertyToID ("_WCECF_ColorShift");
|
|
readonly internal static int _WCECF_SurfaceY = Shader.PropertyToID ("_WCECF_SurfaceY");
|
|
readonly internal static int _WCECF_SurfFadeStart = Shader.PropertyToID ("_WCECF_SurfFadeStart");
|
|
readonly internal static int _WCECF_SurfFadeCoef = Shader.PropertyToID ("_WCECF_SurfFadeCoef");
|
|
readonly internal static int _WCECF_DepthFadeStart = Shader.PropertyToID ("_WCECF_DepthFadeStart");
|
|
readonly internal static int _WCECF_DepthFadeCoef = Shader.PropertyToID ("_WCECF_DepthFadeCoef");
|
|
readonly internal static int _WCECF_DistanceFadeStart = Shader.PropertyToID ("_WCECF_DistanceFadeStart");
|
|
readonly internal static int _WCECF_DistanceFadeCoef = Shader.PropertyToID ("_WCECF_DistanceFadeCoef");
|
|
readonly internal static int _WCECF_LitSaturation = Shader.PropertyToID ("_WCECF_LitSaturation");
|
|
readonly internal static int _WCECF_IntensityAddLit = Shader.PropertyToID ("_WCECF_IntensityAddLit");
|
|
readonly internal static int _WCECF_MultiplyIntensity = Shader.PropertyToID ("_WCECF_MultiplyIntensity");
|
|
readonly internal static int _WCECF_NormalAttenRate = Shader.PropertyToID ("_WCECF_NormalAttenRate");
|
|
readonly internal static int _WCECF_NormalAtten = Shader.PropertyToID ("_WCECF_NormalAtten");
|
|
readonly internal static int _WCECF_TransparentBack = Shader.PropertyToID ("_WCECF_TransparentBack");
|
|
readonly internal static int _WCECF_BacksideShadow = Shader.PropertyToID ("_WCECF_BacksideShadow");
|
|
readonly internal static int _WCECF_ShadowIntensity = Shader.PropertyToID ("_WCECF_ShadowIntensity");
|
|
readonly internal static int _WCECF_WorldToObjMatrix = Shader.PropertyToID ("_WCECF_WorldToObjMatrix");
|
|
readonly internal static int _WCECF_ClipOutside = Shader.PropertyToID ("_WCECF_ClipOutside");
|
|
readonly internal static int _WCECF_UseImageMask = Shader.PropertyToID ("_WCECF_UseImageMask");
|
|
readonly internal static int _WCECF_CausticsTex = Shader.PropertyToID ("_WCECF_CausticsTex");
|
|
readonly internal static int _WCECF_ImageMaskTex = Shader.PropertyToID ("_WCECF_ImageMaskTex");
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------- Material
|
|
private Material __mat;
|
|
private Material getMat () {
|
|
return __mat ? __mat : __mat = createMat (m_shader, "WCausticsEffect");
|
|
}
|
|
|
|
private Material createMat (Shader shader, string name) {
|
|
_needUpdateMat = true;
|
|
if (shader == null) {
|
|
Debug.LogError ("Shader is null. " + this);
|
|
return null;
|
|
} else {
|
|
Material mat = new Material (shader);
|
|
mat.name = name;
|
|
mat.hideFlags = HideFlags.HideAndDontSave | HideFlags.HideInInspector;
|
|
return mat;
|
|
}
|
|
}
|
|
|
|
private float calcFadeCoef (float depth) => 1f / Mathf.Max (depth, 0.0000001f);
|
|
|
|
private void updateMaterialValues () {
|
|
Material mat = getMat ();
|
|
if (mat == null) return;
|
|
mat.SetVector (pID._WCE_TexChannels, _texChannelVec [(int) m_textureChannel]);
|
|
mat.SetVector (pID._WCE_TexRotateSinCos, m_texRotSinCos);
|
|
mat.SetInt (pID._WCE_TilingSeed, m_useRandomTiling ? m_tilingSeed : -1);
|
|
mat.SetFloat (pID._WCE_TilingRot, m_tilingRotation);
|
|
mat.SetFloat (pID._WCE_TilingHard, m_tilingHardness);
|
|
mat.SetFloat (pID._WCE_IntensityMainLit, finalMainLit);
|
|
mat.SetFloat (pID._WCE_IntensityAddLit, finalAddLit);
|
|
mat.SetVector (pID._WCE_ColorShift, calcColorShiftVec ());
|
|
mat.SetFloat (pID._WCE_SurfaceY, m_surfaceY);
|
|
mat.SetFloat (pID._WCE_SurfFadeStart, m_surfFadeStart);
|
|
mat.SetFloat (pID._WCE_SurfFadeCoef, calcFadeCoef (m_surfFadeEnd - m_surfFadeStart));
|
|
mat.SetFloat (pID._WCE_DepthFadeStart, m_depthFadeStart);
|
|
mat.SetFloat (pID._WCE_DepthFadeCoef, m_useDepthFade ? calcFadeCoef (m_depthFadeEnd - m_depthFadeStart) : 0f);
|
|
mat.SetFloat (pID._WCE_DistanceFadeStart, m_distanceFadeStart);
|
|
mat.SetFloat (pID._WCE_DistanceFadeCoef, m_useDistanceFade ? calcFadeCoef (m_distanceFadeEnd - m_distanceFadeStart) : 0f);
|
|
mat.SetFloat (pID._WCE_LitSaturation, m_litSaturation);
|
|
mat.SetFloat (pID._WCE_NormalAttenRate, m_normalAttenRate);
|
|
mat.SetFloat (pID._WCE_NormalAtten, m_normalAtten);
|
|
mat.SetFloat (pID._WCE_TransparentBack, m_transparentBackside);
|
|
mat.SetFloat (pID._WCE_BacksideShadow, m_backsideShadow);
|
|
mat.SetInt (pID._WCE_ClipOutside, System.Convert.ToInt32 (useClipOutside));
|
|
|
|
bool isNoTex = (m_texture == null);
|
|
mat.SetFloat (pID._WCE_Density, 1f / Mathf.Max (isNoTex ? m_scale * 0.333f : m_scale, 0.0001f));
|
|
mat.SetTexture (pID._WCE_CausticsTex, isNoTex ? m_noTexture : m_texture);
|
|
bool useImgMask = (m_useImageMask && m_imageMaskTexture);
|
|
mat.SetInt (pID._WCE_UseImageMask, System.Convert.ToInt32 (useImgMask));
|
|
mat.SetTexture (pID._WCE_ImageMaskTex, useImgMask ? m_imageMaskTexture : null);
|
|
bool useShadow = m_receiveShadows && (m_shadowIntensity > 0f || (m_backsideShadow > 0f && (m_normalAtten < 1f || m_transparentBackside > 0f)));
|
|
setMatKeyword (mat, !useShadow, "_RECEIVE_SHADOWS_OFF");
|
|
mat.SetFloat (pID._WCE_ShadowIntensity, m_shadowIntensity);
|
|
mat.SetFloat (pID._WCE_MultiplyByTex, multiplyByTex);
|
|
|
|
mat.SetInt (pID._BlendSrcFactor, (int) (useBlendMultiply ? BlendMode.DstColor : BlendMode.One));
|
|
mat.SetInt (pID._BlendDstFactor, (int) BlendMode.One);
|
|
mat.SetInt (pID._StencilRef, m_stencilRef);
|
|
mat.SetInt (pID._StencilReadMask, m_stencilReadMask);
|
|
mat.SetInt (pID._StencilWriteMask, m_stencilWriteMask);
|
|
mat.SetInt (pID._StencilComp, (int) m_stencilComp);
|
|
mat.SetInt (pID._StencilPass, (int) m_stencilPass);
|
|
mat.SetInt (pID._StencilFail, (int) m_stencilFail);
|
|
mat.SetInt (pID._StencilZFail, (int) m_stencilZFail);
|
|
|
|
if (m_method == Method.EachMesh) {
|
|
// [EachMesh]
|
|
mat.SetInt (pID._CullMode, (int) m_cullMode);
|
|
mat.SetInt (pID._ZWrite, System.Convert.ToInt32 (m_zWriteMode));
|
|
mat.SetInt (pID._ZTest, (int) m_zTestMode);
|
|
mat.SetFloat (pID._OffsetFactor, m_depthOffsetFactor);
|
|
mat.SetFloat (pID._OffsetUnits, m_depthOffsetUnits);
|
|
mat.DisableKeyword ("_WCE_ONE_PASS_NORMAL");
|
|
mat.DisableKeyword ("_WCE_ONE_PASS_DEPTH");
|
|
mat.renderQueue = -1;
|
|
} else {
|
|
// [AtOnce]
|
|
mat.SetInt (pID._CullMode, (int) CullMode.Back);
|
|
mat.SetInt (pID._ZWrite, 0);
|
|
mat.SetInt (pID._ZTest, (int) CompareFunction.LessEqual);
|
|
mat.SetFloat (pID._OffsetFactor, 0f);
|
|
mat.SetFloat (pID._OffsetUnits, 0f);
|
|
mat.renderQueue = (int) eventAdjusted;
|
|
setMatKeyword (mat, m_normalSrc == NormalSrc.DepthTex, "_WCE_ONE_PASS_DEPTH");
|
|
setMatKeyword (mat, m_normalSrc != NormalSrc.DepthTex, "_WCE_ONE_PASS_NORMAL");
|
|
prepAtOnce ();
|
|
_atOnce.render.renderingLayerMask = m_renderLayerMask;
|
|
_atOnce.render.forceRenderingOff = isIntensityZero;
|
|
}
|
|
#if UNITY_EDITOR
|
|
// ----- for Debug Info Rendering
|
|
bool isDebugNormal = (m_debugInfo && m_debugMode == DebugMode.Normal);
|
|
bool isDebugDepth = (m_debugInfo && m_debugMode == DebugMode.Depth);
|
|
bool isDebugNormalErr = (m_debugInfo && m_debugMode == DebugMode.Facing);
|
|
bool isDebugCaustics = (m_debugInfo && m_debugMode == DebugMode.Caustics);
|
|
bool isDebugLitArea = (m_debugInfo && m_debugMode == DebugMode.LightArea);
|
|
setMatKeyword (mat, isDebugNormal, "WCE_DEBUG_NORMAL");
|
|
setMatKeyword (mat, isDebugDepth, "WCE_DEBUG_DEPTH");
|
|
setMatKeyword (mat, isDebugNormalErr, "WCE_DEBUG_FACING");
|
|
setMatKeyword (mat, isDebugCaustics, "WCE_DEBUG_CAUSTICS");
|
|
setMatKeyword (mat, isDebugLitArea, "WCE_DEBUG_AREA");
|
|
if (isDebugNormal || isDebugDepth || isDebugNormalErr || isDebugCaustics || isDebugLitArea) {
|
|
mat.SetInt (pID._BlendSrcFactor, (int) BlendMode.One);
|
|
mat.SetInt (pID._BlendDstFactor, (int) BlendMode.Zero);
|
|
}
|
|
if (isDebugCaustics) {
|
|
float m = Mathf.Lerp (1f, 0.5f, multiplyRaw);
|
|
mat.SetFloat (pID._WCE_IntensityMainLit, finalMainLit * m);
|
|
mat.SetFloat (pID._WCE_IntensityAddLit, finalAddLit * m);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
private void setMatKeyword (Material mat, bool isEnable, string keyword) {
|
|
if (isEnable)
|
|
mat.EnableKeyword (keyword);
|
|
else
|
|
mat.DisableKeyword (keyword);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------- Sync with Custom Functions
|
|
static private WaterCausticsEffect s_nextSync, s_lastSync;
|
|
private void onDisableForCF () {
|
|
if (s_lastSync == this) {
|
|
s_lastSync = null;
|
|
setCFIntensityZero ();
|
|
}
|
|
}
|
|
private void updateForCF () {
|
|
if (m_useCustomFunc) {
|
|
s_nextSync = this; // 最後にupdateが呼ばれたエフェクトが担当となる
|
|
} else if (s_lastSync == this) {
|
|
s_lastSync = null;
|
|
setCFIntensityZero ();
|
|
}
|
|
}
|
|
|
|
private void lateUpdateForCF () {
|
|
if (m_useCustomFunc && s_nextSync == this) {
|
|
s_nextSync = null;
|
|
s_lastSync = this;
|
|
setCustomFunc ();
|
|
}
|
|
}
|
|
|
|
private void setCustomFunc () {
|
|
setCFIntensity ();
|
|
bool isNoTex = (m_texture == null);
|
|
Shader.SetGlobalFloat (pID._WCECF_Density, 1f / Mathf.Max (isNoTex ? m_scale * 0.333f : m_scale, 0.0001f));
|
|
Shader.SetGlobalFloat (pID._WCECF_SurfaceY, m_surfaceY);
|
|
Shader.SetGlobalFloat (pID._WCECF_SurfFadeStart, m_surfFadeStart);
|
|
Shader.SetGlobalFloat (pID._WCECF_SurfFadeCoef, calcFadeCoef (m_surfFadeEnd - m_surfFadeStart));
|
|
Shader.SetGlobalFloat (pID._WCECF_DepthFadeStart, m_depthFadeStart);
|
|
Shader.SetGlobalFloat (pID._WCECF_DepthFadeCoef, m_useDepthFade ? calcFadeCoef (m_depthFadeEnd - m_depthFadeStart) : 0f);
|
|
Shader.SetGlobalFloat (pID._WCECF_DistanceFadeStart, m_distanceFadeStart);
|
|
Shader.SetGlobalFloat (pID._WCECF_DistanceFadeCoef, m_useDistanceFade ? calcFadeCoef (m_distanceFadeEnd - m_distanceFadeStart) : 0f);
|
|
Shader.SetGlobalVector (pID._WCECF_ColorShift, calcColorShiftVec ());
|
|
Shader.SetGlobalFloat (pID._WCECF_LitSaturation, m_litSaturation);
|
|
Shader.SetGlobalFloat (pID._WCECF_ShadowIntensity, m_shadowIntensity);
|
|
Shader.SetGlobalFloat (pID._WCECF_MultiplyIntensity, multiplyRaw);
|
|
Shader.SetGlobalFloat (pID._WCECF_NormalAttenRate, m_normalAttenRate);
|
|
Shader.SetGlobalFloat (pID._WCECF_NormalAtten, m_normalAtten);
|
|
Shader.SetGlobalFloat (pID._WCECF_TransparentBack, m_transparentBackside);
|
|
Shader.SetGlobalFloat (pID._WCECF_BacksideShadow, m_backsideShadow);
|
|
Shader.SetGlobalMatrix (pID._WCECF_WorldToObjMatrix, transform.worldToLocalMatrix);
|
|
Shader.SetGlobalInt (pID._WCECF_ClipOutside, System.Convert.ToInt32 (useClipOutside));
|
|
Shader.SetGlobalTexture (pID._WCECF_CausticsTex, isNoTex ? m_noTexture : m_texture);
|
|
Shader.SetGlobalVector (pID._WCECF_TexChannels, _texChannelVec [(int) m_textureChannel]);
|
|
Shader.SetGlobalVector (pID._WCECF_TexRotateSinCos, m_texRotSinCos);
|
|
Shader.SetGlobalInt (pID._WCECF_TilingSeed, m_useRandomTiling ? m_tilingSeed : -1);
|
|
Shader.SetGlobalFloat (pID._WCECF_TilingRot, m_tilingRotation);
|
|
Shader.SetGlobalFloat (pID._WCECF_TilingHard, m_tilingHardness);
|
|
bool useImgMask = (m_useImageMask && m_imageMaskTexture);
|
|
Shader.SetGlobalInt (pID._WCECF_UseImageMask, System.Convert.ToInt32 (useImgMask));
|
|
Shader.SetGlobalTexture (pID._WCECF_ImageMaskTex, useImgMask ? m_imageMaskTexture : null);
|
|
}
|
|
|
|
private void setCFIntensityZero () {
|
|
Shader.SetGlobalFloat (pID._WCECF_IntensityMainLit, 0f);
|
|
Shader.SetGlobalFloat (pID._WCECF_IntensityAddLit, 0f);
|
|
}
|
|
|
|
private void setCFIntensity () {
|
|
Shader.SetGlobalFloat (pID._WCECF_IntensityMainLit, finalMainLit);
|
|
Shader.SetGlobalFloat (pID._WCECF_IntensityAddLit, finalAddLit);
|
|
}
|
|
|
|
private void tellCustomFuncNeedDraw (bool needDraw) {
|
|
if (!m_useCustomFunc || s_lastSync != this) return;
|
|
if (needDraw)
|
|
setCFIntensity ();
|
|
else
|
|
setCFIntensityZero ();
|
|
}
|
|
|
|
// ----------------------------------------------------------- Enqueue RenderPass
|
|
#if UNITY_EDITOR
|
|
static private readonly string tempFilePath = "Temp/WCEInitialized";
|
|
[InitializeOnLoadMethod]
|
|
static private void registerFeature () {
|
|
// エディタ起動時、アセットインポート時
|
|
EditorApplication.delayCall += () => {
|
|
if (!File.Exists (tempFilePath)) {
|
|
File.Create (tempFilePath);
|
|
addFeatureIfNeedManage ();
|
|
}
|
|
};
|
|
// シーンを開いた時
|
|
EditorSceneManager.sceneOpened += (Scene scene, OpenSceneMode mode) => {
|
|
if (mode == OpenSceneMode.Single) addFeatureIfNeedManage ();
|
|
};
|
|
// プレイ開始時
|
|
EditorApplication.playModeStateChanged += (PlayModeStateChange state) => {
|
|
if (state == PlayModeStateChange.EnteredPlayMode) addFeatureIfNeedManage ();
|
|
};
|
|
}
|
|
|
|
static private void addFeatureIfNeedManage () {
|
|
// -- 自動管理がOnの場合にRendererFeatureを追加
|
|
if (WaterCausticsEffectData.GetAsset ().AutoManageFeature)
|
|
WaterCausticsEffectFeatureEditor.AddFeatureToAllRenderers (useUndo: false);
|
|
}
|
|
#endif
|
|
|
|
private void onEnableForPass () {
|
|
WaterCausticsEffectFeature.onEnqueue -= enqueuePass;
|
|
WaterCausticsEffectFeature.onEnqueue += enqueuePass;
|
|
}
|
|
|
|
private void onDisableForPass () {
|
|
WaterCausticsEffectFeature.onEnqueue -= enqueuePass;
|
|
}
|
|
|
|
private WCEEachMeshPass _eachMeshPass;
|
|
private WCEAtOncePass _atOncePass;
|
|
private void enqueuePass (ScriptableRenderer renderer, Camera cam) {
|
|
if (isIntensityZero) return;
|
|
|
|
bool needDraw = checkNeedDraw (cam);
|
|
tellCustomFuncNeedDraw (needDraw);
|
|
if (!needDraw) return;
|
|
|
|
if (m_method == Method.EachMesh) {
|
|
// [EachMesh]
|
|
if (m_layerMask == 0) return;
|
|
if (_eachMeshPass == null) _eachMeshPass = new WCEEachMeshPass ();
|
|
bool useOpaqueTex = multiplyByTex > 0f;
|
|
_eachMeshPass.Setup (eventAdjusted, getMat (), m_layerMask, useOpaqueTex);
|
|
renderer.EnqueuePass (_eachMeshPass);
|
|
} else {
|
|
// [AtOnce]
|
|
prepAtOnce ();
|
|
if (_atOncePass == null) _atOncePass = new WCEAtOncePass ();
|
|
bool useNormalTex = (m_normalSrc == NormalSrc.NormalTex);
|
|
bool useOpaqueTex = multiplyByTex > 0f;
|
|
_atOncePass.Setup (eventAdjusted, useNormalTex, useOpaqueTex);
|
|
renderer.EnqueuePass (_atOncePass);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------- カメラ毎に描画するかどうか判別
|
|
readonly Vector3 [] _points = { new Vector3 (-.5f, -.5f, -.5f), new Vector3 (.5f, -.5f, -.5f), new Vector3 (-.5f, .5f, -.5f), new Vector3 (.5f, .5f, -.5f), new Vector3 (-.5f, -.5f, .5f), new Vector3 (.5f, -.5f, .5f), new Vector3 (-.5f, .5f, .5f), new Vector3 (.5f, .5f, .5f), };
|
|
private Plane [] _planes = new Plane [6];
|
|
private bool insightCheck (Camera cam) {
|
|
Bounds bounds = GeometryUtility.CalculateBounds (_points, transform.localToWorldMatrix);
|
|
GeometryUtility.CalculateFrustumPlanes (cam, _planes);
|
|
return GeometryUtility.TestPlanesAABB (_planes, bounds);
|
|
}
|
|
|
|
private bool checkNeedDraw (Camera cam) {
|
|
#if UNITY_EDITOR
|
|
if (cam.cameraType == CameraType.Preview) return false;
|
|
if (cam.cameraType == CameraType.SceneView && !UnityEditor.SceneView.currentDrawingSceneView.sceneLighting) return false;
|
|
#endif
|
|
// レイヤーマスクチェック
|
|
if (((1 << gameObject.layer) & cam.cullingMask) == 0) return false;
|
|
// 視界内チェック
|
|
if (useClipOutside && !insightCheck (cam)) return false;
|
|
return true;
|
|
}
|
|
|
|
// ----------------------------------------------------------- AtOnce Method
|
|
private AtOnce _atOnce;
|
|
internal AtOnce atOnce => _atOnce;
|
|
|
|
private void onDestroyForAtOnce () {
|
|
AtOnce.OnSummonerDestroyed (ref _atOnce);
|
|
}
|
|
|
|
private void prepAtOnce () {
|
|
if (!_atOnce) _atOnce = AtOnce.Create (this, getMat ());
|
|
}
|
|
|
|
// ----------------------------------------------------------- ScriptableRenderPass AtOnce
|
|
internal class WCEAtOncePass : ScriptableRenderPass {
|
|
private ShaderTagId _shaderTagId;
|
|
private FilteringSettings _filteringSettings;
|
|
private bool _useNormalTex, _useOpaqueTex;
|
|
static private HashSet<RenderPassEvent> s_hashSet = new HashSet<RenderPassEvent> ();
|
|
|
|
private RenderPassEvent __evt = (RenderPassEvent) 9999;
|
|
private void setRenderEvt (RenderPassEvent v) {
|
|
if (__evt != v) {
|
|
_filteringSettings = new FilteringSettings (new RenderQueueRange ((int) v, (int) v), layerMask: ~0);
|
|
this.renderPassEvent = __evt = v;
|
|
}
|
|
}
|
|
|
|
internal WCEAtOncePass () {
|
|
base.profilingSampler = new ProfilingSampler (nameof (WCEAtOncePass));
|
|
_shaderTagId = new ShaderTagId ("WCE_EffectPass");
|
|
}
|
|
|
|
internal void Setup (RenderPassEvent evt, bool useNormalTex, bool useOpaqueTex) {
|
|
setRenderEvt (evt);
|
|
_useNormalTex = useNormalTex;
|
|
_useOpaqueTex = useOpaqueTex;
|
|
}
|
|
|
|
public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData rendData) {
|
|
s_hashSet.Add (this.renderPassEvent);
|
|
ScriptableRenderPassInput request = ScriptableRenderPassInput.Depth;
|
|
if (_useNormalTex) request |= ScriptableRenderPassInput.Normal;
|
|
if (_useOpaqueTex) request |= ScriptableRenderPassInput.Color;
|
|
ConfigureInput (request);
|
|
}
|
|
|
|
public override void Execute (ScriptableRenderContext context, ref RenderingData rendData) {
|
|
// ※ renderPassEvent値でまとめて描画
|
|
if (!s_hashSet.Contains (this.renderPassEvent)) return;
|
|
s_hashSet.Remove (this.renderPassEvent);
|
|
|
|
DrawingSettings drawingSettings = CreateDrawingSettings (_shaderTagId, ref rendData, SortingCriteria.None);
|
|
CommandBuffer cmd = CommandBufferPool.Get ();
|
|
using (new ProfilingScope (cmd, base.profilingSampler)) {
|
|
context.ExecuteCommandBuffer (cmd);
|
|
cmd.Clear ();
|
|
context.DrawRenderers (rendData.cullResults, ref drawingSettings, ref _filteringSettings);
|
|
}
|
|
context.ExecuteCommandBuffer (cmd);
|
|
CommandBufferPool.Release (cmd);
|
|
}
|
|
|
|
public override void OnCameraCleanup (CommandBuffer cmd) {
|
|
s_hashSet.Clear ();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------- ScriptableRenderPass EachMesh Effect
|
|
internal class WCEEachMeshPass : ScriptableRenderPass {
|
|
private FilteringSettings _filteringSettings;
|
|
private Material _mat;
|
|
private List<ShaderTagId> _shaderTagIdList;
|
|
private bool _useOpaqueTex;
|
|
|
|
private LayerMask __layerMask = -2;
|
|
private LayerMask layerMask {
|
|
get => __layerMask;
|
|
set {
|
|
if (__layerMask == value) return;
|
|
__layerMask = value;
|
|
_filteringSettings = new FilteringSettings (RenderQueueRange.opaque, value);
|
|
}
|
|
}
|
|
|
|
internal WCEEachMeshPass () {
|
|
base.profilingSampler = new ProfilingSampler (nameof (WCEEachMeshPass));
|
|
_shaderTagIdList = new List<ShaderTagId> () {
|
|
new ShaderTagId ("SRPDefaultUnlit"),
|
|
new ShaderTagId ("UniversalForward"),
|
|
new ShaderTagId ("UniversalForwardOnly"),
|
|
new ShaderTagId ("LightweightForward"),
|
|
};
|
|
}
|
|
|
|
internal void Setup (RenderPassEvent evt, Material mat, LayerMask layerMask, bool useOpaqueTex) {
|
|
this.renderPassEvent = evt;
|
|
this.layerMask = layerMask;
|
|
_mat = mat;
|
|
_useOpaqueTex = useOpaqueTex;
|
|
}
|
|
|
|
public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData rendData) {
|
|
if (_useOpaqueTex)
|
|
ConfigureInput (ScriptableRenderPassInput.Color);
|
|
}
|
|
|
|
public override void Execute (ScriptableRenderContext context, ref RenderingData rendData) {
|
|
if (!_mat) return;
|
|
DrawingSettings drawingSettings = CreateDrawingSettings (_shaderTagIdList, ref rendData, SortingCriteria.None);
|
|
drawingSettings.overrideMaterial = _mat;
|
|
drawingSettings.overrideMaterialPassIndex = 0;
|
|
CommandBuffer cmd = CommandBufferPool.Get ();
|
|
using (new ProfilingScope (cmd, base.profilingSampler)) {
|
|
context.ExecuteCommandBuffer (cmd);
|
|
cmd.Clear ();
|
|
context.DrawRenderers (rendData.cullResults, ref drawingSettings, ref _filteringSettings);
|
|
}
|
|
context.ExecuteCommandBuffer (cmd);
|
|
CommandBufferPool.Release (cmd);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------- Gizmo
|
|
#if UNITY_EDITOR
|
|
private void OnDrawGizmosSelected () {
|
|
if (Selection.gameObjects.Length != 1 || Selection.activeGameObject != gameObject) {
|
|
drawGizmoAACube (1f, new Color (0.8f, 0.4f, 0.0f, 0.5f), true);
|
|
} else {
|
|
drawGizmoAACube (2f, new Color (0.8f, 0.4f, 0.0f, 1f), true);
|
|
drawGizmoAACube (2f, new Color (0.8f, 0.4f, 0.0f, 0.08f), false);
|
|
Gizmos.color = new Color (0.8f, 0.4f, 0.0f, 0.6f);
|
|
Vector3 surfYPos = transform.position + Vector3.up * (m_surfaceY - transform.position.y);
|
|
var tmp = Gizmos.matrix;
|
|
float alpha = 0.5f;
|
|
Gizmos.matrix = Matrix4x4.TRS (surfYPos, Quaternion.Euler (0f, m_textureRotation, 0f), new Vector3 (m_scale, 1f, m_scale));
|
|
if (m_surfFadeEnd > 0f) {
|
|
Gizmos.color = new Color (0f, 1f, 0.35f, 0.35f * alpha);
|
|
Gizmos.DrawWireCube (Vector3.up * m_surfFadeEnd, new Vector3 (1, 0, 1));
|
|
Gizmos.DrawWireCube (Vector3.up * -m_surfFadeEnd, new Vector3 (1, 0, 1));
|
|
if (m_surfFadeStart > 0f) {
|
|
Gizmos.color = new Color (0f, 1f, 0.35f, 0.35f * alpha);
|
|
Gizmos.DrawWireCube (Vector3.up * m_surfFadeStart, new Vector3 (1, 0, 1));
|
|
Gizmos.DrawWireCube (Vector3.up * -m_surfFadeStart, new Vector3 (1, 0, 1));
|
|
}
|
|
}
|
|
if (m_useDepthFade) {
|
|
Gizmos.color = new Color (1f, 0.35f, 0.6f, 0.45f * alpha);
|
|
Gizmos.DrawWireCube (Vector3.up * (m_depthFadeEnd), new Vector3 (1, 0, 1));
|
|
Gizmos.DrawWireCube (Vector3.up * (-m_depthFadeEnd), new Vector3 (1, 0, 1));
|
|
if (m_depthFadeStart > 0f) {
|
|
Gizmos.color = new Color (1f, 0.35f, 0.6f, 0.45f * alpha);
|
|
Gizmos.DrawWireCube (Vector3.up * m_depthFadeStart, new Vector3 (1, 0, 1));
|
|
Gizmos.DrawWireCube (Vector3.up * -m_depthFadeStart, new Vector3 (1, 0, 1));
|
|
}
|
|
}
|
|
Gizmos.color = new Color (0.3f, 0.76f, 1f, 0.65f * alpha);
|
|
Gizmos.DrawWireCube (Vector3.zero, new Vector3 (1, 0, 1));
|
|
Gizmos.color = new Color (0.3f, 0.76f, 1f, 1.3f * alpha);
|
|
Gizmos.DrawLine (Vector3.forward * 0.48f, Vector3.forward * 0.4f + Vector3.right * 0.03f);
|
|
Gizmos.DrawLine (Vector3.forward * 0.48f, Vector3.forward * 0.4f - Vector3.right * 0.03f);
|
|
Gizmos.DrawLine (Vector3.forward * 0.4f + Vector3.right * 0.03f, Vector3.forward * 0.4f - Vector3.right * 0.03f);
|
|
Gizmos.matrix = tmp;
|
|
}
|
|
}
|
|
|
|
private void drawGizmoAACube (float width, Color color, bool zTest) {
|
|
void drawQuart (float rot) {
|
|
Handles.matrix = transform.localToWorldMatrix * Matrix4x4.Rotate (Quaternion.Euler (rot, 0f, 0f));
|
|
Handles.DrawAAPolyLine (Texture2D.whiteTexture, width, new Vector3 (-.5f, -.5f, -.5f), new Vector3 (-.5f, .5f, -.5f), new Vector3 (.5f, .5f, -.5f), new Vector3 (.5f, -.5f, -.5f));
|
|
}
|
|
Handles.color = color;
|
|
Handles.zTest = zTest? CompareFunction.LessEqual : CompareFunction.Greater;
|
|
var tmp = Handles.matrix;
|
|
for (int i = 0; i < 4; i++) drawQuart (i * 90f);
|
|
Handles.matrix = tmp;
|
|
}
|
|
#endif // End of UNITY_EDITOR
|
|
}
|
|
}
|
|
|
|
#endif // End of WCE_URP
|