浏览代码

Merge pull request #47 from Unity-Technologies/SkyFramework

Skyframework
/main
GitHub 8 年前
当前提交
7fa32b4e
共有 55 个文件被更改,包括 1571 次插入367 次删除
  1. 30
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs
  2. 6
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset
  3. 28
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  4. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightLoop.cs
  5. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
  6. 318
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs
  7. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs.meta
  8. 14
      Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs
  9. 172
      Assets/TestScenes/HDTest/GlobalIlluminationTest.unity
  10. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources/SkyHDRI.shader
  11. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader
  12. 27
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopMenuItems.cs
  13. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopMenuItems.cs.meta
  14. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings.meta
  15. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky.meta
  16. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky.meta
  17. 401
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyManager.cs
  18. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyManager.cs.meta
  19. 66
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyParameters.cs
  20. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyParameters.cs.meta
  21. 81
      Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/CommonSettings.cs
  22. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/CommonSettings.cs.meta
  23. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/Editor.meta
  24. 87
      Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/Editor/CommonSettingsEditor.cs
  25. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/Editor/CommonSettingsEditor.cs.meta
  26. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Editor.meta
  27. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Editor/HDRISkyEditor.cs.meta
  28. 61
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Editor/HDRISkyEditor.cs
  29. 13
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/HDRISkyParameters.cs
  30. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/HDRISkyParameters.cs.meta
  31. 42
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/HDRISkyRenderer.cs
  32. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/HDRISkyRenderer.cs.meta
  33. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources.meta
  34. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Editor.meta
  35. 61
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Editor/ProceduralSkyEditor.cs
  36. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Editor/ProceduralSkyEditor.cs.meta
  37. 106
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyParameters.cs
  38. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyParameters.cs.meta
  39. 200
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyRenderer.cs
  40. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyRenderer.cs.meta
  41. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources.meta
  42. 0
      /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources/SkyHDRI.shader.meta
  43. 0
      /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/AtmosphericScattering.hlsl
  44. 0
      /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/AtmosphericScattering.hlsl.meta
  45. 0
      /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader.meta
  46. 0
      /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources/SkyHDRI.shader
  47. 0
      /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader

30
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs


public GUIContent[] debugViewMaterialStrings = null;
public int[] debugViewMaterialValues = null;
public readonly GUIContent skyParameters = new GUIContent("Sky Parameters");
public readonly GUIContent skyResolution = new GUIContent("Sky Resolution");
public readonly GUIContent skyExposure = new GUIContent("Sky Exposure");
public readonly GUIContent skyRotation = new GUIContent("Sky Rotation");
public readonly GUIContent skyMultiplier = new GUIContent("Sky Multiplier");
public readonly GUIContent shadowSettings = new GUIContent("Shadow Settings");
public readonly GUIContent shadowsEnabled = new GUIContent("Enabled");

EditorGUI.indentLevel--;
}
private void SkyParametersUI(HDRenderLoop renderLoop)
{
EditorGUILayout.Space();
var skyParameters = renderLoop.skyParameters;
EditorGUILayout.LabelField(styles.skyParameters);
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
skyParameters.skyHDRI = (Texture)EditorGUILayout.ObjectField("Cubemap", skyParameters.skyHDRI, typeof(Cubemap), false);
skyParameters.skyResolution = (SkyResolution)EditorGUILayout.EnumPopup(styles.skyResolution, skyParameters.skyResolution);
skyParameters.exposure = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.skyExposure, skyParameters.exposure), 32), -32);
skyParameters.multiplier = Mathf.Max(EditorGUILayout.FloatField(styles.skyMultiplier, skyParameters.multiplier), 0);
skyParameters.rotation = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.skyRotation, skyParameters.rotation), 360), -360);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(renderLoop); // Repaint
}
EditorGUI.indentLevel--;
}
private void ShadowParametersUI(HDRenderLoop renderLoop)
{
EditorGUILayout.Space();

return;
DebugParametersUI(renderLoop);
SkyParametersUI(renderLoop);
ShadowParametersUI(renderLoop);
TextureParametersUI(renderLoop);
TilePassUI(renderLoop);

6
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset


m_Script: {fileID: 11500000, guid: 558064ecdbf6b6742892d699acb39aed, type: 3}
m_Name: HDRenderLoop
m_EditorClassIdentifier:
m_SkyParameters:
skyHDRI: {fileID: 0}
rotation: 0
exposure: 0
multiplier: 1
skyResolution: 256
m_ShadowSettings:
enabled: 1
shadowAtlasWidth: 4096

28
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


}
#endif
SkyRenderer m_SkyRenderer = null;
[SerializeField]
SkyParameters m_SkyParameters = new SkyParameters();
SkyManager m_SkyManager = new SkyManager();
public SkyManager skyManager
{
get { return m_SkyManager; }
}
public SkyParameters skyParameters
public void InstantiateSkyRenderer(Type skyRendererType)
get { return m_SkyParameters; }
m_SkyManager.InstantiateSkyRenderer(skyRendererType);
}
public class DebugParameters

m_CameraColorBufferRT = new RenderTargetIdentifier(m_CameraColorBuffer);
m_CameraDepthBufferRT = new RenderTargetIdentifier(m_CameraDepthBuffer);
m_SkyRenderer = new SkyRenderer();
m_SkyRenderer.Build();
m_SkyManager.Build();
m_FinalPassMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/FinalPass");
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/DebugViewMaterialGBuffer");

Utilities.Destroy(m_FinalPassMaterial);
Utilities.Destroy(m_DebugViewMaterialGBuffer);
if (m_SkyRenderer != null)
{
m_SkyRenderer.Cleanup();
}
m_SkyManager.Cleanup();
#if UNITY_EDITOR
UnityEditor.SupportedRenderingFeatures.active = UnityEditor.SupportedRenderingFeatures.Default;

void RenderSky(HDCamera hdCamera, RenderLoop renderLoop)
{
m_SkyRenderer.RenderSky(hdCamera, m_SkyParameters, m_CameraColorBufferRT, m_CameraDepthBufferRT, renderLoop);
m_SkyManager.RenderSky(hdCamera, m_lightLoop.GetCurrentSunLight(), m_CameraColorBufferRT, m_CameraDepthBufferRT, renderLoop);
}
void RenderForward(CullResults cullResults, Camera camera, RenderLoop renderLoop, bool renderOpaque)

