浏览代码

Implement clustering of density volumes

/main
Evgenii Golubev 7 年前
当前提交
e6540dfa
共有 12 个文件被更改,包括 155 次插入79 次删除
  1. 10
      ScriptableRenderPipeline/Core/CoreRP/GeometryUtils.cs
  2. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  3. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  4. 80
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  5. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs.hlsl
  6. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-bigtile.compute
  7. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-clustered.compute
  8. 19
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild.compute
  9. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/HomogeneousDensityVolume.cs
  10. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/HomogeneousDensityVolume.cs.meta
  11. 82
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs
  12. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs.hlsl

10
ScriptableRenderPipeline/Core/CoreRP/GeometryUtils.cs


[GenerateHLSL]
public struct OrientedBBox
{
// 3 x float4 = 48 bytes
public Vector3 center;
public float extentX;
public Vector3 right;

public Vector3 forward { get { return Vector3.Cross(up, right); } }
public static OrientedBBox Create(Transform t)
{

public static bool Overlap(OrientedBBox obb, Vector3 cameraRelativeOffset,
Frustum frustum, int numPlanes, int numCorners)
{
Vector3 center = obb.center + cameraRelativeOffset;
Vector3 forward = Vector3.Cross(obb.up, obb.right);
Vector3 center = obb.center + cameraRelativeOffset;
bool overlap = true;

// Max projection of the half-diagonal onto the normal (always positive).
float maxHalfDiagProj = obb.extentX * Mathf.Abs(Vector3.Dot(n, obb.right))
+ obb.extentY * Mathf.Abs(Vector3.Dot(n, obb.up))
+ obb.extentZ * Mathf.Abs(Vector3.Dot(n, forward));
+ obb.extentZ * Mathf.Abs(Vector3.Dot(n, obb.forward));
// Negative distance -> center behind the plane (outside).
float centerToPlaneDist = Vector3.Dot(n, center) + d;

planes[0].distance = obb.extentX;
planes[1].normal = obb.up;
planes[1].distance = obb.extentY;
planes[2].normal = forward;
planes[2].normal = obb.forward;
planes[2].distance = obb.extentZ;
for (int i = 0; overlap && i < 3; i++)

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


continue;
}
// Frustum cull density volumes on CPU.
DensityVolumeList densityVolumes = m_VolumetricLightingModule.PrepareVisibleDensityVolumeList(hdCamera, cmd);
// Note: Legacy Unity behave like this for ShadowMask
// When you select ShadowMask in Lighting panel it recompile shaders on the fly with the SHADOW_MASK keyword.
// However there is no C# function that we can query to know what mode have been select in Lighting Panel and it will be wrong anyway. Lighting Panel setup what will be the next bake mode. But until light is bake, it is wrong.

bool enableBakeShadowMask;
using (new ProfilingSample(cmd, "TP_PrepareLightsForGPU", CustomSamplerId.TPPrepareLightsForGPU.GetSampler()))
{
enableBakeShadowMask = m_LightLoop.PrepareLightsForGPU(cmd, m_ShadowSettings, m_CullResults, m_ReflectionProbeCullResults, camera) && m_FrameSettings.enableShadowMask;
enableBakeShadowMask = m_LightLoop.PrepareLightsForGPU(cmd, camera, m_ShadowSettings, m_CullResults, m_ReflectionProbeCullResults, densityVolumes) && m_FrameSettings.enableShadowMask;
}
ConfigureForShadowMask(enableBakeShadowMask, cmd);

UpdateSkyEnvironment(hdCamera, cmd);
RenderPyramidDepth(hdCamera, cmd, renderContext, FullScreenDebugMode.DepthPyramid);
if (m_CurrentDebugDisplaySettings.IsDebugMaterialDisplayEnabled())
{

}
// The pass only requires the volume properties, and can run async.
m_VolumetricLightingModule.VoxelizeDensityVolumes(hdCamera, cmd);
//
// Render the volumetric lighting.
// The pass requires the volume properties, the light list and the shadows, and can run async.

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int g_LayeredSingleIdxBuffer = Shader.PropertyToID("g_LayeredSingleIdxBuffer");
public static readonly int _EnvLightIndexShift = Shader.PropertyToID("_EnvLightIndexShift");
public static readonly int _DensityVolumeIndexShift = Shader.PropertyToID("_DensityVolumeIndexShift");
public static readonly int g_isOrthographic = Shader.PropertyToID("g_isOrthographic");
public static readonly int g_iNrVisibLights = Shader.PropertyToID("g_iNrVisibLights");
public static readonly int g_mScrProjection = Shader.PropertyToID("g_mScrProjection");

80
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


Punctual,
Area,
Env,
DensityVolume,
Count
}

Environment = 4,
EnvironmentAndPunctual = 5,
EnvironmentAndArea = 6,
EnvironmentAndAreaAndPunctual = 7
EnvironmentAndAreaAndPunctual = 7,
DensityVolumes = 8
};
public const int k_MaxDirectionalLightsOnScreen = 4;

