Files
Fishing2/Assets/ThirdParty/LuxWater/Scripts/LuxWater_UnderWaterBlur.cs
2025-05-10 12:49:47 +08:00

144 lines
4.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.XR;
namespace LuxWater {
[RequireComponent(typeof(Camera))]
public class LuxWater_UnderWaterBlur : MonoBehaviour {
[Space(6)]
[LuxWater_HelpBtn("h.3a2840a53u5j")]
public float blurSpread = 0.6f;
public int blurDownSample = 4;
public int blurIterations = 4;
private Vector2[] m_offsets = new Vector2[4];
private Material blurMaterial;
private Material blitMaterial;
private LuxWater_UnderWaterRendering waterrendermanager;
private bool doBlur = false;
private bool initBlur = true;
private Camera cam;
// Use this for initialization
void OnEnable () {
blurMaterial = new Material(Shader.Find("Hidden/Lux Water/BlurEffectConeTap"));
blitMaterial = new Material(Shader.Find("Hidden/Lux Water/UnderWaterPost"));
cam = GetComponent<Camera>();
Invoke("GetWaterrendermanagerInstance", 0.0f);
}
void OnDisable () {
if (blurMaterial)
DestroyImmediate(blurMaterial);
if (blitMaterial)
DestroyImmediate(blitMaterial);
}
void GetWaterrendermanagerInstance() {
waterrendermanager = LuxWater_UnderWaterRendering.instance;
}
void OnRenderImage(RenderTexture src, RenderTexture dest) {
if(waterrendermanager == null) {
Graphics.Blit(src, dest);
return;
}
// XR support
var xrSinglePassInstanced = false;
var dim = TextureDimension.Tex2D;
var depth = 1;
var vrUsage = VRTextureUsage.None;
if (cam.stereoEnabled) {
vrUsage = VRTextureUsage.OneEye;
if( XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassInstanced) {
xrSinglePassInstanced = true;
dim = TextureDimension.Tex2DArray;
depth = 2;
vrUsage = VRTextureUsage.TwoEyes;
}
}
// Only blur if any waterVolume is active
doBlur = (waterrendermanager.activeWaterVolume > -1) ? true : false;
// We also call it once at start in order to reduce spikes
if (doBlur || initBlur ) {
initBlur = false;
// Downsample and blur UnderwaterTex
int rtW = src.width / blurDownSample;
int rtH = src.height / blurDownSample;
RenderTextureDescriptor descr = new RenderTextureDescriptor(rtW, rtH, RenderTextureFormat.DefaultHDR, 0);
descr.dimension = dim;
descr.volumeDepth = depth;
// Needed to make blit write into both slices of the array!
descr.vrUsage = vrUsage;
RenderTexture BlurBuffer = RenderTexture.GetTemporary(descr);
// Copy screen to the smaller texture
DownSample(src, BlurBuffer);
// Blur the small texture
for (int i = 0; i < blurIterations; i++) {
RenderTexture BlurBuffer2 = RenderTexture.GetTemporary(descr);
FourTapCone(BlurBuffer, BlurBuffer2, i);
RenderTexture.ReleaseTemporary(BlurBuffer);
BlurBuffer = BlurBuffer2;
}
Shader.SetGlobalTexture("_UnderWaterTex", BlurBuffer);
// Combine Screen Buffer and BlurBuffer based on the Underwatermask
Graphics.Blit(src, dest, blitMaterial, 1);
RenderTexture.ReleaseTemporary(BlurBuffer);
}
else {
Graphics.Blit(src, dest);
}
}
// ////////////////////////////////////
// Helper functions
// Blur
void FourTapCone (RenderTexture source, RenderTexture dest, int iteration) {
float offset = 0.5f + iteration * blurSpread;
m_offsets[0].x = -offset;
m_offsets[0].y = -offset;
m_offsets[1].x = -offset;
m_offsets[1].y = offset;
m_offsets[2].x = offset;
m_offsets[2].y = offset;
m_offsets[3].x = offset;
m_offsets[3].y = -offset;
if (iteration == 0)
Graphics.BlitMultiTap(source, dest, blurMaterial, m_offsets);
else
Graphics.BlitMultiTap(source, dest, blurMaterial, m_offsets);
}
// Downsampling
void DownSample(RenderTexture source, RenderTexture dest) {
float offset = 1.0f;
m_offsets[0].x = -offset;
m_offsets[0].y = -offset;
m_offsets[1].x = -offset;
m_offsets[1].y = offset;
m_offsets[2].x = offset;
m_offsets[2].y = offset;
m_offsets[3].x = offset;
m_offsets[3].y = -offset;
Graphics.BlitMultiTap (source, dest, blurMaterial, m_offsets);
}
}
}