浏览代码

Add lux unit for HDRI sky

/main
Antoine Lelievre 6 年前
当前提交
7ba755b2
共有 14 个文件被更改,包括 226 次插入22 次删除
  1. 1
      com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/HDAssetFactory.cs
  2. 19
      com.unity.render-pipelines.high-definition/HDRP/Editor/Sky/HDRISky/HDRISkyEditor.cs
  3. 4
      com.unity.render-pipelines.high-definition/HDRP/Editor/Sky/ProceduralSky/ProceduralSkyEditor.cs
  4. 29
      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. 8
      com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/HDRISky.shader
  9. 44
      com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/HDRISkyRenderer.cs
  10. 2
      com.unity.render-pipelines.high-definition/HDRP/Sky/SkyRenderer.cs
  11. 8
      com.unity.render-pipelines.high-definition/HDRP/Sky/SkyRenderingContext.cs
  12. 32
      com.unity.render-pipelines.high-definition/HDRP/Sky/SkySettings.cs
  13. 89
      com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/IntegrateHDRISky.shader
  14. 9
      com.unity.render-pipelines.high-definition/HDRP/Sky/HDRISky/IntegrateHDRISky.shader.meta

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");

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


: SkySettingsEditor
{
SerializedDataParameter m_hdriSky;
SerializedDataParameter m_Lux;
SerializedDataParameter m_IntensityMode;
public override void OnEnable()
{

m_hdriSky = Unpack(o.Find(x => x.hdriSky));
m_Lux = Unpack(o.Find(x => x.lux));
m_IntensityMode = Unpack(o.Find(x => x.skyIntensityMode));
}
public override void OnInspectorGUI()

EditorGUILayout.Space();
PropertyField(m_IntensityMode);
if (m_IntensityMode.value.enumValueIndex == (int)SkyIntensityMode.Lux)
{
// Hide EV and Multiplier fields
m_ShowProperties.value.intValue &= ~(int)SkySettingsPropertyFlags.ShowMultiplierAndEV;
PropertyField(m_Lux);
}
else
{
m_ShowProperties.value.intValue |= (int)SkySettingsPropertyFlags.ShowMultiplierAndEV;
}
}
}

4
com.unity.render-pipelines.high-definition/HDRP/Editor/Sky/ProceduralSky/ProceduralSkyEditor.cs


EditorGUILayout.Space();
base.CommonSkySettingsGUI(false);
m_ShowProperties.value.intValue &= ~(int)SkySettingsPropertyFlags.ShowRotation;
base.CommonSkySettingsGUI();
}
}
}

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


SerializedDataParameter m_SkyRotation;
SerializedDataParameter m_EnvUpdateMode;
SerializedDataParameter m_EnvUpdatePeriod;
protected SerializedDataParameter m_ShowProperties;
m_ShowProperties = Unpack(o.Find(x => x.showProperties));
m_SkyExposure = Unpack(o.Find(x => x.exposure));
m_SkyMultiplier = Unpack(o.Find(x => x.multiplier));
m_SkyRotation = Unpack(o.Find(x => x.rotation));

protected void CommonSkySettingsGUI(bool enableRotation = true)
protected void CommonSkySettingsGUI()
PropertyField(m_SkyExposure);
PropertyField(m_SkyMultiplier);
if (enableRotation)
if ((m_ShowProperties.value.intValue & (int)SkySettingsPropertyFlags.ShowMultiplierAndEV) != 0)
{
PropertyField(m_SkyExposure);
PropertyField(m_SkyMultiplier);
}
if ((m_ShowProperties.value.intValue & (int)SkySettingsPropertyFlags.ShowRotation) != 0)
PropertyField(m_EnvUpdateMode);
if (!m_EnvUpdateMode.value.hasMultipleDifferentValues && m_EnvUpdateMode.value.intValue == (int)EnvironementUpdateMode.Realtime)
if ((m_ShowProperties.value.intValue & (int)SkySettingsPropertyFlags.ShowUpdateMode) != 0)
EditorGUI.indentLevel++;
PropertyField(m_EnvUpdatePeriod);
EditorGUI.indentLevel--;
PropertyField(m_EnvUpdateMode);
if (!m_EnvUpdateMode.value.hasMultipleDifferentValues && m_EnvUpdateMode.value.intValue == (int)EnvironementUpdateMode.Realtime)
{
EditorGUI.indentLevel++;
PropertyField(m_EnvUpdatePeriod);
EditorGUI.indentLevel--;
}
}
}

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


