Raymarching Cleanup
Removed redundant code from raymarching implementation Moved last remaining raymarching variable (Extinction) to environment settings
This commit is contained in:
parent
e585a8c3b1
commit
d61d2f19ed
150 changed files with 187 additions and 8921 deletions
|
|
@ -27,6 +27,7 @@ public class NebulaSettings
|
|||
[JsonProperty("fogBlend"), Key(5)] public float FloorBlend;
|
||||
[JsonProperty("cloudBlend"), Key(6)] public float PatchBlend;
|
||||
[JsonProperty("luminance"), Key(7)] public float Luminance;
|
||||
[JsonProperty("extinction"), Key(13)] public float Extinction;
|
||||
[JsonProperty("tintExponent"), Key(8)] public float TintExponent;
|
||||
[JsonProperty("tintLodExponent"), Key(9)] public float TintLodExponent;
|
||||
[JsonProperty("safetyDistance"), Key(10)] public float SafetyDistance;
|
||||
|
|
|
|||
159
Assets/Scripts/Zone Display/VolumeCloudRenderer.cs
Normal file
159
Assets/Scripts/Zone Display/VolumeCloudRenderer.cs
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
/// <summary>
|
||||
/// Based on github.com/yangrc1234/VolumeCloud
|
||||
/// Generate halton sequence.
|
||||
/// code from unity post-processing stack.
|
||||
/// </summary>
|
||||
public class HaltonSequence {
|
||||
public int radix = 3;
|
||||
private int storedIndex = 0;
|
||||
public float Get() {
|
||||
float result = 0f;
|
||||
float fraction = 1f / (float)radix;
|
||||
int index = storedIndex;
|
||||
while (index > 0) {
|
||||
result += (float)(index % radix) * fraction;
|
||||
|
||||
index /= radix;
|
||||
fraction /= (float)radix;
|
||||
}
|
||||
storedIndex++;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Quality {
|
||||
Low,
|
||||
Normal, //Low sample count
|
||||
High, //High sample count and high shadow sample count.
|
||||
Ultra
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cloud renderer post processing.
|
||||
/// </summary>
|
||||
[ImageEffectAllowedInSceneView]
|
||||
[ExecuteInEditMode,RequireComponent(typeof(Camera))]
|
||||
[ImageEffectOpaque]
|
||||
public class VolumeCloudRenderer : EffectBase {
|
||||
[Header("Render Settings")]
|
||||
[Range(0, 2)]
|
||||
public int downSample = 1;
|
||||
public Quality quality;
|
||||
|
||||
private Material mat;
|
||||
private RenderTexture[] fullBuffer;
|
||||
private int fullBufferIndex;
|
||||
private RenderTexture undersampleBuffer;
|
||||
private Matrix4x4 prevV;
|
||||
private Camera mcam;
|
||||
private HaltonSequence sequence = new HaltonSequence() { radix = 3 };
|
||||
// The index of 4x4 pixels.
|
||||
private int frameIndex = 0;
|
||||
private float bayerOffsetIndex = 0;
|
||||
private bool firstFrame = true;
|
||||
|
||||
[SerializeField]
|
||||
private Shader cloudShader;
|
||||
|
||||
void EnsureMaterial(bool force = false) {
|
||||
if (mat == null || force) {
|
||||
mat = new Material(cloudShader);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy() {
|
||||
if (this.fullBuffer != null) {
|
||||
for (int i = 0; i < fullBuffer.Length; i++) {
|
||||
fullBuffer[i].Release();
|
||||
fullBuffer[i] = null;
|
||||
}
|
||||
}
|
||||
if (this.undersampleBuffer != null) {
|
||||
this.undersampleBuffer.Release();
|
||||
this.undersampleBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start() {
|
||||
this.EnsureMaterial(true);
|
||||
}
|
||||
|
||||
[ImageEffectOpaque]
|
||||
private void OnRenderImage(RenderTexture source, RenderTexture destination) {
|
||||
if (cloudShader == null) {
|
||||
Graphics.Blit(source, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
mcam = GetComponent<Camera>();
|
||||
var width = mcam.pixelWidth >> downSample;
|
||||
var height = mcam.pixelHeight >> downSample;
|
||||
|
||||
this.EnsureMaterial();
|
||||
|
||||
EnsureArray(ref fullBuffer, 2);
|
||||
firstFrame |= EnsureRenderTarget(ref fullBuffer[0], width, height, RenderTextureFormat.ARGBFloat, FilterMode.Bilinear);
|
||||
firstFrame |= EnsureRenderTarget(ref fullBuffer[1], width, height, RenderTextureFormat.ARGBFloat, FilterMode.Bilinear);
|
||||
firstFrame |= EnsureRenderTarget(ref undersampleBuffer, width , height, RenderTextureFormat.ARGBFloat, FilterMode.Bilinear);
|
||||
|
||||
frameIndex = (frameIndex + 1)% 16;
|
||||
fullBufferIndex = (fullBufferIndex + 1) % 2;
|
||||
|
||||
/* Some code is from playdead TAA. */
|
||||
|
||||
//1. Pass1, Render a undersampled buffer. The buffer is dithered using bayer matrix(every 3x3 pixel) and halton sequence.
|
||||
//If it's first frame, force a high quality sample to make the initial history buffer good enough.
|
||||
if (firstFrame || quality == Quality.Ultra) {
|
||||
mat.EnableKeyword("ULTRA_QUALITY");
|
||||
mat.DisableKeyword("HIGH_QUALITY");
|
||||
mat.DisableKeyword("MEDIUM_QUALITY");
|
||||
mat.DisableKeyword("LOW_QUALITY");
|
||||
} else if (quality == Quality.High) {
|
||||
mat.DisableKeyword("ULTRA_QUALITY");
|
||||
mat.EnableKeyword("HIGH_QUALITY");
|
||||
mat.DisableKeyword("MEDIUM_QUALITY");
|
||||
mat.DisableKeyword("LOW_QUALITY");
|
||||
} else if (quality == Quality.Normal) {
|
||||
mat.DisableKeyword("ULTRA_QUALITY");
|
||||
mat.DisableKeyword("HIGH_QUALITY");
|
||||
mat.EnableKeyword("MEDIUM_QUALITY");
|
||||
mat.DisableKeyword("LOW_QUALITY");
|
||||
} else if (quality == Quality.Low) {
|
||||
mat.DisableKeyword("ULTRA_QUALITY");
|
||||
mat.DisableKeyword("HIGH_QUALITY");
|
||||
mat.DisableKeyword("MEDIUM_QUALITY");
|
||||
mat.EnableKeyword("LOW_QUALITY");
|
||||
}
|
||||
|
||||
mat.SetVector("_ProjectionExtents", mcam.GetProjectionExtents());
|
||||
mat.SetFloat("_RaymarchOffset", sequence.Get());
|
||||
mat.SetVector("_TexelSize", undersampleBuffer.texelSize);
|
||||
|
||||
Graphics.Blit(null, undersampleBuffer, mat, 0);
|
||||
|
||||
//2. Pass 2, blend undersampled image with history buffer to new buffer.
|
||||
mat.SetTexture("_UndersampleCloudTex", undersampleBuffer);
|
||||
mat.SetMatrix("_PrevVP", GL.GetGPUProjectionMatrix(mcam.projectionMatrix,false) * prevV);
|
||||
mat.SetVector("_ProjectionExtents", mcam.GetProjectionExtents());
|
||||
|
||||
if (firstFrame) { //Wait, is this the first frame? If it is, the history buffer is empty yet. It will cause glitch if we use it directly. Fill it using the undersample buffer.
|
||||
Graphics.Blit(undersampleBuffer, fullBuffer[fullBufferIndex]);
|
||||
}
|
||||
Graphics.Blit(fullBuffer[fullBufferIndex], fullBuffer[fullBufferIndex ^ 1], mat, 1);
|
||||
|
||||
//3. Pass3, Calculate lighting, blend final cloud image with final image.
|
||||
mat.SetTexture("_CloudTex", fullBuffer[fullBufferIndex ^ 1]);
|
||||
Graphics.Blit(source, destination, mat, 2);
|
||||
|
||||
//4. Cleanup
|
||||
prevV = mcam.worldToCameraMatrix;
|
||||
firstFrame = false;
|
||||
}
|
||||
}
|
||||
19
Assets/Scripts/Zone Display/VolumeCloudRenderer.cs.meta
Normal file
19
Assets/Scripts/Zone Display/VolumeCloudRenderer.cs.meta
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9f1db61281524fb40bc9a1f6acce6baf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- cloudShader: {fileID: 4800000, guid: 84e97169589c5e94e8521fe4deb2e3f8, type: 3}
|
||||
- configuration: {fileID: 11400000, guid: a15886e93ac3e7847861da392782f13d, type: 2}
|
||||
- heightPreprocessShader: {fileID: 7200000, guid: 40276bd53f35a694e8d4e025ca310775,
|
||||
type: 3}
|
||||
- cloudHeightProcessShader: {fileID: 4800000, guid: b80bf04ca56d3d642a6b925cff3f5ddf,
|
||||
type: 3}
|
||||
- heightLutTexture: {instanceID: 0}
|
||||
- hiHeightTexture: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -17,12 +17,12 @@ using static Unity.Mathematics.noise;
|
|||
[RequireComponent( typeof( Camera ) )]
|
||||
public class VolumeSampling : MonoBehaviour
|
||||
{
|
||||
public Material VolMaterial;
|
||||
//public Material VolMaterial;
|
||||
public Transform GridTransform;
|
||||
public GameSettings Settings;
|
||||
//public int DownsampleBlurMask = 2;
|
||||
private Camera _camera;
|
||||
private RenderBuffer[] _mrt;
|
||||
// private Camera _camera;
|
||||
// private RenderBuffer[] _mrt;
|
||||
private Texture2D _blurMask;
|
||||
private Texture2D _disabledBlurMask;
|
||||
private float _flowScroll;
|
||||
|
|
@ -38,17 +38,13 @@ public class VolumeSampling : MonoBehaviour
|
|||
private void Start()
|
||||
{
|
||||
//Debug.Log($"Supported MRT count: {SystemInfo.supportedRenderTargetCount}");
|
||||
_camera = GetComponent<Camera>();
|
||||
_mrt = new RenderBuffer[2];
|
||||
// _camera = GetComponent<Camera>();
|
||||
// _mrt = new RenderBuffer[2];
|
||||
//_blurMask = new RenderTexture(Screen.width, Screen.height, 0, GraphicsFormat.R8_UNorm);
|
||||
_blurMask = Color.white.ToTexture();
|
||||
_disabledBlurMask = Color.black.ToTexture();
|
||||
}
|
||||
|
||||
private void OnPreRender()
|
||||
{
|
||||
}
|
||||
|
||||
//[ImageEffectOpaque]
|
||||
void Update()
|
||||
{
|
||||
|
|
@ -97,6 +93,7 @@ public class VolumeSampling : MonoBehaviour
|
|||
Shader.SetGlobalFloat("_NebulaFloorBlend", Settings.DefaultEnvironment.Nebula.FloorBlend);
|
||||
Shader.SetGlobalFloat("_NebulaPatchBlend", Settings.DefaultEnvironment.Nebula.PatchBlend);
|
||||
Shader.SetGlobalFloat("_NebulaLuminance", Settings.DefaultEnvironment.Nebula.Luminance);
|
||||
Shader.SetGlobalFloat("_ExtinctionCoefficient", Settings.DefaultEnvironment.Nebula.Extinction);
|
||||
Shader.SetGlobalFloat("_TintExponent", Settings.DefaultEnvironment.Nebula.TintExponent);
|
||||
Shader.SetGlobalFloat("_TintLodExponent", Settings.DefaultEnvironment.Nebula.TintLodExponent);
|
||||
Shader.SetGlobalFloat("_SafetyDistance", Settings.DefaultEnvironment.Nebula.SafetyDistance);
|
||||
|
|
|
|||
Loading…
Reference in a new issue