fix:代码提初始化
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
#if ENVIRO_HDRP
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Rendering.HighDefinition;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace Enviro
|
||||
{
|
||||
class EnviroHDRPCustomPass : CustomPass
|
||||
{
|
||||
private Material blitTrough;
|
||||
private List<EnviroVolumetricCloudRenderer> volumetricCloudsRender = new List<EnviroVolumetricCloudRenderer>();
|
||||
private Vector3 floatingPointOriginMod = Vector3.zero;
|
||||
|
||||
private RTHandle sourceHandle;
|
||||
private RTHandle temp1Handle;
|
||||
private RTHandle temp2Handle;
|
||||
|
||||
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
|
||||
{
|
||||
if (blitTrough == null)
|
||||
blitTrough = new Material(Shader.Find("Hidden/Enviro/BlitTroughHDRP"));
|
||||
|
||||
// We allocate persistent RTHandles dynamically when Execute runs for the first time
|
||||
sourceHandle = null;
|
||||
temp1Handle = null;
|
||||
temp2Handle = null;
|
||||
}
|
||||
|
||||
|
||||
public RTHandle ReallocateIfNeeded(RTHandle handle, RenderTextureDescriptor desc, string name)
|
||||
{
|
||||
bool needsRealloc = handle == null || handle.rt == null;
|
||||
|
||||
if (!needsRealloc)
|
||||
{
|
||||
var hDesc = handle.rt.descriptor;
|
||||
|
||||
// Compare only the format & dimension
|
||||
if (hDesc.graphicsFormat != desc.graphicsFormat ||
|
||||
hDesc.dimension != desc.dimension)
|
||||
{
|
||||
needsRealloc = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsRealloc)
|
||||
{
|
||||
if (handle != null)
|
||||
RTHandles.Release(handle);
|
||||
|
||||
// Allocate with scale = 1, dynamic scaling will adjust automatically
|
||||
handle = RTHandles.Alloc(
|
||||
Vector2.one,
|
||||
colorFormat: desc.graphicsFormat,
|
||||
dimension: desc.dimension,
|
||||
enableRandomWrite: false,
|
||||
useMipMap: desc.useMipMap,
|
||||
name: name,
|
||||
useDynamicScale: true
|
||||
);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
protected override void Execute(CustomPassContext ctx)
|
||||
{
|
||||
HDCamera camera = ctx.hdCamera;
|
||||
|
||||
if (ctx.cameraColorBuffer == null || ctx.cameraColorBuffer.rt == null ||
|
||||
camera.camera.cameraType == CameraType.Preview ||
|
||||
!EnviroHelper.CanRenderOnCamera(camera.camera) || EnviroManager.instance == null && EnviroManager.instance.configuration != null)
|
||||
return;
|
||||
|
||||
|
||||
var desc = ctx.cameraColorBuffer.rt.descriptor;
|
||||
|
||||
// Reallocate only if needed
|
||||
sourceHandle = ReallocateIfNeeded(sourceHandle, desc, "Enviro Source");
|
||||
temp1Handle = ReallocateIfNeeded(temp1Handle, desc, "Enviro Temp1");
|
||||
|
||||
if (EnviroManager.instance.VolumetricClouds != null && EnviroManager.instance.VolumetricClouds.settingsGlobal.cloudShadows)
|
||||
temp2Handle = ReallocateIfNeeded(temp2Handle, desc, "Enviro Temp2");
|
||||
|
||||
|
||||
|
||||
// Copy camera buffer to persistent source
|
||||
HDUtils.BlitCameraTexture(ctx.cmd, ctx.cameraColorBuffer, sourceHandle);
|
||||
|
||||
// Get quality and flags
|
||||
EnviroQuality myQuality = EnviroHelper.GetQualityForCamera(camera.camera);
|
||||
bool renderVolumetricClouds = EnviroManager.instance.VolumetricClouds != null && myQuality.volumetricCloudsOverride.volumetricClouds;
|
||||
bool renderFog = EnviroManager.instance.Fog != null && myQuality.fogOverride.fog;
|
||||
|
||||
floatingPointOriginMod = EnviroManager.instance.Objects?.worldAnchor != null
|
||||
? EnviroManager.instance.Objects.worldAnchor.transform.position
|
||||
: Vector3.zero;
|
||||
|
||||
// Ensure clouds renderer exists
|
||||
if (renderVolumetricClouds && GetCloudsRenderer(camera.camera) == null)
|
||||
CreateCloudsRenderer(camera.camera);
|
||||
|
||||
SetMatrix(camera.camera);
|
||||
|
||||
EnviroVolumetricCloudRenderer renderer = GetCloudsRenderer(camera.camera);
|
||||
|
||||
// ----- Depth-aware render logic -----
|
||||
if (renderVolumetricClouds && renderFog)
|
||||
{
|
||||
if (camera.camera.transform.position.y - floatingPointOriginMod.y < EnviroManager.instance.VolumetricClouds.settingsVolume.bottomCloudsHeight)
|
||||
{
|
||||
EnviroManager.instance.VolumetricClouds.RenderVolumetricCloudsHDRP(camera.camera, ctx.cmd, sourceHandle, temp1Handle, renderer, myQuality);
|
||||
|
||||
if (EnviroManager.instance.VolumetricClouds.settingsGlobal.cloudShadows &&
|
||||
camera.camera.cameraType != CameraType.Reflection)
|
||||
{
|
||||
EnviroManager.instance.VolumetricClouds.RenderCloudsShadowsHDRP(camera.camera, ctx.cmd, temp1Handle, temp2Handle, renderer);
|
||||
|
||||
EnviroManager.instance.Fog.RenderHeightFogHDRP(camera.camera, ctx.cmd, temp2Handle, ctx.cameraColorBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
EnviroManager.instance.Fog.RenderHeightFogHDRP(camera.camera, ctx.cmd, temp1Handle, ctx.cameraColorBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
EnviroManager.instance.Fog.RenderHeightFogHDRP(camera.camera, ctx.cmd, sourceHandle, temp1Handle);
|
||||
|
||||
if (EnviroManager.instance.VolumetricClouds.settingsGlobal.cloudShadows &&
|
||||
camera.camera.cameraType != CameraType.Reflection)
|
||||
{
|
||||
EnviroManager.instance.VolumetricClouds.RenderCloudsShadowsHDRP(camera.camera, ctx.cmd, temp1Handle, temp2Handle, renderer);
|
||||
|
||||
EnviroManager.instance.VolumetricClouds.RenderVolumetricCloudsHDRP(camera.camera, ctx.cmd, temp2Handle, ctx.cameraColorBuffer, renderer, myQuality);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
EnviroManager.instance.VolumetricClouds.RenderVolumetricCloudsHDRP(camera.camera, ctx.cmd, temp1Handle, ctx.cameraColorBuffer, renderer, myQuality);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (renderVolumetricClouds)
|
||||
{
|
||||
if (EnviroManager.instance.VolumetricClouds.settingsGlobal.cloudShadows &&
|
||||
camera.camera.cameraType != CameraType.Reflection)
|
||||
{
|
||||
EnviroManager.instance.VolumetricClouds.RenderCloudsShadowsHDRP(camera.camera, ctx.cmd, sourceHandle, temp1Handle, renderer);
|
||||
|
||||
EnviroManager.instance.VolumetricClouds.RenderVolumetricCloudsHDRP(camera.camera, ctx.cmd, temp1Handle, ctx.cameraColorBuffer, renderer, myQuality);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
EnviroManager.instance.VolumetricClouds.RenderVolumetricCloudsHDRP(camera.camera, ctx.cmd, sourceHandle, ctx.cameraColorBuffer, renderer, myQuality);
|
||||
}
|
||||
}
|
||||
else if (renderFog)
|
||||
{
|
||||
|
||||
EnviroManager.instance.Fog.RenderHeightFogHDRP(camera.camera, ctx.cmd, sourceHandle, ctx.cameraColorBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// blitTrough.SetTexture("_InputTexture", sourceHandle);
|
||||
// CoreUtils.SetRenderTarget(ctx.cmd, ctx.cameraColorBuffer, ctx.cameraDepthBuffer, ClearFlag.None);
|
||||
// HDUtils.DrawFullScreen(ctx.cmd, blitTrough);
|
||||
}
|
||||
|
||||
if (!renderVolumetricClouds)
|
||||
Shader.SetGlobalTexture("_EnviroClouds", Texture2D.blackTexture);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected override void Cleanup()
|
||||
{
|
||||
if (blitTrough != null) CoreUtils.Destroy(blitTrough);
|
||||
|
||||
if (sourceHandle != null) RTHandles.Release(sourceHandle);
|
||||
if (temp1Handle != null) RTHandles.Release(temp1Handle);
|
||||
if (temp2Handle != null) RTHandles.Release(temp2Handle);
|
||||
|
||||
for (int i = 0; i < volumetricCloudsRender.Count; i++)
|
||||
CleanCloudsRenderer(volumetricCloudsRender[i]);
|
||||
}
|
||||
|
||||
// ---- Cloud renderer helpers -----
|
||||
private EnviroVolumetricCloudRenderer CreateCloudsRenderer(Camera cam)
|
||||
{
|
||||
EnviroVolumetricCloudRenderer r = new EnviroVolumetricCloudRenderer();
|
||||
r.camera = cam;
|
||||
volumetricCloudsRender.Add(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
private void CleanCloudsRenderer(EnviroVolumetricCloudRenderer renderer)
|
||||
{
|
||||
if (renderer.fullBuffer != null)
|
||||
foreach (var b in renderer.fullBuffer) if (b != null) CoreUtils.Destroy(b);
|
||||
|
||||
if (renderer.undersampleBuffer != null) CoreUtils.Destroy(renderer.undersampleBuffer);
|
||||
if (renderer.downsampledDepth != null) CoreUtils.Destroy(renderer.downsampledDepth);
|
||||
if (renderer.raymarchMat != null) CoreUtils.Destroy(renderer.raymarchMat);
|
||||
if (renderer.reprojectMat != null) CoreUtils.Destroy(renderer.reprojectMat);
|
||||
if (renderer.blendAndLightingMat != null) CoreUtils.Destroy(renderer.blendAndLightingMat);
|
||||
if (renderer.depthMat != null) CoreUtils.Destroy(renderer.depthMat);
|
||||
if (renderer.shadowMat != null) CoreUtils.Destroy(renderer.shadowMat);
|
||||
}
|
||||
|
||||
private EnviroVolumetricCloudRenderer GetCloudsRenderer(Camera cam)
|
||||
{
|
||||
foreach (var r in volumetricCloudsRender)
|
||||
if (r.camera == cam) return r;
|
||||
|
||||
return CreateCloudsRenderer(cam);
|
||||
}
|
||||
|
||||
private void SetMatrix(Camera myCam)
|
||||
{
|
||||
#if ENABLE_VR && ENABLE_XR_MODULE
|
||||
if (UnityEngine.XR.XRSettings.enabled && UnityEngine.XR.XRSettings.stereoRenderingMode == UnityEngine.XR.XRSettings.StereoRenderingMode.SinglePassInstanced)
|
||||
{
|
||||
// Both stereo eye inverse view matrices
|
||||
Matrix4x4 left_world_from_view = myCam.GetStereoViewMatrix(Camera.StereoscopicEye.Left).inverse;
|
||||
Matrix4x4 right_world_from_view = myCam.GetStereoViewMatrix(Camera.StereoscopicEye.Right).inverse;
|
||||
|
||||
// Both stereo eye inverse projection matrices, plumbed through GetGPUProjectionMatrix to compensate for render texture
|
||||
Matrix4x4 left_screen_from_view = myCam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left);
|
||||
Matrix4x4 right_screen_from_view = myCam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right);
|
||||
Matrix4x4 left_view_from_screen = GL.GetGPUProjectionMatrix(left_screen_from_view, true).inverse;
|
||||
Matrix4x4 right_view_from_screen = GL.GetGPUProjectionMatrix(right_screen_from_view, true).inverse;
|
||||
|
||||
// Negate [1,1] to reflect Unity's CBuffer state
|
||||
if (SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore && SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3)
|
||||
{
|
||||
left_view_from_screen[1, 1] *= -1;
|
||||
right_view_from_screen[1, 1] *= -1;
|
||||
}
|
||||
|
||||
Shader.SetGlobalMatrix("_LeftWorldFromView", left_world_from_view);
|
||||
Shader.SetGlobalMatrix("_RightWorldFromView", right_world_from_view);
|
||||
Shader.SetGlobalMatrix("_LeftViewFromScreen", left_view_from_screen);
|
||||
Shader.SetGlobalMatrix("_RightViewFromScreen", right_view_from_screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Main eye inverse view matrix
|
||||
Matrix4x4 left_world_from_view = myCam.cameraToWorldMatrix;
|
||||
|
||||
// Inverse projection matrices, plumbed through GetGPUProjectionMatrix to compensate for render texture
|
||||
Matrix4x4 screen_from_view = myCam.projectionMatrix;
|
||||
Matrix4x4 left_view_from_screen = GL.GetGPUProjectionMatrix(screen_from_view, true).inverse;
|
||||
|
||||
// Negate [1,1] to reflect Unity's CBuffer state
|
||||
if (SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore && SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3)
|
||||
left_view_from_screen[1, 1] *= -1;
|
||||
|
||||
Shader.SetGlobalMatrix("_LeftWorldFromView", left_world_from_view);
|
||||
Shader.SetGlobalMatrix("_LeftViewFromScreen", left_view_from_screen);
|
||||
}
|
||||
#else
|
||||
// Main eye inverse view matrix
|
||||
Matrix4x4 left_world_from_view = myCam.cameraToWorldMatrix;
|
||||
|
||||
// Inverse projection matrices, plumbed through GetGPUProjectionMatrix to compensate for render texture
|
||||
Matrix4x4 screen_from_view = myCam.projectionMatrix;
|
||||
Matrix4x4 left_view_from_screen = GL.GetGPUProjectionMatrix(screen_from_view, true).inverse;
|
||||
|
||||
// Negate [1,1] to reflect Unity's CBuffer state
|
||||
if (SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore && SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3)
|
||||
left_view_from_screen[1, 1] *= -1;
|
||||
|
||||
Shader.SetGlobalMatrix("_LeftWorldFromView", left_world_from_view);
|
||||
Shader.SetGlobalMatrix("_LeftViewFromScreen", left_view_from_screen);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user