public static readonly int _Cubemap = Shader.PropertyToID("_Cubemap");
public static readonly int _SkyParam = Shader.PropertyToID("_SkyParam");
public static readonly int _SkyIntensity = Shader.PropertyToID("_SkyIntensity");
public static readonly int _PixelCoordToViewDirWS = Shader.PropertyToID("_PixelCoordToViewDirWS");
public static readonly int _Size = Shader.PropertyToID("_Size");

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;

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


TEXTURECUBE(_Cubemap);
SAMPLER(sampler_Cubemap);
TEXTURE2D(_SkyIntensity);
SAMPLER(sampler_SkyIntensity);
float4 _SkyParam; // x exposure, y multiplier, z rotation
float4x4 _PixelCoordToViewDirWS; // Actually just 3x3, but Unity can only set 4x4

float3 rotDirY = float3(sinPhi, 0, cosPhi);
dir = float3(dot(rotDirX, dir), dir.y, dot(rotDirY, dir));
float3 skyColor = ClampToFloat16Max(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0).rgb * exp2(_SkyParam.x) * _SkyParam.y);
float intensity = _SkyParam.w / SAMPLE_TEXTURE2D_LOD(_SkyIntensity, sampler_SkyIntensity, float2(.5, .5), 0).x;
float3 skyColor = ClampToFloat16Max(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0).rgb * exp2(_SkyParam.x) * _SkyParam.y * intensity);
return float4(skyColor, 1.0);
}

}
Fallback Off
}
}

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


public class HDRISkyRenderer : SkyRenderer
{
Material m_SkyHDRIMaterial; // Renders a cubemap into a render texture (can be cube or 2D)
Material m_IntegrateHDRISkyMaterial; // Compute the HDRI sky intensity in lux for the skybox
RTHandleSystem.RTHandle m_IntensityTexture;
m_IntensityTexture = RTHandles.Alloc(1, 1, colorFormat: RenderTextureFormat.RFloat, sRGB: false);
}
public override void Build()

m_IntegrateHDRISkyMaterial = CoreUtils.CreateEngineMaterial(hdrp.renderPipelineResources.integrateHdriSky);
}
public override void Cleanup()