int m_punctualLightCount = 0;
int m_areaLightCount = 0;
int m_lightCount = 0;
int m_densityVolumeCount = 0;
bool m_enableBakeShadowMask = false; // Track if any light require shadow mask. In this case we will need to enable the keyword shadow mask
float m_maxShadowDistance = 0.0f; // Save value from shadow settings

m_lightList.lightVolumes.Add(lightVolumeData);
}
public void AddBoxVolumeDataAndBound(OrientedBBox obb, LightCategory category, LightFeatureFlags featureFlags, Matrix4x4 worldToView)
{
var bound = new SFiniteLightBound();
var volumeData = new LightVolumeData();
// transform to camera space (becomes a left hand coordinate frame in Unity since Determinant(worldToView)<0)
var positionVS = worldToView.MultiplyPoint(obb.center);
var rightVS = worldToView.MultiplyVector(obb.right);
var upVS = worldToView.MultiplyVector(obb.up);
var forwardVS = Vector3.Cross(upVS, rightVS);
var extents = new Vector3(obb.extentX, obb.extentY, obb.extentZ);
volumeData.lightVolume = (uint)LightVolumeType.Box;
volumeData.lightCategory = (uint)category;
volumeData.featureFlags = (uint)featureFlags;
bound.center = positionVS;
bound.boxAxisX = obb.extentX * rightVS;
bound.boxAxisY = obb.extentY * upVS;
bound.boxAxisZ = obb.extentZ * forwardVS;
bound.radius = extents.magnitude;
bound.scaleXY.Set(1.0f, 1.0f);
// The culling system culls pixels that are further
// than a threshold to the box influence extents.
// So we use an arbitrary threshold here (k_BoxCullingExtentOffset)
volumeData.lightPos = positionVS;
volumeData.lightAxisX = rightVS;
volumeData.lightAxisY = upVS;
volumeData.lightAxisZ = forwardVS;
volumeData.boxInnerDist = extents - k_BoxCullingExtentThreshold; // We have no blend range, but the culling code needs a small EPS value for some reason???
volumeData.boxInvRange.Set(1.0f / k_BoxCullingExtentThreshold.x, 1.0f / k_BoxCullingExtentThreshold.y, 1.0f / k_BoxCullingExtentThreshold.z);
m_lightList.bounds.Add(bound);
m_lightList.lightVolumes.Add(volumeData);
}
public int GetCurrentShadowCount()
{
return m_ShadowRequests.Count;

}
// Return true if BakedShadowMask are enabled
public bool PrepareLightsForGPU(CommandBuffer cmd, ShadowSettings shadowSettings, CullResults cullResults, ReflectionProbeCullResults reflectionProbeCullResults, Camera camera)
public bool PrepareLightsForGPU(CommandBuffer cmd, Camera camera, ShadowSettings shadowSettings, CullResults cullResults,
ReflectionProbeCullResults reflectionProbeCullResults, DensityVolumeList densityVolumes)
{
using (new ProfilingSample(cmd, "Prepare Lights For GPU"))
{

if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Caution: 'DirectionalLightData.positionWS' is camera-relative after this point.
int n = m_lightList.directionalLights.Count;
DirectionalLightData lightData = m_lightList.directionalLights[n - 1];
int last = m_lightList.directionalLights.Count - 1;
DirectionalLightData lightData = m_lightList.directionalLights[last];
m_lightList.directionalLights[n - 1] = lightData;
m_lightList.directionalLights[last] = lightData;
}
}
continue;

