浏览代码

Merge pull request #159 from Unity-Technologies/bloom-removal

Removed broken temporary bloom implementation
/Branch_Batching2
GitHub 8 年前
当前提交
4564bce6
共有 8 个文件被更改,包括 1 次插入482 次删除
  1. 48
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Editor/PostProcessingEditor.cs
  2. 17
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/PostProcessing.Settings.cs
  3. 151
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/PostProcessing.cs
  4. 26
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/FinalPass.shader
  5. 52
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/Bloom.hlsl
  6. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/Bloom.hlsl.meta
  7. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/Bloom.shader.meta
  8. 171
      Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/Bloom.shader

48
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Editor/PostProcessingEditor.cs


public SerializedProperty intensity;
public SerializedProperty smoothness;
}
public class BloomSettings
{
public SerializedProperty enabled;
public SerializedProperty intensity;
public SerializedProperty threshold;
public SerializedProperty softKnee;
public SerializedProperty radius;
public SerializedProperty lensTexture;
public SerializedProperty lensIntensity;
}
#endregion
public ColorGradingSettings colorGrading;

public BloomSettings bloomSettings;
public SerializedProperty globalDithering;
SerializedProperty FindProperty<TValue>(Expression<Func<PostProcessing, TValue>> expr)

smoothness = FindProperty(x => x.vignetteSettings.smoothness)
};
bloomSettings = new BloomSettings
{
enabled = FindProperty(x => x.bloomSettings.enabled),
intensity = FindProperty(x => x.bloomSettings.intensity),
threshold = FindProperty(x => x.bloomSettings.threshold),
softKnee = FindProperty(x => x.bloomSettings.softKnee),
radius = FindProperty(x => x.bloomSettings.radius),
lensTexture = FindProperty(x => x.bloomSettings.lensTexture),
lensIntensity = FindProperty(x => x.bloomSettings.lensIntensity)
};
globalDithering = FindProperty(x => x.globalDithering);
}

Do("Color Grading", ColorGradingUI);
Do("Eye Adaptation", EyeAdaptationUI);
Do("Bloom", BloomUI);
Do("Chromatic Aberration", ChromaticAberrationUI);
Do("Vignette", VignetteUI);

EditorGUILayout.PropertyField(eyeAdaptation.speedDown);
EditorGUI.indentLevel--;
}
}
}
void BloomUI()
{
EditorGUILayout.PropertyField(bloomSettings.enabled);
if (bloomSettings.enabled.boolValue)
{
EditorGUILayout.PropertyField(bloomSettings.intensity);
EditorGUILayout.PropertyField(bloomSettings.threshold);
EditorGUILayout.PropertyField(bloomSettings.softKnee);
EditorGUILayout.PropertyField(bloomSettings.radius);
EditorGUILayout.PropertyField(bloomSettings.lensTexture);
EditorGUILayout.PropertyField(bloomSettings.lensIntensity);
bloomSettings.intensity.floatValue = Mathf.Max(0f, bloomSettings.intensity.floatValue);
bloomSettings.threshold.floatValue = Mathf.Max(0f, bloomSettings.threshold.floatValue);
bloomSettings.lensIntensity.floatValue = Mathf.Max(0f, bloomSettings.lensIntensity.floatValue);
}
}

17
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/PostProcessing.Settings.cs


using System;
using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{

[Range(0f, 1f)] public float intensity = 0.3f;
[Range(0f, 1f)] public float smoothness = 0.3f;
}
[Serializable]
public sealed class BloomSettings
{
public bool enabled = false;
public float intensity = 0.5f;
public float threshold = 1.1f;
[Range(0f, 1f)] public float softKnee = 0.5f;
[Range(1f, 7f)] public float radius = 5f;
public Texture lensTexture;
public float lensIntensity = 3f;
}
}
}

151
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/PostProcessing.cs


