1029 lines
34 KiB
C#
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;
|
|
}
|
|
}
|