浏览代码

Merge pull request #821 from Unity-Technologies/Branch_HeightFog

Implemented height fog for linear and exponential fog.
/main
GitHub 6 年前
当前提交
67a7cae5
共有 11 个文件被更改,包括 280 次插入55 次删除
  1. 94
      SampleScenes/HDTest/SkyFogTest.unity
  2. 104
      SampleScenes/HDTest/Volume Profiles/SkyFog Test Settings.asset
  3. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/AtmosphericScattering/ExponentialFogEditor.cs
  4. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/AtmosphericScattering/LinearFogEditor.cs
  5. 26
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesFunctions.hlsl
  6. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.cs
  7. 70
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.hlsl
  8. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/ExponentialFog.cs
  9. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/LinearFog.cs
  10. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/OpaqueAtmosphericScattering.shader
  11. 7
      Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/SkySettings/HDRP_Default_Sky_LinearFog.asset

94
SampleScenes/HDTest/SkyFogTest.unity


shadowResolution: 1024
shadowDimmer: 1
shadowFadeDistance: 10000
enableContactShadows: 0
contactShadowLength: 0
contactShadowDistanceScaleFactor: 0.5
contactShadowMaxDistance: 50
contactShadowFadeDistance: 5
contactShadowSampleCount: 8
shadowCascadeCount: 4
shadowCascadeRatios:
- 0.05

m_Bits: 4294967295
m_FrameSettings:
enableShadow: 1
enableContactShadows: 1
enableSSR: 1
enableSSAO: 1
enableSubsurfaceScattering: 1

m_PrefabParentObject: {fileID: 4590821631456672, guid: 63d293d8d9b22af4eb3a41f61a9d3538,
type: 2}
m_PrefabInternal: {fileID: 1677549155}
--- !u!1 &1764604543
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1764604547}
- component: {fileID: 1764604546}
- component: {fileID: 1764604545}
- component: {fileID: 1764604544}
m_Layer: 0
m_Name: Plane (1)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!23 &1764604544
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1764604543}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 948836267934e104294e03adad5c7bf7, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!64 &1764604545
MeshCollider:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1764604543}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 3
m_Convex: 0
m_CookingOptions: 14
m_SkinWidth: 0.01
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!33 &1764604546
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1764604543}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &1764604547
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1764604543}
m_LocalRotation: {x: 0, y: 0, z: 0.7071068, w: 0.7071068}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 50, y: 50, z: 50}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 20
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 90}
--- !u!1 &2031183050
GameObject:
m_ObjectHideFlags: 0

104
SampleScenes/HDTest/Volume Profiles/SkyFog Test Settings.asset


- {fileID: 114622818644247598}
- {fileID: 114778021399336454}
- {fileID: 114760446287294382}
- {fileID: 114049855757342906}
- {fileID: 114775890076625852}
--- !u!114 &114049855757342906
MonoBehaviour:
m_ObjectHideFlags: 3
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59b6606ef2548734bb6d11b9d160bc7e, type: 3}
m_Name: HDRISky
m_EditorClassIdentifier:
active: 1
rotation:
m_OverrideState: 1
m_Value: 0
min: 0
max: 360
exposure:
m_OverrideState: 1
m_Value: 0
multiplier:
m_OverrideState: 1
m_Value: 1
min: 0
updateMode:
m_OverrideState: 1
m_Value: 0
updatePeriod:
m_OverrideState: 1
m_Value: 0
min: 0
skyHDRI:
m_OverrideState: 1
m_Value: {fileID: 8900000, guid: de78f930088fc194290da7400c89bfb5, type: 3}
--- !u!114 &114622818644247598
MonoBehaviour:
m_ObjectHideFlags: 3

m_Value: 2
fogType:
m_OverrideState: 1
m_Value: 1
m_Value: 2
--- !u!114 &114760446287294382
MonoBehaviour:
m_ObjectHideFlags: 3

m_OverrideState: 1
m_Value: 0
min: 0
useForBaking: 1
sunSize:
m_OverrideState: 1
m_Value: 0.04