[RequireComponent(typeof(Camera))]
public sealed partial class PostProcessing : MonoBehaviour
{
// Quick & very dirty temporary wrapper used for bloom (easy porting from old school render
// texture blitting to command buffers)
struct RenderTextureWrapper
{
static int s_Counter = 0;
public int id;
public RenderTargetIdentifier identifier;
public int width;
public int height;
public int depth;
public FilterMode filter;
public RenderTextureFormat format;
internal void Release(CommandBuffer cmd)
{
cmd.ReleaseTemporaryRT(id);
id = 0;
}
internal static RenderTextureWrapper Create(CommandBuffer cmd, int width, int height, int depth = 0, FilterMode filter = FilterMode.Bilinear, RenderTextureFormat format = RenderTextureFormat.DefaultHDR)
{
s_Counter++;
int id = Shader.PropertyToID("_TempRenderTexture_" + s_Counter);
cmd.GetTemporaryRT(id, width, height, depth, filter, format);
return new RenderTextureWrapper
{
id = id,
identifier = new RenderTargetIdentifier(id),
width = width,
height = height,
depth = depth,
filter = filter,
format = format
};
}
}
public BloomSettings bloomSettings = new BloomSettings();
Material m_BloomMaterial;
Material m_FinalPassMaterial;
ComputeShader m_EyeCompute;

static uint[] s_EmptyHistogramBuffer = new uint[k_HistogramBins];
const int k_MaxPyramidBlurLevel = 16;
readonly RenderTextureWrapper[] m_BlurBuffer1 = new RenderTextureWrapper[k_MaxPyramidBlurLevel];
readonly RenderTextureWrapper[] m_BlurBuffer2 = new RenderTextureWrapper[k_MaxPyramidBlurLevel];
RenderTextureWrapper m_BloomTex;
bool m_FirstFrame = true;
// Don't forget to update 'EyeAdaptation.cginc' if you change these values !

void OnEnable()
{
m_EyeAdaptationMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/EyeAdaptation");
m_BloomMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Bloom");
m_FinalPassMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/FinalPass");
m_EyeCompute = Resources.Load<ComputeShader>("EyeHistogram");

void OnDisable()
{
Utilities.Destroy(m_EyeAdaptationMaterial);
Utilities.Destroy(m_BloomMaterial);
Utilities.Destroy(m_FinalPassMaterial);
foreach (var rt in m_AutoExposurePool)

Utilities.SafeRelease(m_HistogramBuffer);
m_EyeAdaptationMaterial = null;
m_BloomMaterial = null;
m_FinalPassMaterial = null;
}

if (eyeAdaptation.enabled)
DoEyeAdaptation(camera, cmd, source);
if (bloomSettings.enabled)
DoBloom(camera, cmd, source);
if (chromaSettings.enabled)
DoChromaticAberration();

DoColorGrading();
cmd.Blit(source, destination, m_FinalPassMaterial, 0);
if (bloomSettings.enabled)
m_BloomTex.Release(cmd);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();

m_FirstFrame = false;
}
void DoBloom(Camera camera, CommandBuffer cmd, RenderTargetIdentifier source)
{
m_BloomMaterial.shaderKeywords = null;
// Apply auto exposure before the prefiltering pass if needed
if (eyeAdaptation.enabled)
{
m_BloomMaterial.EnableKeyword("EYE_ADAPTATION");
m_BloomMaterial.SetTexture(Uniforms._AutoExposure, m_CurrentAutoExposure);
}
// Do bloom on a half-res buffer, full-res doesn't bring much and kills performances on
// fillrate limited platforms
int tw = camera.pixelWidth / 2;
int th = camera.pixelHeight / 2;
// Determine the iteration count
float logh = Mathf.Log(th, 2f) + bloomSettings.radius - 8f;
int logh_i = (int)logh;
int iterations = Mathf.Clamp(logh_i, 1, k_MaxPyramidBlurLevel);
// Uupdate the shader properties
float lthresh = Mathf.GammaToLinearSpace(bloomSettings.threshold);;
m_BloomMaterial.SetFloat(Uniforms._Threshold, lthresh);
float knee = lthresh * bloomSettings.softKnee + 1e-5f;
var curve = new Vector3(lthresh - knee, knee * 2f, 0.25f / knee);
m_BloomMaterial.SetVector(Uniforms._Curve, curve);
float sampleScale = 0.5f + logh - logh_i;
m_BloomMaterial.SetFloat(Uniforms._SampleScale, sampleScale);
// Prefilter pass
var prefiltered = RenderTextureWrapper.Create(cmd, tw, th, 0, FilterMode.Point);
cmd.Blit(source, prefiltered.identifier, m_BloomMaterial, 0);
var last = prefiltered;
// Construct a mip pyramid
for (int level = 0; level < iterations; level++)
{
m_BlurBuffer1[level] = RenderTextureWrapper.Create(cmd, last.width / 2, last.height / 2);
cmd.Blit(last.identifier, m_BlurBuffer1[level].identifier, m_BloomMaterial, level == 0 ? 1 : 2);
last = m_BlurBuffer1[level];
}
// Upsample and combine loop
for (int level = iterations - 2; level >= 0; level--)
{
var baseTex = m_BlurBuffer1[level];
cmd.SetGlobalTexture(Uniforms._BaseTex, baseTex.identifier); // Boooo
m_BlurBuffer2[level] = RenderTextureWrapper.Create(cmd, baseTex.width, baseTex.height);
cmd.Blit(last.identifier, m_BlurBuffer2[level].identifier, m_BloomMaterial, 3);
last = m_BlurBuffer2[level];
}
m_BloomTex = last;
// Release the temporary buffers
for (int i = 0; i < k_MaxPyramidBlurLevel; i++)
{
if (m_BlurBuffer1[i].id != 0)
m_BlurBuffer1[i].Release(cmd);
if (m_BlurBuffer2[i].id != 0 && m_BlurBuffer2[i].id != m_BloomTex.id)
m_BlurBuffer2[i].Release(cmd);
}
prefiltered.Release(cmd);
// Push everything to the uber material
m_FinalPassMaterial.EnableKeyword("BLOOM");
cmd.SetGlobalTexture(Uniforms._BloomTex, m_BloomTex.identifier);
cmd.SetGlobalVector(Uniforms._Bloom_Settings, new Vector2(sampleScale, bloomSettings.intensity));
if (bloomSettings.lensIntensity > 0f && bloomSettings.lensTexture != null)
{
m_FinalPassMaterial.EnableKeyword("BLOOM_LENS_DIRT");
cmd.SetGlobalTexture(Uniforms._Bloom_DirtTex, bloomSettings.lensTexture);
cmd.SetGlobalFloat(Uniforms._Bloom_DirtIntensity, bloomSettings.lensIntensity);
}
}
void DoChromaticAberration()
{
var spectralLut = chromaSettings.spectralTexture == null

internal static readonly int _AutoExposure = Shader.PropertyToID("_AutoExposure");
internal static readonly int _DebugWidth = Shader.PropertyToID("_DebugWidth");
internal static readonly int _Threshold = Shader.PropertyToID("_Threshold");
internal static readonly int _Curve = Shader.PropertyToID("_Curve");
internal static readonly int _SampleScale = Shader.PropertyToID("_SampleScale");
internal static readonly int _BaseTex = Shader.PropertyToID("_BaseTex");
internal static readonly int _BloomTex = Shader.PropertyToID("_BloomTex");
internal static readonly int _Bloom_Settings = Shader.PropertyToID("_Bloom_Settings");
internal static readonly int _Bloom_DirtTex = Shader.PropertyToID("_Bloom_DirtTex");
internal static readonly int _Bloom_DirtIntensity = Shader.PropertyToID("_Bloom_DirtIntensity");
internal static readonly int _ChromaticAberration_Amount = Shader.PropertyToID("_ChromaticAberration_Amount");
internal static readonly int _ChromaticAberration_Lut = Shader.PropertyToID("_ChromaticAberration_Lut");

26
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/FinalPass.shader


#include "ShaderLibrary/Common.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "ColorGrading.hlsl"
#include "Bloom.hlsl"
TEXTURE2D(_MainTex);
SAMPLER2D(sampler_MainTex);

float4 _LogLut_Params;
float _Exposure;
TEXTURE2D(_BloomTex);
SAMPLER2D(sampler_BloomTex);
float4 _BloomTex_TexelSize;
float2 _Bloom_Settings; // x: sampleScale, y: bloom.intensity
TEXTURE2D(_Bloom_DirtTex);
SAMPLER2D(sampler_Bloom_DirtTex);
float _Bloom_DirtIntensity;
float4 _NeutralTonemapperParams1;
float4 _NeutralTonemapperParams2;

}
#endif
#if BLOOM
{
float3 bloom = UpsampleFilter(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), uv, _BloomTex_TexelSize.xy, _Bloom_Settings.x) * _Bloom_Settings.y; // Flipped
color += bloom;
#if BLOOM_LENS_DIRT
{
float3 dirt = SAMPLE_TEXTURE2D(_Bloom_DirtTex, sampler_Bloom_DirtTex, uv).rgb * _Bloom_DirtIntensity; // Flipped
color += bloom * dirt;
}
#endif
}
#endif
#if VIGNETTE
{
float2 d = abs(uv - _Vignette_Settings.zw) * _Vignette_Settings.x;

#pragma fragment Frag
#pragma multi_compile __ NEUTRAL_GRADING CUSTOM_GRADING
#pragma multi_compile __ EYE_ADAPTATION
#pragma multi_compile __ BLOOM
#pragma multi_compile __ BLOOM_LENS_DIRT
#pragma multi_compile __ CHROMATIC_ABERRATION
#pragma multi_compile __ VIGNETTE
#pragma multi_compile __ DITHERING

52
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/Bloom.hlsl


#ifndef UNITY_BLOOM
#define UNITY_BLOOM
// Downsample with a 4x4 box filter
float3 DownsampleFilter(TEXTURE2D_ARGS(tex, texSampler), float2 uv, float2 texelSize)
{
float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0);
float3 s;
s = SAMPLE_TEXTURE2D(tex, texSampler, uv + d.xy).rgb;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.zy).rgb;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.xw).rgb;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.zw).rgb;
return s * (1.0 / 4.0);
}
float3 UpsampleFilter(TEXTURE2D_ARGS(tex, texSampler), float2 uv, float2 texelSize, float sampleScale)
{
#if 0
// 4-tap bilinear upsampler
float4 d = texelSize.xyxy * float4(-1.0, -1.0, 1.0, 1.0) * (sampleScale * 0.5);
float3 s;
s = SAMPLE_TEXTURE2D(tex, texSampler, uv + d.xy).rgb;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.zy).rgb;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.xw).rgb;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.zw).rgb;
return s * (1.0 / 4.0);
#else
// 9-tap bilinear upsampler (tent filter)
float4 d = texelSize.xyxy * float4(1.0, 1.0, -1.0, 0.0) * sampleScale;
float3 s;
s = SAMPLE_TEXTURE2D(tex, texSampler, uv - d.xy).rgb;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv - d.wy).rgb * 2.0;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv - d.zy).rgb;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.zw).rgb * 2.0;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv).rgb * 4.0;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.xw).rgb * 2.0;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.zy).rgb;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.wy).rgb * 2.0;
s += SAMPLE_TEXTURE2D(tex, texSampler, uv + d.xy).rgb;
return s * (1.0 / 16.0);
#endif
}
#endif // UNITY_BLOOM

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/Bloom.hlsl.meta


