浏览代码

Merge pull request #1893 from EvgeniiG/fade_for_density_volumes

Add controls for linear fade at the boundary of density volumes
/hdrp-staging
GitHub 6 年前
当前提交
3e708a4a
共有 8 个文件被更改,包括 178 次插入71 次删除
  1. 3
      com.unity.render-pipelines.high-definition/CHANGELOG.md
  2. 52
      com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Volumetric/DensityVolumeEditor.cs
  3. 2
      com.unity.render-pipelines.high-definition/HDRP/Lighting/AtmosphericScattering/AtmosphericScattering.cs
  4. 4
      com.unity.render-pipelines.high-definition/HDRP/Lighting/AtmosphericScattering/VolumetricFog.cs
  5. 72
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/DensityVolume.cs
  6. 34
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumeVoxelization.compute
  7. 41
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs
  8. 41
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs.hlsl

3
com.unity.render-pipelines.high-definition/CHANGELOG.md


## [3.4.0-preview]
### Added
- Added controls for linear fade at the boundary of density volumes
### Fixed
- Stencil test during decals normal buffer update is now properly applied
- Fixed an issue where sometimes the deferred shadow texture would not be valid, causing wrong rendering.

52
com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Volumetric/DensityVolumeEditor.cs


static GUIContent s_TextureScrollLabel = new GUIContent("Texture Scroll Speed");
static GUIContent s_TextureTileLabel = new GUIContent("Texture Tiling Amount");
static GUIContent s_TextureSettingsTitle = new GUIContent("Volume Texture Settings");
static GUIContent s_PositiveFadeLabel = new GUIContent("Positive Fade", "Controls the [0, 1] distance from the +X/+Y/+Z face at which a linear fade ends. 0 means no fade, 1 means the fade ends at the opposite face.");
static GUIContent s_NegativeFadeLabel = new GUIContent("Negative Fade", "Controls the [0, 1] distance from the -X/-Y/-Z face at which a linear fade ends. 0 means no fade, 1 means the fade ends at the opposite face.");
private bool showTextureParams = false;