if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Caution: 'LightData.positionWS' is camera-relative after this point.
int n = m_lightList.lights.Count;
LightData lightData = m_lightList.lights[n - 1];
int last = m_lightList.lights.Count - 1;
LightData lightData = m_lightList.lights[last];
m_lightList.lights[n - 1] = lightData;
m_lightList.lights[last] = lightData;
}
}
}

if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Caution: 'EnvLightData.positionWS' is camera-relative after this point.
int n = m_lightList.envLights.Count;
EnvLightData envLightData = m_lightList.envLights[n - 1];
int last = m_lightList.envLights.Count - 1;
EnvLightData envLightData = m_lightList.envLights[last];
m_lightList.envLights[n - 1] = envLightData;
m_lightList.envLights[last] = envLightData;
// Inject density volumes into the clustered data structure for efficient look up.
m_densityVolumeCount = densityVolumes.bounds != null ? densityVolumes.bounds.Count : 0;
for (int i = 0, n = m_densityVolumeCount; i < n; i++)
{
// Density volumes are not lights and therefore should not affect light classification.
LightFeatureFlags featureFlags = 0;
AddBoxVolumeDataAndBound(densityVolumes.bounds[i], LightCategory.DensityVolume, featureFlags, worldToView);
}
m_lightCount = m_lightList.lights.Count + m_lightList.envLights.Count;
Debug.Assert(m_lightList.bounds.Count == m_lightCount);
Debug.Assert(m_lightList.lightVolumes.Count == m_lightCount);
m_lightCount = m_lightList.lights.Count + m_lightList.envLights.Count + m_densityVolumeCount;
Debug.Assert(m_lightCount == m_lightList.bounds.Count);
Debug.Assert(m_lightCount == m_lightList.lightVolumes.Count);
UpdateDataBuffers();

bool isOrthographic = camera.orthographic;
cmd.SetComputeIntParam(buildPerVoxelLightListShader, HDShaderIDs.g_isOrthographic, isOrthographic ? 1 : 0);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, HDShaderIDs._EnvLightIndexShift, m_lightList.lights.Count);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, HDShaderIDs._DensityVolumeIndexShift, m_lightList.lights.Count + m_lightList.envLights.Count);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, HDShaderIDs.g_iNrVisibLights, m_lightCount);
cmd.SetComputeMatrixParam(buildPerVoxelLightListShader, HDShaderIDs.g_mScrProjection, projscr);
cmd.SetComputeMatrixParam(buildPerVoxelLightListShader, HDShaderIDs.g_mInvScrProjection, invProjscr);

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs.hlsl


#define LIGHTCATEGORY_PUNCTUAL (0)
#define LIGHTCATEGORY_AREA (1)
#define LIGHTCATEGORY_ENV (2)
#define LIGHTCATEGORY_COUNT (3)
#define LIGHTCATEGORY_DENSITY_VOLUME (3)
#define LIGHTCATEGORY_COUNT (4)
//
// UnityEngine.Experimental.Rendering.HDPipeline.LightFeatureFlags: static fields

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-bigtile.compute


uniform float g_fNearPlane;
uniform float g_fFarPlane;
uniform uint g_isOrthographic;
uniform int _EnvLightIndexShift;
StructuredBuffer<float3> g_vBoundsBuffer : register( t1 );
StructuredBuffer<LightVolumeData> _LightVolumeData : register(t2);

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild-clustered.compute


float4x4 g_mScrProjection;
uint g_isOrthographic;
int _EnvLightIndexShift;
int _DensityVolumeIndexShift;
float g_fClustScale;
float g_fClustBase;

