浏览代码

HDRenderLoop: Add tonemapper and exposure control

/main
sebastienlagarde 8 年前
当前提交
e26a36cb
共有 3 个文件被更改,包括 108 次插入1 次删除
  1. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset
  2. 23
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  3. 84
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess/FinalPass.shader

2
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset


m_Script: {fileID: 11500000, guid: 558064ecdbf6b6742892d699acb39aed, type: 3}
m_Name: HDRenderLoop
m_EditorClassIdentifier:
enableTonemap: 0
exposure: 0

23
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


public const int MaxLights = 32;
public bool enableTonemap = true;
public float exposure = 0;
//[SerializeField]
//ShadowSettings m_ShadowSettings = ShadowSettings.Default;
//ShadowRenderPass m_ShadowPass;

void FinalPass(RenderLoop renderLoop)
{
// Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that
const float BlackIn = 0.02f;
const float WhiteIn = 10.0f;
const float BlackOut = 0.0f;
const float WhiteOut = 10.0f;
const float WhiteLevel = 5.3f;
const float WhiteClip = 10.0f;
const float DialUnits = 20.0f;
const float HalfDialUnits = DialUnits * 0.5f;
// converting from artist dial units to easy shader-lerps (0-1)
Vector4 tonemapCoeff1 = new Vector4((BlackIn * DialUnits) + 1.0f, (BlackOut * HalfDialUnits) + 1.0f, (WhiteIn / DialUnits), (1.0f - (WhiteOut / DialUnits)));
Vector4 tonemapCoeff2 = new Vector4(0.0f, 0.0f, WhiteLevel, WhiteClip / HalfDialUnits);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs1", tonemapCoeff1);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs2", tonemapCoeff2);
m_FinalPassMaterial.SetFloat("_EnableToneMap", enableTonemap ? 1.0f : 0.0f);
m_FinalPassMaterial.SetFloat("_Exposure", exposure);
CommandBuffer cmd = new CommandBuffer();
cmd.name = "FinalPass";
// Resolve our HDR texture to CameraTarget.

84
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/PostProcess/FinalPass.shader


// Final compositing pass, just does gamma correction for now.
Shader "Hidden/Unity/FinalPass"
{
Properties { _MainTex ("Texture", any) = "" {} }
Properties
{
_MainTex ("Texture", any) = "" {}
_ToneMapCoeffs1("Parameters for neutral tonemap", Vector) = (0.0, 0.0, 0.0, 0.0)
_ToneMapCoeffs2("Parameters for neutral tonemap", Vector) = (0.0, 0.0, 0.0, 0.0)
_Exposure("Exposure", Range(-32.0, 32.0)) = 0
}
SubShader {
Pass {
ZTest Always Cull Off ZWrite Off

#include "../ShaderVariables.hlsl"
sampler2D _MainTex;
float4 _ToneMapCoeffs1;
float4 _ToneMapCoeffs2;
#define InBlack _ToneMapCoeffs1.x
#define OutBlack _ToneMapCoeffs1.y
#define InWhite _ToneMapCoeffs1.z
#define OutWhite _ToneMapCoeffs1.w
#define WhiteLevel _ToneMapCoeffs2.z
#define WhiteClip _ToneMapCoeffs2.w
float _Exposure;
float _EnableToneMap;
struct Attributes {
float3 vertex : POSITION;

return output;
}
float3 evalCurve(float3 x, float A, float B, float C, float D, float E, float F)
{
return ((x*(A*x + C*B) + D*E) / (x*(A*x + B) + D*F)) - E / F;
}
float3 applyTonemapFilmicAD(float3 linearColor)
{
float blackRatio = InBlack / OutBlack;
float whiteRatio = InWhite / OutWhite;
// blend tunable coefficients
float B = lerp(0.57, 0.37, blackRatio);
float C = lerp(0.01, 0.24, whiteRatio);
float D = lerp(0.02, 0.20, blackRatio);
// constants
float A = 0.2;
float E = 0.02;
float F = 0.30;
// eval and correct for white point
float3 whiteScale = 1.0f / evalCurve(WhiteLevel, A, B, C, D, E, F);
float3 curr = evalCurve(linearColor * whiteScale, A, B, C, D, E, F);
return curr * whiteScale;
}
float3 remapWhite(float3 inPixel, float whitePt)
{
// var breakout for readability
const float inBlack = 0;
const float outBlack = 0;
float inWhite = whitePt;
const float outWhite = 1;
// remap input range to output range
float3 outPixel = ((inPixel.rgb) - inBlack.xxx) / (inWhite.xxx - inBlack.xxx) * (outWhite.xxx - outBlack.xxx) + outBlack.xxx;
return (outPixel.rgb);
}
float3 NeutralTonemap(float3 x)
{
float3 finalColor = applyTonemapFilmicAD(x); // curve (dynamic coeffs differ per level)
finalColor = remapWhite(finalColor, WhiteClip); // post-curve white point adjustment
finalColor = saturate(finalColor);
return finalColor;
}
float3 ApplyToneMap(float3 color)
{
if (_EnableToneMap > 0.0)
{
return NeutralTonemap(color);
}
else
{
return saturate(color);
}
}
float4 Frag(Varyings input) : SV_Target
{
float4 c = tex2D(_MainTex, input.texcoord);

// So we must not correct the sRGB here else it will be done two time.
// To fix!
c.rgb = ApplyToneMap(c.rgb * pow(2.0, _Exposure));
// return LinearToSRGB(c);
return c;

正在加载...
取消
保存