275 lines
8.4 KiB
C#
275 lines
8.4 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Artngame.SKYMASTER
|
|
{
|
|
[ExecuteInEditMode]
|
|
[RequireComponent(typeof(Camera), typeof(FrustumJitter))]
|
|
public class VelocityBuffer : EffectBase
|
|
{
|
|
public enum NeighborMaxSupport
|
|
{
|
|
TileSize10 = 0,
|
|
TileSize20 = 1,
|
|
TileSize40 = 2
|
|
}
|
|
|
|
private const RenderTextureFormat velocityFormat = RenderTextureFormat.RGFloat;
|
|
|
|
private Camera _camera;
|
|
|
|
private FrustumJitter _frustumJitter;
|
|
|
|
public Shader velocityShader;
|
|
|
|
private Material velocityMaterial;
|
|
|
|
private RenderTexture[] velocityBuffer;
|
|
|
|
private RenderTexture[] velocityNeighborMax;
|
|
|
|
private bool[] paramInitialized;
|
|
|
|
private Vector4[] paramProjectionExtents;
|
|
|
|
private Matrix4x4[] paramCurrV;
|
|
|
|
private Matrix4x4[] paramCurrVP;
|
|
|
|
private Matrix4x4[] paramPrevVP;
|
|
|
|
private Matrix4x4[] paramPrevVP_NoFlip;
|
|
|
|
private int activeEyeIndex = -1;
|
|
|
|
public bool neighborMaxGen;
|
|
|
|
public NeighborMaxSupport neighborMaxSupport = NeighborMaxSupport.TileSize20;
|
|
|
|
private float timeScaleNextFrame;
|
|
|
|
public RenderTexture activeVelocityBuffer
|
|
{
|
|
get
|
|
{
|
|
if (activeEyeIndex == -1)
|
|
{
|
|
return null;
|
|
}
|
|
return velocityBuffer[activeEyeIndex];
|
|
}
|
|
}
|
|
|
|
public RenderTexture activeVelocityNeighborMax
|
|
{
|
|
get
|
|
{
|
|
if (activeEyeIndex == -1)
|
|
{
|
|
return null;
|
|
}
|
|
return velocityNeighborMax[activeEyeIndex];
|
|
}
|
|
}
|
|
|
|
public float timeScale { get; private set; }
|
|
|
|
private void Reset()
|
|
{
|
|
_camera = GetComponent<Camera>();
|
|
_frustumJitter = GetComponent<FrustumJitter>();
|
|
}
|
|
|
|
private void Clear()
|
|
{
|
|
EnsureArray(ref paramInitialized, 2, initialValue: false);
|
|
paramInitialized[0] = false;
|
|
paramInitialized[1] = false;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
Reset();
|
|
Clear();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
timeScaleNextFrame = Time.timeScale;
|
|
if (_camera == null)
|
|
{
|
|
_camera = GetComponent<Camera>();
|
|
}
|
|
if (_frustumJitter == null)
|
|
{
|
|
_frustumJitter = GetComponent<FrustumJitter>();
|
|
}
|
|
}
|
|
|
|
private void OnPreRender()
|
|
{
|
|
if (_camera == null)
|
|
{
|
|
_camera = GetComponent<Camera>();
|
|
}
|
|
if (_frustumJitter == null)
|
|
{
|
|
_frustumJitter = GetComponent<FrustumJitter>();
|
|
}
|
|
EnsureDepthTexture(_camera);
|
|
}
|
|
|
|
private void OnPostRender()
|
|
{
|
|
EnsureArray(ref velocityBuffer, 2);
|
|
EnsureArray(ref velocityNeighborMax, 2);
|
|
EnsureArray(ref paramInitialized, 2, initialValue: false);
|
|
EnsureArray(ref paramProjectionExtents, 2);
|
|
EnsureArray(ref paramCurrV, 2);
|
|
EnsureArray(ref paramCurrVP, 2);
|
|
EnsureArray(ref paramPrevVP, 2);
|
|
EnsureArray(ref paramPrevVP_NoFlip, 2);
|
|
EnsureMaterial(ref velocityMaterial, velocityShader);
|
|
if (velocityMaterial == null)
|
|
{
|
|
return;
|
|
}
|
|
timeScale = timeScaleNextFrame;
|
|
timeScaleNextFrame = ((Time.timeScale == 0f) ? timeScaleNextFrame : Time.timeScale);
|
|
if (_camera == null)
|
|
{
|
|
_camera = GetComponent<Camera>();
|
|
}
|
|
if (_frustumJitter == null)
|
|
{
|
|
_frustumJitter = GetComponent<FrustumJitter>();
|
|
}
|
|
int num = ((_camera.stereoActiveEye == Camera.MonoOrStereoscopicEye.Right) ? 1 : 0);
|
|
int pixelWidth = _camera.pixelWidth;
|
|
int pixelHeight = _camera.pixelHeight;
|
|
if (EnsureRenderTarget(ref velocityBuffer[num], pixelWidth, pixelHeight, RenderTextureFormat.RGFloat, FilterMode.Point, 16))
|
|
{
|
|
Clear();
|
|
}
|
|
EnsureKeyword(velocityMaterial, "CAMERA_PERSPECTIVE", !_camera.orthographic);
|
|
EnsureKeyword(velocityMaterial, "CAMERA_ORTHOGRAPHIC", _camera.orthographic);
|
|
EnsureKeyword(velocityMaterial, "TILESIZE_10", neighborMaxSupport == NeighborMaxSupport.TileSize10);
|
|
EnsureKeyword(velocityMaterial, "TILESIZE_20", neighborMaxSupport == NeighborMaxSupport.TileSize20);
|
|
EnsureKeyword(velocityMaterial, "TILESIZE_40", neighborMaxSupport == NeighborMaxSupport.TileSize40);
|
|
if (_camera.stereoEnabled)
|
|
{
|
|
for (int i = 0; i != 2; i++)
|
|
{
|
|
Camera.StereoscopicEye eye = (Camera.StereoscopicEye)i;
|
|
Matrix4x4 stereoViewMatrix = _camera.GetStereoViewMatrix(eye);
|
|
Matrix4x4 gPUProjectionMatrix = GL.GetGPUProjectionMatrix(_camera.GetStereoProjectionMatrix(eye), renderIntoTexture: true);
|
|
Matrix4x4 gPUProjectionMatrix2 = GL.GetGPUProjectionMatrix(_camera.GetStereoProjectionMatrix(eye), renderIntoTexture: false);
|
|
Matrix4x4 matrix4x = (paramInitialized[i] ? paramCurrV[i] : stereoViewMatrix);
|
|
paramInitialized[i] = true;
|
|
paramProjectionExtents[i] = _camera.GetProjectionExtents(eye);
|
|
paramCurrV[i] = stereoViewMatrix;
|
|
paramCurrVP[i] = gPUProjectionMatrix * stereoViewMatrix;
|
|
paramPrevVP[i] = gPUProjectionMatrix * matrix4x;
|
|
paramPrevVP_NoFlip[i] = gPUProjectionMatrix2 * matrix4x;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Matrix4x4 worldToCameraMatrix = _camera.worldToCameraMatrix;
|
|
Matrix4x4 gPUProjectionMatrix3 = GL.GetGPUProjectionMatrix(_camera.projectionMatrix, renderIntoTexture: true);
|
|
Matrix4x4 gPUProjectionMatrix4 = GL.GetGPUProjectionMatrix(_camera.projectionMatrix, renderIntoTexture: false);
|
|
Matrix4x4 matrix4x2 = (paramInitialized[0] ? paramCurrV[0] : worldToCameraMatrix);
|
|
paramInitialized[0] = true;
|
|
paramProjectionExtents[0] = (_frustumJitter.enabled ? _camera.GetProjectionExtents(_frustumJitter.activeSample.x, _frustumJitter.activeSample.y) : _camera.GetProjectionExtents());
|
|
paramCurrV[0] = worldToCameraMatrix;
|
|
paramCurrVP[0] = gPUProjectionMatrix3 * worldToCameraMatrix;
|
|
paramPrevVP[0] = gPUProjectionMatrix3 * matrix4x2;
|
|
paramPrevVP_NoFlip[0] = gPUProjectionMatrix4 * matrix4x2;
|
|
}
|
|
RenderTexture active = RenderTexture.active;
|
|
RenderTexture.active = velocityBuffer[num];
|
|
GL.Clear(clearDepth: true, clearColor: true, Color.black);
|
|
velocityMaterial.SetVectorArray("_ProjectionExtents", paramProjectionExtents);
|
|
velocityMaterial.SetMatrixArray("_CurrV", paramCurrV);
|
|
velocityMaterial.SetMatrixArray("_CurrVP", paramCurrVP);
|
|
velocityMaterial.SetMatrixArray("_PrevVP", paramPrevVP);
|
|
velocityMaterial.SetMatrixArray("_PrevVP_NoFlip", paramPrevVP_NoFlip);
|
|
velocityMaterial.SetPass(0);
|
|
DrawFullscreenQuad();
|
|
List<VelocityBufferTag> activeObjects = VelocityBufferTag.activeObjects;
|
|
int j = 0;
|
|
for (int count = activeObjects.Count; j != count; j++)
|
|
{
|
|
VelocityBufferTag velocityBufferTag = activeObjects[j];
|
|
if (velocityBufferTag != null && velocityBufferTag.rendering && velocityBufferTag.mesh != null)
|
|
{
|
|
velocityMaterial.SetMatrix("_CurrM", velocityBufferTag.localToWorldCurr);
|
|
velocityMaterial.SetMatrix("_PrevM", velocityBufferTag.localToWorldPrev);
|
|
velocityMaterial.SetPass((!velocityBufferTag.meshSmrActive) ? 1 : 2);
|
|
for (int k = 0; k != velocityBufferTag.mesh.subMeshCount; k++)
|
|
{
|
|
Graphics.DrawMeshNow(velocityBufferTag.mesh, Matrix4x4.identity, k);
|
|
}
|
|
}
|
|
}
|
|
if (neighborMaxGen)
|
|
{
|
|
int num2 = 1;
|
|
switch (neighborMaxSupport)
|
|
{
|
|
case NeighborMaxSupport.TileSize10:
|
|
num2 = 10;
|
|
break;
|
|
case NeighborMaxSupport.TileSize20:
|
|
num2 = 20;
|
|
break;
|
|
case NeighborMaxSupport.TileSize40:
|
|
num2 = 40;
|
|
break;
|
|
}
|
|
int num3 = pixelWidth / num2;
|
|
int num4 = pixelHeight / num2;
|
|
EnsureRenderTarget(ref velocityNeighborMax[num], num3, num4, RenderTextureFormat.RGFloat, FilterMode.Bilinear);
|
|
RenderTexture renderTexture = (RenderTexture.active = RenderTexture.GetTemporary(num3, num4, 0, RenderTextureFormat.RGFloat));
|
|
velocityMaterial.SetTexture("_VelocityTex", velocityBuffer[num]);
|
|
velocityMaterial.SetVector("_VelocityTex_TexelSize", new Vector4(1f / (float)pixelWidth, 1f / (float)pixelHeight, 0f, 0f));
|
|
velocityMaterial.SetPass(3);
|
|
DrawFullscreenQuad();
|
|
RenderTexture.active = velocityNeighborMax[num];
|
|
velocityMaterial.SetTexture("_VelocityTex", renderTexture);
|
|
velocityMaterial.SetVector("_VelocityTex_TexelSize", new Vector4(1f / (float)num3, 1f / (float)num4, 0f, 0f));
|
|
velocityMaterial.SetPass(4);
|
|
DrawFullscreenQuad();
|
|
RenderTexture.ReleaseTemporary(renderTexture);
|
|
}
|
|
else
|
|
{
|
|
ReleaseRenderTarget(ref velocityNeighborMax[0]);
|
|
ReleaseRenderTarget(ref velocityNeighborMax[1]);
|
|
}
|
|
RenderTexture.active = active;
|
|
activeEyeIndex = num;
|
|
}
|
|
|
|
private void OnApplicationQuit()
|
|
{
|
|
if (velocityBuffer != null)
|
|
{
|
|
if (velocityBuffer.Length != 0)
|
|
{
|
|
ReleaseRenderTarget(ref velocityBuffer[0]);
|
|
}
|
|
if (velocityBuffer.Length > 1)
|
|
{
|
|
ReleaseRenderTarget(ref velocityBuffer[1]);
|
|
}
|
|
}
|
|
if (velocityNeighborMax != null)
|
|
{
|
|
ReleaseRenderTarget(ref velocityNeighborMax[0]);
|
|
ReleaseRenderTarget(ref velocityNeighborMax[1]);
|
|
}
|
|
}
|
|
}
|
|
}
|