HDUtils.SetRenderTarget(builtinParams.commandBuffer, builtinParams.hdCamera, builtinParams.colorBuffer, builtinParams.depthBuffer);
}
}
public override void UpdateSky(BuiltinSkyParameters builtinParams)
{
using (new ProfilingSample(builtinParams.commandBuffer, "Get hdri skybox intensity"))
{
if (m_HdriSkyParams.updateHDRISkyIntensity)
{
m_IntegrateHDRISkyMaterial.SetTexture(HDShaderIDs._Cubemap, m_HdriSkyParams.hdriSky);
CoreUtils.SetRenderTarget(builtinParams.commandBuffer, m_IntensityTexture, ClearFlag.None);
CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_IntegrateHDRISkyMaterial);
m_HdriSkyParams.updateHDRISkyIntensity.value = false;
}
}
}
m_SkyHDRIMaterial.SetTexture(HDShaderIDs._Cubemap, m_HdriSkyParams.hdriSky);
m_SkyHDRIMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(GetExposure(m_HdriSkyParams, builtinParams.debugSettings), m_HdriSkyParams.multiplier, -m_HdriSkyParams.rotation, 0.0f)); // -rotation to match Legacy...
float lux = (m_HdriSkyParams.skyIntensityMode == SkyIntensityMode.Lux) ? m_HdriSkyParams.lux.value : 1;
float multiplier = (m_HdriSkyParams.skyIntensityMode == SkyIntensityMode.Exposure) ? m_HdriSkyParams.multiplier.value : 1;
float exposure = (m_HdriSkyParams.skyIntensityMode == SkyIntensityMode.Exposure) ? GetExposure(m_HdriSkyParams, builtinParams.debugSettings) : 0;
// This matrix needs to be updated at the draw call frequency.
m_PropertyBlock.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, builtinParams.pixelCoordToViewDirMatrix);
m_SkyHDRIMaterial.SetTexture(HDShaderIDs._Cubemap, m_HdriSkyParams.hdriSky);
m_SkyHDRIMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(exposure, multiplier, -m_HdriSkyParams.rotation, lux)); // -rotation to match Legacy...
CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_SkyHDRIMaterial, m_PropertyBlock, renderForCubemap ? 0 : 1);
using (new ProfilingSample(builtinParams.commandBuffer, "Draw sky"))
{
// Bind a white texture if the intensity mode isn't lux so we sample an intensity of 1
if (m_HdriSkyParams.skyIntensityMode == SkyIntensityMode.Lux)
m_SkyHDRIMaterial.SetTexture(HDShaderIDs._SkyIntensity, m_IntensityTexture);
else
m_SkyHDRIMaterial.SetTexture(HDShaderIDs._SkyIntensity, Texture2D.whiteTexture);
// 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/SkyRenderer.cs


public abstract void RenderSky(BuiltinSkyParameters builtinParams, bool renderForCubemap);
public abstract bool IsValid();
public virtual void UpdateSky(BuiltinSkyParameters builtinParams) {}
protected float GetExposure(SkySettings skySettings, DebugDisplaySettings debugSettings)
{
float debugExposure = 0.0f;

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


m_BuiltinParameters.colorBuffer = m_SkyboxCubemapRT;
m_BuiltinParameters.depthBuffer = null;
m_BuiltinParameters.hdCamera = null;
skyContext.renderer.UpdateSky(m_BuiltinParameters);
CoreUtils.SetRenderTarget(m_BuiltinParameters.commandBuffer, m_SkyboxCubemapRT, ClearFlag.None, 0, (CubemapFace)i);
skyContext.renderer.RenderSky(m_BuiltinParameters, true);

{
using (new ProfilingSample(cmd, "Sky Environment Pass"))
{
skyContext.skySettings.updateHDRISkyIntensity.value = true;
using (new ProfilingSample(cmd, "Update Env: Generate Lighting Cubemap"))
{
RenderSkyToCubemap(skyContext);

m_BuiltinParameters.hdCamera = hdCamera;
m_BuiltinParameters.debugSettings = debugSettings;
skyContext.renderer.UpdateSky(m_BuiltinParameters);
skyContext.renderer.SetRenderTargets(m_BuiltinParameters);
skyContext.renderer.RenderSky(m_BuiltinParameters, false);
}

}
}

32
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("Lux intensity multiplier for the sky")]
public FloatParameter lux = new FloatParameter(20000);
// Display all fields by default
public IntParameter showProperties = new IntParameter(~0);
public BoolParameter updateHDRISkyIntensity = new BoolParameter(false);
// Unused for now. In the future we might want to expose this option for very high range skies.
bool m_useMIS = false;

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

public abstract SkyRenderer CreateRenderer();
}
}
}

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


Shader "Hidden/HDRenderPipeline/IntegrateHDRI"
{
Properties
{
[HideInInspector]
_Cubemap ("", CUBE) = "white" {}
}
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;
Varyings Vert(Attributes input)
{
Varyings output;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
output.texCoord = GetFullScreenTriangleTexCoord(input.vertexID);
return output;
}
real IntegrateHDRISky(TEXTURECUBE_ARGS(skybox, sampler_skybox), real3 N, uint sampleCount = 8192)
{
real acc = 0.0;
// Add some jittering on Hammersley2d
real2 randNum = InitRandom(0.5);
real3x3 localToWorld = GetLocalFrame(N);
for (uint i = 0; i < sampleCount; ++i)
{
real2 u = frac(randNum + Hammersley2d(i, sampleCount));
real NdotL;
real weightOverPdf;
real3 L;
ImportanceSampleLambert(u, localToWorld, L, NdotL, weightOverPdf);
real val = Luminance(SAMPLE_TEXTURECUBE_LOD(skybox, sampler_skybox, L, 0).rgb);
acc += NdotL * val;
}
return acc / sampleCount;
}
float4 Frag(Varyings input) : SV_Target
{
float3 N = float3(0.0, 0.0, 1.0);
float intensity = IntegrateHDRISky(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:
正在加载...
取消
保存