// TODO: This is the wrong way to handle resize/allocation. We can have several different camera here, mean that the loop on camera will allocate and deallocate
// the below buffer which is bad. Best is to have a set of buffer for each camera that is persistent and reallocate resource if need
// For now consider we have only one camera that go to this code, the main one.
m_SkyRenderer.Resize(m_SkyParameters); // TODO: Also a bad naming, here we just want to realloc texture if skyparameters change (usefull for lookdev)
m_SkyManager.Resize(); // TODO: Also a bad naming, here we just want to realloc texture if skyparameters change (usefull for lookdev)
if (camera.pixelWidth != m_currentWidth || camera.pixelHeight != m_currentHeight || m_lightLoop.NeedResize())
{

public void PushGlobalParams(HDCamera hdCamera, RenderLoop renderLoop)
{
if (m_SkyRenderer.IsSkyValid(m_SkyParameters))
if (m_SkyManager.IsSkyValid())
m_SkyRenderer.SetGlobalSkyTexture();
m_SkyManager.SetGlobalSkyTexture();
Shader.SetGlobalInt("_EnvLightSkyEnabled", 1);
}
else

4
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightLoop.cs


{
public class BaseLightLoop
{
protected Light m_CurrentSunLight = null;
// TODO: We should rather put the texture settings in LightLoop, but how do we serialize it ?
public virtual void Build(TextureSettings textureSettings) {}

public virtual void RenderDeferredLighting(HDRenderLoop.HDCamera hdCamera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT) {}
public virtual void RenderForward(Camera camera, RenderLoop renderLoop, bool renderOpaque) {}
public Light GetCurrentSunLight() { return m_CurrentSunLight; }
}
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs


bool hasDirectionalShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasDirectionalNotReachMaxLimit = directionalShadowcount == 0; // Only one cascade shadow allowed
// If we have not found a directional shadow casting light yet, we register the last directional anyway as "sun".
if (directionalShadowcount == 0)
{
m_CurrentSunLight = light.light;
}
// Always choose the directional shadow casting light if it exists.
m_CurrentSunLight = light.light;
directionalLightData.shadowIndex = m_lightList.shadows.Count;
directionalShadowcount += GetShadows(light, lightIndex, ref shadowOutput);

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


namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[Serializable]
public enum SkyResolution
abstract public class SkyRenderer
SkyResolution128 = 128,
SkyResolution256 = 256,
SkyResolution512 = 512,
SkyResolution1024 = 1024,
// TODO: Anything above 1024 cause a crash in Unity...
//SkyResolution2048 = 2048,
//SkyResolution4096 = 4096
}
abstract public void Build();
abstract public void Cleanup();
abstract public void RenderSky(BuiltinSkyParameters builtinParams, SkyParameters skyParameters);
abstract public bool IsSkyValid(SkyParameters skyParameters);
[Serializable]
public class SkyParameters
{
public Texture skyHDRI;
public float rotation = 0.0f;
public float exposure = 0.0f;
public float multiplier = 1.0f;
public SkyResolution skyResolution = SkyResolution.SkyResolution256;
virtual public bool IsParameterValid(SkyParameters skyParameters) { return false; }
virtual public Type GetSkyParameterType() { return typeof(SkyParameters); }
public class SkyRenderer
abstract public class SkyRenderer<ParameterType> : SkyRenderer
where ParameterType : SkyParameters
RenderTexture m_SkyboxCubemapRT = null;
RenderTexture m_SkyboxGGXCubemapRT = null;
Material m_StandardSkyboxMaterial = null; // This is the Unity standard skybox material. Used to pass the correct cubemap to Enlighten.
Material m_SkyHDRIMaterial = null; // Renders a cubemap into a render texture (can be cube or 2D)
Material m_GGXConvolveMaterial = null; // Apply GGX convolution to cubemap
SkyParameters m_bakedSkyParameters = new SkyParameters(); // This is the SkyParam used when baking and convolving the sky.
MaterialPropertyBlock m_RenderSkyPropertyBlock = null;
Vector4 m_screenSize;
Matrix4x4[] m_faceCameraViewProjectionMatrix = new Matrix4x4[6];
Matrix4x4[] m_faceCameraInvViewProjectionMatrix = new Matrix4x4[6];
Mesh[] m_CubemapFaceMesh = new Mesh[6];
Mesh BuildSkyMesh(Vector3 cameraPosition, Matrix4x4 cameraInvViewProjectionMatrix, bool forceUVBottom)
{
Vector4 vertData0 = new Vector4(-1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData1 = new Vector4(1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData2 = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Vector4 vertData3 = new Vector4(-1.0f, 1.0f, 1.0f, 1.0f);
Vector3[] vertData = new Vector3[4];
vertData[0] = new Vector3(vertData0.x, vertData0.y, vertData0.z);
vertData[1] = new Vector3(vertData1.x, vertData1.y, vertData1.z);
vertData[2] = new Vector3(vertData2.x, vertData2.y, vertData2.z);
vertData[3] = new Vector3(vertData3.x, vertData3.y, vertData3.z);
// Get view vector based on the frustum, i.e (invert transform frustum get position etc...)
Vector3[] eyeVectorData = new Vector3[4];
Matrix4x4 transformMatrix = cameraInvViewProjectionMatrix;
Vector4 posWorldSpace0 = transformMatrix * vertData0;
Vector4 posWorldSpace1 = transformMatrix * vertData1;
Vector4 posWorldSpace2 = transformMatrix * vertData2;
Vector4 posWorldSpace3 = transformMatrix * vertData3;
Vector4 cameraPos = new Vector4(cameraPosition.x, cameraPosition.y, cameraPosition.z, 0.0f);
Vector4 direction0 = (posWorldSpace0 / posWorldSpace0.w - cameraPos);
Vector4 direction1 = (posWorldSpace1 / posWorldSpace1.w - cameraPos);
Vector4 direction2 = (posWorldSpace2 / posWorldSpace2.w - cameraPos);
Vector4 direction3 = (posWorldSpace3 / posWorldSpace3.w - cameraPos);
if (SystemInfo.graphicsUVStartsAtTop && !forceUVBottom)
{
eyeVectorData[3] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[2] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[1] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[0] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
else
{
eyeVectorData[0] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[1] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[2] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[3] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
// Write out the mesh
var triangles = new int[6] { 0, 1, 2, 2, 3, 0 };
return new Mesh
{
vertices = vertData,
normals = eyeVectorData,
triangles = triangles
};
}
void RebuildTextures(SkyParameters skyParameters)
{
if ((m_SkyboxCubemapRT != null) && (m_SkyboxCubemapRT.width != (int)skyParameters.skyResolution))
{
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
}
if (m_SkyboxCubemapRT == null)
{
m_SkyboxCubemapRT = new RenderTexture((int)skyParameters.skyResolution, (int)skyParameters.skyResolution, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxCubemapRT.useMipMap = true;
m_SkyboxCubemapRT.autoGenerateMips = true; // Generate regular mipmap for filtered importance sampling
m_SkyboxCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxCubemapRT.Create();
m_SkyboxGGXCubemapRT = new RenderTexture((int)skyParameters.skyResolution, (int)skyParameters.skyResolution, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxGGXCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxGGXCubemapRT.useMipMap = true;
m_SkyboxGGXCubemapRT.autoGenerateMips = false;
m_SkyboxGGXCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxGGXCubemapRT.Create();
}
m_screenSize = new Vector4((float)skyParameters.skyResolution, (float)skyParameters.skyResolution, 1.0f / (float)skyParameters.skyResolution, 1.0f / (float)skyParameters.skyResolution);
}
// Sets the global MIP-mapped cubemap '_SkyTexture' in the shader.
// The texture being set is the sky (environment) map pre-convolved with GGX.
public void SetGlobalSkyTexture()
{
Shader.SetGlobalTexture("_SkyTexture", m_SkyboxGGXCubemapRT);
}
public void Resize(SkyParameters skyParameters)
{
// When loading RenderDoc, RenderTextures will go null
RebuildTextures(skyParameters);
}
public void Build()
{
// TODO: We need to have an API to send our sky information to Enlighten. For now use a workaround through skybox/cubemap material...
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial("Skybox/Cubemap");
m_SkyHDRIMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/SkyHDRI");
m_GGXConvolveMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/GGXConvolve");
m_RenderSkyPropertyBlock = new MaterialPropertyBlock();
Matrix4x4 cubeProj = Matrix4x4.Perspective(90.0f, 1.0f, 0.1f, 1.0f);
Vector3[] lookAtList = {
new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(-1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, -1.0f, 0.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 0.0f, -1.0f),
};
Vector3[] UpVectorList = {
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
};
for (int i = 0; i < 6; ++i)
{
Matrix4x4 lookAt = Matrix4x4.LookAt(Vector3.zero, lookAtList[i], UpVectorList[i]);
m_faceCameraViewProjectionMatrix[i] = Utilities.GetViewProjectionMatrix(lookAt, cubeProj);
m_faceCameraInvViewProjectionMatrix[i] = m_faceCameraViewProjectionMatrix[i].inverse;
// When rendering into a texture the render will be flip (due to legacy unity openGL behavior), so we need to flip UV here...
m_CubemapFaceMesh[i] = BuildSkyMesh(Vector3.zero, m_faceCameraInvViewProjectionMatrix[i], true);
}
}
public void Cleanup()
{
Utilities.Destroy(m_StandardSkyboxMaterial);
Utilities.Destroy(m_SkyHDRIMaterial);
Utilities.Destroy(m_GGXConvolveMaterial);
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
}
public bool IsSkyValid(SkyParameters parameters)
{
// Later we will also test shader for procedural skies.
return parameters.skyHDRI != null;
}
private void RenderSky(Vector4 screenSize, Matrix4x4 viewProjectionMatrix, Matrix4x4 invViewProjectionMatrix, SkyParameters skyParameters, Mesh skyMesh, RenderLoop renderLoop)
override public bool IsParameterValid(SkyParameters skyParameters)
m_RenderSkyPropertyBlock.SetTexture("_Cubemap", skyParameters.skyHDRI);
m_RenderSkyPropertyBlock.SetVector("_SkyParam", new Vector4(skyParameters.exposure, skyParameters.multiplier, skyParameters.rotation, 0.0f));
m_RenderSkyPropertyBlock.SetVector("_ScreenSize", screenSize);
m_RenderSkyPropertyBlock.SetMatrix("_ViewProjMatrix", viewProjectionMatrix);
m_RenderSkyPropertyBlock.SetMatrix("_InvViewProjMatrix", invViewProjectionMatrix);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial, 0, 0, m_RenderSkyPropertyBlock);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
return GetParameters(skyParameters) != null;
private void RenderSkyToCubemap(SkyParameters skyParameters, RenderTexture target, RenderLoop renderLoop)
override public Type GetSkyParameterType()
for (int i = 0; i < 6; ++i)
{
Utilities.SetRenderTarget(renderLoop, target, 0, (CubemapFace)i);
RenderSky(m_screenSize, m_faceCameraViewProjectionMatrix[i], m_faceCameraInvViewProjectionMatrix[i], skyParameters, m_CubemapFaceMesh[i], renderLoop);
}
return typeof(ParameterType);
private void RenderCubemapGGXConvolution(Texture input, RenderTexture target, RenderLoop renderLoop)
protected ParameterType GetParameters(SkyParameters parameters)
using (new Utilities.ProfilingSample("Sky Pass: GGX Convolution", renderLoop))
{
int mipCount = 1 + (int)Mathf.Log(input.width, 2.0f);
if (mipCount < ((int)EnvConstants.SpecCubeLodStep + 1))
{
Debug.LogWarning("RenderCubemapGGXConvolution: Cubemap size is too small for GGX convolution, needs at least " + ((int)EnvConstants.SpecCubeLodStep + 1) + " mip levels");
return;
}
// Copy the first mip.
// TEMP code until CopyTexture is implemented for command buffer
// All parameters are neutral because exposure/multiplier have already been applied in the first copy.
SkyParameters skyParams = new SkyParameters();
skyParams.exposure = 0.0f;
skyParams.multiplier = 1.0f;
skyParams.rotation = 0.0f;
skyParams.skyHDRI = input;
RenderSkyToCubemap(skyParams, target, renderLoop);
// End temp
//for (int f = 0; f < 6; f++)
// Graphics.CopyTexture(input, f, 0, target, f, 0);
// Do the convolution on remaining mipmaps
float invOmegaP = (6.0f * input.width * input.width) / (4.0f * Mathf.PI); // Solid angle associated to a pixel of the cubemap;
m_GGXConvolveMaterial.SetTexture("_MainTex", input);
m_GGXConvolveMaterial.SetFloat("_MipMapCount", mipCount);
m_GGXConvolveMaterial.SetFloat("_InvOmegaP", invOmegaP);
for (int mip = 1; mip < ((int)EnvConstants.SpecCubeLodStep + 1); ++mip)
{
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
propertyBlock.SetFloat("_Level", mip);
for (int face = 0; face < 6; ++face)
{
Utilities.SetRenderTarget(renderLoop, target, mip, (CubemapFace)face);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(m_CubemapFaceMesh[face], Matrix4x4.identity, m_GGXConvolveMaterial, 0, 0, propertyBlock);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
}
}
public void RenderSky(HDRenderLoop.HDCamera hdCamera, SkyParameters skyParameters, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Sky Pass", renderLoop))
{
if (IsSkyValid(skyParameters))
{
// Trigger a rebuild of cubemap / convolution
// TODO: can we have some kind of hash value here ? +> use or override GetHashCode() + include a refresh rate value in parameters
// TODO: we could apply multiplier/exposure and rotation on the final result (i.e on the sky ibl and on lightprobe / lightmap, but can be tricky as Unity seems to merge sky information with
// other lighting into SH / lightmap.
if (skyParameters.skyResolution != m_bakedSkyParameters.skyResolution ||
skyParameters.exposure != m_bakedSkyParameters.exposure ||
skyParameters.rotation != m_bakedSkyParameters.rotation ||
skyParameters.multiplier != m_bakedSkyParameters.multiplier ||
skyParameters.skyHDRI != m_bakedSkyParameters.skyHDRI)
{
using (new Utilities.ProfilingSample("Sky Pass: Render Cubemap", renderLoop))
{
// Render sky into a cubemap - doesn't happen every frame, can be controlled
RenderSkyToCubemap(skyParameters, m_SkyboxCubemapRT, renderLoop);
// Convolve downsampled cubemap
RenderCubemapGGXConvolution(m_SkyboxCubemapRT, m_SkyboxGGXCubemapRT, renderLoop);
// TODO: Properly send the cubemap to Enlighten. Currently workaround is to set the cubemap in a Skybox/cubemap material
m_StandardSkyboxMaterial.SetTexture("_Tex", m_SkyboxCubemapRT);
RenderSettings.skybox = m_StandardSkyboxMaterial; // Setup this material as the default to be use in RenderSettings
RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.reflectionIntensity = 1.0f;
RenderSettings.customReflection = null;
DynamicGI.UpdateEnvironment();
}
// Cleanup all this...
m_bakedSkyParameters.skyHDRI = skyParameters.skyHDRI;
m_bakedSkyParameters.skyResolution = skyParameters.skyResolution;
m_bakedSkyParameters.exposure = skyParameters.exposure;
m_bakedSkyParameters.rotation = skyParameters.rotation;
m_bakedSkyParameters.multiplier = skyParameters.multiplier;
}
// Render the sky itself
Utilities.SetRenderTarget(renderLoop, colorBuffer, depthBuffer);
RenderSky(hdCamera.screenSize, hdCamera.viewProjectionMatrix, hdCamera.invViewProjectionMatrix, skyParameters, BuildSkyMesh(hdCamera.camera.GetComponent<Transform>().position, hdCamera.invViewProjectionMatrix, false), renderLoop);
}
}
return parameters as ParameterType;
}
}
}

4
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs.meta


fileFormatVersion: 2
guid: cf8a015aab8d3b643aa3ef3816f85447
timeCreated: 1479314393
guid: 0dc07ece20cf92244bb1f9c889f3cea5
timeCreated: 1481626426
licenseType: Pro
MonoImporter:
serializedVersion: 2

14
Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs


// Render Target Management.
public const ClearFlag kClearAll = ClearFlag.ClearDepth | ClearFlag.ClearColor;
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier buffer, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier buffer, ClearFlag clearFlag = ClearFlag.ClearNone, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
var cmd = new CommandBuffer();
cmd.name = "";

m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
public static HDRenderLoop GetHDRenderLoop()
{
HDRenderLoop renderLoop = UnityEngine.Rendering.GraphicsSettings.renderPipeline as HDRenderLoop;
if (renderLoop == null)
{
Debug.LogWarning("SkyParameters component can only be used with HDRenderLoop custom RenderPipeline.");
return null;
}
return renderLoop;
}
}
}

172
Assets/TestScenes/HDTest/GlobalIlluminationTest.unity


--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 7
serializedVersion: 8
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3

m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1

m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.6238628, g: 0.56322443, b: 0.5425187, a: 1}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
serializedVersion: 7
m_GIWorkflowMode: 0
serializedVersion: 9
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1

m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 4
serializedVersion: 6
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024

m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_DirectLightInLightProbes: 1
m_StationaryBakeMode: 1
m_ShadowMaskMode: 2
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2

minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &20738779

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 565152814}
m_Enabled: 1
serializedVersion: 7
serializedVersion: 8
m_Type: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 3

m_Lightmapping: 4
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_CCT: 6570
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!114 &565152817

- {fileID: 190482350}
- {fileID: 1232831964}
- {fileID: 1543726726}
- {fileID: 1692663595}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1108908831}
m_Enabled: 1
serializedVersion: 7
serializedVersion: 8
m_Type: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 100

m_Lightmapping: 4
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_CCT: 6570
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!114 &1108908834

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1686135372}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &1692663594
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1692663595}
- component: {fileID: 1692663596}
- component: {fileID: 1692663597}
m_Layer: 0
m_Name: SceneParameters
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1692663595
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1692663594}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1027688891}
m_RootOrder: 11
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1692663596
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1692663594}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59b6606ef2548734bb6d11b9d160bc7e, type: 3}
m_Name:
m_EditorClassIdentifier:
rotation: 0
exposure: 0
multiplier: 1
resolution: 512
skyHDRI: {fileID: 8900000, guid: 9b513842339ef704ca63ef696691bc34, type: 3}
--- !u!114 &1692663597
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1692663594}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 54bcd1d5cb4984847971142e9444d2fb, type: 3}
m_Name:
m_EditorClassIdentifier:
rotation: 0
exposure: 0
multiplier: 1
resolution: 256
worldRayleighColorRamp:
serializedVersion: 2
key0: {r: 1, g: 1, b: 1, a: 1}
key1: {r: 1, g: 1, b: 1, a: 1}
key2: {r: 0, g: 0, b: 0, a: 0}
key3: {r: 0, g: 0, b: 0, a: 0}
key4: {r: 0, g: 0, b: 0, a: 0}
key5: {r: 0, g: 0, b: 0, a: 0}
key6: {r: 0, g: 0, b: 0, a: 0}
key7: {r: 0, g: 0, b: 0, a: 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:
serializedVersion: 2
key0: {r: 1, g: 1, b: 1, a: 1}
key1: {r: 1, g: 1, b: 1, a: 1}
key2: {r: 0, g: 0, b: 0, a: 0}
key3: {r: 0, g: 0, b: 0, a: 0}
key4: {r: 0, g: 0, b: 0, a: 0}
key5: {r: 0, g: 0, b: 0, a: 0}
key6: {r: 0, g: 0, b: 0, a: 0}
key7: {r: 0, g: 0, b: 0, a: 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
skyDomeRotation: {x: 0, y: 0, z: 0}
skyDomeVerticalFlip: 0
skyDomeCubemap: {fileID: 8900000, guid: 9b513842339ef704ca63ef696691bc34, type: 3}
skyDomeExposure: 1
skyDomeTint: {r: 1, g: 1, b: 1, a: 1}
skyDomeTrackedYawRotation: {fileID: 0}
atmosphericShader: {fileID: 0}
worldScaleExponent: 1
depthTexture: 0
debugMode: 0
--- !u!1 &1736468424
GameObject:
m_ObjectHideFlags: 0

2
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources/SkyHDRI.shader


Shader "Hidden/HDRenderLoop/SkyHDRI"
Shader "Hidden/HDRenderLoop/Sky/SkyHDRI"
{
SubShader
{

2
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader


Shader "Hidden/HDRenderLoop/SkyProcedural"
Shader "Hidden/HDRenderLoop/Sky/SkyProcedural"
{
SubShader
{

27
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopMenuItems.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
public class HDRenderLoopMenuItems
{
[UnityEditor.MenuItem("HDRenderLoop/Create Scene Settings")]
static void CreateSceneSettings()
{
CommonSettings[] settings = Object.FindObjectsOfType(typeof(CommonSettings)) as CommonSettings[];
if(settings.Length == 0)
{
GameObject go = new GameObject();
go.name = "SceneSettings";
go.AddComponent(typeof(CommonSettings));
}
else
{
Debug.LogWarning("SceneSettings has already been created.");
}
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopMenuItems.cs.meta


fileFormatVersion: 2
guid: 19042aef0dcb65e4496d778558fefad9
timeCreated: 1481793704
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings.meta


fileFormatVersion: 2
guid: 1b5e87e98ef1994498478f60a6dcdd65
folderAsset: yes
timeCreated: 1481725797
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky.meta


fileFormatVersion: 2
guid: 3dc75ec23ead9c94fa152d2c7c33aee4
folderAsset: yes
timeCreated: 1481626018
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky.meta


fileFormatVersion: 2
guid: 65f9231eb40b6914eb24ea0b555778f0
folderAsset: yes
timeCreated: 1481646017
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

401
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyManager.cs


using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using System.Collections.Generic;
using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[Serializable]
public enum SkyResolution
{
SkyResolution128 = 128,
SkyResolution256 = 256,
SkyResolution512 = 512,
SkyResolution1024 = 1024,
// TODO: Anything above 1024 cause a crash in Unity...
//SkyResolution2048 = 2048,
//SkyResolution4096 = 4096
}
public class BuiltinSkyParameters
{
public Matrix4x4 viewProjMatrix;
public Matrix4x4 invViewProjMatrix;
public Vector4 screenSize;
public Mesh skyMesh;
public RenderLoop renderLoop;
public Light sunLight;
}
public class SkyManager
{
RenderTexture m_SkyboxCubemapRT = null;
RenderTexture m_SkyboxGGXCubemapRT = null;
Material m_StandardSkyboxMaterial = null; // This is the Unity standard skybox material. Used to pass the correct cubemap to Enlighten.
Material m_GGXConvolveMaterial = null; // Apply GGX convolution to cubemap
Vector4 m_CubemapScreenSize;
Matrix4x4[] m_faceCameraViewProjectionMatrix = new Matrix4x4[6];
Matrix4x4[] m_faceCameraInvViewProjectionMatrix = new Matrix4x4[6];
Mesh[] m_CubemapFaceMesh = new Mesh[6];
BuiltinSkyParameters m_BuiltinParameters = new BuiltinSkyParameters();
SkyRenderer m_Renderer = null;
int m_SkyParametersHash = 0;
bool m_NeedUpdateEnvironment = false;
SkyParameters m_SkyParameters = null;
public SkyParameters skyParameters
{
set
{
if(m_Renderer != null)
{
if (value == null || IsSkyParameterValid(value))
{
m_SkyParametersHash = 0;
m_SkyParameters = value;
}
else
{
Debug.LogWarning("Sky renderer needs an instance of " + GetSkyParameterType().ToString() + " to be able to render.");
}
}
}
get { return m_SkyParameters; }
}
public void InstantiateSkyRenderer(Type skyRendererType)
{
if(skyRendererType == null)
{
m_Renderer = null;
}
else if (m_Renderer == null || m_Renderer.GetType() != skyRendererType)
{
m_Renderer = Activator.CreateInstance(skyRendererType) as SkyRenderer;
m_Renderer.Build();
}
}
protected Mesh BuildSkyMesh(Vector3 cameraPosition, Matrix4x4 cameraInvViewProjectionMatrix, bool forceUVBottom)
{
Vector4 vertData0 = new Vector4(-1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData1 = new Vector4(1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData2 = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Vector4 vertData3 = new Vector4(-1.0f, 1.0f, 1.0f, 1.0f);
Vector3[] vertData = new Vector3[4];
vertData[0] = new Vector3(vertData0.x, vertData0.y, vertData0.z);
vertData[1] = new Vector3(vertData1.x, vertData1.y, vertData1.z);
vertData[2] = new Vector3(vertData2.x, vertData2.y, vertData2.z);
vertData[3] = new Vector3(vertData3.x, vertData3.y, vertData3.z);
// Get view vector based on the frustum, i.e (invert transform frustum get position etc...)
Vector3[] eyeVectorData = new Vector3[4];
Matrix4x4 transformMatrix = cameraInvViewProjectionMatrix;
Vector4 posWorldSpace0 = transformMatrix * vertData0;
Vector4 posWorldSpace1 = transformMatrix * vertData1;
Vector4 posWorldSpace2 = transformMatrix * vertData2;
Vector4 posWorldSpace3 = transformMatrix * vertData3;
Vector4 cameraPos = new Vector4(cameraPosition.x, cameraPosition.y, cameraPosition.z, 0.0f);
Vector4 direction0 = (posWorldSpace0 / posWorldSpace0.w - cameraPos);
Vector4 direction1 = (posWorldSpace1 / posWorldSpace1.w - cameraPos);
Vector4 direction2 = (posWorldSpace2 / posWorldSpace2.w - cameraPos);
Vector4 direction3 = (posWorldSpace3 / posWorldSpace3.w - cameraPos);
if (SystemInfo.graphicsUVStartsAtTop && !forceUVBottom)
{
eyeVectorData[3] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[2] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[1] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[0] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
else
{
eyeVectorData[0] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[1] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[2] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[3] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
// Write out the mesh
var triangles = new int[6] { 0, 1, 2, 2, 3, 0 };
return new Mesh
{
vertices = vertData,
normals = eyeVectorData,
triangles = triangles
};
}
void RebuildTextures(SkyParameters skyParameters)
{
int resolution = 256;
// Parameters not set yet. We need them for the resolution.
if (skyParameters != null)
resolution = (int)skyParameters.resolution;
if ((m_SkyboxCubemapRT != null) && (m_SkyboxCubemapRT.width != resolution))
{
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
}
if (m_SkyboxCubemapRT == null)
{
m_SkyboxCubemapRT = new RenderTexture(resolution, resolution, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxCubemapRT.useMipMap = true;
m_SkyboxCubemapRT.autoGenerateMips = true; // Generate regular mipmap for filtered importance sampling
m_SkyboxCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxCubemapRT.Create();
m_SkyboxGGXCubemapRT = new RenderTexture(resolution, resolution, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxGGXCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxGGXCubemapRT.useMipMap = true;
m_SkyboxGGXCubemapRT.autoGenerateMips = false;
m_SkyboxGGXCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxGGXCubemapRT.Create();
}
m_CubemapScreenSize = new Vector4((float)resolution, (float)resolution, 1.0f / (float)resolution, 1.0f / (float)resolution);
}
void RebuildSkyMeshes()
{
if(m_CubemapFaceMesh[0] == null)
{
Matrix4x4 cubeProj = Matrix4x4.Perspective(90.0f, 1.0f, 0.1f, 1.0f);
Vector3[] lookAtList = {
new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(-1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, -1.0f, 0.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 0.0f, -1.0f),
};
Vector3[] UpVectorList = {
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
};
for (int i = 0; i < 6; ++i)
{
Matrix4x4 lookAt = Matrix4x4.LookAt(Vector3.zero, lookAtList[i], UpVectorList[i]);
m_faceCameraViewProjectionMatrix[i] = Utilities.GetViewProjectionMatrix(lookAt, cubeProj);
m_faceCameraInvViewProjectionMatrix[i] = m_faceCameraViewProjectionMatrix[i].inverse;
// When rendering into a texture the render will be flip (due to legacy unity openGL behavior), so we need to flip UV here...
m_CubemapFaceMesh[i] = BuildSkyMesh(Vector3.zero, m_faceCameraInvViewProjectionMatrix[i], true);
}
}
}
// Sets the global MIP-mapped cubemap '_SkyTexture' in the shader.
// The texture being set is the sky (environment) map pre-convolved with GGX.
public void SetGlobalSkyTexture()
{
Shader.SetGlobalTexture("_SkyTexture", m_SkyboxGGXCubemapRT);
}
public void Resize()
{
// When loading RenderDoc, RenderTextures will go null
RebuildTextures(skyParameters);
RebuildSkyMeshes();
}
public void Build()
{
if (m_Renderer != null)
m_Renderer.Build();
// TODO: We need to have an API to send our sky information to Enlighten. For now use a workaround through skybox/cubemap material...
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial("Skybox/Cubemap");
m_GGXConvolveMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/GGXConvolve");
}
public void Cleanup()
{
Utilities.Destroy(m_StandardSkyboxMaterial);
Utilities.Destroy(m_GGXConvolveMaterial);
Utilities.Destroy(m_SkyboxCubemapRT);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
if(m_Renderer != null)
m_Renderer.Cleanup();
}
public bool IsSkyValid()
{
return m_Renderer != null && m_Renderer.IsParameterValid(skyParameters) && m_Renderer.IsSkyValid(skyParameters);
}
private void RenderSkyToCubemap(BuiltinSkyParameters builtinParams, SkyParameters skyParameters, RenderTexture target)
{
for (int i = 0; i < 6; ++i)
{
Utilities.SetRenderTarget(builtinParams.renderLoop, target, ClearFlag.ClearNone, 0, (CubemapFace)i);
builtinParams.invViewProjMatrix = m_faceCameraInvViewProjectionMatrix[i];
builtinParams.viewProjMatrix = m_faceCameraViewProjectionMatrix[i];
builtinParams.screenSize = m_CubemapScreenSize;
builtinParams.skyMesh = m_CubemapFaceMesh[i];
m_Renderer.RenderSky(builtinParams, skyParameters);
}
}
private void RenderCubemapGGXConvolution(RenderLoop renderLoop, BuiltinSkyParameters builtinParams, SkyParameters skyParams, Texture input, RenderTexture target)
{
using (new Utilities.ProfilingSample("Sky Pass: GGX Convolution", renderLoop))
{
int mipCount = 1 + (int)Mathf.Log(input.width, 2.0f);
if (mipCount < ((int)EnvConstants.SpecCubeLodStep + 1))
{
Debug.LogWarning("RenderCubemapGGXConvolution: Cubemap size is too small for GGX convolution, needs at least " + ((int)EnvConstants.SpecCubeLodStep + 1) + " mip levels");
return;
}
// Copy the first mip.
// WARNING:
// Since we can't instanciate the parameters anymore (we don't know the final type here)
// we can't make sure that exposure/multiplier etc are at neutral values
// This will be solved with proper CopyTexture
// TEMP code until CopyTexture is implemented for command buffer
// All parameters are neutral because exposure/multiplier have already been applied in the first copy.
//SkyParameters skyParams = new SkyParameters();
//skyParams.exposure = 0.0f;
//skyParams.multiplier = 1.0f;
//skyParams.rotation = 0.0f;
//skyParams.skyHDRI = input;
RenderSkyToCubemap(builtinParams, skyParams, target);
// End temp
//for (int f = 0; f < 6; f++)
// Graphics.CopyTexture(input, f, 0, target, f, 0);
// Do the convolution on remaining mipmaps
float invOmegaP = (6.0f * input.width * input.width) / (4.0f * Mathf.PI); // Solid angle associated to a pixel of the cubemap;
m_GGXConvolveMaterial.SetTexture("_MainTex", input);
m_GGXConvolveMaterial.SetFloat("_MipMapCount", mipCount);
m_GGXConvolveMaterial.SetFloat("_InvOmegaP", invOmegaP);
for (int mip = 1; mip < ((int)EnvConstants.SpecCubeLodStep + 1); ++mip)
{
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
propertyBlock.SetFloat("_Level", mip);
for (int face = 0; face < 6; ++face)
{
Utilities.SetRenderTarget(renderLoop, target, ClearFlag.ClearNone, mip, (CubemapFace)face);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(m_CubemapFaceMesh[face], Matrix4x4.identity, m_GGXConvolveMaterial, 0, 0, propertyBlock);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
}
}
public bool IsSkyParameterValid(SkyParameters parameters)
{
return m_Renderer != null && m_Renderer.IsParameterValid(parameters);
}
public Type GetSkyParameterType()
{
return (m_Renderer == null) ? null : m_Renderer.GetSkyParameterType();
}
public void RenderSky(HDRenderLoop.HDCamera camera, Light sunLight, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Sky Pass", renderLoop))
{
if (IsSkyValid())
{
m_BuiltinParameters.renderLoop = renderLoop;
m_BuiltinParameters.sunLight = sunLight;
// We need one frame delay for this update to work since DynamicGI.UpdateEnvironment is executed direclty but the renderloop is not (so we need to wait for the sky texture to be rendered first)
if(m_NeedUpdateEnvironment)
{
// TODO: Properly send the cubemap to Enlighten. Currently workaround is to set the cubemap in a Skybox/cubemap material
m_StandardSkyboxMaterial.SetTexture("_Tex", m_SkyboxCubemapRT);
RenderSettings.skybox = m_StandardSkyboxMaterial; // Setup this material as the default to be use in RenderSettings
RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.reflectionIntensity = 1.0f;
RenderSettings.customReflection = null;
DynamicGI.UpdateEnvironment();
m_NeedUpdateEnvironment = false;
}
if (skyParameters.GetHash() != m_SkyParametersHash)
{
using (new Utilities.ProfilingSample("Sky Pass: Render Cubemap", renderLoop))
{
// Render sky into a cubemap - doesn't happen every frame, can be controlled
RenderSkyToCubemap(m_BuiltinParameters, skyParameters, m_SkyboxCubemapRT);
// Convolve downsampled cubemap
RenderCubemapGGXConvolution(renderLoop, m_BuiltinParameters, skyParameters, m_SkyboxCubemapRT, m_SkyboxGGXCubemapRT);
m_NeedUpdateEnvironment = true;
}
m_SkyParametersHash = skyParameters.GetHash();
}
// Render the sky itself
Utilities.SetRenderTarget(renderLoop, colorBuffer, depthBuffer);
m_BuiltinParameters.invViewProjMatrix = camera.invViewProjectionMatrix;
m_BuiltinParameters.viewProjMatrix = camera.viewProjectionMatrix;
m_BuiltinParameters.screenSize = camera.screenSize;
m_BuiltinParameters.skyMesh = BuildSkyMesh(camera.camera.GetComponent<Transform>().position, m_BuiltinParameters.invViewProjMatrix, false);
m_Renderer.RenderSky(m_BuiltinParameters, skyParameters);
}
else
{
// Disabled for now.
// We need to remove RenderSkyToCubemap from the RenderCubemapGGXConvolution first as it needs the skyparameter to be valid.
//if(m_SkyParametersHash != 0)
//{
// // Clear sky light probe
// RenderSettings.skybox = null;
// RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
// RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
// RenderSettings.reflectionIntensity = 1.0f;
// RenderSettings.customReflection = null;
// DynamicGI.UpdateEnvironment();
// // Clear temp cubemap and redo GGX from black
// Utilities.SetRenderTarget(renderLoop, m_SkyboxCubemapRT, ClearFlag.ClearColor);
// RenderCubemapGGXConvolution(renderLoop, m_BuiltinParameters, skyParameters, m_SkyboxCubemapRT, m_SkyboxGGXCubemapRT);
// m_SkyParametersHash = 0;
//}
}
}
}
}
}

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


fileFormatVersion: 2
guid: 8bd4c656fd5e14747b942575f2e7e185
timeCreated: 1481626426
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

66
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyParameters.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using System.Linq;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[ExecuteInEditMode]
public class SkyParameters : MonoBehaviour
{
public float rotation = 0.0f;
public float exposure = 0.0f;
public float multiplier = 1.0f;
public SkyResolution resolution = SkyResolution.SkyResolution256;
protected FieldInfo[] m_Properties;
protected void OnEnable()
{
HDRenderLoop renderLoop = Utilities.GetHDRenderLoop();
if (renderLoop == null)
{
return;
}
// Enumerate properties in order to compute the hash more quickly later on.
m_Properties = GetType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.ToArray();
if (renderLoop.skyManager.skyParameters == null || renderLoop.skyManager.skyParameters.GetType() != this.GetType()) // We allow override of parameters only if the type is different. It means that we changed the Sky Renderer and might need a new set of parameters.
renderLoop.skyManager.skyParameters = this;
else if (renderLoop.skyManager.skyParameters != this && renderLoop.skyManager.skyParameters.GetType() == this.GetType())
Debug.LogWarning("Tried to setup another SkyParameters component although there is already one enabled.");
}
protected void OnDisable()
{
HDRenderLoop renderLoop = Utilities.GetHDRenderLoop();
if (renderLoop == null)
{
return;
}
// Reset the current sky parameter on the render loop
if (renderLoop.skyManager.skyParameters == this)
renderLoop.skyManager.skyParameters = null;
}
public int GetHash()
{
unchecked
{
int hash = 13;
foreach (var p in m_Properties)
{
System.Object obj = p.GetValue(this);
if (obj != null) // Sometimes it can be a null reference.
hash = hash * 23 + obj.GetHashCode();
}
return hash;
}
}
}
}

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


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

81
Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/CommonSettings.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
using System.Reflection;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[ExecuteInEditMode]
[DisallowMultipleComponent]
public class CommonSettings
: MonoBehaviour
{
[SerializeField]
private string m_SkyRendererTypeName = "";
public Type skyRendererType
{
set { m_SkyRendererTypeName = value != null ? value.FullName : ""; OnSkyRendererChanged(); }
get { return m_SkyRendererTypeName == "" ? null : Assembly.GetAssembly(typeof(CommonSettings)).GetType(m_SkyRendererTypeName); }
}
void OnEnable()
{
HDRenderLoop renderLoop = Utilities.GetHDRenderLoop();
if (renderLoop == null)
{
return;
}
OnSkyRendererChanged();
}
void OnDisable()
{
}
void OnSkyRendererChanged()
{
HDRenderLoop renderLoop = Utilities.GetHDRenderLoop();
if (renderLoop == null)
{
return;
}
renderLoop.InstantiateSkyRenderer(skyRendererType);
List<SkyParameters> result = new List<SkyParameters>();
gameObject.GetComponents<SkyParameters>(result);
Type skyParamType = renderLoop.skyManager.GetSkyParameterType();
// Disable all incompatible sky parameters and enable the compatible one
bool found = false;
foreach (SkyParameters param in result)
{
if (param.GetType() == skyParamType)
{
// This is a workaround the fact that we can't control the order in which components are initialized.
// So it can happen that a given SkyParameter is OnEnabled before the CommonSettings and so fail the setup because the SkyRenderer is not yet initialized.
// So we disable it to for OnEnable to be called again.
param.enabled = false;
param.enabled = true;
found = true;
}
else
{
param.enabled = false;
}
}
// If it does not exist, create the parameters
if (!found && skyParamType != null)
{
gameObject.AddComponent(skyParamType);
}
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/CommonSettings.cs.meta


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

9
Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/Editor.meta


fileFormatVersion: 2
guid: a1fd2e77167b0904e9c33020c13d1011
folderAsset: yes
timeCreated: 1481726125
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

87
Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/Editor/CommonSettingsEditor.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.Linq;
using System.Reflection;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[CustomEditor(typeof(CommonSettings))]
public class CommonSettingsEditor
: Editor
{
private class Styles
{
public readonly GUIContent none = new GUIContent("None");
public readonly GUIContent skyRenderer = new GUIContent("Sky Renderer");
}
private static Styles s_Styles = null;
private static Styles styles
{
get
{
if (s_Styles == null)
s_Styles = new Styles();
return s_Styles;
}
}
private List<Type> m_SkyRendererTypes;
private List<GUIContent> m_SkyRendererTypeNames = new List<GUIContent>();
private List<int> m_SkyRendererTypeValues = new List<int>();
void OnEnable()
{
m_SkyRendererTypes = Assembly.GetAssembly(typeof(SkyRenderer))
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(SkyRenderer)) && !t.IsGenericType)
.ToList();
// Prepare the list of available SkyRenderers for the IntPopup
m_SkyRendererTypeNames.Clear();
m_SkyRendererTypeValues.Clear();
for(int i = 0 ; i < m_SkyRendererTypes.Count ; ++i)
{
string longName = m_SkyRendererTypes[i].ToString();
char[] separators = {'.'};
string[] tokens = longName.Split(separators);
m_SkyRendererTypeNames.Add(new GUIContent(tokens[tokens.Length - 1]));
m_SkyRendererTypeValues.Add(i);
}
// Add default null value.
m_SkyRendererTypeNames.Add(styles.none);
m_SkyRendererTypeValues.Add(m_SkyRendererTypeValues.Count);
m_SkyRendererTypes.Add(null);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
CommonSettings settings = target as CommonSettings;
// Retrieve the index of the current SkyRenderer
int index = -1;
for(int i = 0 ; i < m_SkyRendererTypeValues.Count ; ++i )
{
if(m_SkyRendererTypes[i] == settings.skyRendererType)
{
index = i;
break;
}
}
EditorGUI.BeginChangeCheck();
int newValue = EditorGUILayout.IntPopup(styles.skyRenderer, index, m_SkyRendererTypeNames.ToArray(), m_SkyRendererTypeValues.ToArray());
if(EditorGUI.EndChangeCheck())
{
settings.skyRendererType = m_SkyRendererTypes[newValue];
}
serializedObject.ApplyModifiedProperties();
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/SceneSettings/Editor/CommonSettingsEditor.cs.meta


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

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Editor.meta


fileFormatVersion: 2
guid: 132564d35bbdac3458d90dc38649e882
folderAsset: yes
timeCreated: 1481635912
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Editor/HDRISkyEditor.cs.meta


fileFormatVersion: 2
guid: 09663e580f1cc7b409d7ddc7923ec152
timeCreated: 1481635925
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

61
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Editor/HDRISkyEditor.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[CanEditMultipleObjects]
[CustomEditor(typeof(HDRISkyParameters))]
public class HDRISkyParametersEditor
: Editor
{
private class Styles
{
public readonly GUIContent skyHDRI = new GUIContent("HDRI");
public readonly GUIContent skyResolution = new GUIContent("Resolution");
public readonly GUIContent skyExposure = new GUIContent("Exposure");
public readonly GUIContent skyRotation = new GUIContent("Rotation");
public readonly GUIContent skyMultiplier = new GUIContent("Multiplier");
}
private static Styles s_Styles = null;
private static Styles styles
{
get
{
if (s_Styles == null)
s_Styles = new Styles();
return s_Styles;
}
}
private SerializedProperty m_SkyHDRI;
private SerializedProperty m_SkyResolution;
private SerializedProperty m_SkyExposure;
private SerializedProperty m_SkyMultiplier;
private SerializedProperty m_SkyRotation;
void OnEnable()
{
m_SkyHDRI = serializedObject.FindProperty("skyHDRI");
m_SkyResolution = serializedObject.FindProperty("resolution");
m_SkyExposure = serializedObject.FindProperty("exposure");
m_SkyMultiplier = serializedObject.FindProperty("multiplier");
m_SkyRotation = serializedObject.FindProperty("rotation");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_SkyHDRI, styles.skyHDRI);
EditorGUILayout.PropertyField(m_SkyResolution, styles.skyResolution);
EditorGUILayout.PropertyField(m_SkyExposure, styles.skyExposure);
EditorGUILayout.PropertyField(m_SkyMultiplier, styles.skyMultiplier);
EditorGUILayout.PropertyField(m_SkyRotation, styles.skyRotation);
serializedObject.ApplyModifiedProperties();
}
}
}

13
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/HDRISkyParameters.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[DisallowMultipleComponent]
public class HDRISkyParameters
: SkyParameters
{
public Cubemap skyHDRI;
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/HDRISkyParameters.cs.meta


fileFormatVersion: 2
guid: 59b6606ef2548734bb6d11b9d160bc7e
timeCreated: 1481631764
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

42
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/HDRISkyRenderer.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
public class HDRISkyRenderer
: SkyRenderer<HDRISkyParameters>
{
Material m_SkyHDRIMaterial = null; // Renders a cubemap into a render texture (can be cube or 2D)
override public void Build()
{
m_SkyHDRIMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Sky/SkyHDRI");
}
override public void Cleanup()
{
Utilities.Destroy(m_SkyHDRIMaterial);
}
override public bool IsSkyValid(SkyParameters skyParameters)
{
return GetParameters(skyParameters).skyHDRI != null;
}
override public void RenderSky(BuiltinSkyParameters builtinParams, SkyParameters skyParameters)
{
HDRISkyParameters hdriSkyParams = GetParameters(skyParameters);
m_SkyHDRIMaterial.SetTexture("_Cubemap", hdriSkyParams.skyHDRI);
m_SkyHDRIMaterial.SetVector("_SkyParam", new Vector4(hdriSkyParams.exposure, hdriSkyParams.multiplier, hdriSkyParams.rotation, 0.0f));
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(builtinParams.skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial);
builtinParams.renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/HDRISkyRenderer.cs.meta


fileFormatVersion: 2
guid: 85b456caa9945824bb71f0ab97b1dabe
timeCreated: 1481631774
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources.meta


fileFormatVersion: 2
guid: 45faf85c8e652e744a3ce8ead527369d
folderAsset: yes
timeCreated: 1481636169
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Editor.meta


fileFormatVersion: 2
guid: 00372bf7f144a724bba68a081fd79e78
folderAsset: yes
timeCreated: 1481646149
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

61
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Editor/ProceduralSkyEditor.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
//[CanEditMultipleObjects]
//[CustomEditor(typeof(ProceduralSkyParameters))]
//public class ProceduralSkyParametersEditor
// : Editor
//{
// private class Styles
// {
// public readonly GUIContent skyHDRI = new GUIContent("HDRI");
// public readonly GUIContent skyResolution = new GUIContent("Resolution");
// public readonly GUIContent skyExposure = new GUIContent("Exposure");
// public readonly GUIContent skyRotation = new GUIContent("Rotation");
// public readonly GUIContent skyMultiplier = new GUIContent("Multiplier");
// }
// private static Styles s_Styles = null;
// private static Styles styles
// {
// get
// {
// if (s_Styles == null)
// s_Styles = new Styles();
// return s_Styles;
// }
// }
// private SerializedProperty m_SkyHDRI;
// private SerializedProperty m_SkyResolution;
// private SerializedProperty m_SkyExposure;
// private SerializedProperty m_SkyMultiplier;
// private SerializedProperty m_SkyRotation;
// void OnEnable()
// {
// m_SkyHDRI = serializedObject.FindProperty("skyHDRI");
// m_SkyResolution = serializedObject.FindProperty("resolution");
// m_SkyExposure = serializedObject.FindProperty("exposure");
// m_SkyMultiplier = serializedObject.FindProperty("multiplier");
// m_SkyRotation = serializedObject.FindProperty("rotation");
// }
// public override void OnInspectorGUI()
// {
// serializedObject.Update();
// EditorGUILayout.PropertyField(m_SkyHDRI, styles.skyHDRI);
// EditorGUILayout.PropertyField(m_SkyResolution, styles.skyResolution);
// EditorGUILayout.PropertyField(m_SkyExposure, styles.skyExposure);
// EditorGUILayout.PropertyField(m_SkyMultiplier, styles.skyMultiplier);
// EditorGUILayout.PropertyField(m_SkyRotation, styles.skyRotation);
// serializedObject.ApplyModifiedProperties();
// }
//}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Editor/ProceduralSkyEditor.cs.meta


fileFormatVersion: 2
guid: 40b56ef8d02cefa49ab82e6b7df9266b
timeCreated: 1481635925
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

106
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyParameters.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[ExecuteInEditMode]
[DisallowMultipleComponent]
public class ProceduralSkyParameters
: SkyParameters
{
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 skyDomeRotation = Vector3.zero;
public bool skyDomeVerticalFlip = false;
public Cubemap skyDomeCubemap = null;
public float skyDomeExposure = 1f;
public Color skyDomeTint = Color.white;
public Transform skyDomeTrackedYawRotation = null;
/*
[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 atmosphericShader = null;
// public Shader occlusionShader = 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;
// Camera m_currentCamera;
// UnityEngine.Rendering.CommandBuffer m_occlusionCmdAfterShadows, m_occlusionCmdBeforeScreen;
public void OnValidate()
{
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);
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyParameters.cs.meta


fileFormatVersion: 2
guid: 54bcd1d5cb4984847971142e9444d2fb
timeCreated: 1481631764
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

200
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyRenderer.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
public class ProceduralSkyRenderer
: SkyRenderer<ProceduralSkyParameters>
{
Material m_ProceduralSkyMaterial = null; // Renders a cubemap into a render texture (can be cube or 2D)
Gradient m_DefaultWorldRayleighColorRamp = null;
Gradient m_DefaultWorldMieColorRamp = null;
override public void Build()
{
m_ProceduralSkyMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Sky/SkyProcedural");
if (m_DefaultWorldRayleighColorRamp == null)
{
m_DefaultWorldRayleighColorRamp = new Gradient();
m_DefaultWorldRayleighColorRamp.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 (m_DefaultWorldMieColorRamp == null)
{
m_DefaultWorldMieColorRamp = new Gradient();
m_DefaultWorldMieColorRamp.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) }
);
}
}
override public void Cleanup()
{
Utilities.Destroy(m_ProceduralSkyMaterial);
}
override public bool IsSkyValid(SkyParameters skyParameters)
{
//ProceduralSkyParameters proceduralSkyParams = GetParameters(skyParameters);
return true; // TODO: See with Evgenii what makes it valid or invalid.
}
void UpdateKeywords(bool enable, ProceduralSkyParameters param)
{
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_OCCLUSION");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_SUNRAYS");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_DEBUG");
if (enable)
{
/*
if (useOcclusion)
{
m_ProceduralSkyMaterial.EnableKeyword("ATMOSPHERICS_OCCLUSION");
if(occlusionDepthFixup && occlusionDownscale != OcclusionDownscale.x1)
m_ProceduralSkyMaterial.EnableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP");
if(occlusionFullSky)
m_ProceduralSkyMaterial.EnableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY");
}
*/
if (param.debugMode != ProceduralSkyParameters.ScatterDebugMode.None)
{
m_ProceduralSkyMaterial.EnableKeyword("ATMOSPHERICS_DEBUG");
}
}
}
void UpdateStaticUniforms(ProceduralSkyParameters param)
{
m_ProceduralSkyMaterial.SetTexture("_SkyDomeCubemap", param.skyDomeCubemap);
m_ProceduralSkyMaterial.SetFloat("_SkyDomeExposure", param.skyDomeExposure);
m_ProceduralSkyMaterial.SetColor("_SkyDomeTint", param.skyDomeTint);
/*
m_ProceduralSkyMaterial.SetFloat("_ShadowBias", useOcclusion ? occlusionBias : 1f);
m_ProceduralSkyMaterial.SetFloat("_ShadowBiasIndirect", useOcclusion ? occlusionBiasIndirect : 1f);
m_ProceduralSkyMaterial.SetFloat("_ShadowBiasClouds", useOcclusion ? occlusionBiasClouds : 1f);
m_ProceduralSkyMaterial.SetVector("_ShadowBiasSkyRayleighMie", useOcclusion ? new Vector4(occlusionBiasSkyRayleigh, occlusionBiasSkyMie, 0f, 0f) : Vector4.zero);
m_ProceduralSkyMaterial.SetFloat("_OcclusionDepthThreshold", occlusionDepthThreshold);
*/
m_ProceduralSkyMaterial.SetFloat("_WorldScaleExponent", param.worldScaleExponent);
m_ProceduralSkyMaterial.SetFloat("_WorldNormalDistanceRcp", 1f / param.worldNormalDistance);
m_ProceduralSkyMaterial.SetFloat("_WorldNearScatterPush", -Mathf.Pow(Mathf.Abs(param.worldNearScatterPush), param.worldScaleExponent) * Mathf.Sign(param.worldNearScatterPush));
m_ProceduralSkyMaterial.SetFloat("_WorldRayleighDensity", -param.worldRayleighDensity / 100000f);
m_ProceduralSkyMaterial.SetFloat("_MiePhaseAnisotropy", param.worldMiePhaseAnisotropy);
m_ProceduralSkyMaterial.SetVector("_RayleighInScatterPct", new Vector4(1f - param.worldRayleighIndirectScatter, param.worldRayleighIndirectScatter, 0f, 0f));
m_ProceduralSkyMaterial.SetFloat("_HeightNormalDistanceRcp", 1f / param.heightNormalDistance);
m_ProceduralSkyMaterial.SetFloat("_HeightNearScatterPush", -Mathf.Pow(Mathf.Abs(param.heightNearScatterPush), param.worldScaleExponent) * Mathf.Sign(param.heightNearScatterPush));
m_ProceduralSkyMaterial.SetFloat("_HeightRayleighDensity", -param.heightRayleighDensity / 100000f);
m_ProceduralSkyMaterial.SetFloat("_HeightSeaLevel", param.heightSeaLevel);
m_ProceduralSkyMaterial.SetFloat("_HeightDistanceRcp", 1f / param.heightDistance);
m_ProceduralSkyMaterial.SetVector("_HeightPlaneShift", param.heightPlaneShift);
m_ProceduralSkyMaterial.SetVector("_HeightRayleighColor", (Vector4)param.heightRayleighColor * param.heightRayleighIntensity);
m_ProceduralSkyMaterial.SetFloat("_HeightExtinctionFactor", param.heightExtinctionFactor);
m_ProceduralSkyMaterial.SetFloat("_RayleighExtinctionFactor", param.worldRayleighExtinctionFactor);
m_ProceduralSkyMaterial.SetFloat("_MieExtinctionFactor", param.worldMieExtinctionFactor);
Gradient worldRayleighColorRamp = param.worldRayleighColorRamp != null ? param.worldRayleighColorRamp : m_DefaultWorldRayleighColorRamp;
Gradient worldMieColorRamp = param.worldMieColorRamp != null ? param.worldMieColorRamp : m_DefaultWorldMieColorRamp;
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);
m_ProceduralSkyMaterial.SetVector("_RayleighColorM20", (Vector4)rayleighColorM20 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_RayleighColorM10", (Vector4)rayleighColorM10 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_RayleighColorO00", (Vector4)rayleighColorO00 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_RayleighColorP10", (Vector4)rayleighColorP10 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_RayleighColorP20", (Vector4)rayleighColorP20 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_MieColorM20", (Vector4)mieColorM20 * param.worldMieColorIntensity);
m_ProceduralSkyMaterial.SetVector("_MieColorO00", (Vector4)mieColorO00 * param.worldMieColorIntensity);
m_ProceduralSkyMaterial.SetVector("_MieColorP20", (Vector4)mieColorP20 * param.worldMieColorIntensity);
m_ProceduralSkyMaterial.SetInt("_AtmosphericsDebugMode", (int)param.debugMode);
}
void UpdateDynamicUniforms(BuiltinSkyParameters builtinParams, ProceduralSkyParameters param)
{
/* For now, we only use the directional light we are attached to, and the current camera. */
var trackedYaw = param.skyDomeTrackedYawRotation ? param.skyDomeTrackedYawRotation.eulerAngles.y : 0f;
m_ProceduralSkyMaterial.SetMatrix("_SkyDomeRotation",
Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(param.skyDomeRotation.x, 0f, 0f), Vector3.one)
* Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, param.skyDomeRotation.y - trackedYaw, 0f), Vector3.one)
* Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, param.skyDomeVerticalFlip ? -1f : 1f, 1f))
);
Vector3 sunDirection = (builtinParams.sunLight != null) ? -builtinParams.sunLight.transform.forward : Vector3.zero;
m_ProceduralSkyMaterial.SetVector("_SunDirection", sunDirection);
m_ProceduralSkyMaterial.SetFloat("_WorldMieDensity", -param.worldMieDensity / 100000f);
m_ProceduralSkyMaterial.SetFloat("_HeightMieDensity", -param.heightMieDensity / 100000f);
// TODO : We can't pass the camera in builtinParams because when SkyManager call RenderSky for rendering into a cubemap we don't have an actual Camera.
// Maybe pass the rect/viewport directly?
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);
m_ProceduralSkyMaterial.SetVector("_DepthTextureScaledTexelSize", depthTextureScaledTexelSize);
m_ProceduralSkyMaterial.SetMatrix("_InvViewProjMatrix", builtinParams.invViewProjMatrix);
}
override public void RenderSky(BuiltinSkyParameters builtinParams, SkyParameters skyParameters)
{
ProceduralSkyParameters proceduralSkyParams = GetParameters(skyParameters);
// Define select preprocessor symbols.
UpdateKeywords(true, proceduralSkyParams);
// Julien: what is it supposed to do?
if (proceduralSkyParams.depthTexture == ProceduralSkyParameters.DepthTexture.Disable)
{
// Disable depth texture rendering.
Camera.current.depthTextureMode = DepthTextureMode.None;
}
// Set shader constants.
UpdateStaticUniforms(proceduralSkyParams);
UpdateDynamicUniforms(builtinParams, proceduralSkyParams);
m_ProceduralSkyMaterial.SetTexture("_Cubemap", proceduralSkyParams.skyDomeCubemap);
m_ProceduralSkyMaterial.SetVector("_SkyParam", new Vector4(proceduralSkyParams.exposure, proceduralSkyParams.multiplier, proceduralSkyParams.rotation, 0.0f));
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(builtinParams.skyMesh, Matrix4x4.identity, m_ProceduralSkyMaterial);
builtinParams.renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/ProceduralSkyRenderer.cs.meta


fileFormatVersion: 2
guid: 476423447c1989948a128fc0a0b27413
timeCreated: 1481631774
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources.meta


fileFormatVersion: 2
guid: 455c6cbc5c8be404c8ed6ff8b38d1155
folderAsset: yes
timeCreated: 1481646141
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

/Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyHDRI.shader.meta → /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources/SkyHDRI.shader.meta

/Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl → /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/AtmosphericScattering.hlsl

/Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl.meta → /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/AtmosphericScattering.hlsl.meta

/Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyProcedural.shader.meta → /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader.meta

/Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyHDRI.shader → /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/HDRISky/Resources/SkyHDRI.shader

/Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyProcedural.shader → /Assets/ScriptableRenderLoop/HDRenderLoop/Sky/ProceduralSky/Resources/SkyProcedural.shader

正在加载...
取消
保存