SerializedProperty textureScroll;
SerializedProperty textureTile;
SerializedProperty positiveFade;
SerializedProperty negativeFade;
albedo = densityParams.FindPropertyRelative("albedo");
meanFreePath = densityParams.FindPropertyRelative("meanFreePath");
albedo = densityParams.FindPropertyRelative("albedo");
meanFreePath = densityParams.FindPropertyRelative("meanFreePath");
textureTile = densityParams.FindPropertyRelative("textureTiling");
textureTile = densityParams.FindPropertyRelative("textureTiling");
positiveFade = densityParams.FindPropertyRelative("positiveFade");
negativeFade = densityParams.FindPropertyRelative("negativeFade");
if (volumeTexture != null && volumeTexture.objectReferenceValue != null)
{

public override void OnInspectorGUI()
{
albedo.colorValue = EditorGUILayout.ColorField(s_AlbedoLabel, albedo.colorValue, true, false, false);
EditorGUILayout.PropertyField(meanFreePath, s_MeanFreePathLabel);
EditorGUILayout.Space();
serializedObject.Update();
showTextureParams = EditorGUILayout.Foldout(showTextureParams, s_TextureSettingsTitle, true);
if (showTextureParams)
EditorGUI.BeginChangeCheck();
EditorGUI.indentLevel++;
albedo.colorValue = EditorGUILayout.ColorField(s_AlbedoLabel, albedo.colorValue, true, false, false);
EditorGUILayout.PropertyField(meanFreePath, s_MeanFreePathLabel);
EditorGUILayout.Space();
EditorGUILayout.PropertyField(positiveFade, s_PositiveFadeLabel);
EditorGUILayout.PropertyField(negativeFade, s_NegativeFadeLabel);
EditorGUILayout.Space();
EditorGUILayout.PropertyField(textureTile, s_TextureTileLabel);
EditorGUI.indentLevel--;
EditorGUILayout.PropertyField(textureTile, s_TextureTileLabel);
}
if (EditorGUI.EndChangeCheck())
{
Vector3 posFade = new Vector3();
posFade.x = Mathf.Clamp01(positiveFade.vector3Value.x);
posFade.y = Mathf.Clamp01(positiveFade.vector3Value.y);
posFade.z = Mathf.Clamp01(positiveFade.vector3Value.z);
Vector3 negFade = new Vector3();
negFade.x = Mathf.Clamp01(negativeFade.vector3Value.x);
negFade.y = Mathf.Clamp01(negativeFade.vector3Value.y);
negFade.z = Mathf.Clamp01(negativeFade.vector3Value.z);
positiveFade.vector3Value = posFade;
negativeFade.vector3Value = negFade;
}
serializedObject.ApplyModifiedProperties();

2
com.unity.render-pipelines.high-definition/HDRP/Lighting/AtmosphericScattering/AtmosphericScattering.cs


// (not just the atmospheric scattering one) receive neutral parameters.
if (hdCamera.frameSettings.enableVolumetrics)
{
var data = DensityVolumeData.GetNeutralValues();
var data = DensityVolumeEngineData.GetNeutralValues();
cmd.SetGlobalVector(HDShaderIDs._GlobalScattering, data.scattering);
cmd.SetGlobalFloat(HDShaderIDs._GlobalExtinction, data.extinction);

4
com.unity.render-pipelines.high-definition/HDRP/Lighting/AtmosphericScattering/VolumetricFog.cs


public override void PushShaderParameters(HDCamera hdCamera, CommandBuffer cmd)
{
DensityVolumeParameters param = new DensityVolumeParameters(albedo, meanFreePath, anisotropy);
DensityVolumeArtistParameters param = new DensityVolumeArtistParameters(albedo, meanFreePath, anisotropy);
DensityVolumeData data = param.GetData();
DensityVolumeEngineData data = param.GetData();
cmd.SetGlobalInt(HDShaderIDs._AtmosphericScatteringType, (int)FogType.Volumetric);

72
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/DensityVolume.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public struct DensityVolumeParameters
public struct DensityVolumeArtistParameters
public Color albedo; // Single scattering albedo [0, 1]. Alpha is ignored
public float meanFreePath; // In meters [1, inf]. Should be chromatic - this is an optimization!
public float asymmetry; // Only used if (isLocal == false)
public Color albedo; // Single scattering albedo [0, 1]. Alpha is ignored
public float meanFreePath; // In meters [1, inf]. Should be chromatic - this is an optimization!
public float asymmetry; // Only used if (isLocal == false)
public int textureIndex;
public Vector3 textureScrollingSpeed;
public Vector3 textureTiling;
public Vector3 textureScrollingSpeed;
public Vector3 textureTiling;
private Vector3 volumeScrollingAmount;
public Vector3 positiveFade;
public Vector3 negativeFade;
public DensityVolumeParameters(Color color, float _meanFreePath, float _asymmetry)
public int textureIndex; // This shouldn't be public... Internal, maybe?
private Vector3 volumeScrollingAmount;
public DensityVolumeArtistParameters(Color color, float _meanFreePath, float _asymmetry)
albedo = color;
meanFreePath = _meanFreePath;
asymmetry = _asymmetry;
albedo = color;
meanFreePath = _meanFreePath;
asymmetry = _asymmetry;
volumeMask = null;
textureIndex = -1;
volumeMask = null;
textureIndex = -1;
textureTiling = Vector3.one;
textureTiling = Vector3.one;
positiveFade = Vector3.zero;
negativeFade = Vector3.zero;
}
public void Update(bool animate, float time)

volumeScrollingAmount = Vector3.zero;
}
public DensityVolumeData GetData()
public DensityVolumeEngineData GetData()
DensityVolumeData data = new DensityVolumeData();
DensityVolumeEngineData data = new DensityVolumeEngineData();
data.extinction = VolumeRenderingUtils.ExtinctionFromMeanFreePath(meanFreePath);
data.scattering = VolumeRenderingUtils.ScatteringFromExtinctionAndAlbedo(data.extinction, (Vector3)(Vector4)albedo);
data.extinction = VolumeRenderingUtils.ExtinctionFromMeanFreePath(meanFreePath);
data.scattering = VolumeRenderingUtils.ScatteringFromExtinctionAndAlbedo(data.extinction, (Vector3)(Vector4)albedo);
data.textureIndex = textureIndex;
data.textureScroll = volumeScrollingAmount;
data.textureTiling = textureTiling;
data.textureIndex = textureIndex;
data.textureScroll = volumeScrollingAmount;
data.textureTiling = textureTiling;
// Avoid numerical problems by clamping extreme values.
data.rcpPosFade.x = Mathf.Clamp(1.0f / positiveFade.x, 0.00001526f, 65536.0f);
data.rcpNegFade.x = Mathf.Clamp(1.0f / negativeFade.x, 0.00001526f, 65536.0f);
data.rcpPosFade.y = Mathf.Clamp(1.0f / positiveFade.y, 0.00001526f, 65536.0f);
data.rcpNegFade.y = Mathf.Clamp(1.0f / negativeFade.y, 0.00001526f, 65536.0f);
data.rcpPosFade.z = Mathf.Clamp(1.0f / positiveFade.z, 0.00001526f, 65536.0f);
data.rcpNegFade.z = Mathf.Clamp(1.0f / negativeFade.z, 0.00001526f, 65536.0f);
return data;
}

[AddComponentMenu("Rendering/Density Volume", 1100)]
public class DensityVolume : MonoBehaviour
{
public DensityVolumeParameters parameters = new DensityVolumeParameters(Color.white, 10.0f, 0.0f);
public DensityVolumeArtistParameters parameters = new DensityVolumeArtistParameters(Color.white, 10.0f, 0.0f);
private Texture3D previousVolumeMask = null;

void OnDrawGizmos()
{
Gizmos.color = parameters.albedo;
// Positive fade box.
Gizmos.color = Color.red;
Gizmos.DrawWireCube(-0.5f * parameters.positiveFade, Vector3.one - parameters.positiveFade);
// Negative fade box.
Gizmos.color = Color.blue;
Gizmos.DrawWireCube(0.5f * parameters.negativeFade, Vector3.one - parameters.negativeFade);
// Bounding box.
Gizmos.color = parameters.albedo;
Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
}
}

34
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumeVoxelization.compute


//--------------------------------------------------------------------------------------------------
StructuredBuffer<OrientedBBox> _VolumeBounds;
StructuredBuffer<DensityVolumeData> _VolumeData;
StructuredBuffer<DensityVolumeEngineData> _VolumeData;
TEXTURE3D(_VolumeMaskAtlas);

//--------------------------------------------------------------------------------------------------
// Implementation
//--------------------------------------------------------------------------------------------------
float SampleVolumeMask(DensityVolumeData volumeData, float3 voxelCenterUVW, float3 duvw_dx, float3 duvw_dy, float3 duvw_dz)
float ComputeFadeFactor(float3 coordNDC, float3 rcpPosFade, float3 rcpNegFade)
{
// We have to account for handedness.
coordNDC.z = 1 - coordNDC.z;
float3 posT = saturate(coordNDC * rcpPosFade - rcpPosFade + 1);
float3 negT = saturate(1 - coordNDC * rcpNegFade);
return lerp(1, 0, posT.x) * lerp(1, 0, posT.y) * lerp(1, 0, posT.z)
* lerp(1, 0, negT.x) * lerp(1, 0, negT.y) * lerp(1, 0, negT.z);
}
float SampleVolumeMask(DensityVolumeEngineData volumeData, float3 voxelCenterNDC, float3 duvw_dx, float3 duvw_dy, float3 duvw_dz)
voxelCenterUVW = frac(voxelCenterUVW * volumeData.textureTiling + volumeData.textureScroll);
float3 voxelCenterUVW = frac(voxelCenterNDC * volumeData.textureTiling + volumeData.textureScroll);
float rcpNumTextures = _VolumeMaskDimensions.x;
float textureWidth = _VolumeMaskDimensions.y;

int mipSize = textureSize >> (int)ceil(lod);
float halfTexelSize = 0.5f * rcp(mipSize);
voxelCenterUVW.z = clamp(voxelCenterUVW.z, offset + halfTexelSize, offset + rcpNumTextures - halfTexelSize);
void FillVolumetricDensityBuffer(PositionInputs posInput, float3 rayOriginWS, float3 rayUnDirWS,
float3 voxelAxisRight, float3 voxelAxisUp, float3 voxelAxisForward)