fileFormatVersion: 2
guid: 41784642d71cc4a46acbaa1c81d71109
timeCreated: 1486047545
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/Bloom.shader.meta


fileFormatVersion: 2
guid: 0e58ecfc4bcd918478485f7b80aae431
timeCreated: 1486047504
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

171
Assets/ScriptableRenderPipeline/HDRenderPipeline/PostProcess/Resources/Bloom.shader


Shader "Hidden/HDRenderPipeline/Bloom"
{
Properties
{
_MainTex ("", 2D) = "" {}
_BaseTex ("", 2D) = "" {}
_AutoExposure ("", 2D) = "" {}
}
HLSLINCLUDE
#pragma target 4.5
#include "ShaderLibrary/Common.hlsl"
#include "HDRenderPipeline/ShaderVariables.hlsl"
#include "Bloom.hlsl"
TEXTURE2D(_MainTex);
SAMPLER2D(sampler_MainTex);
float4 _MainTex_TexelSize;
TEXTURE2D(_BaseTex);
SAMPLER2D(sampler_BaseTex);
float4 _BaseTex_TexelSize;
TEXTURE2D(_AutoExposure);
SAMPLER2D(sampler_AutoExposure);
float _Threshold;
float3 _Curve;
float _SampleScale;
struct Attributes
{
float3 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct Varyings
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
struct VaryingsMultitex
{
float4 vertex : SV_POSITION;
float2 texcoordMain : TEXCOORD0;
float2 texcoordBase : TEXCOORD1;
};
Varyings Vert(Attributes input)
{
Varyings output;
output.vertex = TransformWorldToHClip(input.vertex);
output.texcoord = input.texcoord.xy;
return output;
}
VaryingsMultitex VertMultitex(Attributes input)
{
VaryingsMultitex o;
o.vertex = TransformWorldToHClip(input.vertex);
o.texcoordMain = input.texcoord.xy;
o.texcoordBase = o.texcoordMain;
#if UNITY_UV_STARTS_AT_TOP
if (_BaseTex_TexelSize.y < 0.0)
o.texcoordMain.y = 1.0 - o.texcoordMain.y;
#endif
return o;
}
float4 FetchAutoExposed(TEXTURE2D_ARGS(tex, texSampler), float2 uv)
{
float autoExposure = 1.0;
#if EYE_ADAPTATION
autoExposure = SAMPLE_TEXTURE2D(_AutoExposure, sampler_AutoExposure, uv).r;
#endif
return SAMPLE_TEXTURE2D(tex, texSampler, uv) * autoExposure;
}
float4 FragPrefilter(Varyings i) : SV_Target
{
float2 uv = i.texcoord;
float4 s0 = min(65504.0, FetchAutoExposed(TEXTURE2D_PARAM(_MainTex, sampler_MainTex), uv));
float3 m = s0.rgb;
// Pixel brightness
float br = max(m.r, max(m.g, m.r));
// Under-threshold part: quadratic curve
float rq = clamp(br - _Curve.x, 0.0, _Curve.y);
rq = _Curve.z * rq * rq;
// Combine and apply the brightness response curve.
m *= max(rq, br - _Threshold) / max(br, 1e-5);
return float4(m, 0.0);
}
float4 FragDownsample1(Varyings i) : SV_Target
{
return float4(DownsampleFilter(TEXTURE2D_PARAM(_MainTex, sampler_MainTex), i.texcoord, _MainTex_TexelSize.xy), 0.0);
}
float4 FragDownsample2(Varyings i) : SV_Target
{
return float4(DownsampleFilter(TEXTURE2D_PARAM(_MainTex, sampler_MainTex), i.texcoord, _MainTex_TexelSize.xy), 0.0);
}
float4 FragUpsample(VaryingsMultitex i) : SV_Target
{
float3 base = SAMPLE_TEXTURE2D(_BaseTex, sampler_BaseTex, i.texcoordBase).rgb;
float3 blur = UpsampleFilter(TEXTURE2D_PARAM(_MainTex, sampler_MainTex), i.texcoordMain, _MainTex_TexelSize.xy, _SampleScale);
return float4(base + blur, 0.0);
}
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
HLSLPROGRAM
#pragma multi_compile __ EYE_ADAPTATION
#pragma vertex Vert
#pragma fragment FragPrefilter
ENDHLSL
}
Pass
{
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment FragDownsample1
ENDHLSL
}
Pass
{
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment FragDownsample2
ENDHLSL
}
Pass
{
HLSLPROGRAM
#pragma vertex VertMultitex
#pragma fragment FragUpsample
ENDHLSL
}
}
Fallback Off
}
正在加载...
取消
保存