enableSunDisk:
m_OverrideState: 1
m_Value: 1
--- !u!114 &114775890076625852
MonoBehaviour:
m_ObjectHideFlags: 3
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2150ee00179b2f4418ea8b21a7e98eea, type: 3}
m_Name: ExponentialFog
m_EditorClassIdentifier:
active: 1
colorMode:
m_OverrideState: 1
m_Value: 1
color:
m_OverrideState: 1
m_Value: {r: 0.509434, g: 0.1994482, b: 0.1994482, a: 1}
hdr: 0
showAlpha: 1
showEyeDropper: 1
density:
m_OverrideState: 1
m_Value: 1
min: 0
max: 1
mipFogMaxMip:
m_OverrideState: 1
m_Value: 0.5
min: 0
max: 1
mipFogNear:
m_OverrideState: 1
m_Value: 200
min: 0
mipFogFar:
m_OverrideState: 1
m_Value: 500
min: 0
fogDistance:
m_OverrideState: 1
m_Value: 50
min: 0
fogBaseHeight:
m_OverrideState: 1
m_Value: 2
fogHeightAttenuation:
m_OverrideState: 1
m_Value: 0.033
min: 0
max: 1
--- !u!114 &114778021399336454
MonoBehaviour:
m_ObjectHideFlags: 3

m_Value: 1
color:
m_OverrideState: 1
m_Value: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_Value: {r: 0.7075472, g: 0.23028658, b: 0.23028658, a: 1}
hdr: 0
showAlpha: 1
showEyeDropper: 1

max: 1
mipFogMaxMip:
m_OverrideState: 1
m_Value: 0.693
m_Value: 0.609
m_Value: 300
m_Value: 50
min: 0
mipFogFar:
m_OverrideState: 1

m_OverrideState: 1
m_Value: 50
m_Value: 20
fogHeightStart:
m_OverrideState: 1
m_Value: 10
fogHeightEnd:
m_OverrideState: 1
m_Value: 20

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/AtmosphericScattering/ExponentialFogEditor.cs


public class ExponentialFogEditor : AtmosphericScatteringEditor
{
private SerializedDataParameter m_FogDistance;
private SerializedDataParameter m_FogBaseHeight;
private SerializedDataParameter m_FogHeightAttenuation;
public override void OnEnable()
{

m_FogDistance = Unpack(o.Find(x => x.fogDistance));
m_FogBaseHeight = Unpack(o.Find(x => x.fogBaseHeight));
m_FogHeightAttenuation = Unpack(o.Find(x => x.fogHeightAttenuation));
}
public override void OnInspectorGUI()

PropertyField(m_FogBaseHeight);
PropertyField(m_FogHeightAttenuation);
}
}
}

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/AtmosphericScattering/LinearFogEditor.cs


{
private SerializedDataParameter m_FogStart;
private SerializedDataParameter m_FogEnd;
private SerializedDataParameter m_FogHeightStart;
private SerializedDataParameter m_FogHeightEnd;
public override void OnEnable()
{

m_FogStart = Unpack(o.Find(x => x.fogStart));
m_FogEnd = Unpack(o.Find(x => x.fogEnd));
m_FogHeightStart = Unpack(o.Find(x => x.fogHeightStart));
m_FogHeightEnd = Unpack(o.Find(x => x.fogHeightEnd));
}
public override void OnInspectorGUI()

PropertyField(m_FogStart);
PropertyField(m_FogEnd);
PropertyField(m_FogHeightStart);
PropertyField(m_FogHeightEnd);
}
}
}

26
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesFunctions.hlsl


}
// Computes the world space view direction (pointing towards the viewer).
float3 GetWorldSpaceViewDir(float3 positionWS)
{
if (IsPerspectiveProjection())
{
// Perspective
return GetCurrentViewPosition() - positionWS;
}
else
{
// Orthographic
return -GetViewForwardDir();
}
}
if (IsPerspectiveProjection())
{
// Perspective
float3 V = GetCurrentViewPosition() - positionWS;
return normalize(V);
}
else
{
// Orthographic
return -GetViewForwardDir();
}
return normalize(GetWorldSpaceViewDir(positionWS));
}
float3x3 CreateWorldToTangent(float3 normal, float3 tangent, float flipSign)

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.cs


