浏览代码

Merge pull request #387 from EvgeniiG/volumetrics

Factor out volumetric lighting code
/main
GitHub 7 年前
当前提交
1068a386
共有 11 个文件被更改,包括 331 次插入191 次删除
  1. 10
      ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl
  2. 109
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  3. 20
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  4. 96
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs
  5. 27
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute
  6. 6
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs.hlsl
  7. 221
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs
  8. 10
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs.hlsl.meta
  9. 13
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs.meta
  10. 10
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs.hlsl.meta
  11. 0
      /ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs.hlsl

10
ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl


return exp(-opticalDepth);
}
float TransmittanceIntegralOverHomogeneousInterval(float extinction, float start, float end)
{
return (exp(-extinction * start) - exp(-extinction * end)) / extinction;
}
float3 OpticalDepthHomogeneous(float3 extinction, float intervalLength)
{
return extinction * intervalLength;

{
return exp(-opticalDepth);
}
float3 TransmittanceIntegralOverHomogeneousInterval(float3 extinction, float start, float end)
{
return (exp(-extinction * start) - exp(-extinction * end)) / extinction;
}
float IsotropicPhaseFunction()

109
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


get { return nonJitteredProjMatrix * viewMatrix; }
}
public bool isFirstFrame
{
get { return m_FirstFrame; }
}
public Vector4 invProjParam
{
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.

RenderTextureReadWrite[] sRGBWrites = new RenderTextureReadWrite[MaxGbuffer];
}
public class HDRenderPipeline : RenderPipeline
public partial class HDRenderPipeline : RenderPipeline
{
readonly HDRenderPipelineAsset m_Asset;

Material m_SssVerticalFilterPass;
Material m_SssHorizontalFilterAndCombinePass;
// <<< Old SSS Model
ComputeShader m_VolumetricLightingCS { get { return m_Asset.renderPipelineResources.volumetricLightingCS; } }
int m_VolumetricLightingKernel;
Material m_CameraMotionVectorsMaterial;

private RenderTexture m_CameraDepthBufferCopy = null;
private RenderTexture m_CameraStencilBufferCopy = null;
private RenderTexture m_HTile = null; // If the hardware does not expose it, we compute our own, optimized to only contain the SSS bit
// Post-processing context and screen-space effects (recycled on every frame to avoid GC alloc)
readonly PostProcessRenderContext m_PostProcessContext;
readonly ScreenSpaceAmbientOcclusionEffect m_SsaoEffect;

m_LightLoop.AllocResolutionDependentBuffers(camera.pixelWidth, camera.pixelHeight);
}
if (resolutionChanged && m_VolumetricLightingEnabled)
{
CreateVolumetricLightingBuffers(camera.pixelWidth, camera.pixelHeight);
}
// update recorded window resolution
m_CurrentWidth = camera.pixelWidth;
m_CurrentHeight = camera.pixelHeight;

cmd.SetGlobalVectorArray(HDShaderIDs._HalfRcpVariancesAndWeights, sssParameters.halfRcpVariancesAndWeights);
cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTints, sssParameters.transmissionTints);
SetGlobalVolumeProperties(cmd);
SetGlobalVolumeProperties(m_VolumetricLightingEnabled, cmd);
}
}

return;
}
InitAndClearBuffer(camera, cmd);
InitAndClearBuffer(hdCamera, cmd);
RenderDepthPrepass(m_CullResults, camera, renderContext, cmd);

RenderForward(m_CullResults, camera, renderContext, cmd, false);
// Render fog.
VolumetricLightingPass(hdCamera, cmd);
VolumetricLightingPass(cmd, hdCamera);
PushFullScreenDebugTexture(cmd, m_CameraColorBuffer, camera, renderContext, FullScreenDebugMode.NanTracker);

RenderTargetIdentifier[] colorRTs = { m_CameraColorBufferRT, m_CameraSssDiffuseLightingBufferRT };
RenderTargetIdentifier depthTexture = GetDepthTexture();
LightLoop.LightingPassOptions options = new LightLoop.LightingPassOptions();
options.volumetricLightingEnabled = m_VolumetricLightingEnabled;
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, true);
options.outputSplitLighting = true;
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, options);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, false);
options.outputSplitLighting = false;
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, options);
}
// Combines specular lighting and diffuse lighting with subsurface scattering.

}
}
// Returns 'true' if the global fog is enabled, 'false' otherwise.
public static bool SetGlobalVolumeProperties(CommandBuffer cmd, ComputeShader cs = null)
{
HomogeneousFog[] fogComponents = Object.FindObjectsOfType(typeof(HomogeneousFog)) as HomogeneousFog[];
HomogeneousFog globalFogComponent = null;
foreach (HomogeneousFog fogComponent in fogComponents)
{
if (fogComponent.enabled && fogComponent.volumeParameters.IsVolumeUnbounded())
{
globalFogComponent = fogComponent;
break;
}
}
// TODO: may want to cache these results somewhere.
VolumeProperties globalFogProperties = (globalFogComponent != null) ? globalFogComponent.volumeParameters.GetProperties()
: VolumeProperties.GetNeutralVolumeProperties();
if (cs)
{
cmd.SetComputeVectorParam(cs, HDShaderIDs._GlobalFog_Scattering, globalFogProperties.scattering);
cmd.SetComputeFloatParam( cs, HDShaderIDs._GlobalFog_Extinction, globalFogProperties.extinction);
cmd.SetComputeFloatParam( cs, HDShaderIDs._GlobalFog_Asymmetry, globalFogProperties.asymmetry);
}
else
{
cmd.SetGlobalVector(HDShaderIDs._GlobalFog_Scattering, globalFogProperties.scattering);
cmd.SetGlobalFloat( HDShaderIDs._GlobalFog_Extinction, globalFogProperties.extinction);
cmd.SetGlobalFloat( HDShaderIDs._GlobalFog_Asymmetry, globalFogProperties.asymmetry);
}
return (globalFogComponent != null);
}
void VolumetricLightingPass(HDCamera hdCamera, CommandBuffer cmd)
{
if (!SetGlobalVolumeProperties(cmd, m_VolumetricLightingCS)) { return; }
using (new Utilities.ProfilingSample("VolumetricLighting", cmd))
{
bool enableClustered = m_Asset.tileSettings.enableClustered && m_Asset.tileSettings.enableTileAndCluster;
m_VolumetricLightingKernel = m_VolumetricLightingCS.FindKernel(enableClustered ? "VolumetricLightingClustered"
: "VolumetricLightingAllLights");
hdCamera.SetupComputeShader(m_VolumetricLightingCS, cmd);
cmd.SetComputeTextureParam(m_VolumetricLightingCS, m_VolumetricLightingKernel, HDShaderIDs._CameraColorTexture, m_CameraColorBufferRT);
cmd.SetComputeTextureParam(m_VolumetricLightingCS, m_VolumetricLightingKernel, HDShaderIDs._DepthTexture, GetDepthTexture());
cmd.SetComputeVectorParam( m_VolumetricLightingCS, HDShaderIDs._Time, Shader.GetGlobalVector(HDShaderIDs._Time));
// Pass clustered light data (if present) into the compute shader.
m_LightLoop.PushGlobalParams(hdCamera.camera, cmd, m_VolumetricLightingCS, m_VolumetricLightingKernel, true);
cmd.SetComputeIntParam(m_VolumetricLightingCS, HDShaderIDs._UseTileLightList, 0);
cmd.DispatchCompute(m_VolumetricLightingCS, m_VolumetricLightingKernel, ((int)hdCamera.screenSize.x + 15) / 16, ((int)hdCamera.screenSize.y + 15) / 16, 1);
}
}
// Render material that are forward opaque only (like eye), this include unlit material
void RenderForwardOnlyOpaque(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{

}
}
void InitAndClearBuffer(Camera camera, CommandBuffer cmd)
void InitAndClearBuffer(HDCamera camera, CommandBuffer cmd)
{
using (new Utilities.ProfilingSample("InitAndClearBuffer", cmd))
{

// Also we manage ourself the HDR format, here allocating fp16 directly.
// With scriptable render loop we can allocate temporary RT in a command buffer, they will not be release with ExecuteCommandBuffer
// These temporary surface are release automatically at the end of the scriptable render pipeline if not release explicitly
int w = camera.pixelWidth;
int h = camera.pixelHeight;
int w = camera.camera.pixelWidth;
int h = camera.camera.pixelHeight;
cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraSssDiffuseLightingBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV

// Clear the diffuse SSS lighting target
using (new Utilities.ProfilingSample("Clear SSS diffuse target", cmd))
{
Utilities.SetRenderTarget(cmd, m_CameraSssDiffuseLightingBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
Utilities.SetRenderTarget(cmd, m_CameraSssDiffuseLightingBufferRT, ClearFlag.ClearColor, Color.black);
}
// Old SSS Model >>>

using (new Utilities.ProfilingSample("Clear SSS filtering target", cmd))
{
Utilities.SetRenderTarget(cmd, m_CameraFilteringBuffer, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
Utilities.SetRenderTarget(cmd, m_CameraFilteringBuffer, ClearFlag.ClearColor, Color.black);
}
}
// <<< Old SSS Model

{
Utilities.SetRenderTarget(cmd, m_HTileRT, ClearFlag.ClearColor, Color.black);
}
}
if (m_VolumetricLightingEnabled)
{
ClearVolumetricLightingBuffers(cmd, camera.isFirstFrame);
}
// TEMP: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later.

20
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


}
}
public struct LightingPassOptions
{
public bool outputSplitLighting;
public bool volumetricLightingEnabled;
}
bool outputSplitLighting)
LightingPassOptions options)
if (m_TileSettings.enableTileAndCluster && m_TileSettings.enableComputeLightEvaluation && outputSplitLighting)
if (m_TileSettings.enableTileAndCluster && m_TileSettings.enableComputeLightEvaluation && options.outputSplitLighting)
{
// The CS is always in the MRT mode. Do not execute the same shader twice.
return;

string SinglePassMRTName = "SinglePass - Deferred Lighting Pass MRT";
using (new Utilities.ProfilingSample(m_TileSettings.enableTileAndCluster ?
(outputSplitLighting ? tilePassMRTName : tilePassName) :
(outputSplitLighting ? SinglePassMRTName : singlePassName), cmd))
(options.outputSplitLighting ? tilePassMRTName : tilePassName) :
(options.outputSplitLighting ? SinglePassMRTName : singlePassName), cmd))
{
var camera = hdCamera.camera;

PushGlobalParams(camera, cmd, null, 0);
// This is a debug brute force renderer to debug tile/cluster which render all the lights
if (outputSplitLighting)
if (options.outputSplitLighting)
{
Utilities.DrawFullScreen(cmd, m_SingleDeferredMaterialMRT, colorBuffers, depthStencilBuffer);
}

cmd.SetComputeTextureParam(deferredComputeShader, kernel, HDShaderIDs.specularLightingUAV, colorBuffers[0]);
cmd.SetComputeTextureParam(deferredComputeShader, kernel, HDShaderIDs.diffuseLightingUAV, colorBuffers[1]);
HDRenderPipeline.SetGlobalVolumeProperties(cmd, deferredComputeShader);
HDRenderPipeline.SetGlobalVolumeProperties(options.volumetricLightingEnabled, cmd, deferredComputeShader);
// always do deferred lighting in blocks of 16x16 (not same as tiled light size)

// Pixel shader evaluation
PushGlobalParams(camera, cmd, null, 0);
if (outputSplitLighting)
if (options.outputSplitLighting)
{
Utilities.SelectKeyword(m_DeferredAllMaterialMRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullScreen(cmd, m_DeferredAllMaterialMRT, colorBuffers, depthStencilBuffer);

96
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs


using UnityEngine.Rendering;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[GenerateHLSL]
public struct VolumeProperties
{
public Vector3 scattering; // [0, 1], prefer sRGB
public float extinction; // [0, 1], prefer sRGB
public float asymmetry; // Global (scene) property
public float align16_0;
public float align16_1;
public float align16_2;
public static VolumeProperties GetNeutralVolumeProperties()
{
VolumeProperties properties = new VolumeProperties();
properties.scattering = Vector3.zero;
properties.extinction = 0;
properties.asymmetry = 0;
return properties;
}
}
[Serializable]
public class VolumeParameters
{
public Bounds bounds; // Position and dimensions in meters
public Color albedo; // Single scattering albedo [0, 1]
public float meanFreePath; // In meters [1, inf]. Should be chromatic - this is an optimization!
public float anisotropy; // [-1, 1]; 0 = isotropic
public VolumeParameters()
{
bounds = new Bounds(Vector3.zero, Vector3.positiveInfinity);
albedo = new Color(0.5f, 0.5f, 0.5f);
meanFreePath = 10.0f;
anisotropy = 0.0f;
}
public bool IsVolumeUnbounded()
{
return bounds.size.x == float.PositiveInfinity &&
bounds.size.y == float.PositiveInfinity &&
bounds.size.z == float.PositiveInfinity;
}
public Vector3 GetAbsorptionCoefficient()
{
float extinction = GetExtinctionCoefficient();
Vector3 scattering = GetScatteringCoefficient();
return Vector3.Max(new Vector3(extinction, extinction, extinction) - scattering, Vector3.zero);
}
public Vector3 GetScatteringCoefficient()
{
float extinction = GetExtinctionCoefficient();
return new Vector3(albedo.r * extinction, albedo.g * extinction, albedo.b * extinction);
}
public float GetExtinctionCoefficient()
{
return 1.0f / meanFreePath;
}
public void Constrain()
{
bounds.size = Vector3.Max(bounds.size, Vector3.zero);
albedo.r = Mathf.Clamp01(albedo.r);
albedo.g = Mathf.Clamp01(albedo.g);
albedo.b = Mathf.Clamp01(albedo.b);
meanFreePath = Mathf.Max(meanFreePath, 1.0f);
anisotropy = Mathf.Clamp(anisotropy, -1.0f, 1.0f);
}
public VolumeProperties GetProperties()
{
VolumeProperties properties = new VolumeProperties();
properties.scattering = GetScatteringCoefficient();
properties.extinction = GetExtinctionCoefficient();
properties.asymmetry = anisotropy;
return properties;
}
}
[ExecuteInEditMode]
[AddComponentMenu("Rendering/Homogeneous Fog", -1)]
public class HomogeneousFog : MonoBehaviour

27
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute


#define SHADERPASS SHADERPASS_VOLUMETRIC_LIGHTING
#define GROUP_SIZE_1D 16
#define GROUP_SIZE_2D (GROUP_SIZE_1D * GROUP_SIZE_1D)
// #define USE_HENYEY_GREENSTEIN_PHASE_FUNCTION
//--------------------------------------------------------------------------------------------------
// Included headers

#include "../../../../Core/ShaderLibrary/SpaceFillingCurves.hlsl"
#include "../../../../Core/ShaderLibrary/VolumeRendering.hlsl"
#include "../HomogeneousFog.cs.hlsl"
#include "../VolumetricLighting.cs.hlsl"
#define UNITY_MATERIAL_LIT // Need to be defined before including Material.hlsl
#include "../../../ShaderVariables.hlsl"
#include "../../../Lighting/Lighting.hlsl" // This includes Material.hlsl

{
float3 scattering = _GlobalFog_Scattering;
float extinction = _GlobalFog_Extinction;
#ifdef USE_HENYEY_GREENSTEIN_PHASE_FUNCTION
#endif
LightLoopContext context;
// ZERO_INITIALIZE(LightLoopContext, context);

float du = rcp(numSteps);
float u0 = 0.25 * du + 0.5 * du * zeta;
float dt = du * ray.maxLength;
float t0 = 0;
float u = u0 + s * du; // [0, 1]
float t = u * ray.maxLength; // [0, ray.maxLength]
float u = u0 + s * du; // [0, 1]
float t = u * ray.maxLength; // [0, ray.maxLength]
float t1 = t + 0.5 * dt;
float T = TransmittanceIntegralOverHomogeneousInterval(extinction, t0, t1);
[branch] if (T < 0.0001) break;
float3 positionWS = ray.originWS + t * ray.directionWS;

float intensity = 1;
float3 color = lightData.color;
#ifdef USE_HENYEY_GREENSTEIN_PHASE_FUNCTION
#endif
[branch] if (lightData.shadowIndex >= 0)
{

float intensity = GetPunctualShapeAttenuation(lightData, L, distSq);
float3 color = lightData.color;
#ifdef USE_HENYEY_GREENSTEIN_PHASE_FUNCTION
#endif
intensity *= Transmittance(OpticalDepthHomogeneous(extinction, dist));
[branch] if (lightData.shadowIndex >= 0)

}
}
radiance += sampleRadiance * (Transmittance(OpticalDepthHomogeneous(extinction, t)) * dt);
radiance += sampleRadiance * T;
t0 = t1;
#ifdef USE_HENYEY_GREENSTEIN_PHASE_FUNCTION
#else
float3 phaseConstant = scattering * IsotropicPhaseFunction();
#endif
return radiance * phaseConstant;
}

6
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs. Please don't edit by hand.
// This file was automatically generated from Assets/SRP/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs. Please don't edit by hand.
#ifndef HOMOGENEOUSFOG_CS_HLSL
#define HOMOGENEOUSFOG_CS_HLSL
#ifndef VOLUMETRICLIGHTING_CS_HLSL
#define VOLUMETRICLIGHTING_CS_HLSL
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.VolumeProperties
// PackingRules = Exact
struct VolumeProperties

221
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs


using System;
using UnityEngine.Rendering;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[GenerateHLSL]
public struct VolumeProperties
{
public Vector3 scattering; // [0, 1], prefer sRGB
public float extinction; // [0, 1], prefer sRGB
public float asymmetry; // Global (scene) property
public float align16_0;
public float align16_1;
public float align16_2;
public static VolumeProperties GetNeutralVolumeProperties()
{
VolumeProperties properties = new VolumeProperties();
properties.scattering = Vector3.zero;
properties.extinction = 0;
properties.asymmetry = 0;
return properties;
}
}
[Serializable]
public class VolumeParameters
{
public Bounds bounds; // Position and dimensions in meters
public Color albedo; // Single scattering albedo [0, 1]
public float meanFreePath; // In meters [1, inf]. Should be chromatic - this is an optimization!
public float anisotropy; // [-1, 1]; 0 = isotropic
public VolumeParameters()
{
bounds = new Bounds(Vector3.zero, Vector3.positiveInfinity);
albedo = new Color(0.5f, 0.5f, 0.5f);
meanFreePath = 10.0f;
anisotropy = 0.0f;
}
public bool IsVolumeUnbounded()
{
return bounds.size.x == float.PositiveInfinity &&
bounds.size.y == float.PositiveInfinity &&
bounds.size.z == float.PositiveInfinity;
}
public Vector3 GetAbsorptionCoefficient()
{
float extinction = GetExtinctionCoefficient();
Vector3 scattering = GetScatteringCoefficient();
return Vector3.Max(new Vector3(extinction, extinction, extinction) - scattering, Vector3.zero);
}
public Vector3 GetScatteringCoefficient()
{
float extinction = GetExtinctionCoefficient();
return new Vector3(albedo.r * extinction, albedo.g * extinction, albedo.b * extinction);
}
public float GetExtinctionCoefficient()
{
return 1.0f / meanFreePath;
}
public void Constrain()
{
bounds.size = Vector3.Max(bounds.size, Vector3.zero);
albedo.r = Mathf.Clamp01(albedo.r);
albedo.g = Mathf.Clamp01(albedo.g);
albedo.b = Mathf.Clamp01(albedo.b);
meanFreePath = Mathf.Max(meanFreePath, 1.0f);
anisotropy = Mathf.Clamp(anisotropy, -1.0f, 1.0f);
}
public VolumeProperties GetProperties()
{
VolumeProperties properties = new VolumeProperties();
properties.scattering = GetScatteringCoefficient();
properties.extinction = GetExtinctionCoefficient();
properties.asymmetry = anisotropy;
return properties;
}
}
public partial class HDRenderPipeline : RenderPipeline
{
bool m_VolumetricLightingEnabled = false; // Must be able to change this dynamically
int m_VolumetricBufferTileSize = 4; // In pixels, must be a power of 2
RenderTexture m_VolumetricLightingBufferCurrentFrame = null;
RenderTexture m_VolumetricLightingBufferAccumulated = null;
RenderTargetIdentifier m_VolumetricLightingBufferCurrentFrameRT;
RenderTargetIdentifier m_VolumetricLightingBufferAccumulatedRT;
ComputeShader m_VolumetricLightingCS { get { return m_Asset.renderPipelineResources.volumetricLightingCS; } }
void CreateVolumetricLightingBuffers(int width, int height)
{
if (m_VolumetricLightingBufferAccumulated != null)
{
m_VolumetricLightingBufferAccumulated.Release();
m_VolumetricLightingBufferCurrentFrame.Release();
}
int s = m_VolumetricBufferTileSize;
Debug.Assert((s & (s - 1)) == 0, "m_VolumetricBufferTileSize must be a power of 2.");
int w = (width + s - 1) / s;
int h = (height + s - 1) / s;
int d = 64;
m_VolumetricLightingBufferCurrentFrame = new RenderTexture(w, h, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_VolumetricLightingBufferCurrentFrame.filterMode = FilterMode.Bilinear; // Custom trilinear
m_VolumetricLightingBufferCurrentFrame.dimension = TextureDimension.Tex3D; // Prefer 3D Thick tiling layout
m_VolumetricLightingBufferCurrentFrame.volumeDepth = d;
m_VolumetricLightingBufferCurrentFrame.enableRandomWrite = true;
m_VolumetricLightingBufferCurrentFrame.Create();
m_VolumetricLightingBufferCurrentFrameRT = new RenderTargetIdentifier(m_VolumetricLightingBufferCurrentFrame);
m_VolumetricLightingBufferAccumulated = new RenderTexture(w, h, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_VolumetricLightingBufferAccumulated.filterMode = FilterMode.Bilinear; // Custom trilinear
m_VolumetricLightingBufferAccumulated.dimension = TextureDimension.Tex3D; // Prefer 3D Thick tiling layout
m_VolumetricLightingBufferAccumulated.volumeDepth = d;
m_VolumetricLightingBufferAccumulated.enableRandomWrite = true;
m_VolumetricLightingBufferAccumulated.Create();
m_VolumetricLightingBufferAccumulatedRT = new RenderTargetIdentifier(m_VolumetricLightingBufferAccumulated);
}
void ClearVolumetricLightingBuffers(CommandBuffer cmd, bool isFirstFrame)
{
using (new Utilities.ProfilingSample("Clear volumetric lighting buffers", cmd))
{
Utilities.SetRenderTarget(cmd, m_VolumetricLightingBufferCurrentFrameRT, ClearFlag.ClearColor, Color.black);
if (isFirstFrame)
{
Utilities.SetRenderTarget(cmd, m_VolumetricLightingBufferAccumulated, ClearFlag.ClearColor, Color.black);
}
}
}
// Returns 'true' if the global fog is enabled, 'false' otherwise.
public static bool SetGlobalVolumeProperties(bool volumetricLightingEnabled, CommandBuffer cmd, ComputeShader cs = null)
{
HomogeneousFog globalFogComponent = null;
if (volumetricLightingEnabled)
{
HomogeneousFog[] fogComponents = Object.FindObjectsOfType(typeof(HomogeneousFog)) as HomogeneousFog[];
foreach (HomogeneousFog fogComponent in fogComponents)
{
if (fogComponent.enabled && fogComponent.volumeParameters.IsVolumeUnbounded())
{
globalFogComponent = fogComponent;
break;
}
}
}
// TODO: may want to cache these results somewhere.
VolumeProperties globalFogProperties = (globalFogComponent != null) ? globalFogComponent.volumeParameters.GetProperties()
: VolumeProperties.GetNeutralVolumeProperties();
if (cs)
{
cmd.SetComputeVectorParam(cs, HDShaderIDs._GlobalFog_Scattering, globalFogProperties.scattering);
cmd.SetComputeFloatParam( cs, HDShaderIDs._GlobalFog_Extinction, globalFogProperties.extinction);
cmd.SetComputeFloatParam( cs, HDShaderIDs._GlobalFog_Asymmetry, globalFogProperties.asymmetry);
}
else
{
cmd.SetGlobalVector(HDShaderIDs._GlobalFog_Scattering, globalFogProperties.scattering);
cmd.SetGlobalFloat( HDShaderIDs._GlobalFog_Extinction, globalFogProperties.extinction);
cmd.SetGlobalFloat( HDShaderIDs._GlobalFog_Asymmetry, globalFogProperties.asymmetry);
}
return (globalFogComponent != null);
}
void VolumetricLightingPass(CommandBuffer cmd, HDCamera hdCamera)
{
if (!SetGlobalVolumeProperties(m_VolumetricLightingEnabled, cmd, m_VolumetricLightingCS)) { return; }
using (new Utilities.ProfilingSample("VolumetricLighting", cmd))
{
bool enableClustered = m_Asset.tileSettings.enableClustered && m_Asset.tileSettings.enableTileAndCluster;
int volumetricLightingKernel = m_VolumetricLightingCS.FindKernel(enableClustered ? "VolumetricLightingClustered"
: "VolumetricLightingAllLights");
hdCamera.SetupComputeShader(m_VolumetricLightingCS, cmd);
cmd.SetComputeTextureParam(m_VolumetricLightingCS, volumetricLightingKernel, HDShaderIDs._CameraColorTexture, m_CameraColorBufferRT);
cmd.SetComputeTextureParam(m_VolumetricLightingCS, volumetricLightingKernel, HDShaderIDs._DepthTexture, GetDepthTexture());
cmd.SetComputeVectorParam( m_VolumetricLightingCS, HDShaderIDs._Time, Shader.GetGlobalVector(HDShaderIDs._Time));
// Pass clustered light data (if present) into the compute shader.
m_LightLoop.PushGlobalParams(hdCamera.camera, cmd, m_VolumetricLightingCS, volumetricLightingKernel, true);
cmd.SetComputeIntParam(m_VolumetricLightingCS, HDShaderIDs._UseTileLightList, 0);
cmd.DispatchCompute(m_VolumetricLightingCS, volumetricLightingKernel, ((int)hdCamera.screenSize.x + 15) / 16, ((int)hdCamera.screenSize.y + 15) / 16, 1);
}
}
} // class HDRenderPipeline
} // namespace UnityEngine.Experimental.Rendering.HDPipeline

10
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs.hlsl.meta


fileFormatVersion: 2
guid: d5c6a48928753954e8b1a84bbde280ec
timeCreated: 1504275050
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

13
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs.meta


fileFormatVersion: 2
guid: 3090aceb9ee51fc4f9d9830cfef9684c
timeCreated: 1504273866
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

10
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs.hlsl.meta


fileFormatVersion: 2
guid: af39a96c040c8ec4da47ed13c6455ffe
timeCreated: 1503567986
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs.hlsl → /ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs.hlsl

正在加载...
取消
保存