浏览代码
Merge pull request #62 from EvgeniiG/master
Merge pull request #62 from EvgeniiG/master
Update the implementation of the procedural sky model/main
GitHub
8 年前
当前提交
980ae986
共有 7 个文件被更改,包括 234 次插入 和 627 次删除
-
143Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyParameters.cs
-
198Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyRenderer.cs
-
67Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/AtmosphericScattering.hlsl
-
43Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader
-
8Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyManager.cs
-
12Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs.meta
-
390Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs
|
|||
fileFormatVersion: 2 |
|||
guid: 97f65a78ace4fbf4187144e9fe724009 |
|||
timeCreated: 1479992550 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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?
|
|||
Cleanup(); |
|||
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 Cleanup() |
|||
{ |
|||
// 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. */ |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue