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

1029 lines
34 KiB
C#

using System;
using System.Runtime.InteropServices;
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
[AddComponentMenu("Image Effects/Sonic Ether/SEGI")]
public class SEGI : MonoBehaviour
{
[Serializable]
public enum VoxelResolution
{
low = 0x80,
high = 0x100
}
private enum RenderState
{
Voxelize = 0,
Bounce = 1
}
[StructLayout(LayoutKind.Sequential, Size = 1)]
private struct Pass
{
public static int DiffuseTrace = 0;
public static int BilateralBlur = 1;
public static int BlendWithScene = 2;
public static int TemporalBlend = 3;
public static int SpecularTrace = 4;
public static int GetCameraDepthTexture = 5;
public static int GetWorldNormals = 6;
public static int VisualizeGI = 7;
public static int WriteBlack = 8;
public static int VisualizeVoxels = 10;
public static int BilateralUpsample = 11;
}
public struct SystemSupported
{
public bool hdrTextures;
public bool rIntTextures;
public bool dx11;
public bool volumeTextures;
public bool postShader;
public bool sunDepthShader;
public bool voxelizationShader;
public bool tracingShader;
public bool fullFunctionality
{
get
{
if (hdrTextures && rIntTextures && dx11 && volumeTextures && postShader && sunDepthShader && voxelizationShader)
{
return tracingShader;
}
return false;
}
}
}
private int updateGIcounter;
public int updateGIevery = 1;
public bool updateGI = true;
public LayerMask giCullingMask = int.MaxValue;
public float shadowSpaceSize = 50f;
public Light sun;
public Color skyColor;
public float voxelSpaceSize = 25f;
public bool useBilateralFiltering;
[Range(0f, 2f)]
public int innerOcclusionLayers = 1;
[Range(0.01f, 1f)]
public float temporalBlendWeight = 0.1f;
public VoxelResolution voxelResolution = VoxelResolution.high;
public bool visualizeSunDepthTexture;
public bool visualizeGI;
public bool visualizeVoxels;
public bool halfResolution = true;
public bool stochasticSampling = true;
public bool infiniteBounces;
public Transform followTransform;
[Range(1f, 128f)]
public int cones = 6;
[Range(1f, 32f)]
public int coneTraceSteps = 14;
[Range(0.1f, 2f)]
public float coneLength = 1f;
[Range(0.5f, 6f)]
public float coneWidth = 5.5f;
[Range(0f, 4f)]
public float occlusionStrength = 1f;
[Range(0f, 4f)]
public float nearOcclusionStrength = 0.5f;
[Range(0.001f, 4f)]
public float occlusionPower = 1.5f;
[Range(0f, 4f)]
public float coneTraceBias = 1f;
[Range(0f, 4f)]
public float nearLightGain = 1f;
[Range(0f, 4f)]
public float giGain = 1f;
[Range(0f, 4f)]
public float secondaryBounceGain = 1f;
[Range(0f, 16f)]
public float softSunlight;
[Range(0f, 8f)]
public float skyIntensity = 1f;
public bool doReflections = true;
[Range(12f, 128f)]
public int reflectionSteps = 64;
[Range(0.001f, 4f)]
public float reflectionOcclusionPower = 1f;
[Range(0f, 1f)]
public float skyReflectionIntensity = 1f;
public bool voxelAA;
public bool gaussianMipFilter;
[Range(0.1f, 4f)]
public float farOcclusionStrength = 1f;
[Range(0.1f, 4f)]
public float farthestOcclusionStrength = 1f;
[Range(3f, 16f)]
public int secondaryCones = 6;
[Range(0.1f, 4f)]
public float secondaryOcclusionStrength = 1f;
public bool sphericalSkylight;
private object initChecker;
private Material material;
private Camera attachedCamera;
private Transform shadowCamTransform;
private Camera shadowCam;
private GameObject shadowCamGameObject;
private Texture2D[] blueNoise;
private int sunShadowResolution = 256;
private int prevSunShadowResolution;
private Shader sunDepthShader;
private float shadowSpaceDepthRatio = 10f;
private int frameCounter;
private RenderTexture sunDepthTexture;
private RenderTexture previousGIResult;
private RenderTexture previousCameraDepth;
private RenderTexture integerVolume;
private RenderTexture[] volumeTextures;
private RenderTexture secondaryIrradianceVolume;
private RenderTexture volumeTextureB;
private RenderTexture activeVolume;
private RenderTexture previousActiveVolume;
private RenderTexture dummyVoxelTextureAAScaled;
private RenderTexture dummyVoxelTextureFixed;
private bool notReadyToRender;
private Shader voxelizationShader;
private Shader voxelTracingShader;
private ComputeShader clearCompute;
private ComputeShader transferIntsCompute;
private ComputeShader mipFilterCompute;
public int numMipLevels = 6;
private Camera voxelCamera;
private GameObject voxelCameraGO;
private GameObject leftViewPoint;
private GameObject topViewPoint;
private Vector3 voxelSpaceOrigin;
private Vector3 previousVoxelSpaceOrigin;
private Vector3 voxelSpaceOriginDelta;
private Quaternion rotationFront = new Quaternion(0f, 0f, 0f, 1f);
private Quaternion rotationLeft = new Quaternion(0f, 0.7f, 0f, 0.7f);
private Quaternion rotationTop = new Quaternion(0.7f, 0f, 0f, 0.7f);
private int voxelFlipFlop;
private RenderState renderState;
public SystemSupported systemSupported;
private CameraClearFlags prevFlags;
private float voxelScaleFactor => (float)voxelResolution / 256f;
public float vramUsage
{
get
{
long num = 0L;
if (sunDepthTexture != null)
{
num += sunDepthTexture.width * sunDepthTexture.height * 16;
}
if (previousGIResult != null)
{
num += previousGIResult.width * previousGIResult.height * 16 * 4;
}
if (previousCameraDepth != null)
{
num += previousCameraDepth.width * previousCameraDepth.height * 32;
}
if (integerVolume != null)
{
num += integerVolume.width * integerVolume.height * integerVolume.volumeDepth * 32;
}
if (volumeTextures != null)
{
for (int i = 0; i < volumeTextures.Length; i++)
{
if (volumeTextures[i] != null)
{
num += volumeTextures[i].width * volumeTextures[i].height * volumeTextures[i].volumeDepth * 16 * 4;
}
}
}
if (secondaryIrradianceVolume != null)
{
num += secondaryIrradianceVolume.width * secondaryIrradianceVolume.height * secondaryIrradianceVolume.volumeDepth * 16 * 4;
}
if (volumeTextureB != null)
{
num += volumeTextureB.width * volumeTextureB.height * volumeTextureB.volumeDepth * 16 * 4;
}
if (dummyVoxelTextureAAScaled != null)
{
num += dummyVoxelTextureAAScaled.width * dummyVoxelTextureAAScaled.height * 8;
}
if (dummyVoxelTextureFixed != null)
{
num += dummyVoxelTextureFixed.width * dummyVoxelTextureFixed.height * 8;
}
return (float)num / 8388608f;
}
}
private int mipFilterKernel
{
get
{
if (!gaussianMipFilter)
{
return 0;
}
return 1;
}
}
private int dummyVoxelResolution => (int)voxelResolution * ((!voxelAA) ? 1 : 2);
private int giRenderRes
{
get
{
if (!halfResolution)
{
return 1;
}
return 2;
}
}
public void ApplyPreset(SEGIPreset preset)
{
voxelResolution = preset.voxelResolution;
voxelAA = preset.voxelAA;
innerOcclusionLayers = preset.innerOcclusionLayers;
infiniteBounces = preset.infiniteBounces;
temporalBlendWeight = preset.temporalBlendWeight;
useBilateralFiltering = preset.useBilateralFiltering;
halfResolution = preset.halfResolution;
stochasticSampling = preset.stochasticSampling;
doReflections = preset.doReflections;
cones = preset.cones;
coneTraceSteps = preset.coneTraceSteps;
coneLength = preset.coneLength;
coneWidth = preset.coneWidth;
coneTraceBias = preset.coneTraceBias;
occlusionStrength = preset.occlusionStrength;
nearOcclusionStrength = preset.nearOcclusionStrength;
occlusionPower = preset.occlusionPower;
nearLightGain = preset.nearLightGain;
giGain = preset.giGain;
secondaryBounceGain = preset.secondaryBounceGain;
reflectionSteps = preset.reflectionSteps;
reflectionOcclusionPower = preset.reflectionOcclusionPower;
skyReflectionIntensity = preset.skyReflectionIntensity;
gaussianMipFilter = preset.gaussianMipFilter;
farOcclusionStrength = preset.farOcclusionStrength;
farthestOcclusionStrength = preset.farthestOcclusionStrength;
secondaryCones = preset.secondaryCones;
secondaryOcclusionStrength = preset.secondaryOcclusionStrength;
}
private void Start()
{
InitCheck();
if (Camera.main != null)
{
_ = Application.isPlaying;
}
}
private void InitCheck()
{
if (initChecker == null)
{
Init();
}
}
private void CreateVolumeTextures()
{
volumeTextures = new RenderTexture[numMipLevels];
for (int i = 0; i < numMipLevels; i++)
{
if ((bool)volumeTextures[i])
{
volumeTextures[i].DiscardContents();
volumeTextures[i].Release();
UnityEngine.Object.DestroyImmediate(volumeTextures[i]);
}
int num = (int)voxelResolution / Mathf.RoundToInt(Mathf.Pow(2f, i));
volumeTextures[i] = new RenderTexture(num, num, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
volumeTextures[i].isVolume = true;
volumeTextures[i].volumeDepth = num;
volumeTextures[i].enableRandomWrite = true;
volumeTextures[i].filterMode = FilterMode.Bilinear;
volumeTextures[i].autoGenerateMips = false;
volumeTextures[i].useMipMap = false;
volumeTextures[i].Create();
volumeTextures[i].hideFlags = HideFlags.HideAndDontSave;
}
if ((bool)volumeTextureB)
{
volumeTextureB.DiscardContents();
volumeTextureB.Release();
UnityEngine.Object.DestroyImmediate(volumeTextureB);
}
volumeTextureB = new RenderTexture((int)voxelResolution, (int)voxelResolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
volumeTextureB.isVolume = true;
volumeTextureB.volumeDepth = (int)voxelResolution;
volumeTextureB.enableRandomWrite = true;
volumeTextureB.filterMode = FilterMode.Bilinear;
volumeTextureB.autoGenerateMips = false;
volumeTextureB.useMipMap = false;
volumeTextureB.Create();
volumeTextureB.hideFlags = HideFlags.HideAndDontSave;
if ((bool)secondaryIrradianceVolume)
{
secondaryIrradianceVolume.DiscardContents();
secondaryIrradianceVolume.Release();
UnityEngine.Object.DestroyImmediate(secondaryIrradianceVolume);
}
secondaryIrradianceVolume = new RenderTexture((int)voxelResolution, (int)voxelResolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
secondaryIrradianceVolume.isVolume = true;
secondaryIrradianceVolume.volumeDepth = (int)voxelResolution;
secondaryIrradianceVolume.enableRandomWrite = true;
secondaryIrradianceVolume.filterMode = FilterMode.Point;
secondaryIrradianceVolume.autoGenerateMips = false;
secondaryIrradianceVolume.useMipMap = false;
secondaryIrradianceVolume.antiAliasing = 1;
secondaryIrradianceVolume.Create();
secondaryIrradianceVolume.hideFlags = HideFlags.HideAndDontSave;
if ((bool)integerVolume)
{
integerVolume.DiscardContents();
integerVolume.Release();
UnityEngine.Object.DestroyImmediate(integerVolume);
}
integerVolume = new RenderTexture((int)voxelResolution, (int)voxelResolution, 0, RenderTextureFormat.RInt, RenderTextureReadWrite.Linear);
integerVolume.isVolume = true;
integerVolume.volumeDepth = (int)voxelResolution;
integerVolume.enableRandomWrite = true;
integerVolume.filterMode = FilterMode.Point;
integerVolume.Create();
integerVolume.hideFlags = HideFlags.HideAndDontSave;
ResizeDummyTexture();
}
private void ResizeDummyTexture()
{
if ((bool)dummyVoxelTextureAAScaled)
{
dummyVoxelTextureAAScaled.DiscardContents();
dummyVoxelTextureAAScaled.Release();
UnityEngine.Object.DestroyImmediate(dummyVoxelTextureAAScaled);
}
dummyVoxelTextureAAScaled = new RenderTexture(dummyVoxelResolution, dummyVoxelResolution, 0, RenderTextureFormat.R8);
dummyVoxelTextureAAScaled.Create();
dummyVoxelTextureAAScaled.hideFlags = HideFlags.HideAndDontSave;
if ((bool)dummyVoxelTextureFixed)
{
dummyVoxelTextureFixed.DiscardContents();
dummyVoxelTextureFixed.Release();
UnityEngine.Object.DestroyImmediate(dummyVoxelTextureFixed);
}
dummyVoxelTextureFixed = new RenderTexture((int)voxelResolution, (int)voxelResolution, 0, RenderTextureFormat.R8);
dummyVoxelTextureFixed.Create();
dummyVoxelTextureFixed.hideFlags = HideFlags.HideAndDontSave;
}
private void Init()
{
sunDepthShader = Shader.Find("Hidden/SEGIRenderSunDepth");
clearCompute = Resources.Load("SEGIClear") as ComputeShader;
transferIntsCompute = Resources.Load("SEGITransferInts") as ComputeShader;
mipFilterCompute = Resources.Load("SEGIMipFilter") as ComputeShader;
voxelizationShader = Shader.Find("Hidden/SEGIVoxelizeScene");
voxelTracingShader = Shader.Find("Hidden/SEGITraceScene");
material = new Material(Shader.Find("Hidden/SEGI"));
material.hideFlags = HideFlags.HideAndDontSave;
attachedCamera = GetComponent<Camera>();
attachedCamera.depthTextureMode |= DepthTextureMode.Depth;
attachedCamera.depthTextureMode |= DepthTextureMode.MotionVectors;
GameObject gameObject = GameObject.Find("SEGI_SHADOWCAM");
if (!gameObject)
{
shadowCamGameObject = new GameObject("SEGI_SHADOWCAM");
shadowCam = shadowCamGameObject.AddComponent<Camera>();
shadowCamGameObject.hideFlags = HideFlags.HideAndDontSave;
shadowCam.enabled = false;
shadowCam.depth = attachedCamera.depth - 1f;
shadowCam.orthographic = true;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.clearFlags = CameraClearFlags.Color;
shadowCam.backgroundColor = new Color(0f, 0f, 0f, 1f);
shadowCam.farClipPlane = shadowSpaceSize * 2f * shadowSpaceDepthRatio;
shadowCam.cullingMask = giCullingMask;
shadowCam.useOcclusionCulling = false;
shadowCamTransform = shadowCamGameObject.transform;
}
else
{
shadowCamGameObject = gameObject;
shadowCam = gameObject.GetComponent<Camera>();
shadowCamTransform = shadowCamGameObject.transform;
}
GameObject gameObject2 = GameObject.Find("SEGI_VOXEL_CAMERA");
if ((bool)gameObject2)
{
UnityEngine.Object.DestroyImmediate(gameObject2);
}
voxelCameraGO = new GameObject("SEGI_VOXEL_CAMERA");
voxelCameraGO.hideFlags = HideFlags.HideAndDontSave;
voxelCamera = voxelCameraGO.AddComponent<Camera>();
voxelCamera.enabled = false;
voxelCamera.orthographic = true;
voxelCamera.orthographicSize = voxelSpaceSize * 0.5f;
voxelCamera.nearClipPlane = 0f;
voxelCamera.farClipPlane = voxelSpaceSize;
voxelCamera.depth = -2f;
voxelCamera.renderingPath = RenderingPath.Forward;
voxelCamera.clearFlags = CameraClearFlags.Color;
voxelCamera.backgroundColor = Color.black;
voxelCamera.useOcclusionCulling = false;
GameObject gameObject3 = GameObject.Find("SEGI_LEFT_VOXEL_VIEW");
if ((bool)gameObject3)
{
UnityEngine.Object.DestroyImmediate(gameObject3);
}
leftViewPoint = new GameObject("SEGI_LEFT_VOXEL_VIEW");
leftViewPoint.hideFlags = HideFlags.HideAndDontSave;
GameObject gameObject4 = GameObject.Find("SEGI_TOP_VOXEL_VIEW");
if ((bool)gameObject4)
{
UnityEngine.Object.DestroyImmediate(gameObject4);
}
topViewPoint = new GameObject("SEGI_TOP_VOXEL_VIEW");
topViewPoint.hideFlags = HideFlags.HideAndDontSave;
blueNoise = null;
blueNoise = new Texture2D[64];
for (int i = 0; i < 64; i++)
{
string text = "LDR_RGBA_" + i;
Texture2D texture2D = Resources.Load("Noise Textures/" + text) as Texture2D;
if (texture2D == null)
{
Debug.LogWarning("Unable to find noise texture \"Assets/SEGI/Resources/Noise Textures/" + text + "\" for SEGI!");
}
blueNoise[i] = texture2D;
}
if ((bool)sunDepthTexture)
{
sunDepthTexture.DiscardContents();
sunDepthTexture.Release();
UnityEngine.Object.DestroyImmediate(sunDepthTexture);
}
sunDepthTexture = new RenderTexture(sunShadowResolution, sunShadowResolution, 16, RenderTextureFormat.RHalf, RenderTextureReadWrite.Linear);
sunDepthTexture.wrapMode = TextureWrapMode.Clamp;
sunDepthTexture.filterMode = FilterMode.Point;
sunDepthTexture.Create();
sunDepthTexture.hideFlags = HideFlags.HideAndDontSave;
CreateVolumeTextures();
initChecker = new object();
}
private void CheckSupport()
{
systemSupported.hdrTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf);
systemSupported.rIntTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RInt);
systemSupported.dx11 = SystemInfo.graphicsShaderLevel >= 50 && SystemInfo.supportsComputeShaders;
systemSupported.volumeTextures = SystemInfo.supports3DTextures;
systemSupported.postShader = material.shader.isSupported;
systemSupported.sunDepthShader = sunDepthShader.isSupported;
systemSupported.voxelizationShader = voxelizationShader.isSupported;
systemSupported.tracingShader = voxelTracingShader.isSupported;
if (!systemSupported.fullFunctionality)
{
Debug.LogWarning("SEGI is not supported on the current platform. Check for shader compile errors in SEGI/Resources");
base.enabled = false;
}
}
private void OnDrawGizmosSelected()
{
Color color = Gizmos.color;
Gizmos.color = new Color(1f, 0.25f, 0f, 0.5f);
Gizmos.DrawCube(voxelSpaceOrigin, new Vector3(voxelSpaceSize, voxelSpaceSize, voxelSpaceSize));
Gizmos.color = new Color(1f, 0f, 0f, 0.1f);
Gizmos.color = color;
}
private void CleanupTexture(ref RenderTexture texture)
{
texture.DiscardContents();
UnityEngine.Object.DestroyImmediate(texture);
}
private void CleanupTextures()
{
CleanupTexture(ref sunDepthTexture);
CleanupTexture(ref previousGIResult);
CleanupTexture(ref previousCameraDepth);
CleanupTexture(ref integerVolume);
for (int i = 0; i < volumeTextures.Length; i++)
{
CleanupTexture(ref volumeTextures[i]);
}
CleanupTexture(ref secondaryIrradianceVolume);
CleanupTexture(ref volumeTextureB);
CleanupTexture(ref dummyVoxelTextureAAScaled);
CleanupTexture(ref dummyVoxelTextureFixed);
}
private void Cleanup()
{
UnityEngine.Object.DestroyImmediate(material);
UnityEngine.Object.DestroyImmediate(voxelCameraGO);
UnityEngine.Object.DestroyImmediate(leftViewPoint);
UnityEngine.Object.DestroyImmediate(topViewPoint);
UnityEngine.Object.DestroyImmediate(shadowCamGameObject);
initChecker = null;
CleanupTextures();
}
private void OnEnable()
{
InitCheck();
ResizeRenderTextures();
CheckSupport();
}
private void OnDisable()
{
Cleanup();
}
private void ResizeRenderTextures()
{
if ((bool)previousGIResult)
{
previousGIResult.DiscardContents();
previousGIResult.Release();
UnityEngine.Object.DestroyImmediate(previousGIResult);
}
int width = ((attachedCamera.pixelWidth == 0) ? 2 : attachedCamera.pixelWidth);
int height = ((attachedCamera.pixelHeight == 0) ? 2 : attachedCamera.pixelHeight);
previousGIResult = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBHalf);
previousGIResult.wrapMode = TextureWrapMode.Clamp;
previousGIResult.filterMode = FilterMode.Bilinear;
previousGIResult.useMipMap = true;
previousGIResult.autoGenerateMips = false;
previousGIResult.Create();
previousGIResult.hideFlags = HideFlags.HideAndDontSave;
if ((bool)previousCameraDepth)
{
previousCameraDepth.DiscardContents();
previousCameraDepth.Release();
UnityEngine.Object.DestroyImmediate(previousCameraDepth);
}
previousCameraDepth = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
previousCameraDepth.wrapMode = TextureWrapMode.Clamp;
previousCameraDepth.filterMode = FilterMode.Bilinear;
previousCameraDepth.Create();
previousCameraDepth.hideFlags = HideFlags.HideAndDontSave;
}
private void ResizeSunShadowBuffer()
{
if ((bool)sunDepthTexture)
{
sunDepthTexture.DiscardContents();
sunDepthTexture.Release();
UnityEngine.Object.DestroyImmediate(sunDepthTexture);
}
sunDepthTexture = new RenderTexture(sunShadowResolution, sunShadowResolution, 16, RenderTextureFormat.RHalf, RenderTextureReadWrite.Linear);
sunDepthTexture.wrapMode = TextureWrapMode.Clamp;
sunDepthTexture.filterMode = FilterMode.Point;
sunDepthTexture.Create();
sunDepthTexture.hideFlags = HideFlags.HideAndDontSave;
}
private void Update()
{
if (notReadyToRender)
{
return;
}
if (previousGIResult == null)
{
ResizeRenderTextures();
}
if (previousGIResult.width != attachedCamera.pixelWidth || previousGIResult.height != attachedCamera.pixelHeight)
{
ResizeRenderTextures();
}
if (sunShadowResolution != prevSunShadowResolution)
{
ResizeSunShadowBuffer();
}
prevSunShadowResolution = sunShadowResolution;
if (volumeTextures[0].width != (int)voxelResolution)
{
if (voxelResolution == VoxelResolution.low)
{
numMipLevels = 5;
}
if (voxelResolution == VoxelResolution.high)
{
numMipLevels = 6;
}
CreateVolumeTextures();
}
if (dummyVoxelTextureAAScaled.width != dummyVoxelResolution)
{
ResizeDummyTexture();
}
}
private Matrix4x4 TransformViewMatrix(Matrix4x4 mat)
{
if (SystemInfo.usesReversedZBuffer)
{
mat[2, 0] = 0f - mat[2, 0];
mat[2, 1] = 0f - mat[2, 1];
mat[2, 2] = 0f - mat[2, 2];
mat[2, 3] = 0f - mat[2, 3];
}
return mat;
}
private void OnPreRender()
{
InitCheck();
if (notReadyToRender)
{
return;
}
updateGIcounter++;
if (!updateGI || (updateGIevery > 1 && updateGIcounter < updateGIevery && Time.fixedTime > 1f))
{
return;
}
updateGIcounter = 0;
RenderTexture active = RenderTexture.active;
Shader.SetGlobalInt("SEGIVoxelAA", voxelAA ? 1 : 0);
if (renderState == RenderState.Voxelize)
{
activeVolume = ((voxelFlipFlop == 0) ? volumeTextures[0] : volumeTextureB);
previousActiveVolume = ((voxelFlipFlop == 0) ? volumeTextureB : volumeTextures[0]);
float num = voxelSpaceSize / 8f;
Vector3 vector = ((!followTransform) ? (base.transform.position + base.transform.forward * voxelSpaceSize / 4f) : followTransform.position);
voxelSpaceOrigin = new Vector3(Mathf.Round(vector.x / num) * num, Mathf.Round(vector.y / num) * num, Mathf.Round(vector.z / num) * num);
voxelSpaceOriginDelta = voxelSpaceOrigin - previousVoxelSpaceOrigin;
Shader.SetGlobalVector("SEGIVoxelSpaceOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize);
previousVoxelSpaceOrigin = voxelSpaceOrigin;
voxelCamera.enabled = false;
voxelCamera.orthographic = true;
voxelCamera.orthographicSize = voxelSpaceSize * 0.5f;
voxelCamera.nearClipPlane = 0f;
voxelCamera.farClipPlane = voxelSpaceSize;
voxelCamera.depth = -2f;
voxelCamera.renderingPath = RenderingPath.Forward;
voxelCamera.clearFlags = CameraClearFlags.Color;
voxelCamera.backgroundColor = Color.black;
voxelCamera.cullingMask = giCullingMask;
voxelCameraGO.transform.position = voxelSpaceOrigin - Vector3.forward * voxelSpaceSize * 0.5f;
voxelCameraGO.transform.rotation = rotationFront;
leftViewPoint.transform.position = voxelSpaceOrigin + Vector3.left * voxelSpaceSize * 0.5f;
leftViewPoint.transform.rotation = rotationLeft;
topViewPoint.transform.position = voxelSpaceOrigin + Vector3.up * voxelSpaceSize * 0.5f;
topViewPoint.transform.rotation = rotationTop;
Shader.SetGlobalMatrix("WorldToCamera", attachedCamera.worldToCameraMatrix);
Shader.SetGlobalMatrix("SEGIVoxelViewFront", TransformViewMatrix(voxelCamera.transform.worldToLocalMatrix));
Shader.SetGlobalMatrix("SEGIVoxelViewLeft", TransformViewMatrix(leftViewPoint.transform.worldToLocalMatrix));
Shader.SetGlobalMatrix("SEGIVoxelViewTop", TransformViewMatrix(topViewPoint.transform.worldToLocalMatrix));
Shader.SetGlobalMatrix("SEGIWorldToVoxel", voxelCamera.worldToCameraMatrix);
Shader.SetGlobalMatrix("SEGIVoxelProjection", voxelCamera.projectionMatrix);
Shader.SetGlobalMatrix("SEGIVoxelProjectionInverse", voxelCamera.projectionMatrix.inverse);
Shader.SetGlobalInt("SEGIVoxelResolution", (int)voxelResolution);
Matrix4x4 value = shadowCam.projectionMatrix * shadowCam.worldToCameraMatrix * voxelCamera.cameraToWorldMatrix;
Shader.SetGlobalMatrix("SEGIVoxelToGIProjection", value);
Shader.SetGlobalVector("SEGISunlightVector", sun ? Vector3.Normalize(sun.transform.forward) : Vector3.up);
Shader.SetGlobalColor("GISunColor", (sun == null) ? Color.black : new Color(Mathf.Pow(sun.color.r, 2.2f), Mathf.Pow(sun.color.g, 2.2f), Mathf.Pow(sun.color.b, 2.2f), Mathf.Pow(sun.intensity, 2.2f)));
Shader.SetGlobalColor("SEGISkyColor", new Color(Mathf.Pow(skyColor.r * skyIntensity * 0.5f, 2.2f), Mathf.Pow(skyColor.g * skyIntensity * 0.5f, 2.2f), Mathf.Pow(skyColor.b * skyIntensity * 0.5f, 2.2f), Mathf.Pow(skyColor.a, 2.2f)));
Shader.SetGlobalFloat("GIGain", giGain);
Shader.SetGlobalFloat("SEGISecondaryBounceGain", infiniteBounces ? secondaryBounceGain : 0f);
Shader.SetGlobalFloat("SEGISoftSunlight", softSunlight);
Shader.SetGlobalInt("SEGISphericalSkylight", sphericalSkylight ? 1 : 0);
Shader.SetGlobalInt("SEGIInnerOcclusionLayers", innerOcclusionLayers);
if (sun != null)
{
shadowCam.cullingMask = giCullingMask;
Vector3 position = voxelSpaceOrigin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio;
shadowCamTransform.position = position;
shadowCamTransform.LookAt(voxelSpaceOrigin, Vector3.up);
shadowCam.renderingPath = RenderingPath.Forward;
shadowCam.depthTextureMode |= DepthTextureMode.None;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.farClipPlane = shadowSpaceSize * 2f * shadowSpaceDepthRatio;
Graphics.SetRenderTarget(sunDepthTexture);
shadowCam.SetTargetBuffers(sunDepthTexture.colorBuffer, sunDepthTexture.depthBuffer);
shadowCam.RenderWithShader(sunDepthShader, "");
Shader.SetGlobalTexture("SEGISunDepth", sunDepthTexture);
}
clearCompute.SetTexture(0, "RG0", integerVolume);
clearCompute.SetInt("Res", (int)voxelResolution);
clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureAAScaled;
voxelCamera.RenderWithShader(voxelizationShader, "");
Graphics.ClearRandomWriteTargets();
transferIntsCompute.SetTexture(0, "Result", activeVolume);
transferIntsCompute.SetTexture(0, "PrevResult", previousActiveVolume);
transferIntsCompute.SetTexture(0, "RG0", integerVolume);
transferIntsCompute.SetInt("VoxelAA", voxelAA ? 1 : 0);
transferIntsCompute.SetInt("Resolution", (int)voxelResolution);
transferIntsCompute.SetVector("VoxelOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize * (float)voxelResolution);
transferIntsCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
Shader.SetGlobalTexture("SEGIVolumeLevel0", activeVolume);
if (voxelResolution == VoxelResolution.low)
{
numMipLevels = 5;
}
if (voxelResolution == VoxelResolution.high)
{
numMipLevels = 6;
}
for (int i = 0; i < numMipLevels - 1; i++)
{
if (i + 1 < volumeTextures.Length)
{
RenderTexture texture = volumeTextures[i];
if (i == 0)
{
texture = activeVolume;
}
int num2 = (int)voxelResolution / Mathf.RoundToInt(Mathf.Pow(2f, (float)i + 1f));
mipFilterCompute.SetInt("destinationRes", num2);
mipFilterCompute.SetTexture(mipFilterKernel, "Source", texture);
mipFilterCompute.SetTexture(mipFilterKernel, "Destination", volumeTextures[i + 1]);
mipFilterCompute.Dispatch(mipFilterKernel, num2 / 8, num2 / 8, 1);
Shader.SetGlobalTexture("SEGIVolumeLevel" + (i + 1), volumeTextures[i + 1]);
}
}
voxelFlipFlop++;
voxelFlipFlop %= 2;
if (infiniteBounces)
{
renderState = RenderState.Bounce;
}
}
else if (renderState == RenderState.Bounce)
{
clearCompute.SetTexture(0, "RG0", integerVolume);
clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
Shader.SetGlobalInt("SEGISecondaryCones", secondaryCones);
Shader.SetGlobalFloat("SEGISecondaryOcclusionStrength", secondaryOcclusionStrength);
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureFixed;
voxelCamera.RenderWithShader(voxelTracingShader, "");
Graphics.ClearRandomWriteTargets();
transferIntsCompute.SetTexture(1, "Result", secondaryIrradianceVolume);
transferIntsCompute.SetTexture(1, "RG0", integerVolume);
transferIntsCompute.SetInt("Resolution", (int)voxelResolution);
transferIntsCompute.Dispatch(1, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
Shader.SetGlobalTexture("SEGIVolumeTexture1", secondaryIrradianceVolume);
renderState = RenderState.Voxelize;
}
RenderTexture.active = active;
}
[ImageEffectOpaque]
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (notReadyToRender)
{
Graphics.Blit(source, destination);
return;
}
Shader.SetGlobalFloat("SEGIVoxelScaleFactor", voxelScaleFactor);
material.SetMatrix("CameraToWorld", attachedCamera.cameraToWorldMatrix);
material.SetMatrix("WorldToCamera", attachedCamera.worldToCameraMatrix);
material.SetMatrix("ProjectionMatrixInverse", attachedCamera.projectionMatrix.inverse);
material.SetMatrix("ProjectionMatrix", attachedCamera.projectionMatrix);
material.SetInt("FrameSwitch", frameCounter);
Shader.SetGlobalInt("SEGIFrameSwitch", frameCounter);
material.SetVector("CameraPosition", base.transform.position);
material.SetFloat("DeltaTime", Time.deltaTime);
material.SetInt("StochasticSampling", stochasticSampling ? 1 : 0);
material.SetInt("TraceDirections", cones);
material.SetInt("TraceSteps", coneTraceSteps);
material.SetFloat("TraceLength", coneLength);
material.SetFloat("ConeSize", coneWidth);
material.SetFloat("OcclusionStrength", occlusionStrength);
material.SetFloat("OcclusionPower", occlusionPower);
material.SetFloat("ConeTraceBias", coneTraceBias);
material.SetFloat("GIGain", giGain);
material.SetFloat("NearLightGain", nearLightGain);
material.SetFloat("NearOcclusionStrength", nearOcclusionStrength);
material.SetInt("DoReflections", doReflections ? 1 : 0);
material.SetInt("HalfResolution", halfResolution ? 1 : 0);
material.SetInt("ReflectionSteps", reflectionSteps);
material.SetFloat("ReflectionOcclusionPower", reflectionOcclusionPower);
material.SetFloat("SkyReflectionIntensity", skyReflectionIntensity);
material.SetFloat("FarOcclusionStrength", farOcclusionStrength);
material.SetFloat("FarthestOcclusionStrength", farthestOcclusionStrength);
material.SetTexture("NoiseTexture", blueNoise[frameCounter % 64]);
material.SetFloat("BlendWeight", temporalBlendWeight);
if (visualizeVoxels)
{
Graphics.Blit(source, destination, material, Pass.VisualizeVoxels);
return;
}
RenderTexture temporary = RenderTexture.GetTemporary(source.width / giRenderRes, source.height / giRenderRes, 0, RenderTextureFormat.ARGBHalf);
RenderTexture temporary2 = RenderTexture.GetTemporary(source.width / giRenderRes, source.height / giRenderRes, 0, RenderTextureFormat.ARGBHalf);
RenderTexture renderTexture = null;
if (doReflections)
{
renderTexture = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
}
RenderTexture temporary3 = RenderTexture.GetTemporary(source.width / giRenderRes, source.height / giRenderRes, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
temporary3.filterMode = FilterMode.Point;
RenderTexture temporary4 = RenderTexture.GetTemporary(source.width / giRenderRes, source.height / giRenderRes, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
temporary4.filterMode = FilterMode.Point;
Graphics.Blit(source, temporary3, material, Pass.GetCameraDepthTexture);
material.SetTexture("CurrentDepth", temporary3);
Graphics.Blit(source, temporary4, material, Pass.GetWorldNormals);
material.SetTexture("CurrentNormal", temporary4);
material.SetTexture("PreviousGITexture", previousGIResult);
Shader.SetGlobalTexture("PreviousGITexture", previousGIResult);
material.SetTexture("PreviousDepth", previousCameraDepth);
Graphics.Blit(source, temporary2, material, Pass.DiffuseTrace);
if (doReflections)
{
Graphics.Blit(source, renderTexture, material, Pass.SpecularTrace);
material.SetTexture("Reflections", renderTexture);
}
if (useBilateralFiltering)
{
material.SetVector("Kernel", new Vector2(0f, 1f));
Graphics.Blit(temporary2, temporary, material, Pass.BilateralBlur);
material.SetVector("Kernel", new Vector2(1f, 0f));
Graphics.Blit(temporary, temporary2, material, Pass.BilateralBlur);
material.SetVector("Kernel", new Vector2(0f, 1f));
Graphics.Blit(temporary2, temporary, material, Pass.BilateralBlur);
material.SetVector("Kernel", new Vector2(1f, 0f));
Graphics.Blit(temporary, temporary2, material, Pass.BilateralBlur);
}
if (giRenderRes == 2)
{
RenderTexture.ReleaseTemporary(temporary);
RenderTexture temporary5 = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
RenderTexture temporary6 = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
temporary2.filterMode = FilterMode.Point;
Graphics.Blit(temporary2, temporary6);
RenderTexture.ReleaseTemporary(temporary2);
temporary6.filterMode = FilterMode.Point;
temporary5.filterMode = FilterMode.Point;
material.SetVector("Kernel", new Vector2(1f, 0f));
Graphics.Blit(temporary6, temporary5, material, Pass.BilateralUpsample);
material.SetVector("Kernel", new Vector2(0f, 1f));
if (temporalBlendWeight < 1f)
{
Graphics.Blit(temporary5, temporary6);
Graphics.Blit(temporary6, temporary5, material, Pass.TemporalBlend);
Graphics.Blit(temporary5, previousGIResult);
Graphics.Blit(source, previousCameraDepth, material, Pass.GetCameraDepthTexture);
}
material.SetTexture("GITexture", temporary5);
Graphics.Blit(source, destination, material, visualizeGI ? Pass.VisualizeGI : Pass.BlendWithScene);
RenderTexture.ReleaseTemporary(temporary5);
RenderTexture.ReleaseTemporary(temporary6);
}
else
{
if (temporalBlendWeight < 1f)
{
Graphics.Blit(temporary2, temporary, material, Pass.TemporalBlend);
Graphics.Blit(temporary, previousGIResult);
Graphics.Blit(source, previousCameraDepth, material, Pass.GetCameraDepthTexture);
}
material.SetTexture("GITexture", (temporalBlendWeight < 1f) ? temporary : temporary2);
Graphics.Blit(source, destination, material, visualizeGI ? Pass.VisualizeGI : Pass.BlendWithScene);
RenderTexture.ReleaseTemporary(temporary);
RenderTexture.ReleaseTemporary(temporary2);
}
RenderTexture.ReleaseTemporary(temporary3);
RenderTexture.ReleaseTemporary(temporary4);
if (visualizeSunDepthTexture)
{
Graphics.Blit(sunDepthTexture, destination);
}
if (doReflections)
{
RenderTexture.ReleaseTemporary(renderTexture);
}
material.SetMatrix("ProjectionPrev", attachedCamera.projectionMatrix);
material.SetMatrix("ProjectionPrevInverse", attachedCamera.projectionMatrix.inverse);
material.SetMatrix("WorldToCameraPrev", attachedCamera.worldToCameraMatrix);
material.SetMatrix("CameraToWorldPrev", attachedCamera.cameraToWorldMatrix);
material.SetVector("CameraPositionPrev", base.transform.position);
frameCounter = (frameCounter + 1) % 64;
}
}