浏览代码

Merge pull request #23 from EvgeniiG/master

Add the initial impl. of the sky model from the Blacksmith demo
/main
GitHub 8 年前
当前提交
06953530
共有 10 个文件被更改,包括 1073 次插入20 次删除
  1. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl
  2. 53
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyHDRI.shader
  3. 1
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs
  4. 12
      Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl
  5. 147
      Assets/TestScenes/HDTest/HDRenderLoopTest.unity
  6. 390
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs
  7. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs.meta
  8. 113
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/README.txt
  9. 354
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl
  10. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl.meta

2
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl


// This code will be inlined as lightLoopContext is hardcoded in the light loop
if (lightLoopContext.sampleReflection == SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES)
{
return SAMPLE_TEXTURECUBE_ARRAY_LOD(_EnvTextures, sampler_EnvTextures, float4(texCoord, index), lod);
return SAMPLE_TEXTURECUBE_ARRAY_LOD(_EnvTextures, sampler_EnvTextures, texCoord, index, lod);
}
else // SINGLE_PASS_SAMPLE_SKY
{

53
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyHDRI.shader


#pragma vertex Vert
#pragma fragment Frag
#pragma multi_compile _ ATMOSPHERICS_OCCLUSION_FULLSKY
#pragma multi_compile _ ATMOSPHERICS_DEBUG
#include "Color.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl"
#define IS_RENDERING_SKY
#include "AtmosphericScattering.hlsl"
float4 _SkyParam; // x exposure, y multiplier, z rotation
float4x4 _InvViewProjMatrix;
float4 _SkyParam; // x exposure, y multiplier, z rotation
struct Attributes
{

float3 rotDirY = float3(sinPhi, 0, cosPhi);
dir = float3(dot(rotDirX, dir), dir.y, dot(rotDirY, dir));
return ClampToFloat16Max(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0) * exp2(_SkyParam.x) * _SkyParam.y);
float3 skyDome = ClampToFloat16Max(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0).rgb * exp2(_SkyParam.x) * _SkyParam.y);
Coordinate coord = GetCoordinate(input.positionCS.xy, _ScreenSize.zw);
// Get the depth value of the scene, or use 0.01 otherwise.
float rawDepth = max(LOAD_TEXTURE2D(_CameraDepthTexture, coord.unPositionSS).r, 0.01);
float3 positionWS = UnprojectToWorld(rawDepth, coord.positionSS, _InvViewProjMatrix);
// Do not perform blending with the environment map if the sky is occluded.
float skyDomeWeight = (rawDepth > 0.01) ? 0.0 : 1.0;
float4 c1, c2, c3;
VolundTransferScatter(positionWS, c1, c2, c3);
float4 coord1 = float4(c1.rgb + c3.rgb, max(0.f, 1.f - c1.a - c3.a));
float3 coord2 = c2.rgb;
float sunCos = dot(normalize(dir), _SunDirection);
float miePh = MiePhase(sunCos, _MiePhaseAnisotropy);
float2 occlusion = float2(1.0, 1.0); // TODO.
float extinction = coord1.a;
float3 scatter = coord1.rgb * occlusion.x + coord2 * miePh * occlusion.y;
#ifdef ATMOSPHERICS_DEBUG
switch (_AtmosphericsDebugMode)
{
case ATMOSPHERICS_DBG_RAYLEIGH: return c1;
case ATMOSPHERICS_DBG_MIE: return c2 * miePh;
case ATMOSPHERICS_DBG_HEIGHT: return c3;
case ATMOSPHERICS_DBG_SCATTERING: return float4(scatter, 0.0);
case ATMOSPHERICS_DBG_OCCLUSION: return float4(occlusion.xy, 0.0, 0.0);
case ATMOSPHERICS_DBG_OCCLUDEDSCATTERING: return float4(scatter, 0.0);
}
#endif
// Blend with the color of the scene.
return float4(skyDome * (skyDomeWeight * extinction) + scatter, 0.0);
}
ENDHLSL

1
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs


m_RenderSkyPropertyBlock.SetTexture("_Cubemap", skyParameters.skyHDRI);
m_RenderSkyPropertyBlock.SetVector("_SkyParam", new Vector4(skyParameters.exposure, skyParameters.multiplier, skyParameters.rotation, 0.0f));
m_RenderSkyPropertyBlock.SetMatrix("_InvViewProjMatrix", Utilities.GetViewProjectionMatrix(camera).inverse);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial, 0, 0, m_RenderSkyPropertyBlock);

12
Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl


#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3((coord2).xy, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3((coord2).xy, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3) textureName.Sample(samplerName, float4((coord3).xyz, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, float4((coord3).xyz, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)

#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))

147
Assets/TestScenes/HDTest/HDRenderLoopTest.unity


objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 3
value: 4
objectReference: {fileID: 0}
- target: {fileID: 115764, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Name

objectReference: {fileID: 0}
- target: {fileID: 400000, guid: 646b4ac0331f8e447bd20f06eba916a3, type: 3}
propertyPath: m_RootOrder
value: 1
value: 2
objectReference: {fileID: 0}
- target: {fileID: 400000, guid: 646b4ac0331f8e447bd20f06eba916a3, type: 3}
propertyPath: m_LocalEulerAnglesHint.x

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 9
m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 37.039, y: 0, z: 0}
--- !u!114 &580932148
MonoBehaviour:

- component: {fileID: 605581071}
- component: {fileID: 605581070}
- component: {fileID: 605581072}
- component: {fileID: 605581073}
m_Name: Directional light
m_Name: Sun (directional light)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 11
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 142.28, y: 106.256996, z: -160.70999}
--- !u!114 &605581072
MonoBehaviour:

