UnityShader屏幕后处理-Bloom效果(朦胧模糊)
2018-03-01 16:35
656 查看
原理:1 取出图片中比较亮(饱和度比较高、远离灰色)的一部分图
2 对1中的图进行高斯模糊的到新的图
3 将2中的图与原图色彩相加
1 取出图片中比较亮的的区域
C#
shader
2 对1中的图进行高斯模糊
C#
shader
参考上一篇博客高斯模糊
3 将2的到的RenderTexture与原图颜色相加
C#
shader
里面使用UNITY_UV_STARTS_AT_TOP来判断是否是DX平台并且开启了抗锯齿效果(Edit-ProjectSetting-Quality-AntiAliasing)….然而我还没遇到过。。。
4代码
Bloom.cs
PostEffectsBase.cs
Bloom.shader
2 对1中的图进行高斯模糊的到新的图
3 将2中的图与原图色彩相加
1 取出图片中比较亮的的区域
C#
material.SetFloat("_LuminanceThreshold", luminanceThreshold); int rtW = src.width/downSample; int rtH = src.height/downSample; RenderTexture buffer0 = RenderTexture.GetTemporary(rtW, rtH, 0); buffer0.filterMode = FilterMode.Bilinear; Graphics.Blit(src, buffer0, material, 0);
shader
v2f vertExtractBright(appdata_img v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } fixed luminance(fixed4 color) { return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b; } fixed4 fragExtractBright(v2f i) : SV_Target { fixed4 c = tex2D(_MainTex, i.uv); fixed val = clamp(luminance(c) - _LuminanceThreshold, 0.0, 1.0); return c * val; }
2 对1中的图进行高斯模糊
C#
for (int i = 0; i < iterations; i++) { material.SetFloat("_BlurSize", 1.0f + i * blurSpread); RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0); // Render the vertical pass Graphics.Blit(buffer0, buffer1, material, 1); RenderTexture.ReleaseTemporary(buffer0); buffer0 = buffer1; buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0); // Render the horizontal pass Graphics.Blit(buffer0, buffer1, material, 2); RenderTexture.ReleaseTemporary(buffer0); buffer0 = buffer1; }
shader
参考上一篇博客高斯模糊
3 将2的到的RenderTexture与原图颜色相加
C#
material.SetTexture ("_Bloom", buffer0); Graphics.Blit (src, dest, material, 3);
shader
v2fBloom vertBloom(appdata_img v) { v2fBloom o; o.pos = UnityObjectToClipPos (v.vertex); o.uv.xy = v.texcoord; o.uv.zw = v.texcoord; #if UNITY_UV_STARTS_AT_TOP if (_MainTex_TexelSize.y < 0.0) o.uv.w = 1.0 - o.uv.w; #endif return o; } fixed4 fragBloom(v2fBloom i) : SV_Target { return tex2D(_MainTex, i.uv.xy) + tex2D(_Bloom, i.uv.zw); }
里面使用UNITY_UV_STARTS_AT_TOP来判断是否是DX平台并且开启了抗锯齿效果(Edit-ProjectSetting-Quality-AntiAliasing)….然而我还没遇到过。。。
4代码
Bloom.cs
using UnityEngine;
using System.Collections;
public class Bloom : PostEffectsBase {
public Shader bloomShader;
private Material bloomMaterial = null;
public Material material {
get {
bloomMaterial = CheckShaderAndCreateMaterial(bloomShader, bloomMaterial);
return bloomMaterial;
}
}
// Blur iterations - larger number means more blur.
[Range(0, 4)]
public int iterations = 3;
// Blur spread for each iteration - larger value means more blur
[Range(0f, 3.0f)]
public float blurSpread = 0.6f;
[Range(1, 8)]
public int downSample = 2;
[Range(0.0f, 4.0f)]
public float luminanceThreshold = 0.6f;
void OnRenderImage (RenderTexture src, RenderTexture dest) {
if (material != null) {
material.SetFloat("_LuminanceThreshold", luminanceThreshold); int rtW = src.width/downSample; int rtH = src.height/downSample; RenderTexture buffer0 = RenderTexture.GetTemporary(rtW, rtH, 0); buffer0.filterMode = FilterMode.Bilinear; Graphics.Blit(src, buffer0, material, 0);
for (int i = 0; i < iterations; i++) { material.SetFloat("_BlurSize", 1.0f + i * blurSpread); RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0); // Render the vertical pass Graphics.Blit(buffer0, buffer1, material, 1); RenderTexture.ReleaseTemporary(buffer0); buffer0 = buffer1; buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0); // Render the horizontal pass Graphics.Blit(buffer0, buffer1, material, 2); RenderTexture.ReleaseTemporary(buffer0); buffer0 = buffer1; }
material.SetTexture ("_Bloom", buffer0);
Graphics.Blit (src, dest, material, 3);
RenderTexture.ReleaseTemporary(buffer0);
} else {
Graphics.Blit(src, dest);
}
}
}
PostEffectsBase.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; [ExecuteInEditMode] [RequireComponent (typeof(Camera))] public class PostEffectsBase : MonoBehaviour { protected bool CheckSupport() { if (SystemInfo.supportsImageEffects == false) { Debug.LogWarning("This platform does not support image effects."); return false; } return true; } protected void NotSupported() { enabled = false; } protected void CheckResources() { bool isSupported = CheckSupport(); if (isSupported == false) { NotSupported(); } } protected void Start() { CheckResources(); } // Called when need to create the material used by this effect protected Material CheckShaderAndCreateMaterial(Shader shader, Material material) { if (shader == null) { return null; } if (shader.isSupported && material && material.shader == shader) return material; if (!shader.isSupported) { return null; } else { material = new Material(shader); material.hideFlags = HideFlags.DontSave; if (material) return material; else return null; } } }
Bloom.shader
Shader "Custom/Bloom" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Bloom ("Bloom (RGB)", 2D) = "black" {}
_LuminanceThreshold ("Luminance Threshold", Float) = 0.5
_BlurSize ("Blur Size", Float) = 1.0
}
SubShader {
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
half4 _MainTex_TexelSize;
sampler2D _Bloom;
float _LuminanceThreshold;
float _BlurSize;
struct v2f {
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
v2f vertExtractBright(appdata_img v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; return o; } fixed luminance(fixed4 color) { return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b; } fixed4 fragExtractBright(v2f i) : SV_Target { fixed4 c = tex2D(_MainTex, i.uv); fixed val = clamp(luminance(c) - _LuminanceThreshold, 0.0, 1.0); return c * val; }
struct v2fBloom {
float4 pos : SV_POSITION;
half4 uv : TEXCOORD0;
};
v2fBloom vertBloom(appdata_img v) {
v2fBloom o;
o.pos = UnityObjectToClipPos (v.vertex);
o.uv.xy = v.texcoord;
o.uv.zw = v.texcoord;
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0.0)
o.uv.w = 1.0 - o.uv.w;
#endif
return o;
}
fixed4 fragBloom(v2fBloom i) : SV_Target {
return tex2D(_MainTex, i.uv.xy) + tex2D(_Bloom, i.uv.zw);
}
ENDCG
ZTest Always Cull Off ZWrite Off
Pass {
CGPROGRAM
#pragma vertex vertExtractBright
#pragma fragment fragExtractBright
ENDCG
}
UsePass "Custom/Gaussian Blur/GAUSSIAN_BLUR_VERTICAL"
UsePass "Custom/Gaussian Blur/GAUSSIAN_BLUR_HORIZONTAL"
Pass {
CGPROGRAM
#pragma vertex vertBloom
#pragma fragment fragBloom
ENDCG
}
}
FallBack Off
}
相关文章推荐
- Unity Shader-后处理:屏幕水波效果
- Unity_Shader高级篇_12.3_后处理_屏幕水波效果
- Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果
- Unity shader学习之屏幕后期处理效果之边缘检测
- Unity Shader-后处理:径向模糊效果
- UnityShader实例16:屏幕特效之径向模糊(Radial Blur)
- UnityShader实例13:屏幕特效之均值模糊(Box Blur)
- Unity shader学习之屏幕后期处理效果之Bloom效果
- Unity Shader-后处理:时空扭曲效果
- Unity Shader-后处理:简单均值模糊
- Unity Shader 学习笔记(22) Bloom效果
- UnityShader屏幕特效之Bloom
- UnityShader屏幕后处理-高斯模糊
- UnityShader高级篇——Bloom效果
- Unity Shader-后处理:Bloom全屏泛光
- 【Unity Shader入门练习】Bloom效果
- UnityShader屏幕后处理
- Unity shader学习之屏幕后期处理效果之均值模糊
- [UnityShader]模糊效果
- Unity shader学习之屏幕后期处理效果之Bloom效果