1184 lines
40 KiB
C#
1184 lines
40 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using UnityEngine;
|
|
|
|
[ExecuteInEditMode]
|
|
[RequireComponent(typeof(Camera))]
|
|
[AddComponentMenu("Image Effects/Sonic Ether/SEGI (Cascaded)")]
|
|
public class SEGICascaded : MonoBehaviour
|
|
{
|
|
[Serializable]
|
|
public enum VoxelResolution
|
|
{
|
|
low = 0x40,
|
|
high = 0x80
|
|
}
|
|
|
|
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 class Clipmap
|
|
{
|
|
public Vector3 origin;
|
|
|
|
public Vector3 originDelta;
|
|
|
|
public Vector3 previousOrigin;
|
|
|
|
public float localScale;
|
|
|
|
public int resolution;
|
|
|
|
public RenderTexture volumeTexture0;
|
|
|
|
public FilterMode filterMode = FilterMode.Bilinear;
|
|
|
|
public RenderTextureFormat renderTextureFormat = RenderTextureFormat.ARGBHalf;
|
|
|
|
public void UpdateTextures()
|
|
{
|
|
if ((bool)volumeTexture0)
|
|
{
|
|
volumeTexture0.DiscardContents();
|
|
volumeTexture0.Release();
|
|
UnityEngine.Object.DestroyImmediate(volumeTexture0);
|
|
}
|
|
volumeTexture0 = new RenderTexture(resolution, resolution, 0, renderTextureFormat, RenderTextureReadWrite.Linear);
|
|
volumeTexture0.wrapMode = TextureWrapMode.Clamp;
|
|
volumeTexture0.isVolume = true;
|
|
volumeTexture0.volumeDepth = resolution;
|
|
volumeTexture0.enableRandomWrite = true;
|
|
volumeTexture0.filterMode = filterMode;
|
|
volumeTexture0.autoGenerateMips = false;
|
|
volumeTexture0.useMipMap = false;
|
|
volumeTexture0.Create();
|
|
volumeTexture0.hideFlags = HideFlags.HideAndDontSave;
|
|
}
|
|
|
|
public void CleanupTextures()
|
|
{
|
|
if ((bool)volumeTexture0)
|
|
{
|
|
volumeTexture0.DiscardContents();
|
|
volumeTexture0.Release();
|
|
UnityEngine.Object.DestroyImmediate(volumeTexture0);
|
|
}
|
|
}
|
|
}
|
|
|
|
private int updateGIcounter;
|
|
|
|
public int updateGIevery = 1;
|
|
|
|
public VoxelResolution voxelResolution = VoxelResolution.high;
|
|
|
|
public bool visualizeSunDepthTexture;
|
|
|
|
public bool visualizeGI;
|
|
|
|
public Light sun;
|
|
|
|
public LayerMask giCullingMask = int.MaxValue;
|
|
|
|
public float shadowSpaceSize = 50f;
|
|
|
|
[Range(0.01f, 1f)]
|
|
public float temporalBlendWeight = 0.1f;
|
|
|
|
public bool visualizeVoxels;
|
|
|
|
public bool updateGI = true;
|
|
|
|
public Color skyColor;
|
|
|
|
public float voxelSpaceSize = 25f;
|
|
|
|
public bool useBilateralFiltering;
|
|
|
|
[Range(0f, 2f)]
|
|
public int innerOcclusionLayers = 1;
|
|
|
|
public bool halfResolution;
|
|
|
|
public bool stochasticSampling = true;
|
|
|
|
public bool infiniteBounces;
|
|
|
|
public Transform followTransform;
|
|
|
|
[Range(1f, 128f)]
|
|
public int cones = 4;
|
|
|
|
[Range(1f, 32f)]
|
|
public int coneTraceSteps = 10;
|
|
|
|
[Range(0.1f, 2f)]
|
|
public float coneLength = 1f;
|
|
|
|
[Range(0.5f, 6f)]
|
|
public float coneWidth = 3.9f;
|
|
|
|
[Range(0f, 2f)]
|
|
public float occlusionStrength = 0.15f;
|
|
|
|
[Range(0f, 4f)]
|
|
public float nearOcclusionStrength = 0.5f;
|
|
|
|
[Range(0.001f, 4f)]
|
|
public float occlusionPower = 0.65f;
|
|
|
|
[Range(0f, 4f)]
|
|
public float coneTraceBias = 2.8f;
|
|
|
|
[Range(0f, 4f)]
|
|
public float nearLightGain = 0.36f;
|
|
|
|
[Range(0f, 4f)]
|
|
public float giGain = 1f;
|
|
|
|
[Range(0f, 4f)]
|
|
public float secondaryBounceGain = 0.9f;
|
|
|
|
[Range(0f, 16f)]
|
|
public float softSunlight;
|
|
|
|
[Range(0f, 8f)]
|
|
public float skyIntensity = 1f;
|
|
|
|
[Range(12f, 128f)]
|
|
public int reflectionSteps = 64;
|
|
|
|
[Range(0.001f, 4f)]
|
|
public float reflectionOcclusionPower = 1f;
|
|
|
|
[Range(0f, 1f)]
|
|
public float skyReflectionIntensity = 1f;
|
|
|
|
[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, 2f)]
|
|
public float secondaryOcclusionStrength = 0.27f;
|
|
|
|
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 = 128;
|
|
|
|
private int prevSunShadowResolution;
|
|
|
|
private Shader sunDepthShader;
|
|
|
|
private float shadowSpaceDepthRatio = 10f;
|
|
|
|
private int frameCounter;
|
|
|
|
private RenderTexture sunDepthTexture;
|
|
|
|
private RenderTexture previousGIResult;
|
|
|
|
private RenderTexture previousDepth;
|
|
|
|
private RenderTexture integerVolume;
|
|
|
|
private RenderTexture dummyVoxelTextureAAScaled;
|
|
|
|
private RenderTexture dummyVoxelTextureFixed;
|
|
|
|
private Clipmap[] clipmaps;
|
|
|
|
private Clipmap[] irradianceClipmaps;
|
|
|
|
private bool notReadyToRender;
|
|
|
|
private Shader voxelizationShader;
|
|
|
|
private Shader voxelTracingShader;
|
|
|
|
private ComputeShader clearCompute;
|
|
|
|
private ComputeShader transferIntsCompute;
|
|
|
|
private ComputeShader mipFilterCompute;
|
|
|
|
private const int numClipmaps = 6;
|
|
|
|
private int clipmapCounter;
|
|
|
|
private int currentClipmapIndex;
|
|
|
|
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 RenderState renderState;
|
|
|
|
public SystemSupported systemSupported;
|
|
|
|
public bool voxelAA;
|
|
|
|
[HideInInspector]
|
|
public bool doReflections
|
|
{
|
|
get
|
|
{
|
|
return false;
|
|
}
|
|
set
|
|
{
|
|
value = false;
|
|
}
|
|
}
|
|
|
|
private float voxelScaleFactor => (float)voxelResolution / 256f;
|
|
|
|
private int giRenderRes
|
|
{
|
|
get
|
|
{
|
|
if (!halfResolution)
|
|
{
|
|
return 1;
|
|
}
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
public float vramUsage
|
|
{
|
|
get
|
|
{
|
|
if (!base.enabled)
|
|
{
|
|
return 0f;
|
|
}
|
|
long num = 0L;
|
|
if (sunDepthTexture != null)
|
|
{
|
|
num += sunDepthTexture.width * sunDepthTexture.height * 16;
|
|
}
|
|
if (previousGIResult != null)
|
|
{
|
|
num += previousGIResult.width * previousGIResult.height * 16 * 4;
|
|
}
|
|
if (previousDepth != null)
|
|
{
|
|
num += previousDepth.width * previousDepth.height * 32;
|
|
}
|
|
if (integerVolume != null)
|
|
{
|
|
num += integerVolume.width * integerVolume.height * integerVolume.volumeDepth * 32;
|
|
}
|
|
if (dummyVoxelTextureAAScaled != null)
|
|
{
|
|
num += dummyVoxelTextureAAScaled.width * dummyVoxelTextureAAScaled.height * 8;
|
|
}
|
|
if (dummyVoxelTextureFixed != null)
|
|
{
|
|
num += dummyVoxelTextureFixed.width * dummyVoxelTextureFixed.height * 8;
|
|
}
|
|
if (clipmaps != null)
|
|
{
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
if (clipmaps[i] != null)
|
|
{
|
|
num += clipmaps[i].volumeTexture0.width * clipmaps[i].volumeTexture0.height * clipmaps[i].volumeTexture0.volumeDepth * 16 * 4;
|
|
}
|
|
}
|
|
}
|
|
return (float)num / 8388608f;
|
|
}
|
|
}
|
|
|
|
public bool gaussianMipFilter
|
|
{
|
|
get
|
|
{
|
|
return false;
|
|
}
|
|
set
|
|
{
|
|
value = false;
|
|
}
|
|
}
|
|
|
|
private int mipFilterKernel
|
|
{
|
|
get
|
|
{
|
|
if (!gaussianMipFilter)
|
|
{
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
private int dummyVoxelResolution => (int)voxelResolution * ((!voxelAA) ? 1 : 4);
|
|
|
|
public void ApplyPreset(SEGICascadedPreset 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();
|
|
}
|
|
|
|
private void InitCheck()
|
|
{
|
|
if (initChecker == null)
|
|
{
|
|
Init();
|
|
}
|
|
}
|
|
|
|
private void CreateVolumeTextures()
|
|
{
|
|
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 BuildClipmaps()
|
|
{
|
|
clipmaps = new Clipmap[6];
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
clipmaps[i] = new Clipmap();
|
|
clipmaps[i].localScale = Mathf.Pow(2f, i);
|
|
clipmaps[i].resolution = (int)voxelResolution;
|
|
clipmaps[i].filterMode = FilterMode.Bilinear;
|
|
clipmaps[i].renderTextureFormat = RenderTextureFormat.ARGBHalf;
|
|
clipmaps[i].UpdateTextures();
|
|
}
|
|
irradianceClipmaps = new Clipmap[6];
|
|
for (int j = 0; j < 6; j++)
|
|
{
|
|
irradianceClipmaps[j] = new Clipmap();
|
|
irradianceClipmaps[j].localScale = Mathf.Pow(2f, j);
|
|
irradianceClipmaps[j].resolution = (int)voxelResolution;
|
|
irradianceClipmaps[j].filterMode = FilterMode.Point;
|
|
irradianceClipmaps[j].renderTextureFormat = RenderTextureFormat.ARGBHalf;
|
|
irradianceClipmaps[j].UpdateTextures();
|
|
}
|
|
}
|
|
|
|
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 GetBlueNoiseTextures()
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
private void Init()
|
|
{
|
|
sunDepthShader = Shader.Find("Hidden/SEGIRenderSunDepth_C");
|
|
clearCompute = Resources.Load("SEGIClear_C") as ComputeShader;
|
|
transferIntsCompute = Resources.Load("SEGITransferInts_C") as ComputeShader;
|
|
mipFilterCompute = Resources.Load("SEGIMipFilter_C") as ComputeShader;
|
|
voxelizationShader = Shader.Find("Hidden/SEGIVoxelizeScene_C");
|
|
voxelTracingShader = Shader.Find("Hidden/SEGITraceScene_C");
|
|
material = new Material(Shader.Find("Hidden/SEGI_C"));
|
|
material.hideFlags = HideFlags.HideAndDontSave;
|
|
attachedCamera = GetComponent<Camera>();
|
|
attachedCamera.depthTextureMode |= DepthTextureMode.Depth;
|
|
attachedCamera.depthTextureMode |= DepthTextureMode.DepthNormals;
|
|
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;
|
|
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();
|
|
BuildClipmaps();
|
|
GetBlueNoiseTextures();
|
|
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()
|
|
{
|
|
if (base.enabled)
|
|
{
|
|
Color color = Gizmos.color;
|
|
Gizmos.color = new Color(1f, 0.25f, 0f, 0.5f);
|
|
float localScale = clipmaps[5].localScale;
|
|
Gizmos.DrawCube(clipmaps[0].origin, new Vector3(voxelSpaceSize * localScale, voxelSpaceSize * localScale, voxelSpaceSize * localScale));
|
|
Gizmos.color = new Color(1f, 0f, 0f, 0.1f);
|
|
Gizmos.color = color;
|
|
}
|
|
}
|
|
|
|
private void CleanupTexture(ref RenderTexture texture)
|
|
{
|
|
if ((bool)texture)
|
|
{
|
|
texture.DiscardContents();
|
|
texture.Release();
|
|
UnityEngine.Object.DestroyImmediate(texture);
|
|
}
|
|
}
|
|
|
|
private void CleanupTextures()
|
|
{
|
|
CleanupTexture(ref sunDepthTexture);
|
|
CleanupTexture(ref previousGIResult);
|
|
CleanupTexture(ref previousDepth);
|
|
CleanupTexture(ref integerVolume);
|
|
CleanupTexture(ref dummyVoxelTextureAAScaled);
|
|
CleanupTexture(ref dummyVoxelTextureFixed);
|
|
if (clipmaps == null)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
if (clipmaps[0] != null)
|
|
{
|
|
clipmaps[0].CleanupTextures();
|
|
}
|
|
}
|
|
}
|
|
|
|
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.Create();
|
|
previousGIResult.hideFlags = HideFlags.HideAndDontSave;
|
|
if ((bool)previousDepth)
|
|
{
|
|
previousDepth.DiscardContents();
|
|
previousDepth.Release();
|
|
UnityEngine.Object.DestroyImmediate(previousDepth);
|
|
}
|
|
previousDepth = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
|
|
previousDepth.wrapMode = TextureWrapMode.Clamp;
|
|
previousDepth.filterMode = FilterMode.Bilinear;
|
|
previousDepth.Create();
|
|
previousDepth.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)
|
|
{
|
|
if (previousGIResult == null)
|
|
{
|
|
ResizeRenderTextures();
|
|
}
|
|
if (previousGIResult.width != attachedCamera.pixelWidth || previousGIResult.height != attachedCamera.pixelHeight)
|
|
{
|
|
ResizeRenderTextures();
|
|
}
|
|
if (sunShadowResolution != prevSunShadowResolution)
|
|
{
|
|
ResizeSunShadowBuffer();
|
|
}
|
|
prevSunShadowResolution = sunShadowResolution;
|
|
if (clipmaps[0].resolution != (int)voxelResolution)
|
|
{
|
|
clipmaps[0].resolution = (int)voxelResolution;
|
|
clipmaps[0].UpdateTextures();
|
|
}
|
|
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 int SelectCascadeBinary(int c)
|
|
{
|
|
float num = (float)c + 0.01f;
|
|
int num2 = 0;
|
|
for (int i = 1; i < 6; i++)
|
|
{
|
|
float num3 = Mathf.Pow(2f, i);
|
|
num2 += Mathf.CeilToInt(num / num3 % 1f - (num3 - 1f) / num3);
|
|
}
|
|
return num2;
|
|
}
|
|
|
|
private void OnPreRender()
|
|
{
|
|
InitCheck();
|
|
if (notReadyToRender)
|
|
{
|
|
return;
|
|
}
|
|
updateGIcounter++;
|
|
if (!updateGI || (updateGIevery > 1 && updateGIcounter < updateGIevery))
|
|
{
|
|
return;
|
|
}
|
|
updateGIcounter = 0;
|
|
RenderTexture active = RenderTexture.active;
|
|
Shader.SetGlobalInt("SEGIVoxelAA", voxelAA ? 3 : 0);
|
|
LightShadows shadows = LightShadows.None;
|
|
if (sun != null)
|
|
{
|
|
shadows = sun.shadows;
|
|
sun.shadows = LightShadows.None;
|
|
}
|
|
if (renderState == RenderState.Voxelize)
|
|
{
|
|
currentClipmapIndex = SelectCascadeBinary(clipmapCounter);
|
|
Clipmap clipmap = clipmaps[currentClipmapIndex];
|
|
Clipmap clipmap2 = null;
|
|
if (currentClipmapIndex != 0)
|
|
{
|
|
clipmap2 = clipmaps[currentClipmapIndex - 1];
|
|
}
|
|
float num = voxelSpaceSize * clipmap.localScale;
|
|
float num2 = num / 8f;
|
|
Vector3 vector = ((!followTransform) ? (base.transform.position + base.transform.forward * num / 4f) : followTransform.position);
|
|
clipmap.previousOrigin = clipmap.origin;
|
|
clipmap.origin = new Vector3(Mathf.Round(vector.x / num2) * num2, Mathf.Round(vector.y / num2) * num2, Mathf.Round(vector.z / num2) * num2);
|
|
clipmap.originDelta = clipmap.origin - clipmap.previousOrigin;
|
|
Shader.SetGlobalVector("SEGIVoxelSpaceOriginDelta", clipmap.originDelta / (voxelSpaceSize * clipmap.localScale));
|
|
Vector3 vector2 = Vector3.zero;
|
|
float w = 0f;
|
|
if (currentClipmapIndex != 0)
|
|
{
|
|
vector2 = (clipmap2.origin - clipmap.origin) / num;
|
|
w = clipmap2.localScale / clipmap.localScale;
|
|
}
|
|
Shader.SetGlobalVector("SEGIClipmapOverlap", new Vector4(vector2.x, vector2.y, vector2.z, w));
|
|
for (int i = 1; i < 6; i++)
|
|
{
|
|
Vector3 zero = Vector3.zero;
|
|
float num3 = 1f;
|
|
zero = (clipmaps[i].origin - clipmaps[0].origin) / (voxelSpaceSize * clipmaps[i].localScale);
|
|
num3 = clipmaps[0].localScale / clipmaps[i].localScale;
|
|
Shader.SetGlobalVector("SEGIClipTransform" + i, new Vector4(zero.x, zero.y, zero.z, num3));
|
|
}
|
|
voxelCamera.enabled = false;
|
|
voxelCamera.orthographic = true;
|
|
voxelCamera.orthographicSize = num * 0.5f;
|
|
voxelCamera.nearClipPlane = 0f;
|
|
voxelCamera.farClipPlane = num;
|
|
voxelCamera.depth = -2f;
|
|
voxelCamera.renderingPath = RenderingPath.Forward;
|
|
voxelCamera.clearFlags = CameraClearFlags.Color;
|
|
voxelCamera.backgroundColor = Color.black;
|
|
voxelCamera.cullingMask = giCullingMask;
|
|
voxelCameraGO.transform.position = clipmap.origin - Vector3.forward * num * 0.5f;
|
|
voxelCameraGO.transform.rotation = rotationFront;
|
|
leftViewPoint.transform.position = clipmap.origin + Vector3.left * num * 0.5f;
|
|
leftViewPoint.transform.rotation = rotationLeft;
|
|
topViewPoint.transform.position = clipmap.origin + Vector3.up * num * 0.5f;
|
|
topViewPoint.transform.rotation = rotationTop;
|
|
Shader.SetGlobalMatrix("WorldToGI", shadowCam.worldToCameraMatrix);
|
|
Shader.SetGlobalMatrix("GIToWorld", shadowCam.cameraToWorldMatrix);
|
|
Shader.SetGlobalMatrix("GIProjection", shadowCam.projectionMatrix);
|
|
Shader.SetGlobalMatrix("GIProjectionInverse", shadowCam.projectionMatrix.inverse);
|
|
Shader.SetGlobalMatrix("WorldToCamera", attachedCamera.worldToCameraMatrix);
|
|
Shader.SetGlobalFloat("GIDepthRatio", shadowSpaceDepthRatio);
|
|
Matrix4x4 matrix4x = TransformViewMatrix(voxelCamera.transform.worldToLocalMatrix);
|
|
Matrix4x4 matrix4x2 = TransformViewMatrix(leftViewPoint.transform.worldToLocalMatrix);
|
|
Matrix4x4 matrix4x3 = TransformViewMatrix(topViewPoint.transform.worldToLocalMatrix);
|
|
Shader.SetGlobalMatrix("SEGIVoxelViewFront", matrix4x);
|
|
Shader.SetGlobalMatrix("SEGIVoxelViewLeft", matrix4x2);
|
|
Shader.SetGlobalMatrix("SEGIVoxelViewTop", matrix4x3);
|
|
Shader.SetGlobalMatrix("SEGIWorldToVoxel", voxelCamera.worldToCameraMatrix);
|
|
Shader.SetGlobalMatrix("SEGIVoxelProjection", voxelCamera.projectionMatrix);
|
|
Shader.SetGlobalMatrix("SEGIVoxelProjectionInverse", voxelCamera.projectionMatrix.inverse);
|
|
Shader.SetGlobalMatrix("SEGIVoxelVPFront", GL.GetGPUProjectionMatrix(voxelCamera.projectionMatrix, renderIntoTexture: true) * matrix4x);
|
|
Shader.SetGlobalMatrix("SEGIVoxelVPLeft", GL.GetGPUProjectionMatrix(voxelCamera.projectionMatrix, renderIntoTexture: true) * matrix4x2);
|
|
Shader.SetGlobalMatrix("SEGIVoxelVPTop", GL.GetGPUProjectionMatrix(voxelCamera.projectionMatrix, renderIntoTexture: true) * matrix4x3);
|
|
Shader.SetGlobalMatrix("SEGIWorldToVoxel" + currentClipmapIndex, voxelCamera.worldToCameraMatrix);
|
|
Shader.SetGlobalMatrix("SEGIVoxelProjection" + currentClipmapIndex, voxelCamera.projectionMatrix);
|
|
Matrix4x4 value = shadowCam.projectionMatrix * shadowCam.worldToCameraMatrix * voxelCamera.cameraToWorldMatrix;
|
|
Shader.SetGlobalMatrix("SEGIVoxelToGIProjection", value);
|
|
Shader.SetGlobalVector("SEGISunlightVector", sun ? Vector3.Normalize(sun.transform.forward) : Vector3.up);
|
|
Shader.SetGlobalInt("SEGIVoxelResolution", (int)voxelResolution);
|
|
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 = clipmap.origin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio;
|
|
shadowCamTransform.position = position;
|
|
shadowCamTransform.LookAt(clipmap.origin, 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", clipmap.resolution);
|
|
clearCompute.Dispatch(0, clipmap.resolution / 16, clipmap.resolution / 16, 1);
|
|
Shader.SetGlobalTexture("SEGICurrentIrradianceVolume", irradianceClipmaps[currentClipmapIndex].volumeTexture0);
|
|
Graphics.SetRandomWriteTarget(1, integerVolume);
|
|
voxelCamera.targetTexture = dummyVoxelTextureAAScaled;
|
|
voxelCamera.RenderWithShader(voxelizationShader, "");
|
|
Graphics.ClearRandomWriteTargets();
|
|
transferIntsCompute.SetTexture(0, "Result", clipmap.volumeTexture0);
|
|
transferIntsCompute.SetTexture(0, "RG0", integerVolume);
|
|
transferIntsCompute.SetInt("VoxelAA", voxelAA ? 3 : 0);
|
|
transferIntsCompute.SetInt("Resolution", clipmap.resolution);
|
|
transferIntsCompute.Dispatch(0, clipmap.resolution / 16, clipmap.resolution / 16, 1);
|
|
for (int j = 1; j < 6; j++)
|
|
{
|
|
Clipmap clipmap3 = clipmaps[j - 1];
|
|
Clipmap clipmap4 = clipmaps[j];
|
|
Vector3 zero2 = Vector3.zero;
|
|
float num4 = 0f;
|
|
zero2 = (clipmap3.origin - clipmap4.origin) / (clipmap4.localScale * voxelSpaceSize);
|
|
num4 = clipmap3.localScale / clipmap4.localScale;
|
|
mipFilterCompute.SetTexture(0, "Source", clipmap3.volumeTexture0);
|
|
mipFilterCompute.SetTexture(0, "Destination", clipmap4.volumeTexture0);
|
|
mipFilterCompute.SetVector("ClipmapOverlap", new Vector4(zero2.x, zero2.y, zero2.z, num4));
|
|
mipFilterCompute.SetInt("destinationRes", clipmap4.resolution);
|
|
mipFilterCompute.Dispatch(0, clipmap4.resolution / 16, clipmap4.resolution / 16, 1);
|
|
}
|
|
for (int k = 0; k < 6; k++)
|
|
{
|
|
Shader.SetGlobalTexture("SEGIVolumeLevel" + k, clipmaps[k].volumeTexture0);
|
|
}
|
|
if (infiniteBounces)
|
|
{
|
|
renderState = RenderState.Bounce;
|
|
}
|
|
else
|
|
{
|
|
clipmapCounter++;
|
|
if (clipmapCounter >= (int)Mathf.Pow(2f, 6f))
|
|
{
|
|
clipmapCounter = 0;
|
|
}
|
|
}
|
|
}
|
|
else if (renderState == RenderState.Bounce)
|
|
{
|
|
Vector3 zero3 = Vector3.zero;
|
|
zero3 = (clipmaps[currentClipmapIndex].origin - clipmaps[0].origin) / (voxelSpaceSize * clipmaps[currentClipmapIndex].localScale);
|
|
float w2 = 1f / clipmaps[currentClipmapIndex].localScale;
|
|
Shader.SetGlobalVector("SEGICurrentClipTransform", new Vector4(zero3.x, zero3.y, zero3.z, w2));
|
|
clearCompute.SetTexture(0, "RG0", integerVolume);
|
|
clearCompute.SetInt("Res", clipmaps[currentClipmapIndex].resolution);
|
|
clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
|
|
if (currentClipmapIndex <= 2)
|
|
{
|
|
Shader.SetGlobalInt("SEGISecondaryCones", secondaryCones);
|
|
Shader.SetGlobalFloat("SEGISecondaryOcclusionStrength", secondaryOcclusionStrength);
|
|
Graphics.SetRandomWriteTarget(1, integerVolume);
|
|
voxelCamera.targetTexture = dummyVoxelTextureFixed;
|
|
voxelCamera.RenderWithShader(voxelTracingShader, "");
|
|
Graphics.ClearRandomWriteTargets();
|
|
transferIntsCompute.SetTexture(1, "Result", irradianceClipmaps[currentClipmapIndex].volumeTexture0);
|
|
transferIntsCompute.SetTexture(1, "RG0", integerVolume);
|
|
transferIntsCompute.SetInt("Resolution", (int)voxelResolution);
|
|
transferIntsCompute.Dispatch(1, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
|
|
}
|
|
clipmapCounter++;
|
|
if (clipmapCounter >= (int)Mathf.Pow(2f, 6f))
|
|
{
|
|
clipmapCounter = 0;
|
|
}
|
|
renderState = RenderState.Voxelize;
|
|
}
|
|
Matrix4x4 value2 = voxelCamera.projectionMatrix * voxelCamera.worldToCameraMatrix * shadowCam.cameraToWorldMatrix;
|
|
Shader.SetGlobalMatrix("GIToVoxelProjection", value2);
|
|
RenderTexture.active = active;
|
|
if (sun != null)
|
|
{
|
|
sun.shadows = shadows;
|
|
}
|
|
}
|
|
|
|
[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]);
|
|
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", previousDepth);
|
|
Graphics.Blit(source, temporary2, material, Pass.DiffuseTrace);
|
|
if (doReflections)
|
|
{
|
|
Graphics.Blit(source, renderTexture, material, Pass.SpecularTrace);
|
|
material.SetTexture("Reflections", renderTexture);
|
|
}
|
|
if (useBilateralFiltering && temporalBlendWeight >= 0.99999f)
|
|
{
|
|
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));
|
|
RenderTexture temporary7 = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
|
|
RenderTexture temporary8 = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
|
|
material.SetVector("Kernel", new Vector2(0f, 1f));
|
|
Graphics.Blit(temporary5, temporary8, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(1f, 0f));
|
|
Graphics.Blit(temporary8, temporary7, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(0f, 2f));
|
|
Graphics.Blit(temporary7, temporary8, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(2f, 0f));
|
|
Graphics.Blit(temporary8, temporary7, material, Pass.BilateralBlur);
|
|
material.SetTexture("BlurredGI", temporary7);
|
|
if (temporalBlendWeight < 1f)
|
|
{
|
|
Graphics.Blit(temporary5, temporary6);
|
|
Graphics.Blit(temporary6, temporary5, material, Pass.TemporalBlend);
|
|
Graphics.Blit(temporary5, previousGIResult);
|
|
Graphics.Blit(source, previousDepth, material, Pass.GetCameraDepthTexture);
|
|
if (useBilateralFiltering)
|
|
{
|
|
material.SetVector("Kernel", new Vector2(0f, 1f));
|
|
Graphics.Blit(temporary5, temporary6, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(1f, 0f));
|
|
Graphics.Blit(temporary6, temporary5, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(0f, 1f));
|
|
Graphics.Blit(temporary5, temporary6, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(1f, 0f));
|
|
Graphics.Blit(temporary6, temporary5, material, Pass.BilateralBlur);
|
|
}
|
|
}
|
|
material.SetTexture("GITexture", temporary5);
|
|
Graphics.Blit(source, destination, material, visualizeGI ? Pass.VisualizeGI : Pass.BlendWithScene);
|
|
RenderTexture.ReleaseTemporary(temporary7);
|
|
RenderTexture.ReleaseTemporary(temporary8);
|
|
RenderTexture.ReleaseTemporary(temporary5);
|
|
RenderTexture.ReleaseTemporary(temporary6);
|
|
}
|
|
else
|
|
{
|
|
if (temporalBlendWeight < 1f)
|
|
{
|
|
RenderTexture temporary9 = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
|
|
RenderTexture temporary10 = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
|
|
material.SetVector("Kernel", new Vector2(0f, 1f));
|
|
Graphics.Blit(temporary2, temporary10, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(1f, 0f));
|
|
Graphics.Blit(temporary10, temporary9, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(0f, 2f));
|
|
Graphics.Blit(temporary9, temporary10, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(2f, 0f));
|
|
Graphics.Blit(temporary10, temporary9, material, Pass.BilateralBlur);
|
|
material.SetTexture("BlurredGI", temporary9);
|
|
Graphics.Blit(temporary2, temporary, material, Pass.TemporalBlend);
|
|
Graphics.Blit(temporary, previousGIResult);
|
|
Graphics.Blit(source, previousDepth, material, Pass.GetCameraDepthTexture);
|
|
if (useBilateralFiltering)
|
|
{
|
|
material.SetVector("Kernel", new Vector2(0f, 1f));
|
|
Graphics.Blit(temporary, temporary2, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(1f, 0f));
|
|
Graphics.Blit(temporary2, temporary, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(0f, 1f));
|
|
Graphics.Blit(temporary, temporary2, material, Pass.BilateralBlur);
|
|
material.SetVector("Kernel", new Vector2(1f, 0f));
|
|
Graphics.Blit(temporary2, temporary, material, Pass.BilateralBlur);
|
|
}
|
|
RenderTexture.ReleaseTemporary(temporary9);
|
|
RenderTexture.ReleaseTemporary(temporary10);
|
|
}
|
|
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;
|
|
}
|
|
}
|