// to make it work correctly
int shiftIndex[LIGHTCATEGORY_COUNT];
ZERO_INITIALIZE_ARRAY(int, shiftIndex, LIGHTCATEGORY_COUNT);
shiftIndex[LIGHTCATEGORY_COUNT - 1] = _EnvLightIndexShift;
shiftIndex[LIGHTCATEGORY_COUNT - 2] = _EnvLightIndexShift;
shiftIndex[LIGHTCATEGORY_COUNT - 1] = _DensityVolumeIndexShift;
int categoryListCount[LIGHTCATEGORY_COUNT]; // direct light count and reflection lights
int categoryListCount[LIGHTCATEGORY_COUNT]; // number of direct lights, reflection probes and density volumes
ZERO_INITIALIZE_ARRAY(int, categoryListCount, LIGHTCATEGORY_COUNT);
uint offs = start;
for(int ll=0; ll<iNrCoarseLights; ll+=4)

{
uint lightCategory = _LightVolumeData[coarseList[l]].lightCategory;
++categoryListCount[lightCategory];
g_vLayeredLightList[offs++] = coarseList[l] - shiftIndex[lightCategory]; // reflection lights will be last since we sorted
g_vLayeredLightList[offs++] = coarseList[l] - shiftIndex[lightCategory];
}
}

19
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/lightlistbuild.compute


#define MAX_NR_COARSE_ENTRIES 64
#define MAX_NR_PRUNED_ENTRIES 24
#define CATEGORY_LIST_SIZE (LIGHTCATEGORY_COUNT - 1) // Skip density volumes
groupshared unsigned int coarseList[MAX_NR_COARSE_ENTRIES];
groupshared unsigned int prunedList[MAX_NR_COARSE_ENTRIES]; // temporarily support room for all 64 while in LDS

#endif
groupshared int ldsNrLightsFinal;
groupshared int ldsCategoryListCount[LIGHTCATEGORY_COUNT];
groupshared int ldsCategoryListCount[CATEGORY_LIST_SIZE];
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
groupshared uint lightOffsSph;

for(int l=(int) t; l<(int) g_iNrVisibLights; l += NR_THREADS)
{
#endif
// Skip density volumes. TODO: improve data locality
if (_LightVolumeData[l].lightCategory == LIGHTCATEGORY_DENSITY_VOLUME) { continue; }
const float3 vMi = g_vBoundsBuffer[l];
const float3 vMa = g_vBoundsBuffer[l+g_iNrVisibLights];

}
#endif
//
if(t<LIGHTCATEGORY_COUNT) ldsCategoryListCount[t]=0;
if(t<CATEGORY_LIST_SIZE) ldsCategoryListCount[t]=0;
#ifdef USE_FEATURE_FLAGS
if(t==0) ldsFeatureFlags=0;
#endif

