Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/ARTNGAME/Skymaster/AtmosphericScatteringSkyMaster.cs
2026-03-04 10:03:45 +08:00

557 lines
19 KiB
C#

using System;
using UnityEngine;
using UnityEngine.Rendering;
namespace Artngame.SKYMASTER
{
[ExecuteInEditMode]
public class AtmosphericScatteringSkyMaster : MonoBehaviour
{
public enum OcclusionDownscale
{
x1 = 1,
x2 = 2,
x4 = 4
}
public enum OcclusionSamples
{
x64 = 0,
x164 = 1,
x244 = 2
}
public enum ScatterDebugMode
{
None = 0,
Scattering = 1,
Occlusion = 2,
OccludedScattering = 3,
Rayleigh = 4,
Mie = 5,
Height = 6
}
public enum DepthTexture
{
Enable = 0,
Disable = 1,
Ignore = 2
}
[Header("World Components")]
public Gradient worldRayleighColorRamp;
public GameObject Sun;
public bool FogSky;
public float FogHorizonLower = 1f;
public float worldRayleighColorIntensity = 1f;
public float worldRayleighDensity = 10f;
public float worldRayleighExtinctionFactor = 1.1f;
public float worldRayleighIndirectScatter = 0.33f;
public Gradient worldMieColorRamp;
public float worldMieColorIntensity = 1f;
public float worldMieDensity = 15f;
public float worldMieExtinctionFactor;
public float worldMiePhaseAnisotropy = 0.9f;
public float worldNearScatterPush;
public float worldNormalDistance = 1000f;
[Header("Height Components")]
public Color heightRayleighColor = Color.white;
public float heightRayleighIntensity = 1f;
public float heightRayleighDensity = 10f;
public float heightMieDensity;
public float heightExtinctionFactor = 1.1f;
public float heightSeaLevel;
public float heightDistance = 50f;
public Vector3 heightPlaneShift = Vector3.zero;
public float heightNearScatterPush;
public float heightNormalDistance = 1000f;
[Header("Sky Dome")]
public Vector3 skyDomeScale = new Vector3(1f, 0.1f, 1f);
public Vector3 skyDomeRotation = Vector3.zero;
public Transform skyDomeTrackedYawRotation;
public bool skyDomeVerticalFlip;
public Cubemap skyDomeCube;
public float skyDomeExposure = 1f;
public Color skyDomeTint = Color.white;
[HideInInspector]
public Vector3 skyDomeOffset = Vector3.zero;
[Header("Scatter Occlusion")]
public bool useOcclusion;
public float occlusionBias;
public float occlusionBiasIndirect = 0.6f;
public float occlusionBiasClouds = 0.3f;
public OcclusionDownscale occlusionDownscale = OcclusionDownscale.x2;
public OcclusionSamples occlusionSamples;
public bool occlusionDepthFixup = true;
public float occlusionDepthThreshold = 25f;
public bool occlusionFullSky;
public float occlusionBiasSkyRayleigh = 0.2f;
public float occlusionBiasSkyMie = 0.4f;
public float backLightDepth = 5000f;
public float backLightIntensity = 0.95f;
[Header("Other")]
public float worldScaleExponent = 1f;
public bool forcePerPixel;
public bool forcePostEffect;
[Tooltip("Soft clouds need depth values. Ignore means externally controlled.")]
public DepthTexture depthTexture;
public ScatterDebugMode debugMode;
[HideInInspector]
public Shader occlusionShader;
private bool m_isAwake;
private Camera m_currentCamera;
private Material m_occlusionMaterial;
private CommandBuffer m_occlusionCmdAfterShadows;
private CommandBuffer m_occlusionCmdBeforeScreen;
public SkyMasterManager SkyManager;
private bool gameStart;
public static AtmosphericScatteringSkyMaster instance { get; private set; }
private void Start()
{
gameStart = true;
OnWillRenderObject();
}
private void Awake()
{
if (!GetComponent<MeshFilter>())
{
MeshFilter meshFilter = base.gameObject.AddComponent<MeshFilter>();
meshFilter.sharedMesh = new Mesh();
meshFilter.sharedMesh.bounds = new Bounds(Vector3.zero, Vector3.one * 10000f);
meshFilter.sharedMesh.SetTriangles((int[])null, 0);
}
if (!GetComponent<MeshRenderer>())
{
MeshRenderer meshRenderer = base.gameObject.AddComponent<MeshRenderer>();
meshRenderer.receiveShadows = false;
meshRenderer.lightProbeUsage = LightProbeUsage.Off;
meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
meshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
}
if (occlusionShader == null)
{
occlusionShader = Shader.Find("Hidden/AtmosphericScattering_OcclusionSM34");
}
m_occlusionMaterial = new Material(occlusionShader);
m_occlusionMaterial.hideFlags = HideFlags.HideAndDontSave;
if (worldRayleighColorRamp == null)
{
worldRayleighColorRamp = new Gradient();
worldRayleighColorRamp.SetKeys(new GradientColorKey[2]
{
new GradientColorKey(new Color(0.3f, 0.4f, 0.6f), 0f),
new GradientColorKey(new Color(0.5f, 0.6f, 0.8f), 1f)
}, new GradientAlphaKey[2]
{
new GradientAlphaKey(1f, 0f),
new GradientAlphaKey(1f, 1f)
});
}
if (worldMieColorRamp == null)
{
worldMieColorRamp = new Gradient();
worldMieColorRamp.SetKeys(new GradientColorKey[2]
{
new GradientColorKey(new Color(0.95f, 0.75f, 0.5f), 0f),
new GradientColorKey(new Color(1f, 0.9f, 8f), 1f)
}, new GradientAlphaKey[2]
{
new GradientAlphaKey(1f, 0f),
new GradientAlphaKey(1f, 1f)
});
}
m_isAwake = true;
if (SkyManager != null && Sun == null)
{
Sun = SkyManager.SUN_LIGHT;
}
}
private void Update()
{
if (!(SkyManager != null))
{
return;
}
if ((!SkyManager.AutoSunPosition && ((SkyManager.Current_Time >= 9f + SkyManager.Shift_dawn) & (SkyManager.Current_Time <= SkyManager.NightTimeMax + SkyManager.Shift_dawn))) || (SkyManager.AutoSunPosition && SkyManager.Rot_Sun_X > 0f))
{
if (Sun != SkyManager.SUN_LIGHT)
{
Sun = SkyManager.SUN_LIGHT;
SkyManager.MOON_LIGHT.GetComponent<Light>().RemoveAllCommandBuffers();
EnsureHookedLightSource(Sun.GetComponent<Light>());
UpdateDynamicUniforms();
}
}
else if (Sun != SkyManager.MOON_LIGHT)
{
Sun = SkyManager.MOON_LIGHT;
SkyManager.SUN_LIGHT.GetComponent<Light>().RemoveAllCommandBuffers();
EnsureHookedLightSource(Sun.GetComponent<Light>());
UpdateDynamicUniforms();
}
}
private void OnEnable()
{
if (m_isAwake)
{
UpdateKeywords(enable: true);
UpdateStaticUniforms();
if ((bool)instance)
{
_ = instance != this;
}
instance = this;
if (SkyManager != null && Sun == null)
{
Sun = SkyManager.SUN_LIGHT;
}
}
}
private void EnsureHookedLightSource(Light light)
{
if ((bool)light && light.commandBufferCount != 2)
{
light.RemoveAllCommandBuffers();
if (m_occlusionCmdAfterShadows != null)
{
m_occlusionCmdAfterShadows.Dispose();
}
if (m_occlusionCmdBeforeScreen != null)
{
m_occlusionCmdBeforeScreen.Dispose();
}
m_occlusionCmdAfterShadows = new CommandBuffer();
m_occlusionCmdAfterShadows.name = "Scatter Occlusion Pass 1";
m_occlusionCmdAfterShadows.SetGlobalTexture("u_SMCascadedShadowMap", new RenderTargetIdentifier(BuiltinRenderTextureType.CurrentActive));
m_occlusionCmdBeforeScreen = new CommandBuffer();
m_occlusionCmdBeforeScreen.name = "Scatter Occlusion Pass 2";
light.AddCommandBuffer(LightEvent.AfterShadowMap, m_occlusionCmdAfterShadows);
light.AddCommandBuffer(LightEvent.BeforeScreenspaceMask, m_occlusionCmdBeforeScreen);
}
}
private void OnDisable()
{
UpdateKeywords(enable: false);
if (Sun != null && (bool)Sun.GetComponent<Light>())
{
Sun.GetComponent<Light>().RemoveAllCommandBuffers();
}
if (SkyManager != null)
{
if (SkyManager.SUN_LIGHT != null && (bool)SkyManager.SUN_LIGHT.GetComponent<Light>())
{
SkyManager.SUN_LIGHT.GetComponent<Light>().RemoveAllCommandBuffers();
}
if (SkyManager.MOON_LIGHT != null && (bool)SkyManager.MOON_LIGHT.GetComponent<Light>())
{
SkyManager.MOON_LIGHT.GetComponent<Light>().RemoveAllCommandBuffers();
}
}
if (instance != this)
{
_ = (bool)instance;
}
else
{
instance = null;
}
}
private void UpdateKeywords(bool enable)
{
if (enable)
{
_ = forcePerPixel;
_ = useOcclusion;
_ = debugMode;
}
}
public void OnValidate()
{
if (m_isAwake)
{
occlusionBias = Mathf.Clamp01(occlusionBias);
occlusionBiasIndirect = Mathf.Clamp01(occlusionBiasIndirect);
occlusionBiasClouds = Mathf.Clamp01(occlusionBiasClouds);
occlusionBiasSkyRayleigh = Mathf.Clamp01(occlusionBiasSkyRayleigh);
occlusionBiasSkyMie = Mathf.Clamp01(occlusionBiasSkyMie);
worldScaleExponent = Mathf.Clamp(worldScaleExponent, 1f, 2f);
worldNormalDistance = Mathf.Clamp(worldNormalDistance, 1f, 10000f);
worldNearScatterPush = Mathf.Clamp(worldNearScatterPush, -200f, 300f);
worldRayleighDensity = Mathf.Clamp(worldRayleighDensity, 0f, 1000f);
worldMieDensity = Mathf.Clamp(worldMieDensity, 0f, 1000f);
worldRayleighIndirectScatter = Mathf.Clamp(worldRayleighIndirectScatter, 0f, 1f);
heightNormalDistance = Mathf.Clamp(heightNormalDistance, 1f, 10000f);
heightNearScatterPush = Mathf.Clamp(heightNearScatterPush, -200f, 300f);
heightRayleighDensity = Mathf.Clamp(heightRayleighDensity, 0f, 1000f);
heightMieDensity = Mathf.Clamp(heightMieDensity, 0f, 1000f);
worldMiePhaseAnisotropy = Mathf.Clamp01(worldMiePhaseAnisotropy);
skyDomeExposure = Mathf.Clamp(skyDomeExposure, 0f, 8f);
if (instance == this)
{
OnDisable();
OnEnable();
}
}
}
private void OnWillRenderObject()
{
if (!m_isAwake || (bool)m_currentCamera)
{
return;
}
if (Sun != null)
{
EnsureHookedLightSource(Sun.GetComponent<Light>());
}
if (gameStart)
{
gameStart = false;
return;
}
m_currentCamera = Camera.current;
if ((SystemInfo.graphicsShaderLevel >= 40 || depthTexture == DepthTexture.Enable) && m_currentCamera.depthTextureMode == DepthTextureMode.None)
{
m_currentCamera.depthTextureMode = DepthTextureMode.Depth;
}
else if (depthTexture == DepthTexture.Disable && m_currentCamera.depthTextureMode != DepthTextureMode.None)
{
m_currentCamera.depthTextureMode = DepthTextureMode.None;
}
UpdateDynamicUniforms();
if (useOcclusion)
{
Vector3 right = m_currentCamera.transform.right;
Vector3 up = m_currentCamera.transform.up;
Vector3 forward = m_currentCamera.transform.forward;
float num = Mathf.Tan(m_currentCamera.fieldOfView * 0.5f * (MathF.PI / 180f));
float num2 = num * m_currentCamera.aspect;
Vector3 vector = forward * m_currentCamera.farClipPlane;
Vector3 vector2 = right * num2 * m_currentCamera.farClipPlane;
Vector3 vector3 = up * num * m_currentCamera.farClipPlane;
m_occlusionMaterial.SetFloat("_ToggleForward", 0f);
m_occlusionMaterial.SetVector("u_SMCameraPosition", m_currentCamera.transform.position);
m_occlusionMaterial.SetVector("u_SMViewportCorner", vector - vector2 - vector3);
m_occlusionMaterial.SetVector("u_SMViewportRight", vector2 * 2f);
m_occlusionMaterial.SetVector("u_SMViewportUp", vector3 * 2f);
float num3 = (m_currentCamera ? m_currentCamera.farClipPlane : 1000f);
float value = (Mathf.Min(num3, QualitySettings.shadowDistance) - 1f) / num3;
m_occlusionMaterial.SetFloat("u_SMOcclusionSkyRefDistance", value);
Rect pixelRect = m_currentCamera.pixelRect;
float num4 = 1f / (float)occlusionDownscale;
int width = Mathf.RoundToInt(pixelRect.width * num4);
int height = Mathf.RoundToInt(pixelRect.height * num4);
int num5 = Shader.PropertyToID("u_SMOcclusionTexture");
if (m_occlusionCmdBeforeScreen != null)
{
m_occlusionCmdBeforeScreen.Clear();
m_occlusionCmdBeforeScreen.GetTemporaryRT(num5, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.R8, RenderTextureReadWrite.sRGB);
m_occlusionCmdBeforeScreen.Blit(null, num5, m_occlusionMaterial, (int)occlusionSamples);
m_occlusionCmdBeforeScreen.SetGlobalTexture(num5, num5);
m_occlusionCmdBeforeScreen.ReleaseTemporaryRT(num5);
}
}
}
private void OnRenderObject()
{
if (m_currentCamera == Camera.current)
{
m_currentCamera = null;
}
}
private void UpdateStaticUniforms()
{
Shader.SetGlobalVector("u_SMSkyDomeOffset", skyDomeOffset);
Shader.SetGlobalVector("u_SMSkyDomeScale", skyDomeScale);
Shader.SetGlobalTexture("u_SMSkyDomeCube", skyDomeCube);
Shader.SetGlobalFloat("u_SMSkyDomeExposure", skyDomeExposure);
Shader.SetGlobalColor("u_SMSkyDomeTint", skyDomeTint);
Shader.SetGlobalFloat("u_SMShadowBias", useOcclusion ? occlusionBias : 1f);
Shader.SetGlobalFloat("u_SMShadowBiasIndirect", useOcclusion ? occlusionBiasIndirect : 1f);
Shader.SetGlobalFloat("u_SMShadowBiasClouds", useOcclusion ? occlusionBiasClouds : 1f);
Shader.SetGlobalVector("u_SMShadowBiasSkyRayleighMie", useOcclusion ? new Vector4(occlusionBiasSkyRayleigh, occlusionBiasSkyMie, 0f, 0f) : Vector4.zero);
Shader.SetGlobalFloat("u_SMOcclusionDepthThreshold", occlusionDepthThreshold);
Shader.SetGlobalFloat("u_SMWorldScaleExponent", worldScaleExponent);
Shader.SetGlobalFloat("u_SMWorldNormalDistanceRcp", 1f / worldNormalDistance);
Shader.SetGlobalFloat("u_SMWorldNearScatterPush", (0f - Mathf.Pow(Mathf.Abs(worldNearScatterPush), worldScaleExponent)) * Mathf.Sign(worldNearScatterPush));
Shader.SetGlobalFloat("u_SMWorldRayleighDensity", (0f - worldRayleighDensity) / 100000f);
Shader.SetGlobalFloat("u_SMMiePhaseAnisotropy", worldMiePhaseAnisotropy);
Shader.SetGlobalVector("u_SMRayleighInScatterPct", new Vector4(1f - worldRayleighIndirectScatter, worldRayleighIndirectScatter, 0f, 0f));
Shader.SetGlobalFloat("u_SMHeightNormalDistanceRcp", 1f / heightNormalDistance);
Shader.SetGlobalFloat("u_SMHeightNearScatterPush", (0f - Mathf.Pow(Mathf.Abs(heightNearScatterPush), worldScaleExponent)) * Mathf.Sign(heightNearScatterPush));
Shader.SetGlobalFloat("u_SMHeightRayleighDensity", (0f - heightRayleighDensity) / 100000f);
Shader.SetGlobalFloat("u_SMHeightSeaLevel", heightSeaLevel);
Shader.SetGlobalFloat("u_SMHeightDistanceRcp", 1f / heightDistance);
Shader.SetGlobalVector("u_SMHeightPlaneShift", heightPlaneShift);
Shader.SetGlobalVector("u_SMHeightRayleighColor", (Vector4)heightRayleighColor * heightRayleighIntensity);
Shader.SetGlobalFloat("u_SMHeightExtinctionFactor", heightExtinctionFactor);
Shader.SetGlobalFloat("u_SMRayleighExtinctionFactor", worldRayleighExtinctionFactor);
Shader.SetGlobalFloat("u_SMMieExtinctionFactor", worldMieExtinctionFactor);
Color color = worldRayleighColorRamp.Evaluate(0f);
Color color2 = worldRayleighColorRamp.Evaluate(0.25f);
Color color3 = worldRayleighColorRamp.Evaluate(0.5f);
Color color4 = worldRayleighColorRamp.Evaluate(0.75f);
Color color5 = worldRayleighColorRamp.Evaluate(1f);
Color color6 = worldMieColorRamp.Evaluate(0f);
Color color7 = worldMieColorRamp.Evaluate(0.5f);
Color color8 = worldMieColorRamp.Evaluate(1f);
Shader.SetGlobalVector("u_SMRayleighColorM20", (Vector4)color * worldRayleighColorIntensity);
Shader.SetGlobalVector("u_SMRayleighColorM10", (Vector4)color2 * worldRayleighColorIntensity);
Shader.SetGlobalVector("u_SMRayleighColorO00", (Vector4)color3 * worldRayleighColorIntensity);
Shader.SetGlobalVector("u_SMRayleighColorP10", (Vector4)color4 * worldRayleighColorIntensity);
Shader.SetGlobalVector("u_SMRayleighColorP20", (Vector4)color5 * worldRayleighColorIntensity);
Shader.SetGlobalVector("u_SMMieColorM20", (Vector4)color6 * worldMieColorIntensity);
Shader.SetGlobalVector("u_SMMieColorO00", (Vector4)color7 * worldMieColorIntensity);
Shader.SetGlobalVector("u_SMMieColorP20", (Vector4)color8 * worldMieColorIntensity);
Shader.SetGlobalFloat("u_SMAtmosphericsDebugMode", (float)debugMode);
if (occlusionFullSky)
{
Shader.SetGlobalFloat("u_SMOcclusionSkyToggle", 1f);
}
else
{
Shader.SetGlobalFloat("u_SMOcclusionSkyToggle", 0f);
}
if (FogSky)
{
Shader.SetGlobalFloat("u_SMFogSkyToggle", 1f);
}
else
{
Shader.SetGlobalFloat("u_SMFogSkyToggle", 0f);
}
Shader.SetGlobalFloat("u_SMFogHorizonLower", FogHorizonLower);
Shader.SetGlobalFloat("backLightDepth", backLightDepth);
Shader.SetGlobalFloat("backLightIntensity", backLightIntensity);
}
private void UpdateDynamicUniforms()
{
bool flag = false;
flag = ((SkyManager != null) ? true : false);
if (SkyManager != null)
{
if (SkyManager.currentWeatherName == SkyMasterManager.Volume_Weather_types.HeavyStorm || SkyManager.currentWeatherName == SkyMasterManager.Volume_Weather_types.HeavyStormDark)
{
Shader.SetGlobalVector("u_SMHeightRayleighColor", (Vector4)heightRayleighColor * heightRayleighIntensity * 0.6f);
}
else
{
Shader.SetGlobalVector("u_SMHeightRayleighColor", (Vector4)heightRayleighColor * heightRayleighIntensity);
}
}
else
{
Shader.SetGlobalVector("u_SMHeightRayleighColor", (Vector4)heightRayleighColor * heightRayleighIntensity);
}
Shader.SetGlobalFloat("u_SMHeightSeaLevel", heightSeaLevel);
Shader.SetGlobalFloat("u_SMHeightDistanceRcp", 1f / heightDistance);
if (!Application.isPlaying)
{
if (occlusionFullSky)
{
Shader.SetGlobalFloat("u_SMOcclusionSkyToggle", 1f);
}
else
{
Shader.SetGlobalFloat("u_SMOcclusionSkyToggle", 0f);
}
if (FogSky)
{
Shader.SetGlobalFloat("u_SMFogSkyToggle", 1f);
}
else
{
Shader.SetGlobalFloat("u_SMFogSkyToggle", 0f);
}
Shader.SetGlobalFloat("u_SMShadowBias", useOcclusion ? occlusionBias : 1f);
Shader.SetGlobalFloat("u_SMShadowBiasIndirect", useOcclusion ? occlusionBiasIndirect : 1f);
Shader.SetGlobalFloat("u_SMShadowBiasClouds", useOcclusion ? occlusionBiasClouds : 1f);
Shader.SetGlobalVector("u_SMShadowBiasSkyRayleighMie", useOcclusion ? new Vector4(occlusionBiasSkyRayleigh, occlusionBiasSkyMie, 0f, 0f) : Vector4.zero);
}
Shader.SetGlobalFloat("u_SMFogHorizonLower", FogHorizonLower);
Shader.SetGlobalFloat("backLightDepth", backLightDepth);
Shader.SetGlobalFloat("backLightIntensity", backLightIntensity);
float num = (skyDomeTrackedYawRotation ? skyDomeTrackedYawRotation.eulerAngles.y : 0f);
Shader.SetGlobalMatrix("u_SMSkyDomeRotation", Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(skyDomeRotation.x, 0f, 0f), Vector3.one) * Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, skyDomeRotation.y - num, 0f), Vector3.one) * Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, skyDomeVerticalFlip ? (-1f) : 1f, 1f)));
Shader.SetGlobalVector("u_SMSunDirection", flag ? (-Sun.transform.forward) : Vector3.down);
Shader.SetGlobalFloat("u_SMWorldMieDensity", flag ? ((0f - worldMieDensity) / 100000f) : 0f);
Shader.SetGlobalFloat("u_SMHeightMieDensity", flag ? ((0f - heightMieDensity) / 100000f) : 0f);
Rect rect = (m_currentCamera ? m_currentCamera.pixelRect : new Rect(0f, 0f, Screen.width, Screen.height));
float num2 = (float)occlusionDownscale;
Vector4 value = new Vector4(num2 / rect.width, num2 / rect.height, (0f - num2) / rect.width, (0f - num2) / rect.height);
Shader.SetGlobalVector("u_SMDepthTextureScaledTexelSize", value);
}
}
}