浏览代码

Merge pull request #1776 from Unity-Technologies/LuxIntensityForHDRISky

Lux intensity for hdri sky
/main
GitHub 7 年前
当前提交
8b3692f4
共有 14 个文件被更改,包括 235 次插入23 次删除
  1. 1
      com.unity.render-pipelines.high-definition/CHANGELOG.md
  2. 1
      com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/HDAssetFactory.cs
  3. 85
      com.unity.render-pipelines.high-definition/HDRP/Editor/Sky/HDRISky/HDRISkyEditor.cs
  4. 10
      com.unity.render-pipelines.high-definition/HDRP/Editor/Sky/SkySettingsEditor.cs
  5. 1
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDStringConstants.cs
  6. 1
      com.unity.render-pipelines.high-definition/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset
  7. 1
      com.unity.render-pipelines.high-definition/HDRP/RenderPipelineResources/RenderPipelineResources.cs
  8. 2
      com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/HDRISky.shader
  9. 21
      com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/HDRISkyRenderer.cs
  10. 2
      com.unity.render-pipelines.high-definition/HDRP/Sky/SkyRenderingContext.cs
  11. 31
      com.unity.render-pipelines.high-definition/HDRP/Sky/SkySettings.cs
  12. 85
      com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/IntegrateHDRISky.shader
  13. 9
      com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/IntegrateHDRISky.shader.meta
  14. 8
      com.unity.render-pipelines.high-definition/HDRP/Sky/AtmosphericScattering.meta

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


- Added LightLayers support (Base on mask from renderers name RenderingLayers and mask from light name LightLayers - if they match, the light apply) - cost an extra GBuffer in deferred (more bandwidth)
- When LightLayers is enabled, the AmbientOclusion is store in the GBuffer in deferred path allowing to avoid double occlusion with SSAO. In forward the double occlusion is now always avoided.
- Added the possibility to add an override transform on the camera for volume interpolation
- Added desired lux intensity and auto multiplier for HDRI sky
### Fixed
- Fixed an issue with PreIntegratedFGD texture being sometimes destroyed and not regenerated causing rendering to break

1
com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/HDAssetFactory.cs


newAsset.GGXConvolve = Load<Shader>(HDRenderPipelinePath + "Material/GGXConvolution/GGXConvolve.shader");
newAsset.opaqueAtmosphericScattering = Load<Shader>(HDRenderPipelinePath + "Sky/OpaqueAtmosphericScattering.shader");
newAsset.hdriSky = Load<Shader>(HDRenderPipelinePath + "Sky/HDRISky/HDRISky.shader");
newAsset.integrateHdriSky = Load<Shader>(HDRenderPipelinePath + "Sky/HDRISky/IntegrateHDRISky.shader");
newAsset.proceduralSky = Load<Shader>(HDRenderPipelinePath + "Sky/ProceduralSky/ProceduralSky.shader");
// Skybox/Cubemap is a builtin shader, must use Sahder.Find to access it. It is fine because we are in the editor
newAsset.skyboxCubemap = Shader.Find("Skybox/Cubemap");

85
com.unity.render-pipelines.high-definition/HDRP/Editor/Sky/HDRISky/HDRISkyEditor.cs


using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline

: SkySettingsEditor
{
SerializedDataParameter m_hdriSky;
SerializedDataParameter m_DesiredLuxValue;
SerializedDataParameter m_IntensityMode;
SerializedDataParameter m_UpperHemisphereLuxValue;
RTHandleSystem.RTHandle m_IntensityTexture;
Material m_IntegrateHDRISkyMaterial; // Compute the HDRI sky intensity in lux for the skybox
Texture2D readBackTexture;
public override void OnEnable()
{

var o = new PropertyFetcher<HDRISky>(serializedObject);
m_hdriSky = Unpack(o.Find(x => x.hdriSky));
m_DesiredLuxValue = Unpack(o.Find(x => x.desiredLuxValue));
m_IntensityMode = Unpack(o.Find(x => x.skyIntensityMode));
m_UpperHemisphereLuxValue = Unpack(o.Find(x => x.upperHemisphereLuxValue));
m_IntensityTexture = RTHandles.Alloc(1, 1, colorFormat: RenderTextureFormat.ARGBFloat, sRGB: false);
var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
m_IntegrateHDRISkyMaterial = CoreUtils.CreateEngineMaterial(hdrp.renderPipelineResources.integrateHdriSky);
readBackTexture = new Texture2D(1, 1, TextureFormat.RGBAFloat, false, false);
}
public override void OnDisable()
{
if (m_IntensityTexture != null)
RTHandles.Release(m_IntensityTexture);
readBackTexture = null;
}
// Compute the lux value in the upper hemisphere of the HDRI skybox
public void GetUpperHemisphereLuxValue()
{
Cubemap hdri = m_hdriSky.value.objectReferenceValue as Cubemap;
if (hdri == null)
return;
float omegaP = (Mathf.PI * 4) / (6.0f * hdri.width * hdri.width);
m_IntegrateHDRISkyMaterial.SetTexture(HDShaderIDs._Cubemap, hdri);
m_IntegrateHDRISkyMaterial.SetFloat(HDShaderIDs._InvOmegaP, 1.0f / omegaP);
Graphics.Blit(Texture2D.whiteTexture, m_IntensityTexture.rt, m_IntegrateHDRISkyMaterial);
// Copy the rendertexture containing the lux value inside a Texture2D
RenderTexture.active = m_IntensityTexture.rt;
readBackTexture.ReadPixels(new Rect(0.0f, 0.0f, 1, 1), 0, 0);
RenderTexture.active = null;
// And then the value inside this texture
Color hdriIntensity = readBackTexture.GetPixel(0, 0);
m_UpperHemisphereLuxValue.value.floatValue = hdriIntensity.r;
PropertyField(m_hdriSky);
EditorGUI.BeginChangeCheck();
{
PropertyField(m_hdriSky);
EditorGUILayout.Space();
PropertyField(m_IntensityMode);
}
if (EditorGUI.EndChangeCheck())
{
GetUpperHemisphereLuxValue();
}
EditorGUILayout.Space();
if (m_IntensityMode.value.enumValueIndex == (int)SkyIntensityMode.Lux)
{
EditorGUI.indentLevel++;
PropertyField(m_DesiredLuxValue);
// Hide exposure and multiplier
m_CommonUIElementsMask &= ~(uint)(SkySettingsUIElement.Exposure | SkySettingsUIElement.Multiplier);
m_CommonUIElementsMask |= (uint)SkySettingsUIElement.IndentExposureAndMultiplier;
// Show the multiplier as read-only
EditorGUI.BeginDisabledGroup(true);
PropertyField(m_UpperHemisphereLuxValue);
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel--;
}
else
{
m_CommonUIElementsMask |= (uint)(SkySettingsUIElement.Exposure | SkySettingsUIElement.Multiplier);
}
}
}

10
com.unity.render-pipelines.high-definition/HDRP/Editor/Sky/SkySettingsEditor.cs


Multiplier = 1 << 1,
Rotation = 1 << 2,
UpdateMode = 1 << 3,
IncludeSunInBaking = 1 << 4
IncludeSunInBaking = 1 << 4,
IndentExposureAndMultiplier = 1 << 5,
}
SerializedDataParameter m_SkyExposure;

protected void CommonSkySettingsGUI()
{
if ((m_CommonUIElementsMask & (uint)SkySettingsUIElement.IndentExposureAndMultiplier) != 0)
EditorGUI.indentLevel++;
if ((m_CommonUIElementsMask & (uint)SkySettingsUIElement.IndentExposureAndMultiplier) != 0)
EditorGUI.indentLevel--;
if ((m_CommonUIElementsMask & (uint)SkySettingsUIElement.Rotation) != 0)
PropertyField(m_SkyRotation);

PropertyField(m_IncludeSunInBaking);
}
}
}
}

1
com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDStringConstants.cs