public ColorParameter color = new ColorParameter(Color.grey);
public ClampedFloatParameter density = new ClampedFloatParameter(1.0f, 0.0f, 1.0f);
[Tooltip("Maximum mip map used for mip fog (0 being lowest and 1 highest mip).")]
public ClampedFloatParameter mipFogMaxMip = new ClampedFloatParameter(1.0f, 0.0f, 1.0f);
public ClampedFloatParameter mipFogMaxMip = new ClampedFloatParameter(0.5f, 0.0f, 1.0f);
[Tooltip("Distance at which minimum mip of blurred sky texture is used as fog color.")]
public MinFloatParameter mipFogNear = new MinFloatParameter(0.0f, 0.0f);
[Tooltip("Distance at which maximum mip of blurred sky texture is used as fog color.")]

70
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.hlsl


float4 _ExpFogParameters;
CBUFFER_END
#define _MipFogNear _MipFogParameters.x
#define _MipFogFar _MipFogParameters.y
#define _MipFogMaxMip _MipFogParameters.z
#define _MipFogNear _MipFogParameters.x
#define _MipFogFar _MipFogParameters.y
#define _MipFogMaxMip _MipFogParameters.z
#define _FogDensity _FogColorDensity.w
#define _FogColor _FogColorDensity
#define _FogDensity _FogColorDensity.w
#define _FogColor _FogColorDensity
#define _LinearFogStart _LinearFogParameters.x
#define _LinearFogEnd _LinearFogParameters.y
#define _LinearFogOneOverRange _LinearFogParameters.z
#define _LinearFogStart _LinearFogParameters.x
#define _LinearFogOneOverRange _LinearFogParameters.y
#define _LinearFogHeightEnd _LinearFogParameters.z
#define _LinearFogHeightOneOverRange _LinearFogParameters.w
#define _ExpFogDistance _ExpFogParameters.x
#define _ExpFogDistance _ExpFogParameters.x
#define _ExpFogBaseHeight _ExpFogParameters.y
#define _ExpFogHeightAttenuation _ExpFogParameters.z
float3 GetFogColor(PositionInputs posInput)
{

{
// Based on Uncharted 4 "Mip Sky Fog" trick: http://advances.realtimerendering.com/other/2016/naughty_dog/NaughtyDog_TechArt_Final.pdf
float mipLevel = (1.0 - _MipFogMaxMip * saturate((posInput.linearDepth - _MipFogNear) / (_MipFogFar - _MipFogNear))) * _SkyTextureMipCount;
float3 dir = normalize(posInput.positionWS - GetPrimaryCameraPosition());
float3 dir = -GetWorldSpaceNormalizeViewDir(posInput.positionWS);
return SampleSkyTexture(dir, mipLevel).rgb;
}
else // Should not be possible.

// Returns fog color in rgb and fog factor in alpha.
float4 EvaluateAtmosphericScattering(PositionInputs posInput)
{
float3 fogColor = 0;
float fogFactor = 0;
float3 fogColor = 0;
float fogFactor = 0;
float4 volFog = SampleInScatteredRadianceAndTransmittance(TEXTURE3D_PARAM(_VBufferLighting, s_trilinear_clamp_sampler),
posInput.positionNDC, posInput.linearDepth,
_VBufferResolution, _VBufferScaleAndSliceCount,
_VBufferDepthEncodingParams);
fogColor = volFog.rgb;
fogFactor = 1 - volFog.a;
float4 volFog = SampleInScatteredRadianceAndTransmittance(TEXTURE3D_PARAM(_VBufferLighting, s_trilinear_clamp_sampler),
posInput.positionNDC, posInput.linearDepth,
_VBufferResolution, _VBufferScaleAndSliceCount,
_VBufferDepthEncodingParams);
fogColor = volFog.rgb;
fogFactor = 1 - volFog.a;
if (_AtmosphericScatteringType == FOGTYPE_EXPONENTIAL)
{
fogColor = GetFogColor(posInput);
fogFactor = _FogDensity * (1.0f - TransmittanceHomogeneousMedium(1.0f / _ExpFogDistance, posInput.linearDepth));
}
else if (_AtmosphericScatteringType == FOGTYPE_LINEAR)
{
fogColor = GetFogColor(posInput);
fogFactor = _FogDensity * saturate((posInput.linearDepth - _LinearFogStart) * _LinearFogOneOverRange);
}
else // NONE
{
}
if (_AtmosphericScatteringType == FOGTYPE_EXPONENTIAL)
{
fogColor = GetFogColor(posInput);
float3 distance = length(GetWorldSpaceViewDir(posInput.positionWS));
float fogHeight = max(0.0, GetAbsolutePositionWS(posInput.positionWS).y - _ExpFogBaseHeight);
fogFactor = _FogDensity * TransmittanceHomogeneousMedium(_ExpFogHeightAttenuation, fogHeight) * (1.0f - TransmittanceHomogeneousMedium(1.0f / _ExpFogDistance, distance));
}
else if (_AtmosphericScatteringType == FOGTYPE_LINEAR)
{
fogColor = GetFogColor(posInput);
fogFactor = _FogDensity * saturate((posInput.linearDepth - _LinearFogStart) * _LinearFogOneOverRange) * saturate((_LinearFogHeightEnd - GetAbsolutePositionWS(posInput.positionWS).y) * _LinearFogHeightOneOverRange);
}
else // NONE
{
}
return float4(fogColor, fogFactor);
return float4(fogColor, fogFactor);
}
#endif

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/ExponentialFog.cs


{
private readonly static int m_ExpFogParam = Shader.PropertyToID("_ExpFogParameters");
public MinFloatParameter fogDistance = new MinFloatParameter(200.0f, 0.0f);
public MinFloatParameter fogDistance = new MinFloatParameter(200.0f, 0.0f);
public FloatParameter fogBaseHeight = new FloatParameter(0.0f);
public ClampedFloatParameter fogHeightAttenuation = new ClampedFloatParameter(0.2f, 0.0f, 1.0f);
cmd.SetGlobalVector(m_ExpFogParam, new Vector4(Mathf.Max(0.0f, fogDistance), 0.0f, 0.0f, 0.0f));
cmd.SetGlobalVector(m_ExpFogParam, new Vector4(Mathf.Max(1e-6f, fogDistance), fogBaseHeight, fogHeightAttenuation, 0.0f));
}
}

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/LinearFog.cs


