Net.Like.Xue.Tokyo/Assets/ARTnGAME/Lumina/Scripts/LUMINA_FAR.cs

2849 lines
123 KiB
C#
Raw Normal View History

2025-02-26 15:34:59 +08:00
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
// v0.3
using System.Reflection;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Artngame.LUMINA
{
[ExecuteInEditMode]
//#if UNITY_5_4_OR_NEWER
// [ImageEffectAllowedInSceneView]
//#endif
[RequireComponent(typeof(Camera))]
public class LUMINA_FAR : MonoBehaviour
{
//v1.6
public bool renderSunWithSRP = false; //use Standard pipeline to render sun depth texture
public Vector3 cutoff = new Vector3(1, 1, 0);
//v1.5
public bool enableLocalLightGI = false;
public float shadowedLocalPower = 0;
public float shadowlessLocalPower = 0;
public float shadowlessLocalOcclusion = 0;
//v1.3
public bool proxyNoGeom = false;
//v1.2
public float smoothNormals = 0;
//v0.4
public bool disableGI = false;
public float contrastA = 0;
public Vector4 ReflectControl = new Vector4(1, 1, 0, 0);
//v0.7
public Vector4 DitherControl = new Vector4(0, 1, 1, 1);
//v0.3
public bool setupForwardRendererLUMINA = false;
public bool setupForwardRendererHELPER = false;
public int helperRendererID = 1;//2ond renderer in the pipeline, with render objects renderer feature with preRenderers override material
//v0.2
public bool colorizeVolume = true;
public bool updatePerDistance = false;
public bool updatePerTime = false;
public float updateTime = 1;
public float updateDistance = 10;
float lastUpdateTime = 0;
Vector3 lastUpdatePos = Vector3.zero;
Vector3 lastTransformPos = Vector3.zero;
public bool clearBounceCameraTarget = false;
//v0.1
public Material preRenderers;//feed the material to renderer feature
public Material debugSceneColorMat;
#region Parameters
[Serializable]
public enum VoxelResolution
{
low = 128,
high = 256,
insane = 512
}
public bool updateGI = true;
public LayerMask giCullingMask = 2147483647;
public float shadowSpaceSize = 50.0f;
public Light sun;
public Color skyColor;
public float voxelSpaceSize = 25.0f;
public bool useBilateralFiltering = false;
[Range(0, 2)]
public int innerOcclusionLayers = 1;
[Range(0.01f, 1.0f)]
public float temporalBlendWeight = 0.1f;
public Artngame.LUMINA.LUMINA.VoxelResolution voxelResolution = Artngame.LUMINA.LUMINA.VoxelResolution.high;
public bool visualizeSunDepthTexture = false;
public bool visualizeGI = false;
public bool visualizeVoxels = false;
public bool visualizeDEPTH = false;
public bool visualizeNORMALS = false;
public bool halfResolution = true;
public bool stochasticSampling = true;
public bool infiniteBounces = false;
public Transform followTransform;
[Range(1, 128)]
public int cones = 6;
[Range(1, 32)]
public int coneTraceSteps = 14;
[Range(0.1f, 2.0f)]
public float coneLength = 1.0f;
[Range(0.5f, 6.0f)]
public float coneWidth = 5.5f;
[Range(0.0f, 4.0f)]
public float occlusionStrength = 1.0f;
[Range(0.0f, 4.0f)]
public float nearOcclusionStrength = 0.5f;
[Range(0.001f, 4.0f)]
public float occlusionPower = 1.5f;
[Range(0.0f, 4.0f)]
public float coneTraceBias = 1.0f;
[Range(0.0f, 14.0f)]
public float nearLightGain = 1.0f;
[Range(0.0f, 14.0f)]
public float giGain = 1.0f;
[Range(0.0f, 14.0f)]
public float secondaryBounceGain = 1.0f;
[Range(0.0f, 16.0f)]
public float softSunlight = 0.0f;
[Range(0.0f, 8.0f)]
public float skyIntensity = 1.0f;
public bool doReflections = true;
[Range(12, 128)]
public int reflectionSteps = 64;
[Range(0.001f, 4.0f)]
public float reflectionOcclusionPower = 1.0f;
[Range(0.0f, 1.0f)]
public float skyReflectionIntensity = 1.0f;
public bool voxelAA = false;
public bool gaussianMipFilter = false;
[Range(0.1f, 4.0f)]
public float farOcclusionStrength = 1.0f;
[Range(0.1f, 4.0f)]
public float farthestOcclusionStrength = 1.0f;
[Range(3, 16)]
public int secondaryCones = 6;
[Range(0.1f, 4.0f)]
public float secondaryOcclusionStrength = 1.0f;
public bool sphericalSkylight = false;
#endregion
#region InternalVariables
public object initChecker;
public bool initChecker2;//v0.2
public Material material;
public Camera attachedCamera;
public Transform shadowCamTransform;
public Camera shadowCam;
public GameObject shadowCamGameObject;
public Texture2D[] blueNoise;
public int sunShadowResolution = 256;
public int prevSunShadowResolution;
public Shader sunDepthShader;
public float shadowSpaceDepthRatio = 10.0f;
public int frameCounter = 0;
public RenderTexture sunDepthTexture;
public RenderTexture previousGIResult;
public RenderTexture previousCameraDepth;
///<summary>This is a volume texture that is immediately written to in the voxelization shader. The RInt format enables atomic writes to avoid issues where multiple fragments are trying to write to the same voxel in the volume.</summary>
public RenderTexture integerVolume;
///<summary>An array of volume textures where each element is a mip/LOD level. Each volume is half the resolution of the previous volume. Separate textures for each mip level are required for manual mip-mapping of the main GI volume texture.</summary>
public RenderTexture[] volumeTextures;
///<summary>The secondary volume texture that holds irradiance calculated during the in-volume GI tracing that occurs when Infinite Bounces is enabled. </summary>
public RenderTexture secondaryIrradianceVolume;
///<summary>The alternate mip level 0 main volume texture needed to avoid simultaneous read/write errors while performing temporal stabilization on the main voxel volume.</summary>
public RenderTexture volumeTextureB;
///<summary>The current active volume texture that holds GI information to be read during GI tracing.</summary>
public RenderTexture activeVolume;
///<summary>The volume texture that holds GI information to be read during GI tracing that was used in the previous frame.</summary>
public RenderTexture previousActiveVolume;
///<summary>A 2D texture with the size of [voxel resolution, voxel resolution] that must be used as the active render texture when rendering the scene for voxelization. This texture scales depending on whether Voxel AA is enabled to ensure correct voxelization.</summary>
public RenderTexture dummyVoxelTextureAAScaled;
///<summary>A 2D texture with the size of [voxel resolution, voxel resolution] that must be used as the active render texture when rendering the scene for voxelization. This texture is always the same size whether Voxel AA is enabled or not.</summary>
public RenderTexture dummyVoxelTextureFixed;
public bool notReadyToRender = false;
public Shader voxelizationShader;
public Shader voxelTracingShader;
//v1.3
public Shader voxelizationShaderVERT;
public Shader voxelTracingShaderVERT;
//v1.5
public Shader voxelizationShaderL;
public Shader voxelizationShaderVERTL;
public ComputeShader clearCompute;
public ComputeShader transferIntsCompute;
public ComputeShader mipFilterCompute;
// public const int numMipLevels = 6;
public int numMipLevels = 6;
public Camera voxelCamera;
public GameObject voxelCameraGO;
public GameObject leftViewPoint;
public GameObject topViewPoint;
public float voxelScaleFactor
{
get
{
return (float)voxelResolution / 256.0f;
}
}
public Vector3 voxelSpaceOrigin;
public Vector3 previousVoxelSpaceOrigin;
public Vector3 voxelSpaceOriginDelta;
public Quaternion rotationFront = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
public Quaternion rotationLeft = new Quaternion(0.0f, 0.7f, 0.0f, 0.7f);
public Quaternion rotationTop = new Quaternion(0.7f, 0.0f, 0.0f, 0.7f);
public int voxelFlipFlop = 0;
public enum RenderState
{
Voxelize,
Bounce
}
public RenderState renderState = RenderState.Voxelize;
#endregion
#region SupportingObjectsAndProperties
public 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;
//v1.3
public bool voxelizationShaderVERT;
public bool tracingShaderVERT;
//v1.5
public bool voxelizationShaderL;
public bool voxelizationShaderVERTL;
public bool fullFunctionality
{
get
{
return hdrTextures && rIntTextures && dx11 && volumeTextures && postShader && sunDepthShader && voxelizationShader && tracingShader
&& voxelizationShaderVERT && tracingShaderVERT && voxelizationShaderVERTL && voxelizationShaderL;
}
}
}
/// <summary>
/// Contains info on system compatibility of required hardware functionality
/// </summary>
public SystemSupported systemSupported;
/// <summary>
/// Estimates the VRAM usage of all the render textures used to render GI.
/// </summary>
public float vramUsage
{
get
{
long v = 0;
if (sunDepthTexture != null)
v += sunDepthTexture.width * sunDepthTexture.height * 16;
if (previousGIResult != null)
v += previousGIResult.width * previousGIResult.height * 16 * 4;
if (previousCameraDepth != null)
v += previousCameraDepth.width * previousCameraDepth.height * 32;
if (integerVolume != null)
v += integerVolume.width * integerVolume.height * integerVolume.volumeDepth * 32;
if (volumeTextures != null)
{
for (int i = 0; i < volumeTextures.Length; i++)
{
if (volumeTextures[i] != null)
v += volumeTextures[i].width * volumeTextures[i].height * volumeTextures[i].volumeDepth * 16 * 4;
}
}
if (secondaryIrradianceVolume != null)
v += secondaryIrradianceVolume.width * secondaryIrradianceVolume.height * secondaryIrradianceVolume.volumeDepth * 16 * 4;
if (volumeTextureB != null)
v += volumeTextureB.width * volumeTextureB.height * volumeTextureB.volumeDepth * 16 * 4;
if (dummyVoxelTextureAAScaled != null)
v += dummyVoxelTextureAAScaled.width * dummyVoxelTextureAAScaled.height * 8;
if (dummyVoxelTextureFixed != null)
v += dummyVoxelTextureFixed.width * dummyVoxelTextureFixed.height * 8;
float vram = (v / 8388608.0f);
return vram;
}
}
public int mipFilterKernel
{
get
{
return gaussianMipFilter ? 1 : 0;
}
}
//v0.8
public int downscaleFactor = 2;
public int dummyVoxelResolution
{
get
{
return (int)voxelResolution * (voxelAA ? 2 : 1);
}
}
public int giRenderRes
{
get
{
return halfResolution ? downscaleFactor : 1;// return halfResolution ? 2 : 1;
}
}
#endregion
///<summary>Applies an SEGIPreset to this instance of SEGI.</summary>
public void ApplyPreset(LUMINAPreset 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;
//v0.6
contrastA = preset.contrastA;
ReflectControl = preset.ReflectControl;
//v0.7
DitherControl = preset.DitherControl;
//v.2
smoothNormals = preset.smoothNormals;
//v1.3
proxyNoGeom = preset.proxyNoGeom;
//v1.5
enableLocalLightGI = preset.enableLocalLightGI;
shadowedLocalPower = preset.shadowedLocalPower;
shadowlessLocalPower = preset.shadowlessLocalPower;
shadowlessLocalOcclusion = preset.shadowlessLocalOcclusion;
//v1.6
cutoff = preset.cutoff;
}
void Start()
{
InitCheck();
}
public void InitCheck()
{
if (initChecker == null)
{
if (!initChecker2)//v0.2
{
CleanupTextures();//v0.2
Init();
}
}
}
//v0.2a
bool createdVolumeTexturesPlayMode = false;
void CreateVolumeTextures()
{
if (volumeTextures != null)
{
for (int i = 0; i < numMipLevels; i++)
{
if (volumeTextures[i] != null)
{
volumeTextures[i].DiscardContents();
volumeTextures[i].Release();
DestroyImmediate(volumeTextures[i]);
}
}
}
volumeTextures = new RenderTexture[numMipLevels];
for (int i = 0; i < numMipLevels; i++)
{
int resolution = (int)voxelResolution / Mathf.RoundToInt(Mathf.Pow((float)2, (float)i));
volumeTextures[i] = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
#if UNITY_5_4_OR_NEWER
volumeTextures[i].dimension = TextureDimension.Tex3D;
#else
volumeTextures[i].isVolume = true;
#endif
volumeTextures[i].volumeDepth = resolution;
volumeTextures[i].enableRandomWrite = true;
volumeTextures[i].filterMode = FilterMode.Bilinear;
#if UNITY_5_4_OR_NEWER
volumeTextures[i].autoGenerateMips = false;
#else
volumeTextures[i].generateMips = false;
#endif
volumeTextures[i].useMipMap = false;
volumeTextures[i].Create();
volumeTextures[i].hideFlags = HideFlags.HideAndDontSave;
}
if (volumeTextureB)
{
volumeTextureB.DiscardContents();
volumeTextureB.Release();
DestroyImmediate(volumeTextureB);
}
volumeTextureB = new RenderTexture((int)voxelResolution, (int)voxelResolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
#if UNITY_5_4_OR_NEWER
volumeTextureB.dimension = TextureDimension.Tex3D;
#else
volumeTextureB.isVolume = true;
#endif
volumeTextureB.volumeDepth = (int)voxelResolution;
volumeTextureB.enableRandomWrite = true;
volumeTextureB.filterMode = FilterMode.Bilinear;
#if UNITY_5_4_OR_NEWER
volumeTextureB.autoGenerateMips = false;
#else
volumeTextureB.generateMips = false;
#endif
volumeTextureB.useMipMap = false;
volumeTextureB.Create();
volumeTextureB.hideFlags = HideFlags.HideAndDontSave;
if (secondaryIrradianceVolume)
{
secondaryIrradianceVolume.DiscardContents();
secondaryIrradianceVolume.Release();
DestroyImmediate(secondaryIrradianceVolume);
}
secondaryIrradianceVolume = new RenderTexture((int)voxelResolution, (int)voxelResolution, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
#if UNITY_5_4_OR_NEWER
secondaryIrradianceVolume.dimension = TextureDimension.Tex3D;
#else
secondaryIrradianceVolume.isVolume = true;
#endif
secondaryIrradianceVolume.volumeDepth = (int)voxelResolution;
secondaryIrradianceVolume.enableRandomWrite = true;
secondaryIrradianceVolume.filterMode = FilterMode.Point;
#if UNITY_5_4_OR_NEWER
secondaryIrradianceVolume.autoGenerateMips = false;
#else
secondaryIrradianceVolume.generateMips = false;
#endif
secondaryIrradianceVolume.useMipMap = false;
secondaryIrradianceVolume.antiAliasing = 1;
secondaryIrradianceVolume.Create();
secondaryIrradianceVolume.hideFlags = HideFlags.HideAndDontSave;
if (integerVolume)
{
integerVolume.DiscardContents();
integerVolume.Release();
DestroyImmediate(integerVolume);
}
integerVolume = new RenderTexture((int)voxelResolution, (int)voxelResolution, 0, RenderTextureFormat.RInt, RenderTextureReadWrite.Linear);
#if UNITY_5_4_OR_NEWER
integerVolume.dimension = TextureDimension.Tex3D;
#else
integerVolume.isVolume = true;
#endif
integerVolume.volumeDepth = (int)voxelResolution;
integerVolume.enableRandomWrite = true;
integerVolume.filterMode = FilterMode.Point;
integerVolume.Create();
integerVolume.hideFlags = HideFlags.HideAndDontSave;
//v0.1
integerVolume.depth = 0;
ResizeDummyTexture();
}
void ResizeDummyTexture()
{
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
//Debug.Log("No cam3b");
return;
}
if (dummyVoxelTextureAAScaled)
{
dummyVoxelTextureAAScaled.DiscardContents();
dummyVoxelTextureAAScaled.Release();
DestroyImmediate(dummyVoxelTextureAAScaled);
}
dummyVoxelTextureAAScaled = new RenderTexture(dummyVoxelResolution, dummyVoxelResolution, 0, RenderTextureFormat.RInt);
dummyVoxelTextureAAScaled.Create();
dummyVoxelTextureAAScaled.hideFlags = HideFlags.HideAndDontSave;
if (dummyVoxelTextureFixed)
{
dummyVoxelTextureFixed.DiscardContents();
dummyVoxelTextureFixed.Release();
DestroyImmediate(dummyVoxelTextureFixed);
}
dummyVoxelTextureFixed = new RenderTexture((int)voxelResolution, (int)voxelResolution, 0, RenderTextureFormat.RInt);
dummyVoxelTextureFixed.Create();
dummyVoxelTextureFixed.hideFlags = HideFlags.HideAndDontSave;
}
void Init()
{
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
// Debug.Log("No cam3c");
return;
}
//Setup shaders and materials
sunDepthShader = Shader.Find("SEGI/SEGIRenderSunDepth");
clearCompute = Resources.Load("SEGIClear") as ComputeShader;
transferIntsCompute = Resources.Load("SEGITransferInts") as ComputeShader;
mipFilterCompute = Resources.Load("SEGIMipFilter") as ComputeShader;
voxelizationShader = Shader.Find("SEGI/SEGIVoxelizeScene_FAR");
voxelTracingShader = Shader.Find("SEGI/SEGITraceScene_FAR");
//v1.3
voxelizationShaderVERT = Shader.Find("SEGI/SEGIVoxelizeSceneVERT");
voxelTracingShaderVERT = Shader.Find("SEGI/SEGITraceSceneVERT");
//v1.5
voxelizationShaderL = Shader.Find("SEGI/SEGIVoxelizeSceneL");
voxelizationShaderVERTL = Shader.Find("SEGI/SEGIVoxelizeSceneVERTL");
if (!material)
{
material = new Material(Shader.Find("Hidden/SEGI_FAR"));
//material.hideFlags = HideFlags.HideAndDontSave;//v0.2
}
//Get the camera attached to this game object
attachedCamera = this.GetComponent<Camera>();
attachedCamera.depthTextureMode |= DepthTextureMode.Depth;
#if UNITY_5_4_OR_NEWER
attachedCamera.depthTextureMode |= DepthTextureMode.MotionVectors;
#endif
//Find the proxy shadow rendering camera if it exists
GameObject scgo = GameObject.Find("SEGI_SHADOWCAM");
//If not, create it
if (!scgo)
{
shadowCamGameObject = new GameObject("SEGI_SHADOWCAM");
shadowCam = shadowCamGameObject.AddComponent<Camera>();
// shadowCamGameObject.hideFlags = HideFlags.HideAndDontSave;//v0.2
shadowCamGameObject.hideFlags = HideFlags.HideInHierarchy;//v0.2a
shadowCam.enabled = false;//true;//= false;
shadowCam.depth = attachedCamera.depth - 1;
shadowCam.orthographic = true;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.clearFlags = CameraClearFlags.SolidColor;
shadowCam.backgroundColor = new Color(0.0f, 0.0f, 0.0f, 1.0f);
shadowCam.farClipPlane = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio;
shadowCam.cullingMask = giCullingMask;
shadowCam.useOcclusionCulling = false;
shadowCamTransform = shadowCamGameObject.transform;
//v0.3
UnityEngine.Rendering.Universal.UniversalAdditionalCameraData additionalCameraData = shadowCam.transform.GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>();
if (additionalCameraData == null)
{
additionalCameraData = shadowCam.gameObject.AddComponent<UniversalAdditionalCameraData>();
}
additionalCameraData.SetRenderer(helperRendererID);
}
else //Otherwise, it already exists, just get it
{
shadowCamGameObject = scgo;
shadowCam = scgo.GetComponent<Camera>();
shadowCam.enabled = false; //true;//= false;
shadowCam.depth = attachedCamera.depth - 1;
shadowCam.orthographic = true;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.clearFlags = CameraClearFlags.SolidColor;
shadowCam.backgroundColor = new Color(0.0f, 0.0f, 0.0f, 1.0f);
shadowCam.farClipPlane = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio;
shadowCam.cullingMask = giCullingMask;
shadowCam.useOcclusionCulling = false;
shadowCamTransform = shadowCamGameObject.transform;
//shadowCamTransform = shadowCamGameObject.transform;
//v0.3
UnityEngine.Rendering.Universal.UniversalAdditionalCameraData additionalCameraData = shadowCam.transform.GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>();
if (additionalCameraData == null)
{
additionalCameraData = shadowCam.gameObject.AddComponent<UniversalAdditionalCameraData>();
}
additionalCameraData.SetRenderer(helperRendererID);
}
//Create the proxy camera objects responsible for rendering the scene to voxelize the scene. If they already exist, destroy them
GameObject vcgo = GameObject.Find("SEGI_VOXEL_CAMERA_FAR");
if (!vcgo)
{
voxelCameraGO = new GameObject("SEGI_VOXEL_CAMERA_FAR");
// voxelCameraGO.hideFlags = HideFlags.HideAndDontSave;//v0.2
voxelCameraGO.hideFlags = HideFlags.HideInHierarchy;//v0.2a
voxelCamera = voxelCameraGO.AddComponent<Camera>();
voxelCamera.enabled = false; //true;//v0.1 false;
voxelCamera.orthographic = true;
voxelCamera.orthographicSize = voxelSpaceSize * 0.5f;
voxelCamera.nearClipPlane = 0.0f;
voxelCamera.farClipPlane = voxelSpaceSize;
voxelCamera.depth = -2;
voxelCamera.renderingPath = RenderingPath.Forward;
voxelCamera.clearFlags = CameraClearFlags.Color;
voxelCamera.backgroundColor = Color.black;
voxelCamera.useOcclusionCulling = false;
//v0.3
UnityEngine.Rendering.Universal.UniversalAdditionalCameraData additionalCameraData = voxelCamera.transform.GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>();
if (additionalCameraData == null)
{
additionalCameraData = voxelCamera.gameObject.AddComponent<UniversalAdditionalCameraData>();
}
additionalCameraData.SetRenderer(helperRendererID);
}
else
{
voxelCameraGO = vcgo;
voxelCamera = vcgo.GetComponent<Camera>();
//v0.1
//Debug.Log("Setup voxel camera found");
//voxelCameraGO.hideFlags = HideFlags.HideAndDontSave;
//voxelCamera = voxelCameraGO.AddComponent<Camera>();
voxelCamera.enabled = false;// true;//v0.1 false;
voxelCamera.orthographic = true;
voxelCamera.orthographicSize = voxelSpaceSize * 0.5f;
voxelCamera.nearClipPlane = 0.0f;
voxelCamera.farClipPlane = voxelSpaceSize;
voxelCamera.depth = -2;
voxelCamera.renderingPath = RenderingPath.Forward;
voxelCamera.clearFlags = CameraClearFlags.Color;
voxelCamera.backgroundColor = Color.black;
voxelCamera.useOcclusionCulling = false;
//v0.3
UnityEngine.Rendering.Universal.UniversalAdditionalCameraData additionalCameraData = voxelCamera.transform.GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>();
if (additionalCameraData == null)
{
additionalCameraData = voxelCamera.gameObject.AddComponent<UniversalAdditionalCameraData>();
}
additionalCameraData.SetRenderer(helperRendererID);
}
GameObject lvp = GameObject.Find("SEGI_LEFT_VOXEL_VIEW_FAR");
if (!lvp)
{
leftViewPoint = new GameObject("SEGI_LEFT_VOXEL_VIEW_FAR");
// leftViewPoint.hideFlags = HideFlags.HideAndDontSave;//v0.2
leftViewPoint.hideFlags = HideFlags.HideInHierarchy;//v0.2a
}
else
{
leftViewPoint = lvp;
}
GameObject tvp = GameObject.Find("SEGI_TOP_VOXEL_VIEW_FAR");
if (!tvp)
{
topViewPoint = new GameObject("SEGI_TOP_VOXEL_VIEW_FAR");
//topViewPoint.hideFlags = HideFlags.HideAndDontSave;//v0.2
topViewPoint.hideFlags = HideFlags.HideInHierarchy;//v0.2a
}
else
{
topViewPoint = tvp;
}
//Get blue noise textures
blueNoise = null;
blueNoise = new Texture2D[64];
for (int i = 0; i < 64; i++)
{
string fileName = "LDR_RGBA_" + i.ToString();
Texture2D blueNoiseTexture = Resources.Load("Noise Textures/" + fileName) as Texture2D;
if (blueNoiseTexture == null)
{
Debug.LogWarning("Unable to find noise texture \"Assets/SEGI/Resources/Noise Textures/" + fileName + "\" for SEGI!");
}
blueNoise[i] = blueNoiseTexture;
}
//Setup sun depth texture
if (sunDepthTexture)
{
sunDepthTexture.DiscardContents();
sunDepthTexture.Release();
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;
//v0.2a
if (createdVolumeTexturesPlayMode)
{
// return;
}
if (Application.isPlaying)
{
createdVolumeTexturesPlayMode = true;
}
//Create the volume textures
CreateVolumeTextures();
initChecker2 = true;//v0.2
initChecker = new object();
}
void CheckSupport()
{
if (material == null)
{
return;
}
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;
//1.3
systemSupported.voxelizationShaderVERT = voxelizationShaderVERT.isSupported;
systemSupported.tracingShaderVERT = voxelTracingShaderVERT.isSupported;
//1.5
systemSupported.voxelizationShaderL = voxelizationShaderL.isSupported;
systemSupported.voxelizationShaderVERTL = voxelizationShaderVERTL.isSupported;
if (!systemSupported.fullFunctionality)
{
Debug.LogWarning("SEGI is not supported on the current platform. Check for shader compile errors in SEGI/Resources");
enabled = false;
}
}
void OnDrawGizmosSelectedA()
{
if (!enabled)
return;
Color prevColor = Gizmos.color;
Gizmos.color = new Color(1.0f, 0.25f, 0.0f, 0.5f);
Gizmos.DrawCube(voxelSpaceOrigin, new Vector3(voxelSpaceSize, voxelSpaceSize, voxelSpaceSize));
Gizmos.color = new Color(1.0f, 0.0f, 0.0f, 0.1f);
Gizmos.color = prevColor;
}
void CleanupTexture(ref RenderTexture texture)
{
if (texture)
{
texture.DiscardContents();
texture.Release();
if (voxelCamera != null)
{
voxelCamera.targetTexture = null;//v0.2
}
DestroyImmediate(texture);
}
}
void CleanupTextures()
{
CleanupTexture(ref sunDepthTexture);
CleanupTexture(ref previousGIResult);
CleanupTexture(ref previousCameraDepth);
CleanupTexture(ref integerVolume);
if (volumeTextures != null)//v0.2
{
for (int i = 0; i < volumeTextures.Length; i++)
{
CleanupTexture(ref volumeTextures[i]);
}
}
CleanupTexture(ref secondaryIrradianceVolume);
CleanupTexture(ref volumeTextureB);
CleanupTexture(ref dummyVoxelTextureAAScaled);
CleanupTexture(ref dummyVoxelTextureFixed);
}
void Cleanup()
{
DestroyImmediate(material);
//DestroyImmediate(voxelCameraGO); //v0.1
//DestroyImmediate(leftViewPoint);//v0.2a
//DestroyImmediate(topViewPoint);//v0.2a
//DestroyImmediate(shadowCamGameObject);//v0.2a
initChecker = null;
initChecker2 = false;//v0.2
CleanupTextures();
//v0.1
RenderPipelineManager.beginCameraRendering -= ExecuteBeforeCameraRender;
}
void OnEnable()
{
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
//Debug.Log("No cam3d");
return;
}
// InitCheck();
// ResizeRenderTextures();
// CheckSupport();
//v0.1
RenderPipelineManager.beginCameraRendering += ExecuteBeforeCameraRender;
}
void OnDisable()
{
Cleanup();
}
void ResizeRenderTextures()
{
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
// Debug.Log("No cam3e");
return;
}
if (previousGIResult)
{
previousGIResult.DiscardContents();
previousGIResult.Release();
DestroyImmediate(previousGIResult);
}
//v0.6
int width = (attachedCamera == null || attachedCamera.pixelWidth == 0) ? 2 : attachedCamera.pixelWidth;
int height = (attachedCamera == null || attachedCamera.pixelHeight == 0) ? 2 : attachedCamera.pixelHeight;
//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;
#if UNITY_5_4_OR_NEWER
previousGIResult.autoGenerateMips = false;
#else
previousResult.generateMips = false;
#endif
previousGIResult.Create();
previousGIResult.hideFlags = HideFlags.HideAndDontSave;
if (previousCameraDepth)
{
previousCameraDepth.DiscardContents();
previousCameraDepth.Release();
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;
}
void ResizeSunShadowBuffer()
{
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
//Debug.Log("No cam3f");
return;
}
if (sunDepthTexture)
{
sunDepthTexture.DiscardContents();
sunDepthTexture.Release();
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;
}
void Update()
{
//v0.3
//v1.1.8n - pipeline setup automation
if (setupForwardRendererLUMINA)
{
#if (UNITY_EDITOR)
UniversalRenderPipelineAsset pipeline = ((UniversalRenderPipelineAsset)GraphicsSettings.renderPipelineAsset);
//m_DefaultRendererIndex
FieldInfo propertyInfoA = pipeline.GetType().GetField("m_DefaultRendererIndex", BindingFlags.Instance | BindingFlags.NonPublic);//REFLECTION
int rendererDefaultIndex = ((int)propertyInfoA?.GetValue(pipeline));
Debug.Log("Default renderer ID = " + rendererDefaultIndex);
FieldInfo propertyInfo = pipeline.GetType().GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic);//REFLECTION
ScriptableRendererData renderDATA = ((ScriptableRendererData[])propertyInfo?.GetValue(pipeline))?[rendererDefaultIndex];
//BlitVolumeFogSRP volumeFOGFeature = (BlitVolumeFogSRP)renderDATA.rendererFeatures[0];
List<ScriptableRendererFeature> features = renderDATA.rendererFeatures;
bool foundFogFeature = false;
for (int i = 0; i < features.Count; i++)
{
//if find, all good, if not set it up
if (features[i].GetType() == typeof(VolumetricLightedSEGI)) //if (features[i].name == "NewBlitVolumeFogSRP")
{
foundFogFeature = true;
}
//Debug.Log(features[i].name);
}
if (foundFogFeature)
{
Debug.Log("The LUMINA forward renderer feature is already added in the Default renderer in the URP pipeline asset.");
}
else
{
//SET IT UP
//if (volumeFogMaterial != null)
//{
VolumetricLightedSEGI volumeFOGFeature = ScriptableObject.CreateInstance<VolumetricLightedSEGI>(); //new BlitVolumeFogSRP();
//volumeFOGFeature.settings.blitMaterial = volumeFogMaterial;
//new1 // v1.1.9f
//volumeFOGFeature.settings.Event = RenderPassEvent.AfterRenderingSkybox;
volumeFOGFeature.name = "NewBlitLUMINA";
ScriptableRendererFeature BlitVolumeFogSRPfeature = volumeFOGFeature as ScriptableRendererFeature;
BlitVolumeFogSRPfeature.Create();
#if UNITY_EDITOR
//new1 // v1.1.9f
AssetDatabase.AddObjectToAsset(BlitVolumeFogSRPfeature, renderDATA);
AssetDatabase.TryGetGUIDAndLocalFileIdentifier(BlitVolumeFogSRPfeature, out var guid, out long localId);
//List<ScriptableRendererFeature> featuresA = renderDATA.rendererFeatures;
#endif
renderDATA.rendererFeatures.Add(BlitVolumeFogSRPfeature);
renderDATA.SetDirty();
#if UNITY_EDITOR
//new1 // v1.1.9f
EditorUtility.SetDirty(renderDATA);
#endif
Debug.Log("The LUMINA forward renderer feature is now added in the Default renderer in the URP pipeline asset.");
//}
//else
//{
// Debug.Log("The Ethereal volumetric fog material is not assigned, please assign the 'VolumeFogSRP_FORWARD_URP' material in the 'VolumeFogMaterial' slot in the " +
// "connect script and then enable the 'Setup Forward Renderer' checkbox to setup the fog.");
//}
}
//add normals
// foundFogFeature = false;
// for (int i = 0; i < features.Count; i++)
// {
// //if find, all good, if not set it up
// if (features[i].GetType() == typeof(DepthNormalsLUMINAFeature)) //if (features[i].name == "NewBlitVolumeFogSRP")
// {
// foundFogFeature = true;
// }
// //Debug.Log(features[i].name);
// }
// if (foundFogFeature)
// {
// Debug.Log("The LUMINA Depth Normals forward renderer feature is already added in the Default renderer in the URP pipeline asset.");
// }
// else
// {
// //SET IT UP
// //if (volumeFogMaterial != null)
// //{
// DepthNormalsLUMINAFeature volumeFOGFeature = ScriptableObject.CreateInstance<DepthNormalsLUMINAFeature>(); //new BlitVolumeFogSRP();
// //volumeFOGFeature.settings.blitMaterial = volumeFogMaterial;
// //new1 // v1.1.9f
// //volumeFOGFeature.settings.Event = RenderPassEvent.AfterRenderingSkybox;
// volumeFOGFeature.name = "NewBlitDepthNormalsLUMINA";
// ScriptableRendererFeature BlitVolumeFogSRPfeature = volumeFOGFeature as ScriptableRendererFeature;
// BlitVolumeFogSRPfeature.Create();
//#if UNITY_EDITOR
// //new1 // v1.1.9f
// AssetDatabase.AddObjectToAsset(BlitVolumeFogSRPfeature, renderDATA);
// AssetDatabase.TryGetGUIDAndLocalFileIdentifier(BlitVolumeFogSRPfeature, out var guid, out long localId);
// //List<ScriptableRendererFeature> featuresA = renderDATA.rendererFeatures;
//#endif
// renderDATA.rendererFeatures.Add(BlitVolumeFogSRPfeature);
// renderDATA.SetDirty();
//#if UNITY_EDITOR
// //new1 // v1.1.9f
// EditorUtility.SetDirty(renderDATA);
//#endif
// Debug.Log("The LUMINA Depth Normals forward renderer feature is now added in the Default renderer in the URP pipeline asset.");
// }
#endif
setupForwardRendererLUMINA = false;
}
if (setupForwardRendererHELPER)
{
#if (UNITY_EDITOR)
UniversalRenderPipelineAsset pipeline = ((UniversalRenderPipelineAsset)GraphicsSettings.renderPipelineAsset);
//m_DefaultRendererIndex
FieldInfo propertyInfoA = pipeline.GetType().GetField("m_DefaultRendererIndex", BindingFlags.Instance | BindingFlags.NonPublic);//REFLECTION
int rendererDefaultIndex = helperRendererID; //// ((int)propertyInfoA?.GetValue(pipeline));
Debug.Log("Default renderer ID = " + rendererDefaultIndex);
FieldInfo propertyInfo = pipeline.GetType().GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic);//REFLECTION
ScriptableRendererData renderDATA = ((ScriptableRendererData[])propertyInfo?.GetValue(pipeline))?[rendererDefaultIndex];
//BlitVolumeFogSRP volumeFOGFeature = (BlitVolumeFogSRP)renderDATA.rendererFeatures[0];
List<ScriptableRendererFeature> features = renderDATA.rendererFeatures;
bool foundFogFeature = false;
for (int i = 0; i < features.Count; i++)
{
//if find, all good, if not set it up
if (features[i].GetType() == typeof(UnityEngine.Experimental.Rendering.Universal.RenderObjects))
{
//add material
UnityEngine.Experimental.Rendering.Universal.RenderObjects rendererOBJ = (UnityEngine.Experimental.Rendering.Universal.RenderObjects)features[i];
rendererOBJ.settings.overrideMaterial = preRenderers;
rendererOBJ.settings.filterSettings.LayerMask = ~0; //v0.7
foundFogFeature = true;
}
//Debug.Log(features[i].name);
}
if (foundFogFeature)
{
Debug.Log("The LUMINA Render Objects forward renderer feature is already added in the Default renderer in the URP pipeline asset.");
}
else
{
//SET IT UP
if (preRenderers != null)
{
UnityEngine.Experimental.Rendering.Universal.RenderObjects volumeFOGFeature = ScriptableObject.CreateInstance<UnityEngine.Experimental.Rendering.Universal.RenderObjects>(); //new BlitVolumeFogSRP();
volumeFOGFeature.settings.overrideMaterial = preRenderers;//volumeFOGFeature.settings.blitMaterial = volumeFogMaterial;
volumeFOGFeature.settings.filterSettings.LayerMask = ~0; //v0.7
//new1 // v1.1.9f
//volumeFOGFeature.settings.Event = RenderPassEvent.AfterRenderingSkybox;
volumeFOGFeature.name = "Render Objects LUMINA Voxelizer";
ScriptableRendererFeature BlitVolumeFogSRPfeature = volumeFOGFeature as ScriptableRendererFeature;
BlitVolumeFogSRPfeature.Create();
#if UNITY_EDITOR
//new1 // v1.1.9f
AssetDatabase.AddObjectToAsset(BlitVolumeFogSRPfeature, renderDATA);
AssetDatabase.TryGetGUIDAndLocalFileIdentifier(BlitVolumeFogSRPfeature, out var guid, out long localId);
//List<ScriptableRendererFeature> featuresA = renderDATA.rendererFeatures;
#endif
renderDATA.rendererFeatures.Add(BlitVolumeFogSRPfeature);
renderDATA.SetDirty();
#if UNITY_EDITOR
//new1 // v1.1.9f
EditorUtility.SetDirty(renderDATA);
#endif
Debug.Log("The LUMINA Render Objects forward renderer feature is now added in the Default renderer in the URP pipeline asset.");
}
else
{
Debug.Log("The LUMINA Render Objects material is not assigned, please assign the 'VolumeLitSEGIPreRender' material in the 'preRenderers' slot in the " +
"VolumeLitSEGI script.");
}
}
#endif
setupForwardRendererHELPER = false;
}
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
//Debug.Log("No cam1");
return;
}
if (previousGIResult == null)
{
ResizeRenderTextures();
}
//v0.6
if (attachedCamera != null)
{
if (previousGIResult.width != attachedCamera.pixelWidth || previousGIResult.height != attachedCamera.pixelHeight)
{
ResizeRenderTextures();
}
}
if ((int)sunShadowResolution != prevSunShadowResolution)
{
ResizeSunShadowBuffer();
}
prevSunShadowResolution = (int)sunShadowResolution;
if (volumeTextures[0] != null && volumeTextures[0].width != (int)voxelResolution)
{
CreateVolumeTextures();
}
if (dummyVoxelTextureAAScaled != null && dummyVoxelTextureAAScaled.width != dummyVoxelResolution)
{
ResizeDummyTexture();
}
}
public Matrix4x4 TransformViewMatrix(Matrix4x4 mat)
{
//Since the third column of the view matrix needs to be reversed if using reversed z-buffer, do so here
#if UNITY_5_5_OR_NEWER
if (SystemInfo.usesReversedZBuffer)
{
mat[2, 0] = -mat[2, 0];
mat[2, 1] = -mat[2, 1];
mat[2, 2] = -mat[2, 2];
mat[2, 3] = -mat[2, 3];
}
#endif
return mat;
}
//v0.2
public Camera savedCam;
public RenderTexture gi1;
//v0.4
void ExecuteBeforeCameraRenderA(ScriptableRenderContext context, Camera camera) //void OnPreRender()
{
//return;
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
// Debug.Log("No cam4a");
return;
}
var urpAsset = (UniversalRenderPipelineAsset)GraphicsSettings.renderPipelineAsset;
var urpAsset0 = (UniversalRenderPipelineAsset)GraphicsSettings.defaultRenderPipeline;
GraphicsSettings.renderPipelineAsset = null;
GraphicsSettings.defaultRenderPipeline = null;
//v0.3
var urpAsset2 = (UniversalRenderPipelineAsset)QualitySettings.renderPipeline;
QualitySettings.renderPipeline = null;
//Force reinitialization to make sure that everything is working properly if one of the cameras was unexpectedly destroyed
if (!voxelCamera || !shadowCam)
initChecker = null; CleanupTextures(); initChecker2 = false;//v0.2
InitCheck();
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
//Debug.Log("No cam2");
return;
}
if (!updateGI)
{
return;
}
//Cache the previous active render texture to avoid issues with other Unity rendering going on
RenderTexture previousActive = RenderTexture.active;
Shader.SetGlobalInt("SEGIVoxelAA", voxelAA ? 1 : 0);
//Main voxelization work
if (renderState == RenderState.Voxelize)
{
activeVolume = voxelFlipFlop == 0 ? volumeTextures[0] : volumeTextureB; //Flip-flopping volume textures to avoid simultaneous read and write errors in shaders
previousActiveVolume = voxelFlipFlop == 0 ? volumeTextureB : volumeTextures[0];
//float voxelTexel = (1.0f * voxelSpaceSize) / (int)voxelResolution * 0.5f; //Calculate the size of a voxel texel in world-space units
//Setup the voxel volume origin position
float interval = voxelSpaceSize / 8.0f; //The interval at which the voxel volume will be "locked" in world-space
Vector3 origin;
if (followTransform)
{
origin = followTransform.position;
}
else
{
//GI is still flickering a bit when the scene view and the game view are opened at the same time
origin = transform.position + transform.forward * voxelSpaceSize / 4.0f;
}
//Lock the voxel volume origin based on the interval
voxelSpaceOrigin = new Vector3(Mathf.Round(origin.x / interval) * interval, Mathf.Round(origin.y / interval) * interval, Mathf.Round(origin.z / interval) * interval);
//Calculate how much the voxel origin has moved since last voxelization pass. Used for scrolling voxel data in shaders to avoid ghosting when the voxel volume moves in the world
voxelSpaceOriginDelta = voxelSpaceOrigin - previousVoxelSpaceOrigin;
//Shader.SetGlobalVector("SEGIVoxelSpaceOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize);
material.SetVector("SEGIVoxelSpaceOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize);
previousVoxelSpaceOrigin = voxelSpaceOrigin;
//Set the voxel camera (proxy camera used to render the scene for voxelization) parameters
voxelCamera.enabled = false;
voxelCamera.orthographic = true;
voxelCamera.orthographicSize = voxelSpaceSize * 0.5f;
voxelCamera.nearClipPlane = 0.0f;
voxelCamera.farClipPlane = voxelSpaceSize;
voxelCamera.depth = -2;
voxelCamera.renderingPath = RenderingPath.Forward;
voxelCamera.clearFlags = CameraClearFlags.Color;
voxelCamera.backgroundColor = Color.black;
voxelCamera.cullingMask = giCullingMask;
//Move the voxel camera game object and other related objects to the above calculated voxel space origin
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;
//Set matrices needed for voxelization
//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);
material.SetMatrix("WorldToCamera", attachedCamera.worldToCameraMatrix);
material.SetMatrix("SEGIVoxelViewFront", TransformViewMatrix(voxelCamera.transform.worldToLocalMatrix));
material.SetMatrix("SEGIVoxelViewLeft", TransformViewMatrix(leftViewPoint.transform.worldToLocalMatrix));
material.SetMatrix("SEGIVoxelViewTop", TransformViewMatrix(topViewPoint.transform.worldToLocalMatrix));
material.SetMatrix("SEGIWorldToVoxel", voxelCamera.worldToCameraMatrix);
material.SetMatrix("SEGIVoxelProjection", voxelCamera.projectionMatrix);
material.SetMatrix("SEGIVoxelProjectionInverse", voxelCamera.projectionMatrix.inverse);
//Shader.SetGlobalInt("SEGIVoxelResolution", (int)voxelResolution);
material.SetInt("SEGIVoxelResolution", (int)voxelResolution);
Matrix4x4 voxelToGIProjection = (shadowCam.projectionMatrix) * (shadowCam.worldToCameraMatrix) * (voxelCamera.cameraToWorldMatrix);
//Shader.SetGlobalMatrix("SEGIVoxelToGIProjection", voxelToGIProjection);
material.SetMatrix("SEGIVoxelToGIProjection", voxelToGIProjection);
Shader.SetGlobalVector("SEGISunlightVector", sun ? Vector3.Normalize(sun.transform.forward) : Vector3.up);
//Set paramteters
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 : 0.0f);
Shader.SetGlobalFloat("SEGISoftSunlight", softSunlight);
Shader.SetGlobalInt("SEGISphericalSkylight", sphericalSkylight ? 1 : 0);
Shader.SetGlobalInt("SEGIInnerOcclusionLayers", innerOcclusionLayers);
//Render the depth texture from the sun's perspective in order to inject sunlight with shadows during voxelization
if (sun != null)
{
if (renderSunWithSRP)
{
shadowCam.cullingMask = giCullingMask;
Vector3 shadowCamPosition = voxelSpaceOrigin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio;
shadowCamTransform.position = shadowCamPosition;
shadowCamTransform.LookAt(voxelSpaceOrigin, Vector3.up);
shadowCam.renderingPath = RenderingPath.Forward;
shadowCam.depthTextureMode |= DepthTextureMode.None;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.farClipPlane = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio;
Graphics.SetRenderTarget(sunDepthTexture);
shadowCam.SetTargetBuffers(sunDepthTexture.colorBuffer, sunDepthTexture.depthBuffer);
shadowCam.RenderWithShader(sunDepthShader, "");
shadowCam.targetTexture = sunDepthTexture;
preRenderers.shader = sunDepthShader;
//UniversalRenderPipeline.RenderSingleCamera(context, shadowCam);
Shader.SetGlobalTexture("SEGISunDepth", sunDepthTexture);
}
else
{
shadowCam.cullingMask = giCullingMask;
Vector3 shadowCamPosition = voxelSpaceOrigin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio;
shadowCamTransform.position = shadowCamPosition;
shadowCamTransform.LookAt(voxelSpaceOrigin, Vector3.up);
shadowCam.renderingPath = RenderingPath.Forward;
shadowCam.depthTextureMode |= DepthTextureMode.None;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.farClipPlane = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio;
Graphics.SetRenderTarget(sunDepthTexture);
shadowCam.SetTargetBuffers(sunDepthTexture.colorBuffer, sunDepthTexture.depthBuffer);
shadowCam.RenderWithShader(sunDepthShader, "");
Shader.SetGlobalTexture("SEGISunDepth", sunDepthTexture);
}
}
//Clear the volume texture that is immediately written to in the voxelization scene shader
clearCompute.SetTexture(0, "RG0", integerVolume);
clearCompute.SetInt("Res", (int)voxelResolution);
clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
//Render the scene with the voxel proxy camera object with the voxelization shader to voxelize the scene to the volume integer texture
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureAAScaled;
Shader.SetGlobalVector("_CutoffGI", cutoff); //v1.6
if (proxyNoGeom) //v1.3
{
if (enableLocalLightGI)//v1.5
{
Shader.SetGlobalFloat("shadowedLocalPower", shadowedLocalPower);
Shader.SetGlobalFloat("shadowlessLocalPower", shadowlessLocalPower);
Shader.SetGlobalFloat("shadowlessLocalOcclusion", shadowlessLocalOcclusion);
voxelCamera.RenderWithShader(voxelizationShaderVERTL, "");
}
else
{
voxelCamera.RenderWithShader(voxelizationShaderVERT, "");
}
}
else
{
if (enableLocalLightGI)//v1.5
{
Shader.SetGlobalFloat("shadowedLocalPower", shadowedLocalPower);
Shader.SetGlobalFloat("shadowlessLocalPower", shadowlessLocalPower);
Shader.SetGlobalFloat("shadowlessLocalOcclusion", shadowlessLocalOcclusion);
voxelCamera.RenderWithShader(voxelizationShaderL, "");
}
else
{
voxelCamera.RenderWithShader(voxelizationShader, "");
}
}
Graphics.ClearRandomWriteTargets();
//Transfer the data from the volume integer texture to the main volume texture used for GI tracing.
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) * (int)voxelResolution);
transferIntsCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
//Shader.SetGlobalTexture("SEGIVolumeLevel0", activeVolume);
material.SetTexture("SEGIVolumeLevel0", activeVolume);
//Manually filter/render mip maps
for (int i = 0; i < numMipLevels - 1; i++)
{
RenderTexture source = volumeTextures[i];
if (i == 0)
{
source = activeVolume;
}
int destinationRes = (int)voxelResolution / Mathf.RoundToInt(Mathf.Pow((float)2, (float)i + 1.0f));
mipFilterCompute.SetInt("destinationRes", destinationRes);
mipFilterCompute.SetTexture(mipFilterKernel, "Source", source);
mipFilterCompute.SetTexture(mipFilterKernel, "Destination", volumeTextures[i + 1]);
mipFilterCompute.Dispatch(mipFilterKernel, destinationRes / 8, destinationRes / 8, 1);
//Shader.SetGlobalTexture("SEGIVolumeLevel" + (i + 1).ToString(), volumeTextures[i + 1]);
material.SetTexture("SEGIVolumeLevel" + (i + 1).ToString(), volumeTextures[i + 1]);
}
//Advance the voxel flip flop counter
voxelFlipFlop += 1;
voxelFlipFlop = voxelFlipFlop % 2;
if (infiniteBounces)
{
renderState = RenderState.Bounce;
}
}
else if (renderState == RenderState.Bounce)
{
//Clear the volume texture that is immediately written to in the voxelization scene shader
clearCompute.SetTexture(0, "RG0", integerVolume);
clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
//Set secondary tracing parameters
Shader.SetGlobalInt("SEGISecondaryCones", secondaryCones);
Shader.SetGlobalFloat("SEGISecondaryOcclusionStrength", secondaryOcclusionStrength);
//Render the scene from the voxel camera object with the voxel tracing shader to render a bounce of GI into the irradiance volume
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureFixed;
//v1.3
if (proxyNoGeom)
{
voxelCamera.RenderWithShader(voxelTracingShaderVERT, "");
}
else
{
voxelCamera.RenderWithShader(voxelTracingShader, "");
}
Graphics.ClearRandomWriteTargets();
//Transfer the data from the volume integer texture to the irradiance volume texture. This result is added to the next main voxelization pass to create a feedback loop for infinite bounces
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);
material.SetTexture("SEGIVolumeTexture1", secondaryIrradianceVolume);
renderState = RenderState.Voxelize;
}
RenderTexture.active = previousActive;
//v0.3
if (urpAsset != null)
{
GraphicsSettings.renderPipelineAsset = urpAsset;
}
if (urpAsset2 != null)
{
QualitySettings.renderPipeline = urpAsset2;
}
if (urpAsset0 != null)
{
GraphicsSettings.defaultRenderPipeline = urpAsset0;
}
}
void OnPreRenderA()
{
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
//Debug.Log("No cam4b");
return;
}
//Force reinitialization to make sure that everything is working properly if one of the cameras was unexpectedly destroyed
if (!voxelCamera || !shadowCam)
initChecker = null; CleanupTextures(); initChecker2 = false;//v0.2
InitCheck();
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
//Debug.Log("No cam3");
return;
}
if (!updateGI)
{
return;
}
//Cache the previous active render texture to avoid issues with other Unity rendering going on
RenderTexture previousActive = RenderTexture.active;
Shader.SetGlobalInt("SEGIVoxelAA", voxelAA ? 1 : 0);
//Main voxelization work
if (renderState == RenderState.Voxelize)
{
activeVolume = voxelFlipFlop == 0 ? volumeTextures[0] : volumeTextureB; //Flip-flopping volume textures to avoid simultaneous read and write errors in shaders
previousActiveVolume = voxelFlipFlop == 0 ? volumeTextureB : volumeTextures[0];
//float voxelTexel = (1.0f * voxelSpaceSize) / (int)voxelResolution * 0.5f; //Calculate the size of a voxel texel in world-space units
//Setup the voxel volume origin position
float interval = voxelSpaceSize / 8.0f; //The interval at which the voxel volume will be "locked" in world-space
Vector3 origin;
if (followTransform)
{
origin = followTransform.position;
}
else
{
//GI is still flickering a bit when the scene view and the game view are opened at the same time
origin = transform.position + transform.forward * voxelSpaceSize / 4.0f;
}
//Lock the voxel volume origin based on the interval
voxelSpaceOrigin = new Vector3(Mathf.Round(origin.x / interval) * interval, Mathf.Round(origin.y / interval) * interval, Mathf.Round(origin.z / interval) * interval);
//Calculate how much the voxel origin has moved since last voxelization pass. Used for scrolling voxel data in shaders to avoid ghosting when the voxel volume moves in the world
voxelSpaceOriginDelta = voxelSpaceOrigin - previousVoxelSpaceOrigin;
//Shader.SetGlobalVector("SEGIVoxelSpaceOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize);
material.SetVector("SEGIVoxelSpaceOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize);
previousVoxelSpaceOrigin = voxelSpaceOrigin;
//Set the voxel camera (proxy camera used to render the scene for voxelization) parameters
voxelCamera.enabled = false;
voxelCamera.orthographic = true;
voxelCamera.orthographicSize = voxelSpaceSize * 0.5f;
voxelCamera.nearClipPlane = 0.0f;
voxelCamera.farClipPlane = voxelSpaceSize;
voxelCamera.depth = -2;
voxelCamera.renderingPath = RenderingPath.Forward;
voxelCamera.clearFlags = CameraClearFlags.Color;
voxelCamera.backgroundColor = Color.black;
voxelCamera.cullingMask = giCullingMask;
//Move the voxel camera game object and other related objects to the above calculated voxel space origin
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;
//Set matrices needed for voxelization
//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);
material.SetMatrix("WorldToCamera", attachedCamera.worldToCameraMatrix);
material.SetMatrix("SEGIVoxelViewFront", TransformViewMatrix(voxelCamera.transform.worldToLocalMatrix));
material.SetMatrix("SEGIVoxelViewLeft", TransformViewMatrix(leftViewPoint.transform.worldToLocalMatrix));
material.SetMatrix("SEGIVoxelViewTop", TransformViewMatrix(topViewPoint.transform.worldToLocalMatrix));
material.SetMatrix("SEGIWorldToVoxel", voxelCamera.worldToCameraMatrix);
material.SetMatrix("SEGIVoxelProjection", voxelCamera.projectionMatrix);
material.SetMatrix("SEGIVoxelProjectionInverse", voxelCamera.projectionMatrix.inverse);
//Shader.SetGlobalInt("SEGIVoxelResolution", (int)voxelResolution);
material.SetInt("SEGIVoxelResolution", (int)voxelResolution);
Matrix4x4 voxelToGIProjection = (shadowCam.projectionMatrix) * (shadowCam.worldToCameraMatrix) * (voxelCamera.cameraToWorldMatrix);
//Shader.SetGlobalMatrix("SEGIVoxelToGIProjection", voxelToGIProjection);
material.SetMatrix("SEGIVoxelToGIProjection", voxelToGIProjection);
Shader.SetGlobalVector("SEGISunlightVector", sun ? Vector3.Normalize(sun.transform.forward) : Vector3.up);
//Set paramteters
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 : 0.0f);
Shader.SetGlobalFloat("SEGISoftSunlight", softSunlight);
Shader.SetGlobalInt("SEGISphericalSkylight", sphericalSkylight ? 1 : 0);
Shader.SetGlobalInt("SEGIInnerOcclusionLayers", innerOcclusionLayers);
//Render the depth texture from the sun's perspective in order to inject sunlight with shadows during voxelization
if (sun != null)
{
if (renderSunWithSRP)
{
var urpAsset = (UniversalRenderPipelineAsset)GraphicsSettings.renderPipelineAsset;
var urpAsset0 = (UniversalRenderPipelineAsset)GraphicsSettings.defaultRenderPipeline;
GraphicsSettings.renderPipelineAsset = null;
GraphicsSettings.defaultRenderPipeline = null;
//v0.3
var urpAsset2 = (UniversalRenderPipelineAsset)QualitySettings.renderPipeline;
QualitySettings.renderPipeline = null;
shadowCam.cullingMask = giCullingMask;
Vector3 shadowCamPosition = voxelSpaceOrigin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio;
shadowCamTransform.position = shadowCamPosition;
shadowCamTransform.LookAt(voxelSpaceOrigin, Vector3.up);
shadowCam.renderingPath = RenderingPath.Forward;
shadowCam.depthTextureMode |= DepthTextureMode.None;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.farClipPlane = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio;
Graphics.SetRenderTarget(sunDepthTexture);
shadowCam.SetTargetBuffers(sunDepthTexture.colorBuffer, sunDepthTexture.depthBuffer);
shadowCam.RenderWithShader(sunDepthShader, "");
shadowCam.targetTexture = sunDepthTexture;
preRenderers.shader = sunDepthShader;
//UniversalRenderPipeline.RenderSingleCamera(context, shadowCam);
Shader.SetGlobalTexture("SEGISunDepth", sunDepthTexture);
//v0.3
if (urpAsset != null)
{
GraphicsSettings.renderPipelineAsset = urpAsset;
}
if (urpAsset2 != null)
{
QualitySettings.renderPipeline = urpAsset2;
}
if (urpAsset0 != null)
{
GraphicsSettings.defaultRenderPipeline = urpAsset0;
}
}
else
{
shadowCam.cullingMask = giCullingMask;
Vector3 shadowCamPosition = voxelSpaceOrigin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio;
shadowCamTransform.position = shadowCamPosition;
shadowCamTransform.LookAt(voxelSpaceOrigin, Vector3.up);
shadowCam.renderingPath = RenderingPath.Forward;
shadowCam.depthTextureMode |= DepthTextureMode.None;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.farClipPlane = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio;
Graphics.SetRenderTarget(sunDepthTexture);
shadowCam.SetTargetBuffers(sunDepthTexture.colorBuffer, sunDepthTexture.depthBuffer);
shadowCam.RenderWithShader(sunDepthShader, "");
Shader.SetGlobalTexture("SEGISunDepth", sunDepthTexture);
}
}
//Clear the volume texture that is immediately written to in the voxelization scene shader
clearCompute.SetTexture(0, "RG0", integerVolume);
clearCompute.SetInt("Res", (int)voxelResolution);
clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
//Render the scene with the voxel proxy camera object with the voxelization shader to voxelize the scene to the volume integer texture
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureAAScaled;
Shader.SetGlobalVector("_CutoffGI", cutoff); //v1.6
if (proxyNoGeom) //v1.3
{
if (enableLocalLightGI)//v1.5
{
Shader.SetGlobalFloat("shadowedLocalPower", shadowedLocalPower);
Shader.SetGlobalFloat("shadowlessLocalPower", shadowlessLocalPower);
Shader.SetGlobalFloat("shadowlessLocalOcclusion", shadowlessLocalOcclusion);
voxelCamera.RenderWithShader(voxelizationShaderVERTL, "");
}
else
{
voxelCamera.RenderWithShader(voxelizationShaderVERT, "");
}
}
else
{
if (enableLocalLightGI)//v1.5
{
Shader.SetGlobalFloat("shadowedLocalPower", shadowedLocalPower);
Shader.SetGlobalFloat("shadowlessLocalPower", shadowlessLocalPower);
Shader.SetGlobalFloat("shadowlessLocalOcclusion", shadowlessLocalOcclusion);
voxelCamera.RenderWithShader(voxelizationShaderL, "");
}
else
{
voxelCamera.RenderWithShader(voxelizationShader, "");
}
}
Graphics.ClearRandomWriteTargets();
//Transfer the data from the volume integer texture to the main volume texture used for GI tracing.
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) * (int)voxelResolution);
transferIntsCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
//Shader.SetGlobalTexture("SEGIVolumeLevel0", activeVolume);
material.SetTexture("SEGIVolumeLevel0", activeVolume);
//Manually filter/render mip maps
for (int i = 0; i < numMipLevels - 1; i++)
{
RenderTexture source = volumeTextures[i];
if (i == 0)
{
source = activeVolume;
}
int destinationRes = (int)voxelResolution / Mathf.RoundToInt(Mathf.Pow((float)2, (float)i + 1.0f));
mipFilterCompute.SetInt("destinationRes", destinationRes);
mipFilterCompute.SetTexture(mipFilterKernel, "Source", source);
mipFilterCompute.SetTexture(mipFilterKernel, "Destination", volumeTextures[i + 1]);
mipFilterCompute.Dispatch(mipFilterKernel, destinationRes / 8, destinationRes / 8, 1);
//Shader.SetGlobalTexture("SEGIVolumeLevel" + (i + 1).ToString(), volumeTextures[i + 1]);
material.SetTexture("SEGIVolumeLevel" + (i + 1).ToString(), volumeTextures[i + 1]);
}
//Advance the voxel flip flop counter
voxelFlipFlop += 1;
voxelFlipFlop = voxelFlipFlop % 2;
if (infiniteBounces)
{
renderState = RenderState.Bounce;
}
}
else if (renderState == RenderState.Bounce)
{
//Clear the volume texture that is immediately written to in the voxelization scene shader
clearCompute.SetTexture(0, "RG0", integerVolume);
clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
//Set secondary tracing parameters
Shader.SetGlobalInt("SEGISecondaryCones", secondaryCones);
Shader.SetGlobalFloat("SEGISecondaryOcclusionStrength", secondaryOcclusionStrength);
//Render the scene from the voxel camera object with the voxel tracing shader to render a bounce of GI into the irradiance volume
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureFixed;
//v1.3
if (proxyNoGeom)
{
voxelCamera.RenderWithShader(voxelTracingShaderVERT, "");
}
else
{
voxelCamera.RenderWithShader(voxelTracingShader, "");
}
Graphics.ClearRandomWriteTargets();
//Transfer the data from the volume integer texture to the irradiance volume texture. This result is added to the next main voxelization pass to create a feedback loop for infinite bounces
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);
material.SetTexture("SEGIVolumeTexture1", secondaryIrradianceVolume);
renderState = RenderState.Voxelize;
}
RenderTexture.active = previousActive;
}
void ExecuteBeforeCameraRender(ScriptableRenderContext context, Camera camera) //void OnPreRender()
{
if (Camera.main == null || integerVolume == null)// || Camera.current != null
{
if (integerVolume == null)
{
Init();//v0.2
}
//Debug.Log("No cam4c");
return;
}
//v0.6
if (Camera.main == null || camera != Camera.main)
{
return;
}
//Force reinitialization to make sure that everything is working properly if one of the cameras was unexpectedly destroyed
if (!voxelCamera || !shadowCam)
{
initChecker = null; CleanupTextures(); initChecker2 = false;//v0.2
}
InitCheck();
if (notReadyToRender || Camera.main == null)// || Camera.current != null)
{
// Debug.Log("No cam4");
return;
}
//v0.2
if (Application.isPlaying && updatePerDistance && (transform.position - lastUpdatePos).magnitude < updateDistance && transform.position != lastTransformPos)//v0.3
{
lastTransformPos = transform.position;
return;
}
lastUpdatePos = transform.position;
if (Application.isPlaying && updatePerTime && Time.fixedTime - lastUpdateTime < updateTime)
{
return;
}
lastUpdateTime = Time.fixedTime;
if (!updateGI)
{
return;
}
// return;
//Cache the previous active render texture to avoid issues with other Unity rendering going on
RenderTexture previousActive = RenderTexture.active;
Shader.SetGlobalInt("SEGIVoxelAA", voxelAA ? 1 : 0);
//v0.2
//RenderTexture gi1 = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, RenderTextureFormat.ARGBHalf);
//Camera.main.targetTexture = gi1;
//UniversalRenderPipeline.RenderSingleCamera(context, Camera.main);
//preRenderers.SetTexture("_MainTex", gi1);
//Camera.main.targetTexture = null;
//Main voxelization work
if (renderState == RenderState.Voxelize)
{
activeVolume = voxelFlipFlop == 0 ? volumeTextures[0] : volumeTextureB; //Flip-flopping volume textures to avoid simultaneous read and write errors in shaders
previousActiveVolume = voxelFlipFlop == 0 ? volumeTextureB : volumeTextures[0];
//float voxelTexel = (1.0f * voxelSpaceSize) / (int)voxelResolution * 0.5f; //Calculate the size of a voxel texel in world-space units
//Setup the voxel volume origin position
float interval = voxelSpaceSize / 8.0f; //The interval at which the voxel volume will be "locked" in world-space
Vector3 origin;
if (followTransform)
{
origin = followTransform.position;
}
else
{
//GI is still flickering a bit when the scene view and the game view are opened at the same time
origin = transform.position + transform.forward * voxelSpaceSize / 4.0f;
}
//Lock the voxel volume origin based on the interval
voxelSpaceOrigin = new Vector3(Mathf.Round(origin.x / interval) * interval, Mathf.Round(origin.y / interval) * interval, Mathf.Round(origin.z / interval) * interval);
//Calculate how much the voxel origin has moved since last voxelization pass. Used for scrolling voxel data in shaders to avoid ghosting when the voxel volume moves in the world
voxelSpaceOriginDelta = voxelSpaceOrigin - previousVoxelSpaceOrigin;
//Shader.SetGlobalVector("SEGIVoxelSpaceOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize);
material.SetVector("SEGIVoxelSpaceOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize);
previousVoxelSpaceOrigin = voxelSpaceOrigin;
//Set the voxel camera (proxy camera used to render the scene for voxelization) parameters
voxelCamera.enabled = false;//true;//v0.1 false;
voxelCamera.orthographic = true;
voxelCamera.orthographicSize = voxelSpaceSize * 0.5f;
voxelCamera.nearClipPlane = 0.0f;
voxelCamera.farClipPlane = voxelSpaceSize;
voxelCamera.depth = -2;
voxelCamera.renderingPath = RenderingPath.Forward;
voxelCamera.clearFlags = CameraClearFlags.Color;
voxelCamera.backgroundColor = Color.black;
voxelCamera.cullingMask = giCullingMask;
//Move the voxel camera game object and other related objects to the above calculated voxel space origin
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;
////Set matrices needed for voxelization
//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 voxelToGIProjection = (shadowCam.projectionMatrix) * (shadowCam.worldToCameraMatrix) * (voxelCamera.cameraToWorldMatrix);
//Shader.SetGlobalMatrix("SEGIVoxelToGIProjection", voxelToGIProjection);
material.SetMatrix("WorldToCamera", attachedCamera.worldToCameraMatrix);
material.SetMatrix("SEGIVoxelViewFront", TransformViewMatrix(voxelCamera.transform.worldToLocalMatrix));
material.SetMatrix("SEGIVoxelViewLeft", TransformViewMatrix(leftViewPoint.transform.worldToLocalMatrix));
material.SetMatrix("SEGIVoxelViewTop", TransformViewMatrix(topViewPoint.transform.worldToLocalMatrix));
//
Shader.SetGlobalMatrix("SEGIVoxelViewFront_FAR", TransformViewMatrix(voxelCamera.transform.worldToLocalMatrix));
Shader.SetGlobalMatrix("SEGIVoxelViewLeft_FAR", TransformViewMatrix(leftViewPoint.transform.worldToLocalMatrix));
Shader.SetGlobalMatrix("SEGIVoxelViewTop_FAR", TransformViewMatrix(topViewPoint.transform.worldToLocalMatrix));
material.SetMatrix("SEGIWorldToVoxel", voxelCamera.worldToCameraMatrix);
material.SetMatrix("SEGIVoxelProjection", voxelCamera.projectionMatrix);
material.SetMatrix("SEGIVoxelProjectionInverse", voxelCamera.projectionMatrix.inverse);
//Shader.SetGlobalInt("SEGIVoxelResolution", (int)voxelResolution);
material.SetInt("SEGIVoxelResolution", (int)voxelResolution);
Matrix4x4 voxelToGIProjection = (shadowCam.projectionMatrix) * (shadowCam.worldToCameraMatrix) * (voxelCamera.cameraToWorldMatrix);
//Shader.SetGlobalMatrix("SEGIVoxelToGIProjection", voxelToGIProjection);
material.SetMatrix("SEGIVoxelToGIProjection", voxelToGIProjection);
Shader.SetGlobalVector("SEGISunlightVector", sun ? Vector3.Normalize(sun.transform.forward) : Vector3.up);
//Set paramteters
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 : 0.0f);
Shader.SetGlobalFloat("SEGISoftSunlight", softSunlight);
Shader.SetGlobalInt("SEGISphericalSkylight", sphericalSkylight ? 1 : 0);
Shader.SetGlobalInt("SEGIInnerOcclusionLayers", innerOcclusionLayers);
//Render the depth texture from the sun's perspective in order to inject sunlight with shadows during voxelization
if (sun != null)
{
if (renderSunWithSRP)
{
var urpAsset = (UniversalRenderPipelineAsset)GraphicsSettings.renderPipelineAsset;
var urpAsset0 = (UniversalRenderPipelineAsset)GraphicsSettings.defaultRenderPipeline;
GraphicsSettings.renderPipelineAsset = null;
GraphicsSettings.defaultRenderPipeline = null;
//v0.3
var urpAsset2 = (UniversalRenderPipelineAsset)QualitySettings.renderPipeline;
QualitySettings.renderPipeline = null;
shadowCam.cullingMask = giCullingMask;
Vector3 shadowCamPosition = voxelSpaceOrigin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio;
shadowCamTransform.position = shadowCamPosition;
shadowCamTransform.LookAt(voxelSpaceOrigin, Vector3.up);
shadowCam.renderingPath = RenderingPath.Forward;
shadowCam.depthTextureMode |= DepthTextureMode.None;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.farClipPlane = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio;
Graphics.SetRenderTarget(sunDepthTexture);
shadowCam.SetTargetBuffers(sunDepthTexture.colorBuffer, sunDepthTexture.depthBuffer);
shadowCam.RenderWithShader(sunDepthShader, "");
shadowCam.targetTexture = sunDepthTexture;
preRenderers.shader = sunDepthShader;
//UniversalRenderPipeline.RenderSingleCamera(context, shadowCam);
Shader.SetGlobalTexture("SEGISunDepth", sunDepthTexture);
//v0.3
if (urpAsset != null)
{
GraphicsSettings.renderPipelineAsset = urpAsset;
}
if (urpAsset2 != null)
{
QualitySettings.renderPipeline = urpAsset2;
}
if (urpAsset0 != null)
{
GraphicsSettings.defaultRenderPipeline = urpAsset0;
}
}
else
{
shadowCam.cullingMask = giCullingMask;
Vector3 shadowCamPosition = voxelSpaceOrigin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio;
shadowCamTransform.position = shadowCamPosition;
shadowCamTransform.LookAt(voxelSpaceOrigin, Vector3.up);
shadowCam.renderingPath = RenderingPath.Forward;
shadowCam.depthTextureMode |= DepthTextureMode.None;
shadowCam.orthographicSize = shadowSpaceSize;
shadowCam.farClipPlane = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio;
Graphics.SetRenderTarget(sunDepthTexture);
shadowCam.SetTargetBuffers(sunDepthTexture.colorBuffer, sunDepthTexture.depthBuffer);
//shadowCam.RenderWithShader(sunDepthShader, "");
shadowCam.targetTexture = sunDepthTexture;
preRenderers.shader = sunDepthShader;
UniversalRenderPipeline.RenderSingleCamera(context, shadowCam);
Shader.SetGlobalTexture("SEGISunDepth", sunDepthTexture);
}
}
//Clear the volume texture that is immediately written to in the voxelization scene shader
clearCompute.SetTexture(0, "RG0", integerVolume);
clearCompute.SetInt("Res", (int)voxelResolution);
clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
//v0.2
//RenderTexture gi1 = RenderTexture.GetTemporary(dummyVoxelTextureAAScaled.width, dummyVoxelTextureAAScaled.height, 0, RenderTextureFormat.ARGBHalf);
//voxelCamera.targetTexture = gi1;
//preRenderers.shader = null;
//UniversalRenderPipeline.RenderSingleCamera(context, voxelCamera);
//preRenderers.SetTexture("_MainTex", gi1);
//voxelCamera.targetTexture = dummyVoxelTextureAAScaled;
//v0.2
//if(gi1 == null)
//{
// gi1 = new RenderTexture(dummyVoxelTextureAAScaled.width, dummyVoxelTextureAAScaled.height, 0, RenderTextureFormat.ARGBHalf);
//}
// RenderTexture gi1 = RenderTexture.GetTemporary(dummyVoxelTextureAAScaled.width, dummyVoxelTextureAAScaled.height, 0, RenderTextureFormat.ARGBHalf);
//if (Camera.main != null && 1==1)
//{
// //Camera.main.targetTexture = gi1;
// if (savedCam == null)
// {
// GameObject savedCamOBJ = new GameObject();
// savedCam = savedCamOBJ.AddComponent<Camera>();
// savedCam.enabled = false;
// }
// savedCam.CopyFrom(voxelCamera);
// savedCam.enabled = false;
// savedCam.hideFlags = HideFlags.None;
// if (savedCam.targetTexture == null)
// {
// savedCam.targetTexture = gi1;
// }
// UniversalRenderPipeline.RenderSingleCamera(context, savedCam);
// preRenderers.SetTexture("_MainTex", gi1);
// //Camera.main.targetTexture = null;
// //Camera.main.CopyFrom(savedCam);
//}
//v0.2
//if (debugSceneColorMat != null)
//{
// debugSceneColorMat.SetTexture("_BaseMap", gi1);
//}
// preRenderers.SetTexture("_MainTex", gi1);
//if (savedCam != null)
//{
// savedCam.targetTexture = gi1;
// UniversalRenderPipeline.RenderSingleCamera(context, savedCam);
// preRenderers.SetTexture("_MainTex", gi1);
//}
if (!colorizeVolume)
{
//Render the scene with the voxel proxy camera object with the voxelization shader to voxelize the scene to the volume integer texture
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureAAScaled;
//v0.1
//voxelCamera.RenderWithShader(voxelizationShader, "");
if (proxyNoGeom) //v1.3
{
if (enableLocalLightGI)//v1.5
{
preRenderers.shader = voxelizationShaderVERTL;
}
else
{
preRenderers.shader = voxelizationShaderVERT;
}
}
else
{
if (enableLocalLightGI)//v1.5
{
preRenderers.shader = voxelizationShaderL;
}
else
{
preRenderers.shader = voxelizationShader;
}
}
//preRenderers.SetTexture("_MainTex", gi1);
UniversalRenderPipeline.RenderSingleCamera(context, voxelCamera);
Graphics.ClearRandomWriteTargets();
}
else
{
var urpAsset = (UniversalRenderPipelineAsset)GraphicsSettings.renderPipelineAsset;
var urpAsset0 = (UniversalRenderPipelineAsset)GraphicsSettings.defaultRenderPipeline;
GraphicsSettings.renderPipelineAsset = null;
GraphicsSettings.defaultRenderPipeline = null;
//v0.3
var urpAsset2 = (UniversalRenderPipelineAsset)QualitySettings.renderPipeline;
QualitySettings.renderPipeline = null;
//Render the scene with the voxel proxy camera object with the voxelization shader to voxelize the scene to the volume integer texture
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureAAScaled;
Shader.SetGlobalVector("_CutoffGI", cutoff); //v1.6
if (proxyNoGeom) //v1.3
{
if (enableLocalLightGI)//v1.5
{
Shader.SetGlobalFloat("shadowedLocalPower", shadowedLocalPower);
Shader.SetGlobalFloat("shadowlessLocalPower", shadowlessLocalPower);
Shader.SetGlobalFloat("shadowlessLocalOcclusion", shadowlessLocalOcclusion);
voxelCamera.RenderWithShader(voxelizationShaderVERTL, "");
}
else
{
voxelCamera.RenderWithShader(voxelizationShaderVERT, "");
}
}
else
{
if (enableLocalLightGI)//v1.5
{
Shader.SetGlobalFloat("shadowedLocalPower", shadowedLocalPower);
Shader.SetGlobalFloat("shadowlessLocalPower", shadowlessLocalPower);
Shader.SetGlobalFloat("shadowlessLocalOcclusion", shadowlessLocalOcclusion);
voxelCamera.RenderWithShader(voxelizationShaderL, "");
}
else
{
//v0.1
voxelCamera.RenderWithShader(voxelizationShader, "");
}
}
//preRenderers.shader = voxelizationShader;
//preRenderers.SetTexture("_MainTex", gi1);
//UniversalRenderPipeline.RenderSingleCamera(context, voxelCamera);
Graphics.ClearRandomWriteTargets();
//v0.3
if (urpAsset != null)
{
GraphicsSettings.renderPipelineAsset = urpAsset;
}
if (urpAsset2 != null)
{
QualitySettings.renderPipeline = urpAsset2;
}
if (urpAsset0 != null)
{
GraphicsSettings.defaultRenderPipeline = urpAsset0;
}
//UniversalRenderPipeline.RenderSingleCamera(context, Camera.main);
}
//v0.2
//gi1.Release();
// RenderTexture.ReleaseTemporary(gi1);
//Transfer the data from the volume integer texture to the main volume texture used for GI tracing.
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) * (int)voxelResolution);
transferIntsCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
//Shader.SetGlobalTexture("SEGIVolumeLevel0", activeVolume);
material.SetTexture("SEGIVolumeLevel0", activeVolume);
//Manually filter/render mip maps
for (int i = 0; i < numMipLevels - 1; i++)
{
RenderTexture source = volumeTextures[i];
if (i == 0)
{
source = activeVolume;
}
int destinationRes = (int)voxelResolution / Mathf.RoundToInt(Mathf.Pow((float)2, (float)i + 1.0f));
mipFilterCompute.SetInt("destinationRes", destinationRes);
mipFilterCompute.SetTexture(mipFilterKernel, "Source", source);
mipFilterCompute.SetTexture(mipFilterKernel, "Destination", volumeTextures[i + 1]);
//v0.6
int threadGroupSize = destinationRes / 8;
threadGroupSize = (threadGroupSize > 0) ? threadGroupSize : 1;
mipFilterCompute.Dispatch(mipFilterKernel, threadGroupSize, threadGroupSize, 1);
//mipFilterCompute.Dispatch(mipFilterKernel, destinationRes / 8, destinationRes / 8, 1);
// Shader.SetGlobalTexture("SEGIVolumeLevel" + (i + 1).ToString(), volumeTextures[i + 1]);
material.SetTexture("SEGIVolumeLevel" + (i + 1).ToString(), volumeTextures[i + 1]);
}
//Advance the voxel flip flop counter
voxelFlipFlop += 1;
voxelFlipFlop = voxelFlipFlop % 2;
if (infiniteBounces)
{
renderState = RenderState.Bounce;
}
//v0.2
// RenderTexture.ReleaseTemporary(gi1);
}
else if (renderState == RenderState.Bounce)
{
//Clear the volume texture that is immediately written to in the voxelization scene shader
clearCompute.SetTexture(0, "RG0", integerVolume);
clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);
//Set secondary tracing parameters
Shader.SetGlobalInt("SEGISecondaryCones", secondaryCones);
Shader.SetGlobalFloat("SEGISecondaryOcclusionStrength", secondaryOcclusionStrength);
////v0.2
//RenderTexture gi1 = RenderTexture.GetTemporary(dummyVoxelTextureAAScaled.width, dummyVoxelTextureAAScaled.height, 0, RenderTextureFormat.ARGBHalf);
//if (Camera.main != null && 1 == 1)
//{
// //Camera.main.targetTexture = gi1;
// if (savedCam == null)
// {
// GameObject savedCamOBJ = new GameObject();
// savedCam = savedCamOBJ.AddComponent<Camera>();
// savedCam.enabled = false;
// }
// savedCam.CopyFrom(voxelCamera);
// savedCam.enabled = false;
// savedCam.hideFlags = HideFlags.None;
// if (savedCam.targetTexture == null)
// {
// savedCam.targetTexture = gi1;
// }
// UniversalRenderPipeline.RenderSingleCamera(context, savedCam);
// preRenderers.SetTexture("_MainTex", gi1);
// //Camera.main.targetTexture = null;
// //Camera.main.CopyFrom(savedCam);
//}
if (!colorizeVolume || 1 == 1)
{
//Render the scene from the voxel camera object with the voxel tracing shader to render a bounce of GI into the irradiance volume
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureFixed;
//v0.1
//voxelCamera.RenderWithShader(voxelTracingShader, "");
//v1.3
if (proxyNoGeom)
{
preRenderers.shader = voxelTracingShaderVERT;
}
else
{
preRenderers.shader = voxelTracingShader;
}
UniversalRenderPipeline.RenderSingleCamera(context, voxelCamera);
Graphics.ClearRandomWriteTargets();
}
else
{
var urpAsset = (UniversalRenderPipelineAsset)GraphicsSettings.renderPipelineAsset;
GraphicsSettings.renderPipelineAsset = null;
//v0.3
var urpAsset2 = (UniversalRenderPipelineAsset)QualitySettings.renderPipeline;
QualitySettings.renderPipeline = null;
Graphics.SetRandomWriteTarget(1, integerVolume);
voxelCamera.targetTexture = dummyVoxelTextureFixed;
//v1.3
if (proxyNoGeom)
{
voxelCamera.RenderWithShader(voxelTracingShaderVERT, "");
}
else
{
//v0.1
voxelCamera.RenderWithShader(voxelTracingShader, "");
}
//preRenderers.shader = voxelTracingShader;
//UniversalRenderPipeline.RenderSingleCamera(context, voxelCamera);
Graphics.ClearRandomWriteTargets();
//v0.3
if (urpAsset != null)
{
GraphicsSettings.renderPipelineAsset = urpAsset;
}
if (urpAsset2 != null)
{
QualitySettings.renderPipeline = urpAsset2;
}
}
//v0.2
if (clearBounceCameraTarget)
{
voxelCamera.targetTexture = null;
}
//Transfer the data from the volume integer texture to the irradiance volume texture. This result is added to the next main voxelization pass to create a feedback loop for infinite bounces
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);
material.SetTexture("SEGIVolumeTexture1", secondaryIrradianceVolume);
renderState = RenderState.Voxelize;
//v0.2
//RenderTexture.ReleaseTemporary(gi1);
}
//v0.1 - added so depth texture returns to main camera one !!!!!!!!!!!!!!!!!
//UniversalRenderPipeline.RenderSingleCamera(context, Camera.main);
RenderTexture.active = previousActive;
}
//[ImageEffectOpaque]
//void OnRenderImage(RenderTexture source, RenderTexture destination)
//{
// if (notReadyToRender)
// {
// Graphics.Blit(source, destination);
// return;
// }
// //Set parameters
// 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", 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 Visualize Voxels is enabled, just render the voxel visualization shader pass and return
// if (visualizeVoxels)
// {
// Graphics.Blit(source, destination, material, Pass.VisualizeVoxels);
// return;
// }
// //Setup temporary textures
// RenderTexture gi1 = RenderTexture.GetTemporary(source.width / giRenderRes, source.height / giRenderRes, 0, RenderTextureFormat.ARGBHalf);
// RenderTexture gi2 = RenderTexture.GetTemporary(source.width / giRenderRes, source.height / giRenderRes, 0, RenderTextureFormat.ARGBHalf);
// RenderTexture reflections = null;
// //If reflections are enabled, create a temporary render buffer to hold them
// if (doReflections)
// {
// reflections = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
// }
// //Setup textures to hold the current camera depth and normal
// RenderTexture currentDepth = RenderTexture.GetTemporary(source.width / giRenderRes, source.height / giRenderRes, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
// currentDepth.filterMode = FilterMode.Point;
// RenderTexture currentNormal = RenderTexture.GetTemporary(source.width / giRenderRes, source.height / giRenderRes, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
// currentNormal.filterMode = FilterMode.Point;
// //Get the camera depth and normals
// Graphics.Blit(source, currentDepth, material, Pass.GetCameraDepthTexture);
// material.SetTexture("CurrentDepth", currentDepth);
// Graphics.Blit(source, currentNormal, material, Pass.GetWorldNormals);
// material.SetTexture("CurrentNormal", currentNormal);
// //Set the previous GI result and camera depth textures to access them in the shader
// material.SetTexture("PreviousGITexture", previousGIResult);
// Shader.SetGlobalTexture("PreviousGITexture", previousGIResult);
// material.SetTexture("PreviousDepth", previousCameraDepth);
// //Render diffuse GI tracing result
// Graphics.Blit(source, gi2, material, Pass.DiffuseTrace);
// if (doReflections)
// {
// //Render GI reflections result
// Graphics.Blit(source, reflections, material, Pass.SpecularTrace);
// material.SetTexture("Reflections", reflections);
// }
// //Perform bilateral filtering
// if (useBilateralFiltering)
// {
// material.SetVector("Kernel", new Vector2(0.0f, 1.0f));
// Graphics.Blit(gi2, gi1, material, Pass.BilateralBlur);
// material.SetVector("Kernel", new Vector2(1.0f, 0.0f));
// Graphics.Blit(gi1, gi2, material, Pass.BilateralBlur);
// material.SetVector("Kernel", new Vector2(0.0f, 1.0f));
// Graphics.Blit(gi2, gi1, material, Pass.BilateralBlur);
// material.SetVector("Kernel", new Vector2(1.0f, 0.0f));
// Graphics.Blit(gi1, gi2, material, Pass.BilateralBlur);
// }
// //If Half Resolution tracing is enabled
// if (giRenderRes == 2)
// {
// RenderTexture.ReleaseTemporary(gi1);
// //Setup temporary textures
// RenderTexture gi3 = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
// RenderTexture gi4 = RenderTexture.GetTemporary(source.width, source.height, 0, RenderTextureFormat.ARGBHalf);
// //Prepare the half-resolution diffuse GI result to be bilaterally upsampled
// gi2.filterMode = FilterMode.Point;
// Graphics.Blit(gi2, gi4);
// RenderTexture.ReleaseTemporary(gi2);
// gi4.filterMode = FilterMode.Point;
// gi3.filterMode = FilterMode.Point;
// //Perform bilateral upsampling on half-resolution diffuse GI result
// material.SetVector("Kernel", new Vector2(1.0f, 0.0f));
// Graphics.Blit(gi4, gi3, material, Pass.BilateralUpsample);
// material.SetVector("Kernel", new Vector2(0.0f, 1.0f));
// //Perform temporal reprojection and blending
// if (temporalBlendWeight < 1.0f)
// {
// Graphics.Blit(gi3, gi4);
// Graphics.Blit(gi4, gi3, material, Pass.TemporalBlend);
// Graphics.Blit(gi3, previousGIResult);
// Graphics.Blit(source, previousCameraDepth, material, Pass.GetCameraDepthTexture);
// }
// //Set the result to be accessed in the shader
// material.SetTexture("GITexture", gi3);
// //Actually apply the GI to the scene using gbuffer data
// Graphics.Blit(source, destination, material, visualizeGI ? Pass.VisualizeGI : Pass.BlendWithScene);
// //Release temporary textures
// RenderTexture.ReleaseTemporary(gi3);
// RenderTexture.ReleaseTemporary(gi4);
// }
// else //If Half Resolution tracing is disabled
// {
// //Perform temporal reprojection and blending
// if (temporalBlendWeight < 1.0f)
// {
// Graphics.Blit(gi2, gi1, material, Pass.TemporalBlend);
// Graphics.Blit(gi1, previousGIResult);
// Graphics.Blit(source, previousCameraDepth, material, Pass.GetCameraDepthTexture);
// }
// //Actually apply the GI to the scene using gbuffer data
// material.SetTexture("GITexture", temporalBlendWeight < 1.0f ? gi1 : gi2);
// Graphics.Blit(source, destination, material, visualizeGI ? Pass.VisualizeGI : Pass.BlendWithScene);
// //Release temporary textures
// RenderTexture.ReleaseTemporary(gi1);
// RenderTexture.ReleaseTemporary(gi2);
// }
// //Release temporary textures
// RenderTexture.ReleaseTemporary(currentDepth);
// RenderTexture.ReleaseTemporary(currentNormal);
// //Visualize the sun depth texture
// if (visualizeSunDepthTexture)
// Graphics.Blit(sunDepthTexture, destination);
// //Release the temporary reflections result texture
// if (doReflections)
// {
// RenderTexture.ReleaseTemporary(reflections);
// }
// //Set matrices/vectors for use during temporal reprojection
// material.SetMatrix("ProjectionPrev", attachedCamera.projectionMatrix);
// material.SetMatrix("ProjectionPrevInverse", attachedCamera.projectionMatrix.inverse);
// material.SetMatrix("WorldToCameraPrev", attachedCamera.worldToCameraMatrix);
// material.SetMatrix("CameraToWorldPrev", attachedCamera.cameraToWorldMatrix);
// material.SetVector("CameraPositionPrev", transform.position);
// //Advance the frame counter
// frameCounter = (frameCounter + 1) % (64);
//}
}
}