升级水插件
This commit is contained in:
@@ -16,21 +16,19 @@ namespace WaveHarmonic.Crest
|
||||
/// <summary>
|
||||
/// What side of the water surface to render planar reflections for.
|
||||
/// </summary>
|
||||
[@GenerateDoc]
|
||||
public enum WaterReflectionSide
|
||||
{
|
||||
/// <summary>
|
||||
/// Both sides. Most expensive.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Generated.WaterReflectionSide.Both"/>
|
||||
[Tooltip("Both sides. Most expensive.")]
|
||||
Both,
|
||||
|
||||
/// <summary>
|
||||
/// Above only. Typical for planar reflections.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Generated.WaterReflectionSide.Above"/>
|
||||
[Tooltip("Above only. Typical for planar reflections.")]
|
||||
Above,
|
||||
|
||||
/// <summary>
|
||||
/// Below only. For total internal reflections.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Generated.WaterReflectionSide.Below"/>
|
||||
[Tooltip("Below only. For total internal reflections.")]
|
||||
Below,
|
||||
}
|
||||
|
||||
@@ -269,27 +267,48 @@ namespace WaveHarmonic.Crest
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnPreRenderCamera(Camera camera)
|
||||
bool ShouldRender(Camera camera)
|
||||
{
|
||||
// If no surface, then do not execute the reflection camera.
|
||||
if (!WaterRenderer.ShouldRender(camera, _Water.Surface.Layer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// This method could be executed twice: once by the camera rendering the surface,
|
||||
// and once again by the planar reflection camera. For the latter, we do not want
|
||||
// to proceed or infinite recursion. For safety.
|
||||
if (camera == CurrentCamera)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid these types for now.
|
||||
if (camera.cameraType == CameraType.Reflection)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
|
||||
{
|
||||
if (!ShouldRender(camera))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SupportsRecursiveRendering)
|
||||
{
|
||||
if (camera.cameraType is CameraType.Preview or CameraType.Reflection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Helpers.MaskIncludesLayer(camera.cullingMask, _Water.Layer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// This option only valid for recursive, otherwise, it is always single camera.
|
||||
if (_RenderOnlySingleCamera && camera != _Water.Viewer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_CameraViewpoint = camera;
|
||||
LateUpdate();
|
||||
LateUpdate(context);
|
||||
}
|
||||
|
||||
if (camera == _CameraViewpoint)
|
||||
@@ -299,13 +318,17 @@ namespace WaveHarmonic.Crest
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnAfterCameraRender(Camera camera)
|
||||
internal void OnEndCameraRendering(Camera camera)
|
||||
{
|
||||
if (SupportsRecursiveRendering && !_RenderOnlySingleCamera) return;
|
||||
if (!ShouldRender(camera))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Shader.SetGlobalTexture(ShaderIDs.s_ReflectionTexture, Texture2D.blackTexture);
|
||||
}
|
||||
|
||||
internal void LateUpdate()
|
||||
internal void LateUpdate(ScriptableRenderContext context)
|
||||
{
|
||||
// Frame rate limiter.
|
||||
if (_LastRefreshOnFrame > 0 && RefreshPerFrames > 1)
|
||||
@@ -362,7 +385,7 @@ namespace WaveHarmonic.Crest
|
||||
}
|
||||
|
||||
// We do not want the water plane when rendering planar reflections.
|
||||
_Water.Root.gameObject.SetActive(false);
|
||||
_Water.Surface.Root.gameObject.SetActive(false);
|
||||
|
||||
CurrentCamera = _CameraReflections;
|
||||
|
||||
@@ -390,7 +413,7 @@ namespace WaveHarmonic.Crest
|
||||
try
|
||||
#endif
|
||||
{
|
||||
Render();
|
||||
Render(context);
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
// Ensure that any global settings are restored.
|
||||
@@ -414,15 +437,18 @@ namespace WaveHarmonic.Crest
|
||||
_QualitySettingsOverride.Restore();
|
||||
|
||||
CurrentCamera = null;
|
||||
_Water.Root.gameObject.SetActive(true);
|
||||
_Water.Surface.Root.gameObject.SetActive(true);
|
||||
|
||||
// Remember this frame as last refreshed.
|
||||
_LastRefreshOnFrame = Time.renderedFrameCount;
|
||||
}
|
||||
}
|
||||
|
||||
void Render()
|
||||
void Render(ScriptableRenderContext context)
|
||||
{
|
||||
#if UNITY_6000_0_OR_NEWER && d_UnityURP
|
||||
_CameraReflections.targetTexture = _ReflectionTexture;
|
||||
#else
|
||||
var descriptor = _ReflectionTexture.descriptor;
|
||||
descriptor.dimension = TextureDimension.Tex2D;
|
||||
descriptor.volumeDepth = 1;
|
||||
@@ -430,6 +456,7 @@ namespace WaveHarmonic.Crest
|
||||
// No need to clear, as camera clears using the skybox.
|
||||
var target = RenderTexture.GetTemporary(descriptor);
|
||||
_CameraReflections.targetTexture = target;
|
||||
#endif
|
||||
|
||||
if (_Mode != WaterReflectionSide.Below)
|
||||
{
|
||||
@@ -441,8 +468,11 @@ namespace WaveHarmonic.Crest
|
||||
_CameraReflections.cullingMask = _Layers & ~(1 << _UnderWater.Layer);
|
||||
}
|
||||
|
||||
RenderCamera(_CameraReflections, Vector3.up, false);
|
||||
RenderCamera(context, _CameraReflections, Vector3.up, false, 0);
|
||||
|
||||
#if !(UNITY_6000_0_OR_NEWER && d_UnityURP)
|
||||
Graphics.CopyTexture(target, 0, 0, _ReflectionTexture, 0, 0);
|
||||
#endif
|
||||
|
||||
_CameraReflections.ResetProjectionMatrix();
|
||||
}
|
||||
@@ -459,29 +489,33 @@ namespace WaveHarmonic.Crest
|
||||
_CameraReflections.depthTextureMode = DepthTextureMode.Depth;
|
||||
}
|
||||
|
||||
RenderCamera(_CameraReflections, Vector3.down, _NonObliqueNearSurface);
|
||||
RenderCamera(context, _CameraReflections, Vector3.down, _NonObliqueNearSurface, 1);
|
||||
|
||||
#if !(UNITY_6000_0_OR_NEWER && d_UnityURP)
|
||||
Graphics.CopyTexture(target, 0, 0, _ReflectionTexture, 1, 0);
|
||||
#endif
|
||||
|
||||
_CameraReflections.ResetProjectionMatrix();
|
||||
}
|
||||
|
||||
|
||||
#if !(UNITY_6000_0_OR_NEWER && d_UnityURP)
|
||||
RenderTexture.ReleaseTemporary(target);
|
||||
#endif
|
||||
|
||||
_ReflectionTexture.GenerateMips();
|
||||
|
||||
Shader.SetGlobalVectorArray(ShaderIDs.s_ReflectionPositionNormal, _ReflectionPositionNormal);
|
||||
}
|
||||
|
||||
void RenderCamera(Camera camera, Vector3 planeNormal, bool nonObliqueNearSurface)
|
||||
void RenderCamera(ScriptableRenderContext context, Camera camera, Vector3 planeNormal, bool nonObliqueNearSurface, int slice)
|
||||
{
|
||||
// Find out the reflection plane: position and normal in world space
|
||||
var planePosition = _Water.Root.position;
|
||||
var planePosition = _Water.Position;
|
||||
|
||||
var offset = _ClipPlaneOffset;
|
||||
{
|
||||
var viewpoint = _CameraViewpoint.transform;
|
||||
if (offset == 0f && viewpoint.position.y == 0f && viewpoint.rotation.eulerAngles.y == 0f)
|
||||
if (offset == 0f && viewpoint.position.y == planePosition.y)
|
||||
{
|
||||
// Minor offset to prevent "Screen position out of view frustum". Smallest number
|
||||
// to work with both above and below. Smallest number to work with both above and
|
||||
@@ -518,7 +552,7 @@ namespace WaveHarmonic.Crest
|
||||
|
||||
if (SupportsRecursiveRendering)
|
||||
{
|
||||
Helpers.RenderCamera(camera, _Water._Context);
|
||||
Helpers.RenderCamera(camera, context, slice);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user