public MinFloatParameter fogStart = new MinFloatParameter(500.0f, 0.0f);
public MinFloatParameter fogEnd = new MinFloatParameter(1000.0f, 0.0f);
public FloatParameter fogHeightStart = new FloatParameter(0.0f);
public FloatParameter fogHeightEnd = new FloatParameter(10.0f);
cmd.SetGlobalVector(m_LinearFogParam, new Vector4(fogStart, fogEnd, 1.0f / (fogEnd - fogStart), 0.0f));
cmd.SetGlobalVector(m_LinearFogParam, new Vector4(fogStart, 1.0f / (fogEnd - fogStart), fogHeightEnd, 1.0f / (fogHeightEnd - fogHeightStart)));
}
}

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/OpaqueAtmosphericScattering.shader


float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.positionSS).x;
UpdatePositionInput(depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP, posInput);
if (depth == UNITY_RAW_FAR_CLIP_VALUE)
{
// When a pixel is at far plane, the world space coordinate reconstruction is not reliable.
// So in order to have a valid position (for example for height fog) we just consider that the sky is a sphere centered on camera with a radius of 5km (arbitrarily chosen value!)
// And recompute the position on the sphere with the current camera direction.
float3 viewDirection = -GetWorldSpaceNormalizeViewDir(posInput.positionWS) * 5000.0f;
posInput.positionWS = GetPrimaryCameraPosition() + viewDirection;
}
return EvaluateAtmosphericScattering(posInput);
}
ENDHLSL

7
Tests/GraphicsTests/RenderPipeline/HDRenderPipeline/CommonAssets/SkySettings/HDRP_Default_Sky_LinearFog.asset


m_OverrideState: 1
m_Value: 15
min: 0
fogHeightStart:
m_OverrideState: 1
m_Value: 5000
fogHeightEnd:
m_OverrideState: 1
m_Value: 5001
--- !u!114 &114488915870882762
MonoBehaviour:
m_ObjectHideFlags: 3

m_OverrideState: 1
m_Value: 0
min: 0
useForBaking: 1
skyHDRI:
m_OverrideState: 1
m_Value: {fileID: 8900000, guid: fb0bf2eac2381484187ba8a68cdca165, type: 3}

正在加载...
取消
保存