int localOffs=0;
int offs = tileIDX.y*nrTilesX + tileIDX.x;
// All our cull data are in the same list, but at render time envLights are separated so we need to shit the index
// All our cull data are in the same list, but at render time envLights are separated so we need to shift the index
int shiftIndex[LIGHTCATEGORY_COUNT];
ZERO_INITIALIZE_ARRAY(int, shiftIndex, LIGHTCATEGORY_COUNT);
shiftIndex[LIGHTCATEGORY_COUNT - 1] = _EnvLightIndexShift;
int shiftIndex[CATEGORY_LIST_SIZE];
ZERO_INITIALIZE_ARRAY(int, shiftIndex, CATEGORY_LIST_SIZE);
shiftIndex[CATEGORY_LIST_SIZE - 1] = _EnvLightIndexShift;
for(int category=0; category<LIGHTCATEGORY_COUNT; category++)
for(int category=0; category<CATEGORY_LIST_SIZE; category++)
{
int nrLightsFinal = ldsCategoryListCount[category];
int nrLightsFinalClamped = nrLightsFinal<MAX_NR_PRUNED_ENTRIES ? nrLightsFinal : MAX_NR_PRUNED_ENTRIES;

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/HomogeneousDensityVolume.cs


[AddComponentMenu("RenderPipeline/High Definition/Homogeneous Density Volume", -1)]
public class HomogeneousDensityVolume : MonoBehaviour
{
public VolumeParameters volumeParameters = new VolumeParameters();
public DensityVolumeParameters parameters = new DensityVolumeParameters();
private void Awake()
{

private void OnValidate()
{
volumeParameters.Constrain();
parameters.Constrain();
if (volumeParameters.IsLocalVolume())
if (parameters.IsLocalVolume())
Gizmos.color = volumeParameters.albedo;
Gizmos.color = parameters.albedo;
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
}

foreach (HomogeneousDensityVolume volume in volumes)
{
if (volume.enabled && !volume.volumeParameters.IsLocalVolume())
if (volume.enabled && !volume.parameters.IsLocalVolume())
{
globalVolume = volume;
break;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/HomogeneousDensityVolume.cs.meta


fileFormatVersion: 2
guid: 1c273c50d71d46a4f98a1d23256a8c63
guid: e1fbb15bf92b84f40a1eb030765b5afe
MonoImporter:
externalObjects: {}
serializedVersion: 2

82
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[GenerateHLSL]
public struct VolumeProperties
public struct DensityVolumeProperties
public static VolumeProperties GetNeutralVolumeProperties()
public static DensityVolumeProperties GetNeutralProperties()
VolumeProperties properties = new VolumeProperties();
DensityVolumeProperties properties = new DensityVolumeProperties();
properties.scattering = Vector3.zero;
properties.extinction = 0;

} // struct VolumeProperties
[Serializable]
public class VolumeParameters
public class DensityVolumeParameters
public bool isLocal; // Enables voxelization
public Color albedo; // Single scattering albedo [0, 1]
public float meanFreePath; // In meters [1, inf]. Should be chromatic - this is an optimization!
public float asymmetry; // Single global parameter for all volumes. TODO: UX
public bool isLocal; // Enables voxelization
public Color albedo; // Single scattering albedo [0, 1]
public float meanFreePath; // In meters [1, inf]. Should be chromatic - this is an optimization!
public float asymmetry; // Only used if (isLocal == false)
public VolumeParameters()
public DensityVolumeParameters()
{
isLocal = true;
albedo = new Color(0.5f, 0.5f, 0.5f);

asymmetry = Mathf.Clamp(asymmetry, -1.0f, 1.0f);
}
public VolumeProperties GetProperties()
public DensityVolumeProperties GetProperties()
VolumeProperties properties = new VolumeProperties();
DensityVolumeProperties properties = new DensityVolumeProperties();
properties.scattering = GetScatteringCoefficient();
properties.extinction = GetExtinctionCoefficient();

} // class VolumeParameters
public struct DensityVolumeList
{
public List<OrientedBBox> bounds;
public List<DensityVolumeProperties> properties;
}
public class VolumetricLightingModule
{

ComputeShader m_VolumetricLightingCS = null;
List<VBuffer> m_VBuffers = null;
List<OrientedBBox> m_VisibleVolumes = null;
List<VolumeProperties> m_VisibleVolumeProperties = null;
public const int k_MaxVisibleVolumeCount = 512;
List<VBuffer> m_VBuffers = null;
List<OrientedBBox> m_VisibleVolumeBounds = null;
List<DensityVolumeProperties> m_VisibleVolumeProperties = null;
public const int k_MaxVisibleVolumeCount = 512;
static ComputeBuffer s_VisibleVolumesBuffer = null;
static ComputeBuffer s_VisibleVolumeBoundsBuffer = null;
static ComputeBuffer s_VisibleVolumePropertiesBuffer = null;
float m_VBufferNearPlane = 0.5f; // Distance in meters; dynamic modifications not handled by reprojection

m_VolumetricLightingCS = asset.renderPipelineResources.volumetricLightingCS;
m_VBuffers = new List<VBuffer>();
m_VisibleVolumes = new List<OrientedBBox>();
m_VisibleVolumeProperties = new List<VolumeProperties>();
s_VisibleVolumesBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(OrientedBBox)));
s_VisibleVolumePropertiesBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(VolumeProperties)));
m_VisibleVolumeBounds = new List<OrientedBBox>();
m_VisibleVolumeProperties = new List<DensityVolumeProperties>();
s_VisibleVolumeBoundsBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(OrientedBBox)));
s_VisibleVolumePropertiesBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DensityVolumeProperties)));
}
public void Cleanup()

}
m_VBuffers = null;
m_VisibleVolumes = null;
m_VisibleVolumeBounds = null;
CoreUtils.SafeRelease(s_VisibleVolumesBuffer);
CoreUtils.SafeRelease(s_VisibleVolumeBoundsBuffer);
CoreUtils.SafeRelease(s_VisibleVolumePropertiesBuffer);
}