public static readonly int _ThicknessRemap = Shader.PropertyToID("_ThicknessRemap");
public static readonly int _Cubemap = Shader.PropertyToID("_Cubemap");
public static readonly int _InvOmegaP = Shader.PropertyToID("_InvOmegaP");
public static readonly int _SkyParam = Shader.PropertyToID("_SkyParam");
public static readonly int _PixelCoordToViewDirWS = Shader.PropertyToID("_PixelCoordToViewDirWS");

1
com.unity.render-pipelines.high-definition/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset


GGXConvolve: {fileID: 4800000, guid: 123ed592ad5c2494b8aed301fd609e7b, type: 3}
opaqueAtmosphericScattering: {fileID: 4800000, guid: 32f724728cf19904291226f239ec16f0, type: 3}
hdriSky: {fileID: 4800000, guid: 9bd32a6ece529fd4f9408b8d7e00c10d, type: 3}
integrateHdriSky: {fileID: 4800000, guid: 48db2705cf2856d4e893eb30a6892d1b, type: 3}
proceduralSky: {fileID: 4800000, guid: ec63f47fd265df243a7b1d40f9ef7fe7, type: 3}
skyboxCubemap: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
preIntegratedFGD_GGXDisneyDiffuse: {fileID: 4800000, guid: 123f13d52852ef547b2962de4bd9eaad, type: 3}

1
com.unity.render-pipelines.high-definition/HDRP/RenderPipelineResources/RenderPipelineResources.cs


public Shader GGXConvolve;
public Shader opaqueAtmosphericScattering;
public Shader hdriSky;
public Shader integrateHdriSky;
public Shader proceduralSky;
public Shader skyboxCubemap;

2
com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/HDRISky.shader


}
Fallback Off
}
}

21
com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/HDRISkyRenderer.cs


HDUtils.SetRenderTarget(builtinParams.commandBuffer, builtinParams.hdCamera, builtinParams.colorBuffer, builtinParams.depthBuffer);
}
}
float luxMultiplier = m_HdriSkyParams.desiredLuxValue.value / m_HdriSkyParams.upperHemisphereLuxValue.value;
float multiplier = (m_HdriSkyParams.skyIntensityMode == SkyIntensityMode.Exposure) ? m_HdriSkyParams.multiplier.value : luxMultiplier;
float exposure = (m_HdriSkyParams.skyIntensityMode == SkyIntensityMode.Exposure) ? GetExposure(m_HdriSkyParams, builtinParams.debugSettings) : 0;
m_SkyHDRIMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(GetExposure(m_HdriSkyParams, builtinParams.debugSettings), m_HdriSkyParams.multiplier, -m_HdriSkyParams.rotation, 0.0f)); // -rotation to match Legacy...
m_SkyHDRIMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(exposure, multiplier, -m_HdriSkyParams.rotation, 0.0f)); // -rotation to match Legacy...
// This matrix needs to be updated at the draw call frequency.
m_PropertyBlock.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, builtinParams.pixelCoordToViewDirMatrix);
CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_SkyHDRIMaterial, m_PropertyBlock, renderForCubemap ? 0 : 1);
using (new ProfilingSample(builtinParams.commandBuffer, "Draw sky"))
{
// This matrix needs to be updated at the draw call frequency.
m_PropertyBlock.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, builtinParams.pixelCoordToViewDirMatrix);
CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_SkyHDRIMaterial, m_PropertyBlock, renderForCubemap ? 0 : 1);
}
}
public override bool IsValid()

}
}
}

2
com.unity.render-pipelines.high-definition/HDRP/Sky/SkyRenderingContext.cs


}
}
}
}
}

31
com.unity.render-pipelines.high-definition/HDRP/Sky/SkySettings.cs