if (overlapFraction > 0)
{
float densityMask = 1.0f;
float3 voxelCenterNDC = voxelCenterCS * 0.5 + 0.5;
overlapFraction *= ComputeFadeFactor(voxelCenterNDC, _VolumeData[volumeIndex].rcpPosFade, _VolumeData[volumeIndex].rcpNegFade);
//Sample the volumeMask
if (_VolumeData[volumeIndex].textureIndex != -1)
{

float3 voxelGradForwardUVW = halfDZ * voxelAxisForwardBS / obbExtents;
float3 voxelCenterUVW = voxelCenterCS * 0.5 + 0.5;
densityMask = SampleVolumeMask(_VolumeData[volumeIndex], voxelCenterUVW, voxelGradRightUVW, voxelGradUpUVW, voxelGradForwardUVW);
overlapFraction *= SampleVolumeMask(_VolumeData[volumeIndex], voxelCenterNDC, voxelGradRightUVW, voxelGradUpUVW, voxelGradForwardUVW);
voxelScattering += overlapFraction * _VolumeData[volumeIndex].scattering * densityMask;
voxelExtinction += overlapFraction * _VolumeData[volumeIndex].extinction * densityMask;
voxelScattering += overlapFraction * _VolumeData[volumeIndex].scattering;
voxelExtinction += overlapFraction * _VolumeData[volumeIndex].extinction;
}
#ifndef USE_CLUSTERED_LIGHTLIST

41
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
// TODO: pack better. This data structure contains a bunch of UNORMs.
public struct DensityVolumeData
public struct DensityVolumeEngineData
{
public Vector3 scattering; // [0, 1]
public float extinction; // [0, 1]

public float pad0;
public Vector3 rcpPosFade;
public float pad1;
public Vector3 rcpNegFade;
public float pad2;
public static DensityVolumeData GetNeutralValues()
public static DensityVolumeEngineData GetNeutralValues()
DensityVolumeData data;
DensityVolumeEngineData data;
data.scattering = Vector3.zero;
data.extinction = 0;

data.rcpPosFade = new Vector3(65536.0f, 65536.0f, 65536.0f);
data.rcpNegFade = new Vector3(65536.0f, 65536.0f, 65536.0f);
data.pad0 = 0;
data.pad1 = 0;
data.pad2 = 0;
return data;
}

public struct DensityVolumeList
{
public List<OrientedBBox> bounds;
public List<DensityVolumeData> density;
public List<DensityVolumeEngineData> density;
}
public class VolumetricLightingSystem

public VolumetricLightingPreset preset = VolumetricLightingPreset.Off;
static ComputeShader m_VolumeVoxelizationCS = null;
static ComputeShader m_VolumetricLightingCS = null;
static ComputeShader m_VolumeVoxelizationCS = null;
static ComputeShader m_VolumetricLightingCS = null;
List<OrientedBBox> m_VisibleVolumeBounds = null;
List<DensityVolumeData> m_VisibleVolumeData = null;
public const int k_MaxVisibleVolumeCount = 512;
List<OrientedBBox> m_VisibleVolumeBounds = null;
List<DensityVolumeEngineData> m_VisibleVolumeData = null;
public const int k_MaxVisibleVolumeCount = 512;
static ComputeBuffer s_VisibleVolumeBoundsBuffer = null;
static ComputeBuffer s_VisibleVolumeDataBuffer = null;
static ComputeBuffer s_VisibleVolumeBoundsBuffer = null;
static ComputeBuffer s_VisibleVolumeDataBuffer = null;
RTHandleSystem.RTHandle m_DensityBufferHandle;
RTHandleSystem.RTHandle m_LightingBufferHandle;
RTHandleSystem.RTHandle m_DensityBufferHandle;
RTHandleSystem.RTHandle m_LightingBufferHandle;
// Is the feature globally disabled?
bool m_supportVolumetrics = false;

Debug.Assert(m_VolumetricLightingCS != null);
m_VisibleVolumeBounds = new List<OrientedBBox>();
m_VisibleVolumeData = new List<DensityVolumeData>();
m_VisibleVolumeData = new List<DensityVolumeEngineData>();
s_VisibleVolumeDataBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, Marshal.SizeOf(typeof(DensityVolumeData)));
s_VisibleVolumeDataBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, Marshal.SizeOf(typeof(DensityVolumeEngineData)));
int d = ComputeVBufferSliceCount(preset);

41
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs.hlsl


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

float pad0;
float3 rcpPosFade;
float pad1;
float3 rcpNegFade;
float pad2;
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.DensityVolumeData
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.DensityVolumeEngineData
float3 GetScattering(DensityVolumeData value)
float3 GetScattering(DensityVolumeEngineData value)
float GetExtinction(DensityVolumeData value)
float GetExtinction(DensityVolumeEngineData value)
float3 GetTextureTiling(DensityVolumeData value)
float3 GetTextureTiling(DensityVolumeEngineData value)
int GetTextureIndex(DensityVolumeData value)
int GetTextureIndex(DensityVolumeEngineData value)
float3 GetTextureScroll(DensityVolumeData value)
float3 GetTextureScroll(DensityVolumeEngineData value)
}
float GetPad0(DensityVolumeEngineData value)
{
return value.pad0;
}
float3 GetRcpPosFade(DensityVolumeEngineData value)
{
return value.rcpPosFade;
}
float GetPad1(DensityVolumeEngineData value)
{
return value.pad1;
}
float3 GetRcpNegFade(DensityVolumeEngineData value)
{
return value.rcpNegFade;
}
float GetPad2(DensityVolumeEngineData value)
{
return value.pad2;
}
正在加载...
取消
保存