HomogeneousDensityVolume globalVolume = HomogeneousDensityVolume.GetGlobalHomogeneousDensityVolume();
// TODO: may want to cache these results somewhere.
VolumeProperties globalVolumeProperties = (globalVolume != null) ? globalVolume.volumeParameters.GetProperties()
: VolumeProperties.GetNeutralVolumeProperties();
DensityVolumeProperties globalVolumeProperties = (globalVolume != null) ? globalVolume.parameters.GetProperties()
: DensityVolumeProperties.GetNeutralProperties();
float asymmetry = globalVolume != null ? globalVolume.volumeParameters.asymmetry : 0;
float asymmetry = globalVolume != null ? globalVolume.parameters.asymmetry : 0;
cmd.SetGlobalVector(HDShaderIDs._Global_Scattering, globalVolumeProperties.scattering);
cmd.SetGlobalFloat( HDShaderIDs._Global_Extinction, globalVolumeProperties.extinction);
cmd.SetGlobalFloat( HDShaderIDs._Global_Asymmetry, asymmetry);

cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, vBuffer.GetLightingIntegralBuffer());
}
public void VoxelizeDensityVolumes(HDCamera camera, CommandBuffer cmd)
public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera camera, CommandBuffer cmd)
if (preset == VolumetricLightingPreset.Off) return;
DensityVolumeList densityVolumes = new DensityVolumeList();
if (preset == VolumetricLightingPreset.Off) return densityVolumes;
Vector3 camPosition = camera.camera.transform.position;
Vector3 camOffset = Vector3.zero; // World-origin-relative

camOffset = -camPosition; // Camera-relative
}
m_VisibleVolumes.Clear();
m_VisibleVolumeBounds.Clear();
// Collect all the visible volume data, and upload it to the GPU.
// Collect all visible finite volume data, and upload it to the GPU.
if (volume.enabled && volume.volumeParameters.IsLocalVolume())
if (volume.enabled && volume.parameters.IsLocalVolume())
{
// TODO: cache these?
var obb = OrientedBBox.Create(volume.transform);

{
// TODO: cache these?
var properties = volume.volumeParameters.GetProperties();
var properties = volume.parameters.GetProperties();
m_VisibleVolumes.Add(obb);
m_VisibleVolumeBounds.Add(obb);
s_VisibleVolumesBuffer.SetData(m_VisibleVolumes);
s_VisibleVolumeBoundsBuffer.SetData(m_VisibleVolumeBounds);
// Fill the struct with pointers in order to share the data with the light loop.
densityVolumes.bounds = m_VisibleVolumeBounds;
densityVolumes.properties = m_VisibleVolumeProperties;
return densityVolumes;
}
// Ref: https://en.wikipedia.org/wiki/Close-packing_of_equal_spheres

Debug.Assert(vBuffer != null);
HomogeneousDensityVolume globalVolume = HomogeneousDensityVolume.GetGlobalHomogeneousDensityVolume();
float asymmetry = globalVolume != null ? globalVolume.volumeParameters.asymmetry : 0;
float asymmetry = globalVolume != null ? globalVolume.parameters.asymmetry : 0;
if (globalVolume == null)
{

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


#ifndef VOLUMETRICLIGHTING_CS_HLSL
#define VOLUMETRICLIGHTING_CS_HLSL
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.VolumeProperties
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.DensityVolumeProperties
struct VolumeProperties
struct DensityVolumeProperties
{
float3 scattering;
float extinction;

// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.VolumeProperties
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.DensityVolumeProperties
float3 GetScattering(VolumeProperties value)
float3 GetScattering(DensityVolumeProperties value)
float GetExtinction(VolumeProperties value)
float GetExtinction(DensityVolumeProperties value)
{
return value.extinction;
}

正在加载...
取消
保存