: base(value, overrideState) {}
}
public enum SkyIntensityMode
{
Exposure,
Lux,
}
[System.Flags]
public enum SkySettingsPropertyFlags
{
ShowMultiplierAndEV = (1 << 0),
ShowRotation = (1 << 1),
ShowUpdateMode = (1 << 2),
}
[Serializable, DebuggerDisplay(k_DebuggerDisplay)]
public sealed class SkyIntensityParameter : VolumeParameter<SkyIntensityMode>
{
public SkyIntensityParameter(SkyIntensityMode value, bool overrideState = false)
: base(value, overrideState) {}
}
[Tooltip("Sky intensity mode")]
public SkyIntensityParameter skyIntensityMode = new SkyIntensityParameter(SkyIntensityMode.Exposure);
[Tooltip("Auto multiplier from the HDRI sky")]
public MinFloatParameter upperHemisphereLuxValue = new MinFloatParameter(1.0f, 0.0f);
[Tooltip("Lux intensity multiplier for the sky")]
public FloatParameter desiredLuxValue = new FloatParameter(20000);
[Tooltip("Specify how the environment lighting should be updated.")]
public EnvUpdateParameter updateMode = new EnvUpdateParameter(EnvironementUpdateMode.OnChanged);
[Tooltip("If environment update is set to realtime, period in seconds at which it is updated (0.0 means every frame).")]

hash = hash * 23 + rotation.GetHashCode();
hash = hash * 23 + exposure.GetHashCode();
hash = hash * 23 + multiplier.GetHashCode();
hash = hash * 23 + desiredLuxValue.GetHashCode();
hash = hash * 23 + ((int)skyIntensityMode.value).GetHashCode();
//<<<
hash = hash * 23 + updatePeriod.GetHashCode();

public abstract SkyRenderer CreateRenderer();
}
}
}

85
com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/IntegrateHDRISky.shader


Shader "Hidden/HDRenderPipeline/IntegrateHDRI"
{
Properties
{
[HideInInspector]
_Cubemap ("", CUBE) = "white" {}
_InvOmegaP ("", Float) = 0
}
SubShader
{
Tags{ "RenderPipeline" = "HDRenderPipeline" }
Pass
{
ZTest Always Cull Off ZWrite Off
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#pragma target 4.5
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "CoreRP/ShaderLibrary/Color.hlsl"
#include "CoreRP/ShaderLibrary/ImageBasedLighting.hlsl"
#include "../../ShaderVariables.hlsl"
struct Attributes
{
uint vertexID : SV_VertexID;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 texCoord : TEXCOORD0;
};
TextureCube<float4> _Cubemap;
float _InvOmegaP;
Varyings Vert(Attributes input)
{
Varyings output;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
output.texCoord = GetFullScreenTriangleTexCoord(input.vertexID);
return output;
}
// Spherical integration of the upper hemisphere
real GetUpperHemisphereLuxValue(TEXTURECUBE_ARGS(skybox, sampler_skybox), real3 N)
{
float sum = 0.0;
float dphi = 0.005;
float dtheta = 0.005;
for (float phi = 0; phi < 2.0 * PI; phi += dphi)
{
for (float theta = 0; theta < PI / 2.0; theta += dtheta)
{
float3 L = TransformGLtoDX(SphericalToCartesian(phi, cos(theta)));
real val = Luminance(SAMPLE_TEXTURECUBE_LOD(skybox, sampler_skybox, L, 0).rgb);
sum += cos(theta) * sin(theta) * val;
}
}
sum *= dphi * dtheta;
return sum;
}
float4 Frag(Varyings input) : SV_Target
{
float3 N = float3(0.0, 1.0, 0.0);
float intensity = GetUpperHemisphereLuxValue(TEXTURECUBE_PARAM(_Cubemap, s_trilinear_clamp_sampler), N);
return float4(intensity, 1.0, 1.0, 1.0);
}
ENDHLSL
}
}
Fallback Off
}

9
com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/IntegrateHDRISky.shader.meta


fileFormatVersion: 2
guid: 48db2705cf2856d4e893eb30a6892d1b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

8
com.unity.render-pipelines.high-definition/HDRP/Sky/AtmosphericScattering.meta


fileFormatVersion: 2
guid: d522828bc0314e14cb6faa4291bb64da
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存