isDoubleSided: 0
areaLightLength: 0
areaLightWidth: 0
--- !u!114 &605581073
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 605581069}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 97f65a78ace4fbf4187144e9fe724009, type: 3}
m_Name:
m_EditorClassIdentifier:
worldRayleighColorRamp:
key0:
serializedVersion: 2
rgba: 4288243277
key1:
serializedVersion: 2
rgba: 4291598720
key2:
serializedVersion: 2
rgba: 0
key3:
serializedVersion: 2
rgba: 0
key4:
serializedVersion: 2
rgba: 0
key5:
serializedVersion: 2
rgba: 0
key6:
serializedVersion: 2
rgba: 0
key7:
serializedVersion: 2
rgba: 0
ctime0: 0
ctime1: 65535
ctime2: 0
ctime3: 0
ctime4: 0
ctime5: 0
ctime6: 0
ctime7: 0
atime0: 0
atime1: 65535
atime2: 0
atime3: 0
atime4: 0
atime5: 0
atime6: 0
atime7: 0
m_Mode: 0
m_NumColorKeys: 2
m_NumAlphaKeys: 2
worldRayleighColorIntensity: 1
worldRayleighDensity: 10
worldRayleighExtinctionFactor: 1.1
worldRayleighIndirectScatter: 0.33
worldMieColorRamp:
key0:
serializedVersion: 2
rgba: 4286627826
key1:
serializedVersion: 2
rgba: 4294960895
key2:
serializedVersion: 2
rgba: 0
key3:
serializedVersion: 2
rgba: 0
key4:
serializedVersion: 2
rgba: 0
key5:
serializedVersion: 2
rgba: 0
key6:
serializedVersion: 2
rgba: 0
key7:
serializedVersion: 2
rgba: 0
ctime0: 0
ctime1: 65535
ctime2: 0
ctime3: 0
ctime4: 0
ctime5: 0
ctime6: 0
ctime7: 0
atime0: 0
atime1: 65535
atime2: 0
atime3: 0
atime4: 0
atime5: 0
atime6: 0
atime7: 0
m_Mode: 0
m_NumColorKeys: 2
m_NumAlphaKeys: 2
worldMieColorIntensity: 1
worldMieDensity: 15
worldMieExtinctionFactor: 0
worldMiePhaseAnisotropy: 0.9
worldNearScatterPush: 0
worldNormalDistance: 1000
heightRayleighColor: {r: 1, g: 1, b: 1, a: 1}
heightRayleighIntensity: 1
heightRayleighDensity: 10
heightMieDensity: 0
heightExtinctionFactor: 1.1
heightSeaLevel: 0
heightDistance: 50
heightPlaneShift: {x: 0, y: 0, z: 0}
heightNearScatterPush: 0
heightNormalDistance: 1000
worldScaleExponent: 1
atmosphericShader: {fileID: 0}
debugMode: 0
--- !u!1 &609148480
GameObject:
m_ObjectHideFlags: 0

objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 2
value: 3
objectReference: {fileID: 0}
- target: {fileID: 115764, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Name

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 10
m_RootOrder: 11
m_LocalEulerAnglesHint: {x: 37.039, y: 0, z: 0}
--- !u!114 &970745598
MonoBehaviour:

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 7
m_RootOrder: 8
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1175446862
GameObject:

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 8
m_RootOrder: 9
m_LocalEulerAnglesHint: {x: -0.39200002, y: 1.033, z: -0.92}
--- !u!114 &1220024536
MonoBehaviour:

objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 5
value: 6
objectReference: {fileID: 0}
- target: {fileID: 115764, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Name

objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 6
value: 7
objectReference: {fileID: 0}
- target: {fileID: 2374582, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Materials.Array.data[0]

objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 4
value: 5
objectReference: {fileID: 0}
- target: {fileID: 115764, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Name

390
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs


using UnityEngine;
[ExecuteInEditMode]
public class AtmosphericParameters : MonoBehaviour
{
public enum OcclusionDownscale { x1 = 1, x2 = 2, x4 = 4 }
public enum OcclusionSamples { x64 = 0, x164 = 1, x244 = 2 }
public enum DepthTexture { Enable, Disable/*, Ignore*/ } // 'Ignore' appears to be currently unused.
public enum ScatterDebugMode { None, Scattering, Occlusion, OccludedScattering, Rayleigh, Mie, Height }
[Header("Global Settings")]
public Gradient worldRayleighColorRamp = null;
public float worldRayleighColorIntensity = 1f;
public float worldRayleighDensity = 10f;
public float worldRayleighExtinctionFactor = 1.1f;
public float worldRayleighIndirectScatter = 0.33f;
public Gradient worldMieColorRamp = null;
public float worldMieColorIntensity = 1f;
public float worldMieDensity = 15f;
public float worldMieExtinctionFactor = 0f;
public float worldMiePhaseAnisotropy = 0.9f;
public float worldNearScatterPush = 0f;
public float worldNormalDistance = 1000f;
[Header("Height Settings")]
public Color heightRayleighColor = Color.white;
public float heightRayleighIntensity = 1f;
public float heightRayleighDensity = 10f;
public float heightMieDensity = 0f;
public float heightExtinctionFactor = 1.1f;
public float heightSeaLevel = 0f;
public float heightDistance = 50f;
public Vector3 heightPlaneShift = Vector3.zero;
public float heightNearScatterPush = 0f;
public float heightNormalDistance = 1000f;
[Header("Sky Dome")]
/*public*/ Vector3 skyDomeScale = new Vector3(1f, 1f, 1f);
/*public*/ Vector3 skyDomeRotation = Vector3.zero;
/*public*/ Transform skyDomeTrackedYawRotation = null;
/*public*/ bool skyDomeVerticalFlip = false;
/*public*/ Cubemap skyDomeCube = null;
/*public*/ float skyDomeExposure = 1f;
/*public*/ Color skyDomeTint = Color.white;
/*public*/ Vector3 skyDomeOffset = Vector3.zero;
/*
[Header("Scatter Occlusion")]
public bool useOcclusion = false;
public float occlusionBias = 0f;
public float occlusionBiasIndirect = 0.6f;
public float occlusionBiasClouds = 0.3f;
public OcclusionDownscale occlusionDownscale = OcclusionDownscale.x2;
public OcclusionSamples occlusionSamples = OcclusionSamples.x64;
public bool occlusionDepthFixup = true;
public float occlusionDepthThreshold = 25f;
public bool occlusionFullSky = false;
public float occlusionBiasSkyRayleigh = 0.2f;
public float occlusionBiasSkyMie = 0.4f;
*/
[Header("Other")]
public Shader atmosphericShaderOverride = null;
// public Shader occlusionShaderOverride = null;
public float worldScaleExponent = 1.0f;
// public bool forcePerPixel = true;
// public bool forcePostEffect = true;
[Tooltip("Soft clouds need depth values. Ignore means externally controlled.")]
public DepthTexture depthTexture = DepthTexture.Enable;
public ScatterDebugMode debugMode = ScatterDebugMode.None;
// [HideInInspector] public Shader occlusionShaderOverride;
// Camera m_currentCamera;
// UnityEngine.Rendering.CommandBuffer m_occlusionCmdAfterShadows, m_occlusionCmdBeforeScreen;
Material m_atmosphericMaterial = null;
// Material m_occlusionMaterial = null;
bool m_isAwake = false;
public static AtmosphericParameters instance { get; private set; }
void Awake()
{
if (worldRayleighColorRamp == null)
{
worldRayleighColorRamp = new Gradient();
worldRayleighColorRamp.SetKeys(
new[] { new GradientColorKey(new Color(0.3f, 0.4f, 0.6f), 0f),
new GradientColorKey(new Color(0.5f, 0.6f, 0.8f), 1f) },
new[] { new GradientAlphaKey(1f, 0f),
new GradientAlphaKey(1f, 1f) }
);
}
if (worldMieColorRamp == null)
{
worldMieColorRamp = new Gradient();
worldMieColorRamp.SetKeys(
new[] { new GradientColorKey(new Color(0.95f, 0.75f, 0.5f), 0f),
new GradientColorKey(new Color(1f, 0.9f, 8.0f), 1f) },
new[] { new GradientAlphaKey(1f, 0f),
new GradientAlphaKey(1f, 1f) }
);
}
if (atmosphericShaderOverride != null)
{
// Override the default shader.
m_atmosphericMaterial = new Material(atmosphericShaderOverride);
m_atmosphericMaterial.hideFlags = HideFlags.HideAndDontSave;
}
/*
if (occlusionShaderOverride != null)
{
// Override the default shader.
m_occlusionMaterial = new Material(occlusionShaderOverride);
m_occlusionMaterial.hideFlags = HideFlags.HideAndDontSave;
}
*/
m_isAwake = true;
}
public void OnValidate()
{
if (!m_isAwake) return;
Light light = gameObject.GetComponentInParent<Light>();
if (light == null || light.type != LightType.Directional)
{
Debug.LogErrorFormat("Unexpected: AtmosphericParameters is not attached to a directional light.");
return;
}
worldScaleExponent = Mathf.Clamp(worldScaleExponent, 1f, 2f);
worldNormalDistance = Mathf.Clamp(worldNormalDistance, 1f, 10000f);
worldNearScatterPush = Mathf.Clamp(worldNearScatterPush, -200f, 300f);
worldRayleighDensity = Mathf.Clamp(worldRayleighDensity, 0, 1000f);
worldMieDensity = Mathf.Clamp(worldMieDensity, 0f, 1000f);
worldRayleighIndirectScatter = Mathf.Clamp(worldRayleighIndirectScatter, 0f, 1f);
worldMiePhaseAnisotropy = Mathf.Clamp01(worldMiePhaseAnisotropy);
heightNormalDistance = Mathf.Clamp(heightNormalDistance, 1f, 10000f);
heightNearScatterPush = Mathf.Clamp(heightNearScatterPush, -200f, 300f);
heightRayleighDensity = Mathf.Clamp(heightRayleighDensity, 0, 1000f);
heightMieDensity = Mathf.Clamp(heightMieDensity, 0, 1000f);
/*
occlusionBias = Mathf.Clamp01(occlusionBias);
occlusionBiasIndirect = Mathf.Clamp01(occlusionBiasIndirect);
occlusionBiasClouds = Mathf.Clamp01(occlusionBiasClouds);
occlusionBiasSkyRayleigh = Mathf.Clamp01(occlusionBiasSkyRayleigh);
occlusionBiasSkyMie = Mathf.Clamp01(occlusionBiasSkyMie);
*/
skyDomeExposure = Mathf.Clamp(skyDomeExposure, 0f, 8f);
if (instance == this)
{
// TODO: what's the point of doing this?
OnDisable();
OnEnable();
}
// TODO: why would I want to do that here?
// #if UNITY_EDITOR
// UnityEditor.SceneView.RepaintAll();
// #endif
}
void OnEnable()
{
if (!m_isAwake) return;
// Define select preprocessor symbols.
UpdateKeywords(true);
if (depthTexture == DepthTexture.Disable)
{
// Disable depth texture rendering.
Camera.current.depthTextureMode = DepthTextureMode.None;
}
// Set shader constants.
UpdateStaticUniforms();
UpdateDynamicUniforms();
if (instance && instance != this)
{
Debug.LogErrorFormat("Unexpected: AtmosphericParameters.instance already set (to: {0}). Still overriding with: {1}.", instance.name, name);
}
instance = this;
}
void OnDisable()
{
// Undefine all preprocessor symbols.
UpdateKeywords(false);
if (instance && instance != this)
{
Debug.LogErrorFormat("Unexpected: AtmosphericParameters.instance set to: {0}, not to: {1}. Leaving alone.", instance.name, name);
}
else
{
instance = null;
}
}
void UpdateKeywords(bool enable)
{
Shader.DisableKeyword("ATMOSPHERICS_OCCLUSION");
Shader.DisableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY");
Shader.DisableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP");
Shader.DisableKeyword("ATMOSPHERICS_SUNRAYS");
Shader.DisableKeyword("ATMOSPHERICS_DEBUG");
if (enable)
{
/*
if (useOcclusion)
{
Shader.EnableKeyword("ATMOSPHERICS_OCCLUSION");
if(occlusionDepthFixup && occlusionDownscale != OcclusionDownscale.x1)
Shader.EnableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP");
if(occlusionFullSky)
Shader.EnableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY");
}
*/
if (debugMode != ScatterDebugMode.None)
{
Shader.EnableKeyword("ATMOSPHERICS_DEBUG");
}
}
}
void UpdateStaticUniforms()
{
Shader.SetGlobalVector("_SkyDomeOffset", skyDomeOffset);
Shader.SetGlobalVector("_SkyDomeScale", skyDomeScale);
Shader.SetGlobalTexture("_SkyDomeCube", skyDomeCube);
Shader.SetGlobalFloat("_SkyDomeExposure", skyDomeExposure);
Shader.SetGlobalColor("_SkyDomeTint", skyDomeTint);
/*
Shader.SetGlobalFloat("_ShadowBias", useOcclusion ? occlusionBias : 1f);
Shader.SetGlobalFloat("_ShadowBiasIndirect", useOcclusion ? occlusionBiasIndirect : 1f);
Shader.SetGlobalFloat("_ShadowBiasClouds", useOcclusion ? occlusionBiasClouds : 1f);
Shader.SetGlobalVector("_ShadowBiasSkyRayleighMie", useOcclusion ? new Vector4(occlusionBiasSkyRayleigh, occlusionBiasSkyMie, 0f, 0f) : Vector4.zero);
Shader.SetGlobalFloat("_OcclusionDepthThreshold", occlusionDepthThreshold);
*/
Shader.SetGlobalFloat("_WorldScaleExponent", worldScaleExponent);
Shader.SetGlobalFloat("_WorldNormalDistanceRcp", 1f/worldNormalDistance);
Shader.SetGlobalFloat("_WorldNearScatterPush", -Mathf.Pow(Mathf.Abs(worldNearScatterPush), worldScaleExponent) * Mathf.Sign(worldNearScatterPush));
Shader.SetGlobalFloat("_WorldRayleighDensity", -worldRayleighDensity / 100000f);
Shader.SetGlobalFloat("_MiePhaseAnisotropy", worldMiePhaseAnisotropy);
Shader.SetGlobalVector("_RayleighInScatterPct", new Vector4(1f - worldRayleighIndirectScatter, worldRayleighIndirectScatter, 0f, 0f));
Shader.SetGlobalFloat("_HeightNormalDistanceRcp", 1f/heightNormalDistance);
Shader.SetGlobalFloat("_HeightNearScatterPush", -Mathf.Pow(Mathf.Abs(heightNearScatterPush), worldScaleExponent) * Mathf.Sign(heightNearScatterPush));
Shader.SetGlobalFloat("_HeightRayleighDensity", -heightRayleighDensity / 100000f);
Shader.SetGlobalFloat("_HeightSeaLevel", heightSeaLevel);
Shader.SetGlobalFloat("_HeightDistanceRcp", 1f/heightDistance);
Shader.SetGlobalVector("_HeightPlaneShift", heightPlaneShift);
Shader.SetGlobalVector("_HeightRayleighColor", (Vector4)heightRayleighColor * heightRayleighIntensity);
Shader.SetGlobalFloat("_HeightExtinctionFactor", heightExtinctionFactor);
Shader.SetGlobalFloat("_RayleighExtinctionFactor", worldRayleighExtinctionFactor);
Shader.SetGlobalFloat("_MieExtinctionFactor", worldMieExtinctionFactor);
var rayleighColorM20 = worldRayleighColorRamp.Evaluate(0.00f);
var rayleighColorM10 = worldRayleighColorRamp.Evaluate(0.25f);
var rayleighColorO00 = worldRayleighColorRamp.Evaluate(0.50f);
var rayleighColorP10 = worldRayleighColorRamp.Evaluate(0.75f);
var rayleighColorP20 = worldRayleighColorRamp.Evaluate(1.00f);
var mieColorM20 = worldMieColorRamp.Evaluate(0.00f);
var mieColorO00 = worldMieColorRamp.Evaluate(0.50f);
var mieColorP20 = worldMieColorRamp.Evaluate(1.00f);
Shader.SetGlobalVector("_RayleighColorM20", (Vector4)rayleighColorM20 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_RayleighColorM10", (Vector4)rayleighColorM10 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_RayleighColorO00", (Vector4)rayleighColorO00 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_RayleighColorP10", (Vector4)rayleighColorP10 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_RayleighColorP20", (Vector4)rayleighColorP20 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_MieColorM20", (Vector4)mieColorM20 * worldMieColorIntensity);
Shader.SetGlobalVector("_MieColorO00", (Vector4)mieColorO00 * worldMieColorIntensity);
Shader.SetGlobalVector("_MieColorP20", (Vector4)mieColorP20 * worldMieColorIntensity);
Shader.SetGlobalInt("_AtmosphericsDebugMode", (int)debugMode);
}
void OnWillRenderObject()
{
/*
if (!m_isAwake) return;
// For now, we only use the directional light we are attached to, and the current camera.
if (depthTexture == DepthTexture.Disable)
{
// Disable depth texture rendering.
Camera.current.depthTextureMode = DepthTextureMode.None;
}
// Set shader constants.
UpdateDynamicUniforms();
if (useOcclusion) {
var camRgt = m_currentCamera.transform.right;
var camUp = m_currentCamera.transform.up;
var camFwd = m_currentCamera.transform.forward;
var dy = Mathf.Tan(m_currentCamera.fieldOfView * 0.5f * Mathf.Deg2Rad);
var dx = dy * m_currentCamera.aspect;
var vpCenter = camFwd * m_currentCamera.farClipPlane;
var vpRight = camRgt * dx * m_currentCamera.farClipPlane;
var vpUp = camUp * dy * m_currentCamera.farClipPlane;
m_occlusionMaterial.SetVector("_CameraPosition", m_currentCamera.transform.position);
m_occlusionMaterial.SetVector("_ViewportCorner", vpCenter - vpRight - vpUp);
m_occlusionMaterial.SetVector("_ViewportRight", vpRight * 2f);
m_occlusionMaterial.SetVector("_ViewportUp", vpUp * 2f);
var farDist = m_currentCamera ? m_currentCamera.farClipPlane : 1000f;
var refDist = (Mathf.Min(farDist, QualitySettings.shadowDistance) - 1f) / farDist;
m_occlusionMaterial.SetFloat("_OcclusionSkyRefDistance", refDist);
var srcRect = m_currentCamera.pixelRect;
var downscale = 1f / (float)(int)occlusionDownscale;
var occWidth = Mathf.RoundToInt(srcRect.width * downscale);
var occHeight = Mathf.RoundToInt(srcRect.height * downscale);
var occlusionId = Shader.PropertyToID("_OcclusionTexture");
m_occlusionCmdBeforeScreen.Clear();
m_occlusionCmdBeforeScreen.GetTemporaryRT(occlusionId, occWidth, occHeight, 0, FilterMode.Bilinear, RenderTextureFormat.R8, RenderTextureReadWrite.sRGB);
m_occlusionCmdBeforeScreen.Blit(
null,
occlusionId,
m_occlusionMaterial,
(int)occlusionSamples
);
m_occlusionCmdBeforeScreen.SetGlobalTexture(occlusionId, occlusionId);
}
*/
}
void UpdateDynamicUniforms()
{
/* For now, we only use the directional light we are attached to, and the current camera. */
var trackedYaw = skyDomeTrackedYawRotation ? skyDomeTrackedYawRotation.eulerAngles.y : 0f;
Shader.SetGlobalMatrix("_SkyDomeRotation",
Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(skyDomeRotation.x, 0f, 0f), Vector3.one)
* Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, skyDomeRotation.y - trackedYaw, 0f), Vector3.one)
* Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, skyDomeVerticalFlip ? -1f : 1f, 1f))
);
Shader.SetGlobalVector("_SunDirection", -transform.forward);
Shader.SetGlobalFloat("_WorldMieDensity", -worldMieDensity / 100000f);
Shader.SetGlobalFloat("_HeightMieDensity", -heightMieDensity / 100000f);
var pixelRect = Camera.current ? Camera.current.pixelRect
: new Rect(0f, 0f, Screen.width, Screen.height);
var scale = 1.0f; //(float)(int)occlusionDownscale;
var depthTextureScaledTexelSize = new Vector4(scale / pixelRect.width,
scale / pixelRect.height,
-scale / pixelRect.width,
-scale / pixelRect.height);
Shader.SetGlobalVector("_DepthTextureScaledTexelSize", depthTextureScaledTexelSize);
}
void OnRenderObject()
{
/* This component is not rendered directly. */
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs.meta


fileFormatVersion: 2
guid: 97f65a78ace4fbf4187144e9fe724009
timeCreated: 1479992550
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

113
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/README.txt


# Atmospheric Scattering
Atmospheric scattering is a solution developed for nicer aerial perspective in The Blacksmith. It provides a model emulating atmospheric Rayleigh, Mie and height scattering (and also takes a lot of shortcuts in the name of performance and artistic control). Take a look at the blog post at this address http://blogs.unity3d.com/?p=27218 to get a high-level overview of the components making up the final composition.
### Options description
This component comes with quite a lot of options - but you normally don't have to tweak more than a handful of them to get good results - start with the densities and colors and that will get you started nicely.
#### World Components
**World Rayleigh Color Ramp**: The color or colors used for rayleigh scattering. It's a ramp instead of a single color because you can have different scattering colors depending on the angle to the unit being shaded. Values to the left in the ramp are mapped to angles below horizon, whereas values to the right are mapped to angles above the horizon.
**World Rayleigh Color Intensity**: An HDR color scale for the rayleigh color ramp.
**World Rayleigh Density**: The density of the rayleigh component.
**World Rayleigh Extinction Factor**: How much light is out-scattered or absorbed on its way to the eye. Basically how much to darken the shaded pixel.
**World Rayleigh Indirect Scatter**: Which percentage of the rayleigh scattering should be considered 'indirect' scattering. (relevant for occlusion only)
**World Mie Color Ramp**: The color or colors used for mie scattering. It's a ramp instead of a single color because you can have different scattering colors depending on the angle to the unit being shaded. Values to the left in the ramp are mapped to angles below horizon, whereas values to the right are mapped to angles above the horizon.
**World Mie Color Intensity**: An HDR color scale for the mie color ramp.
**World Mie Density**: The density of the mie component.
**World Mie Extinction Factor**: How much light is out-scattered or absorbed on its way to the eye. Basically how much to darken the shaded pixel.
**World Mie Phase Anisotropy**: How focused the forward directionality of the mie scattering is. Values close to 1 produce a small, very sharp mie component, whereas values below 0.5 creates a very large and unfocused mie component.
**World Near Scatter Push**: Allows the scattering to be pushed out to have no scattering directly in front of the camera, or pulled in to have more scattering close to the camera.
**World Normal Distance**: A measure of the scale of the scene. Essentially this desaturates the scattering near the camera, and interpolates into full color ramp at the edge of the specified distance.
#### Height Components
**Height Rayleigh Color**: The general global scattering color for height fog.
**Height Rayleigh Intensity**: An HDR color scale for the height global fog color.
**Height Rayleigh Density**: The density of the global height fog.
**Height Mie Density**: The density of the mie scattering being added to the global height fog.
**Height Extinction Factor**: How much light is out-scattered or absorbed on its way to the eye. Basically how much to darken the shaded pixel.
**Height Sea Level**: Sea level height offset from origin.
**Height Distance**: Falloff distance from sea level
**Height Plane Shift**: An optional plane vector for a tilted sea level.
**Height Near Scatter Push**: Allows the scattering to be pushed out to have no scattering directly in front of the camera, or pulled in to have more scattering close to the camera.
**Height Normal Distance**: A measure of the scale of the scene. Essentially this desaturates the scattering near the camera, and interpolates into full color at the edge of the specified distance.
#### Sky Dome
**Sky Dome Scale**: The scale of the skydome. We use this to virtually squash the sky sphere into behaving like a dome. The xz-dimensions affect how much scattering the horizon picks up, whereas the y-dimension dictates how far up on the sky the scattering is blended.
**Sky Dome Rotation**: An optional rotation of the skydome. Usually, only Y-rotation makes sense.
**Sky Dome Tracked Yaw Rotation**: Optionally have the skydome rotate to track a transform, typically a light source. Use in combination with rotation to perfectly align and track the sun to the skydome.
**Sky Dome Vertical Flip**: We have the option of putting two skybox textures into the same cubemap. This flags flips the UV projection to show the bottom half instead of the top half.
**Sky Dome Cube**: An HDR cubemap to use as sky dome.
**Sky Dome Exposure**: The exposure of the sky cubemap.
**Sky Dome Tint**: Tint color for the cubemap.
#### Scatter Occlusion
**Use Occlusion**: This flag enables scatter occlusion.
**Occlusion Bias**: Controls how strongly occlusion affects direct scattering.
**Occlusion BiasIndirect**: Controls how strongly occlusion affects indirect scattering.
**Occlusion BiasClouds**: Controls how strongly occlusion affects placed clouds.
**Occlusion Downscale**: Controls the downscale factor for occlusion gathering.
**Occlusion Samples**: The number of samples to use in gathering.
**Occlusion DepthFixup**: Whether to attempt to fix upsampling across depth discontinuities (currently d3d11 only).
**Occlusion DepthThreshold**: The threshold defining discontinuous depth.
**Occlusion FullSky**: Whether to gather occlusion even for skydome pixels.
**Occlusion BiasSkyRayleigh **: Controls how strongly occlusion affects rayleigh scattering on the skydome.
**Occlusion BiasSkyMie **: Controls how strongly occlusion affects mie scattering on the skydome.
#### Other
**World ScaleExponent**: An option to exponentially scale the world for scattering calculations (fake aerial perspective in small scenes).
**Force Per Pixel**: Force all scatter calculations to run at per-pixel frequency.
**Force Post Effect**: Force all scatter calculations to run in a post-process (requires the AtmosphericScatteringDeferred component on the camera, and doesn't apply to transparent object)
**Depth Texture**: Whether to enable, disable or leave alone the camera depth texture settings. (required for depth fixup and soft cloud planes)
**Debug Mode**: Various debug visualizations of the different rendering components.

354
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl


#ifndef FILE_ATMOSPHERICSCATTERING
#define FILE_ATMOSPHERICSCATTERING
#define ATMOSPHERICS_DBG_NONE 0
#define ATMOSPHERICS_DBG_SCATTERING 1
#define ATMOSPHERICS_DBG_OCCLUSION 2
#define ATMOSPHERICS_DBG_OCCLUDEDSCATTERING 3
#define ATMOSPHERICS_DBG_RAYLEIGH 4
#define ATMOSPHERICS_DBG_MIE 5
#define ATMOSPHERICS_DBG_HEIGHT 6
uniform int _AtmosphericsDebugMode;
uniform float3 _SunDirection;
uniform float _ShadowBias;
uniform float _ShadowBiasIndirect;
uniform float _ShadowBiasClouds;
uniform float _OcclusionDepthThreshold;
uniform float4 _OcclusionTexture_TexelSize;
uniform float4 _DepthTextureScaledTexelSize;
uniform float _WorldScaleExponent;
uniform float _WorldNormalDistanceRcp;
uniform float _WorldNearScatterPush;
uniform float _WorldRayleighDensity;
uniform float _WorldMieDensity;
uniform float3 _RayleighColorM20;
uniform float3 _RayleighColorM10;
uniform float3 _RayleighColorO00;
uniform float3 _RayleighColorP10;
uniform float3 _RayleighColorP20;
uniform float3 _RayleighColorP45;
uniform float3 _MieColorM20;
uniform float3 _MieColorO00;
uniform float3 _MieColorP20;
uniform float3 _MieColorP45;
uniform float _HeightNormalDistanceRcp;
uniform float _HeightNearScatterPush;
uniform float _HeightRayleighDensity;
uniform float _HeightMieDensity;
uniform float _HeightSeaLevel;
uniform float3 _HeightPlaneShift;
uniform float _HeightDistanceRcp;
uniform float _RayleighCoeffScale;
uniform float3 _RayleighSunTintIntensity;
uniform float2 _RayleighInScatterPct;
uniform float _MieCoeffScale;
uniform float3 _MieSunTintIntensity;
uniform float _MiePhaseAnisotropy;
uniform float _HeightExtinctionFactor;
uniform float _RayleighExtinctionFactor;
uniform float _MieExtinctionFactor;
uniform float4 _HeightRayleighColor;
SAMPLER2D(sampler_CameraDepthTexture)
#define SRL_BilinearSampler sampler_CameraDepthTexture // Used for all textures
TEXTURE2D(_CameraDepthTexture);
TEXTURE2D(_OcclusionTexture);
float HenyeyGreensteinPhase(float g, float cosTheta) {
float gSqr = g * g;
float a1 = (1.f - gSqr);
float a2 = (2.f + gSqr);
float b1 = 1.f + cosTheta * cosTheta;
float b2 = pow(abs(1.f + gSqr - 2.f * g * cosTheta), 1.5f);
return (a1 / a2) * (b1 / b2);
}
float RayleighPhase(float cosTheta) {
const float f = 3.f / (16.f * PI);
return f + f * cosTheta * cosTheta;
}
float MiePhase(float cosTheta, float anisotropy) {
const float f = 3.f / (8.f * PI);
return f * HenyeyGreensteinPhase(anisotropy, cosTheta);
}
float HeightDensity(float h, float H) {
return exp(-h/H);
}
float3 WorldScale(float3 p) {
p.xz = sign(p.xz) * pow(abs(p.xz), _WorldScaleExponent);
return p;
}
void VolundTransferScatter(float3 worldPos, out float4 coords1, out float4 coords2, out float4 coords3) {
const float3 scaledWorldPos = WorldScale(worldPos);
const float3 worldCamPos = WorldScale(_WorldSpaceCameraPos.xyz);
const float c_MieScaleHeight = 1200.f;
const float worldRayleighDensity = 1.f;
const float worldMieDensity = HeightDensity(scaledWorldPos.y, c_MieScaleHeight);
const float3 worldVec = scaledWorldPos.xyz - worldCamPos.xyz;
const float worldVecLen = length(worldVec);
const float3 worldDir = worldVec / worldVecLen;
const float3 worldDirUnscaled = normalize(worldPos - _WorldSpaceCameraPos.xyz);
const float viewSunCos = dot(worldDirUnscaled, _SunDirection);
const float rayleighPh = min(1.f, RayleighPhase(viewSunCos) * 12.f);
const float miePh = MiePhase(viewSunCos, _MiePhaseAnisotropy);
const float angle20 = 0.324f / 1.5f;
const float angle10 = 0.174f / 1.5f;
const float angleY = worldDir.y * saturate(worldVecLen / 250.0);
float3 rayleighColor;
if(angleY >= angle10) rayleighColor = lerp(_RayleighColorP10, _RayleighColorP20, saturate((angleY - angle10) / (angle20 - angle10)));
else if(angleY >= 0.f) rayleighColor = lerp(_RayleighColorO00, _RayleighColorP10, angleY / angle10);
else if(angleY >= -angle10) rayleighColor = lerp(_RayleighColorM10, _RayleighColorO00, (angleY + angle10) / angle10);
else rayleighColor = lerp(_RayleighColorM20, _RayleighColorM10, saturate((angleY + angle20) / (angle20 - angle10)));
float3 mieColor;
if(angleY >= 0.f) mieColor = lerp(_MieColorO00, _MieColorP20, saturate(angleY / angle20));
else mieColor = lerp(_MieColorM20, _MieColorO00, saturate((angleY + angle20) / angle20));
const float pushedDistance = max(0.f, worldVecLen + _WorldNearScatterPush);
const float pushedDensity = /*HeightDensity **/ pushedDistance /** exp(-scaledWorldPos.y / 8000.f)*/;
const float rayleighScatter = (1.f - exp(_WorldRayleighDensity * pushedDensity)) * rayleighPh;
#ifdef IS_RENDERING_SKY
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedDensity));
#else
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedDensity)) * miePh;
#endif
const float heightShift = dot(worldVec, _HeightPlaneShift);
const float heightScaledOffset = (scaledWorldPos.y - heightShift - _HeightSeaLevel) * _HeightDistanceRcp;
const float HeightDensity = exp(-heightScaledOffset);
const float pushedHeightDistance = max(0.f, worldVecLen + _HeightNearScatterPush);
const float heightScatter = (1.f - exp(_HeightRayleighDensity * pushedHeightDistance)) * HeightDensity;
#ifdef IS_RENDERING_SKY
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedHeightDistance)) * HeightDensity;
#else
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedHeightDistance)) * HeightDensity * miePh;
#endif
rayleighColor = lerp(Luminance(rayleighColor).rrr, rayleighColor, saturate(pushedDistance * _WorldNormalDistanceRcp));
float3 heightRayleighColor = lerp(Luminance(_HeightRayleighColor.xyz).rrr, _HeightRayleighColor.xyz, saturate(pushedHeightDistance * _HeightNormalDistanceRcp));
coords1.rgb = rayleighScatter * rayleighColor;
coords1.a = rayleighScatter;
coords3.rgb = saturate(heightScatter) * heightRayleighColor;
coords3.a = heightScatter;
coords2.rgb = mieScatter * mieColor + saturate(heightMieScatter) * mieColor;
coords2.a = mieScatter;
}
void VolundTransferScatter(float3 scaledWorldPos, out float4 coords1) {
float4 c1, c2, c3;
VolundTransferScatter(scaledWorldPos, c1, c2, c3);
#ifdef IS_RENDERING_SKY
coords1.rgb = c3.rgb;
coords1.a = max(0.f, 1.f - c3.a * _HeightExtinctionFactor);
#else
coords1.rgb = c1.rgb;
coords1.rgb += c3.rgb;
coords1.a = max(0.f, 1.f - c1.a * _RayleighExtinctionFactor - c3.a * _HeightExtinctionFactor);
#endif
coords1.rgb += c2.rgb;
coords1.a *= max(0.f, 1.f - c2.a * _MieExtinctionFactor);
#ifdef ATMOSPHERICS_DEBUG
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH)
coords1.rgb = c1.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE)
coords1.rgb = c2.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT)
coords1.rgb = c3.rgb;
#endif
}
float2 UVFromPos(float2 pos) {
return pos / _ScreenParams.xy;
}
float3 VolundApplyScatter(float4 coords1, float2 pos, float3 color) {
#ifdef ATMOSPHERICS_DEBUG
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUSION)
return 1;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_SCATTERING || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUDEDSCATTERING)
return coords1.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT)
return coords1.rgb;
#endif
return color * coords1.a + coords1.rgb;
}
float3 VolundApplyScatterAdd(float coords1, float3 color) {
return color * coords1;
}
void VolundTransferScatterOcclusion(float3 scaledWorldPos, out float4 coords1, out float3 coords2) {
float4 c1, c2, c3;
VolundTransferScatter(scaledWorldPos, c1, c2, c3);
coords1.rgb = c1.rgb * _RayleighInScatterPct.x;
coords1.a = max(0.f, 1.f - c1.a * _RayleighExtinctionFactor - c3.a * _HeightExtinctionFactor);
coords1.rgb += c2.rgb;
coords1.a *= max(0.f, 1.f - c2.a * _MieExtinctionFactor);
coords2.rgb = c3.rgb + c1.rgb * _RayleighInScatterPct.y;
#ifdef ATMOSPHERICS_DEBUG
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH)
coords1.rgb = c1.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE)
coords1.rgb = c2.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT)
coords1.rgb = c3.rgb;
#endif
}
float VolundSampleScatterOcclusion(float2 pos) {
#if defined(ATMOSPHERICS_OCCLUSION)
float2 uv = UVFromPos(pos);
#if defined(ATMOSPHERICS_OCCLUSION_EDGE_FIXUP)
float4 baseUV = float4(uv.x, uv.y, 0.f, 0.f);
float cDepth = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV, 0.f).r;
cDepth = LinearEyeDepth(cDepth);
float4 xDepth;
baseUV.xy = uv + _DepthTextureScaledTexelSize.zy; xDepth.x = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.xy; xDepth.y = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.xw; xDepth.z = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.zw; xDepth.w = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
xDepth.x = LinearEyeDepth4(xDepth.x);
xDepth.y = LinearEyeDepth4(xDepth.y);
xDepth.z = LinearEyeDepth4(xDepth.z);
xDepth.w = LinearEyeDepth4(xDepth.w);
float4 diffDepth = xDepth - cDepth.rrrr;
float4 maskDepth = abs(diffDepth) < _OcclusionDepthThreshold;
float maskWeight = dot(maskDepth, maskDepth);
UNITY_BRANCH
if(maskWeight == 4.f || maskWeight == 0.f) {
return SAMPLE_TEXTURE2D_LOD(_OcclusionTexture, SRL_BilinearSampler, uv, 0.f).r;
} else {
float4 occ = GATHER_TEXTURE2D(_OcclusionTexture, SRL_BilinearSampler, uv);
float4 fWeights;
fWeights.xy = frac(uv * _OcclusionTexture_TexelSize.zw - 0.5f);
fWeights.zw = float2(1.f, 1.f) - fWeights.xy;
float4 mfWeights = float4(fWeights.z * fWeights.y, fWeights.x * fWeights.y, fWeights.x * fWeights.w, fWeights.z * fWeights.w);
return dot(occ, mfWeights * maskDepth) / dot(mfWeights, maskDepth);
}
#endif //defined(ATMOSPHERICS_OCCLUSION_EDGE_FIXUP)
#else //defined(ATMOSPHERICS_OCCLUSION)
return 1.f;
#endif //defined(ATMOSPHERICS_OCCLUSION)
}
float3 VolundApplyScatterOcclusion(float4 coords1, float3 coords2, float2 pos, float3 color) {
float occlusion = VolundSampleScatterOcclusion(pos);
#ifdef ATMOSPHERICS_DEBUG
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_SCATTERING)
return coords1.rgb + coords2.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUSION)
return occlusion;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUDEDSCATTERING)
return coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect);
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT)
return coords1.rgb;
#endif
return
color * coords1.a
+ coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect);
;
}
float VolundCloudOcclusion(float2 pos) {
#if defined(ATMOSPHERICS_OCCLUSION)
return min(1.f, VolundSampleScatterOcclusion(pos) + _ShadowBiasClouds);
#else
return 1.f;
#endif
}
float4 VolundApplyCloudScatter(float4 coords1, float4 color) {
#if defined(DBG_ATMOSPHERICS_SCATTERING) || defined(DBG_ATMOSPHERICS_OCCLUDEDSCATTERING)
return float4(coords1.rgb, color.a);
#elif defined(DBG_ATMOSPHERICS_OCCLUSION)
return 1;
#endif
color.rgb = color.rgb * coords1.a + coords1.rgb;
return color;
}
float4 VolundApplyCloudScatterOcclusion(float4 coords1, float3 coords2, float2 pos, float4 color) {
float occlusion = VolundSampleScatterOcclusion(pos);
#ifdef ATMOSPHERICS_OCCLUSION_DEBUG2
color.rgb = coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect);
return color;
#endif
#ifdef ATMOSPHERICS_OCCLUSION_DEBUG
return occlusion;
#endif
color.rgb = color.rgb * coords1.a + coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect);
float cloudOcclusion = min(1.f, occlusion + _ShadowBiasClouds);
color.a *= cloudOcclusion;
return color;
}
// Original vert/frag macros
#if defined(ATMOSPHERICS_OCCLUSION)
#define VOLUND_SCATTER_COORDS(idx1, idx2) float4 scatterCoords1 : TEXCOORD##idx1; float3 scatterCoords2 : TEXCOORD##idx2;
#define VOLUND_TRANSFER_SCATTER(pos, o) o.scatterCoords1 = pos.xyzz; o.scatterCoords2 = pos.xyz;
#define VOLUND_APPLY_SCATTER(i, color) VolundTransferScatterOcclusion(i.scatterCoords1.xyz, i.scatterCoords1, i.scatterCoords2); color = VolundApplyScatterOcclusion(i.scatterCoords1, i.scatterCoords2, i.pos.xy, color)
#define VOLUND_CLOUD_SCATTER(i, color) VolundTransferScatterOcclusion(i.scatterCoords1.xyz, i.scatterCoords1, i.scatterCoords2); color = VolundApplyCloudScatterOcclusion(i.scatterCoords1, i.scatterCoords2, i.pos.xy, color)
#else
#define VOLUND_SCATTER_COORDS(idx1, idx2) float4 scatterCoords1 : TEXCOORD##idx1;
#define VOLUND_TRANSFER_SCATTER(pos, o) o.scatterCoords1 = pos.xyzz;
#define VOLUND_APPLY_SCATTER(i, color) VolundTransferScatter(i.scatterCoords1.xyz, i.scatterCoords1); color = VolundApplyScatter(i.scatterCoords1, i.pos.xy, color);
#define VOLUND_CLOUD_SCATTER(i, color) VolundTransferScatter(i.scatterCoords1.xyz, i.scatterCoords1); color = VolundApplyCloudScatter(i.scatterCoords1, color);
#endif
#if !defined(SURFACE_SCATTER_COORDS)
/* surface shader analysis currently forces us to include stuff even when unused */
/* we also have to convince the analyzer to not optimize out stuff we need */
#define SURFACE_SCATTER_COORDS float3 scaledWorldPos; float4 scatterCoords1; float3 scatterCoords2;
#define SURFACE_SCATTER_TRANSFER(pos, o) o.scatterCoords1.r = o.scatterCoords2.r = pos.x;
#define SURFACE_SCATTER_APPLY(i, color) color += (i.scaledWorldPos + i.scatterCoords1.xyz + i.scatterCoords2.xyz) * 0.000001f
#endif
#endif //FILE_ATMOSPHERICSCATTERING

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl.meta


fileFormatVersion: 2
guid: b0be9dce952dbb9479a5eb30e49c07a3
timeCreated: 1480068393
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存