Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/UltimateWater/MaskModule.cs
2026-03-04 10:03:45 +08:00

176 lines
6.4 KiB
C#

using System.Collections.Generic;
using UltimateWater.Internal;
using UnityEngine;
using UnityEngine.Rendering;
namespace UltimateWater
{
public class MaskModule : IRenderModule
{
private CommandBuffer _Commands;
private int _SubtractiveMaskId;
private int _AdditiveMaskId;
private Shader _VolumeFrontFastShader;
private Shader _VolumeFrontShader;
private Shader _VolumeBackShader;
public void OnEnable(WaterCamera waterCamera)
{
_Commands = new CommandBuffer
{
name = "[Water] : Render Volumes and Masks"
};
_SubtractiveMaskId = ShaderVariables.SubtractiveMask;
_AdditiveMaskId = ShaderVariables.AdditiveMask;
_VolumeFrontFastShader = ShaderUtility.Instance.Get(ShaderList.VolumesFrontSimple);
_VolumeFrontShader = ShaderUtility.Instance.Get(ShaderList.VolumesFront);
_VolumeBackShader = ShaderUtility.Instance.Get(ShaderList.VolumesBack);
}
public void OnDisable(WaterCamera waterCamera)
{
if (_Commands != null)
{
Camera cameraComponent = waterCamera.CameraComponent;
CameraEvent evt = GetEvent(waterCamera);
cameraComponent.RemoveCommandBuffer(evt, _Commands);
_Commands.Release();
_Commands = null;
}
}
public void OnValidate(WaterCamera waterCamera)
{
ShaderUtility instance = ShaderUtility.Instance;
instance.Use(ShaderList.VolumesFrontSimple);
instance.Use(ShaderList.VolumesFront);
instance.Use(ShaderList.VolumesBack);
}
public void Process(WaterCamera waterCamera)
{
if (waterCamera.RenderVolumes)
{
bool hasSubtractiveVolumes = false;
bool hasAdditiveVolumes = false;
bool hasFlatMasks = false;
List<Water> waters = ApplicationSingleton<WaterSystem>.Instance.Waters;
for (int num = waters.Count - 1; num >= 0; num--)
{
waters[num].Renderer.OnSharedSubtractiveMaskRender(ref hasSubtractiveVolumes, ref hasAdditiveVolumes, ref hasFlatMasks);
}
SetupCamera(waterCamera);
_Commands.Clear();
SubtractiveMask(waterCamera, hasSubtractiveVolumes, hasFlatMasks);
AdditiveMask(waterCamera, hasAdditiveVolumes);
if (_Commands.sizeInBytes != 0)
{
Camera cameraComponent = waterCamera.CameraComponent;
CameraEvent evt = GetEvent(waterCamera);
cameraComponent.RemoveCommandBuffer(evt, _Commands);
cameraComponent.AddCommandBuffer(evt, _Commands);
}
for (int num2 = waters.Count - 1; num2 >= 0; num2--)
{
waters[num2].Renderer.OnSharedMaskPostRender();
}
}
}
public void Render(WaterCamera waterCamera, RenderTexture source, RenderTexture destination)
{
}
private void SubtractiveMask(WaterCamera waterCamera, bool hasSubtractiveVolumes, bool hasFlatMasks)
{
if (hasSubtractiveVolumes || hasFlatMasks)
{
RenderSubtractivePass(waterCamera, hasSubtractiveVolumes, hasFlatMasks);
}
else
{
Shader.SetGlobalTexture(_SubtractiveMaskId, DefaultTextures.Get(Color.clear));
}
}
private void AdditiveMask(WaterCamera waterCamera, bool hasAdditiveVolumes)
{
if (hasAdditiveVolumes)
{
RenderAdditivePass(waterCamera);
}
else
{
Shader.SetGlobalTexture(_AdditiveMaskId, DefaultTextures.Get(Color.clear));
}
}
private void RenderSubtractivePass(WaterCamera waterCamera, bool hasSubtractiveVolumes, bool hasFlatMasks)
{
int baseEffectWidth = waterCamera.BaseEffectWidth;
int baseEffectHeight = waterCamera.BaseEffectHeight;
FilterMode filter = ((!(waterCamera.BaseEffectsQuality > 0.98f)) ? FilterMode.Bilinear : FilterMode.Point);
Camera effectsCamera = waterCamera.EffectsCamera;
WaterCamera component = effectsCamera.GetComponent<WaterCamera>();
_Commands.GetTemporaryRT(_SubtractiveMaskId, baseEffectWidth, baseEffectHeight, 24, filter, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
_Commands.SetRenderTarget(_SubtractiveMaskId);
_Commands.ClearRenderTarget(clearDepth: true, clearColor: true, new Color(0f, 0f, 0f, 0f));
if (hasSubtractiveVolumes)
{
Shader shader = (waterCamera.IsInsideSubtractiveVolume ? _VolumeFrontShader : _VolumeFrontFastShader);
effectsCamera.cullingMask = 1 << WaterProjectSettings.Instance.WaterLayer;
component.AddWaterRenderCommands(_Commands, shader, surfaces: false, volumes: true, waterCamera.IsInsideSubtractiveVolume);
component.AddWaterRenderCommands(_Commands, _VolumeBackShader, surfaces: false, volumes: true, volumesTwoPass: false);
}
if (hasFlatMasks && waterCamera.RenderFlatMasks)
{
effectsCamera.cullingMask = 1 << WaterProjectSettings.Instance.WaterTempLayer;
component.AddWaterMasksRenderCommands(_Commands);
}
}
private void RenderAdditivePass(WaterCamera waterCamera)
{
int baseEffectWidth = waterCamera.BaseEffectWidth;
int baseEffectHeight = waterCamera.BaseEffectHeight;
List<Water> waters = ApplicationSingleton<WaterSystem>.Instance.Waters;
Camera effectsCamera = waterCamera.EffectsCamera;
WaterCamera component = effectsCamera.GetComponent<WaterCamera>();
Shader shader = (waterCamera.IsInsideAdditiveVolume ? _VolumeFrontShader : _VolumeFrontFastShader);
FilterMode filter = ((!(waterCamera.BaseEffectsQuality > 0.98f)) ? FilterMode.Bilinear : FilterMode.Point);
for (int num = waters.Count - 1; num >= 0; num--)
{
waters[num].Renderer.OnSharedMaskAdditiveRender();
}
effectsCamera.cullingMask = 1 << WaterProjectSettings.Instance.WaterLayer;
_Commands.GetTemporaryRT(_AdditiveMaskId, baseEffectWidth, baseEffectHeight, 24, filter, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
_Commands.SetRenderTarget(_AdditiveMaskId);
_Commands.ClearRenderTarget(clearDepth: true, clearColor: true, new Color(0f, 0f, 0f, 0f));
component.AddWaterRenderCommands(_Commands, shader, surfaces: false, volumes: true, waterCamera.IsInsideAdditiveVolume);
component.AddWaterRenderCommands(_Commands, _VolumeBackShader, surfaces: false, volumes: true, volumesTwoPass: false);
}
private static void SetupCamera(WaterCamera waterCamera)
{
Camera effectsCamera = waterCamera.EffectsCamera;
effectsCamera.transform.position = waterCamera.transform.position;
effectsCamera.transform.rotation = waterCamera.transform.rotation;
effectsCamera.projectionMatrix = waterCamera.CameraComponent.projectionMatrix;
}
private static CameraEvent GetEvent(WaterCamera waterCamera)
{
if (waterCamera.CameraComponent.actualRenderingPath != RenderingPath.Forward)
{
return CameraEvent.BeforeGBuffer;
}
return CameraEvent.BeforeForwardOpaque;
}
}
}