来自于《Unity Shader 入门精要》书本的学习

先上图

代码分3部分

1.PostEffectsBase.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//在编辑器状态下可执行该脚本来查看效果
[ExecuteInEditMode]
//屏幕后处理特效一般需要绑定在摄像机上
[RequireComponent(typeof(Camera))]
public class PostEffectsBase : MonoBehaviour {void Start () {CheckResources();}protected void CheckResources(){bool isSupported = CheckSupport();//如果显卡检测 返回falseif (isSupported == false){//NotSupported()方法,即不显示
            NotSupported();}}//检查显卡是否支持protected bool CheckSupport(){//如果显卡不支持图像后期处理if (SystemInfo.supportsImageEffects == false){//返回falsereturn false;}//如果支持图像后处理,返回truereturn true;}//图像不显示protected void NotSupported(){enabled = false;}//CheckShaderAndCreateMaterial函数接受两个参数,第一个参数指定了改特效需要使用的Shader//第二个参数则是用于后期处理的材质。该函数首先检查Shader的可用性,检查通过后就返回一个使//用了该shader的材质,否则返回null.protected Material CheckShaderAndCreateMaterial(Shader shader, Material material){   //如果shader为空if (shader == null){return null;}//shader.isSupported:能在终端用户的图形卡上运行这个着色器&& 并且存在material 他的shader是我们输入的shaderif (shader.isSupported && material && material.shader == shader){return material;}if (!shader.isSupported){return null;}//上面都不满足的话,重新创建新的材质球else{material = new Material(shader);//hideFlags:控制对象销毁的位掩码//HideFlags.DontSave对象不会保存到场景中。加载新场景时不会被破坏。material.hideFlags = HideFlags.DontSave;return material;}}}

2.bloom.using System.Collections;

using System.Collections.Generic;
using UnityEngine;public class bloom : PostEffectsBase {public Shader bloomShader;private Material bloomMaterial;public Material material{get{//根据PostEffectsBase中的方法检测,第一个参数指定了该特效需要使用的Shader,第二个参数则是用于后期处理的材质;//该函数首先检查Shader的可用性,检查通过后返回一个使用了该shader的材质,否则返回Null.bloomMaterial = CheckShaderAndCreateMaterial(bloomShader, bloomMaterial);return bloomMaterial;}}//高斯模糊的叠带次数[Range(0, 4)]public int iterations = 3;//高斯模糊的叠带范围[Range(0.2f, 4.0f)]public float blurSpread = 0.6f;//降采样的数值[Range(1, 8)]public int downSample = 2;//luminanceThreshold,大多数情况下图像亮度不会超过1.但如果我们开启了HDR,硬件会允许我们把颜色值储存在一个更高精度范围的缓冲中,//此时像素的亮度就会超过1.[Range(0.0f, 4.0f)]public float luminanceThreshold = 0.6f;//OnRenderImage函数void OnRenderImage (RenderTexture src , RenderTexture dest){if (material != null){material.SetFloat("_luminanceThreshold", luminanceThreshold);//将图像进行降采样不仅可以减少需要处理的像素,提高性能,而且适当的降采样旺旺还可以得到更好的模糊效果int rtW = src.width / downSample;int rtH = src.height / downSample;//定义第一个缓存buffer0,并吧src中的图像缩放后储存到buffer0中。RenderTexture buffer0 = RenderTexture.GetTemporary(rtW, rtH, 0);buffer0.filterMode = FilterMode.Bilinear;//调用shader中的第一个Pass提取图像中较亮的区域,提到的较亮区域将储存在buffer0 中。Graphics.Blit(src, buffer0, material, 0);for (int i = 0; i < iterations; i++){material.SetFloat("_BlurSize", 1.0f + i * blurSpread);//定义buffer1RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);//调用第二个pass,输入buffer0,输出buffer1.Graphics.Blit(buffer0, buffer1, material, 1);RenderTexture.ReleaseTemporary(buffer0);//将输出的buffer1重新赋值给buffer0buffer0 = buffer1;buffer1 = RenderTexture.GetTemporary(rtW, rtH,0);//调用第三个pass,输入buffer0(上面输出的buffer1),输出buffer1(新的buffer1)Graphics.Blit(buffer0, buffer1, material, 2);//将新的buffer1再次给buffer0赋值buffer0 = buffer1;}//第四个Pass,将buffer0赋值给贴图_Bloommaterial.SetTexture("_Bloom", buffer0);Graphics.Blit(src, dest, material, 3);RenderTexture.ReleaseTemporary(buffer0);}else{Graphics.Blit(src, dest);}}

}

3.bloom.shader

Shader "Unlit/Bloom"
{Properties{_MainTex ("Texture", 2D) = "white" {}//高斯模糊较亮的区域 _Bloom ("Bloom(RGB)",2D) = "Black"{}//阔值,提取大于这个亮度的区域 后面将在 大于这个值 的区域里进行高斯模糊_luminanceThreshold("luminanceThreshold",Float) = 0.5//控制不同迭代之间高斯模糊的模糊区域范围  也就是uv偏移的范围_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;}//通过主贴图得到一个灰度值
        fixed4 luminance (fixed4 color){return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;}fixed4 fragExtractBright (v2f i ):SV_Target {///我们降采样得到的亮度值减去阔值_luminanceThreshold,并把结果截取到0到1的范围内,然后///我们把该值和原像素相乘,得到提取后的两部区域///这样就是低于_luminanceThreshold显示为黑色fixed c = tex2D(_MainTex , i.uv);//clamp(x,a,b),如果x<a,返回a,x>b,返回b,否则返回为x;fixed val = clamp (luminance(c) - _luminanceThreshold, 0.0, 1.0);return c * val;}///使用Unity提供的_MainTex_Texel_TexelSize变量,计算相邻文理坐标的的偏移(也是高斯模糊的写法)//竖方向跟横方向的两个顶点着色器公用的v2f输出定义struct v2fBlur {float4 pos : SV_POSITION;half2 uv[5]:TEXCOORD0;};//竖直方向的
        v2fBlur vertBlurV (appdata_img v){v2fBlur o;o.pos = UnityObjectToClipPos (v.vertex);half2 uv = v.texcoord;o.uv[0] = uv;o.uv[1] = uv + float2 (0.0,_MainTex_TexelSize.y * 1.0) * _BlurSize;o.uv[2] = uv - float2 (0.0,_MainTex_TexelSize.y * 1.0) * _BlurSize;o.uv[3] = uv + float2 (0.0,_MainTex_TexelSize.y * 2.0) * _BlurSize;o.uv[4] = uv - float2 (0.0,_MainTex_TexelSize.y * 2.0) * _BlurSize;return o;}//水平方向的
        v2fBlur vertBlurH (appdata_img v){v2fBlur o;o.pos = UnityObjectToClipPos (v.vertex);half2 uv = v.texcoord;o.uv[0] = uv;o.uv[1] = uv + float2 (_MainTex_TexelSize.x * 1.0 , 0.0) * _BlurSize;o.uv[2] = uv - float2 (_MainTex_TexelSize.x * 1.0 , 0.0) * _BlurSize;o.uv[3] = uv + float2 (_MainTex_TexelSize.x * 2.0 , 0.0) * _BlurSize;o.uv[4] = uv - float2 (_MainTex_TexelSize.x * 2.0 , 0.0) * _BlurSize;return o;}//定义两个pass公用的片元着色器
        fixed4 fragBlur (v2fBlur i) : SV_Target{float weight [3] = {0.4026, 0.2442, 0.0545};fixed3 sum = tex2D (_MainTex,i.uv[0]).rgb * weight[0];for (int j = 1; j<3; j++ ){sum += tex2D(_MainTex,i.uv[j*2-1]).rgb * weight[j];sum += tex2D(_MainTex,i.uv[j*2]).rgb * weight[j];}return fixed4 (sum,1.0);}///混合亮部图像和原图像时使用的 顶点.片元 着色器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_TOPif (_MainTex_TexelSize.y < 0.0)o.uv.w = 1.0 - o.uv.w;#endifreturn o;}fixed4 fragBloom (v2fBloom i):SV_Target{return tex2D(_MainTex, i.uv.xy) + tex2D(_Bloom,i.uv.zw);}ENDCGZTest Always Cull Off ZWrite Off pass { CGPROGRAM#pragma vertex vertExtractBright#pragma fragment  fragExtractBrightENDCG}pass {CGPROGRAM#pragma vertex vertBlurV#pragma fragment  fragBlurENDCG}pass {CGPROGRAM#pragma vertex vertBlurH#pragma fragment  fragBlurENDCG}pass {CGPROGRAM#pragma vertex vertBloom#pragma fragment  fragBloomENDCG}}FallBack Off
}

转载于:https://www.cnblogs.com/baicaishisan/p/7693146.html

屏幕后处理——Bloom相关推荐

  1. UnityShader屏幕后处理-Bloom效果(朦胧模糊)

    原理:1 取出图片中比较亮(饱和度比较高.远离灰色)的一部分图 2 对1中的图进行高斯模糊的到新的图 3 将2中的图与原图色彩相加 1 取出图片中比较亮的的区域 C# material.SetFloa ...

  2. UnityShader入门精要-屏幕后处理效果 亮度饱和度对比度、边缘检测、高斯模糊、bloom效果、运动模糊

    (从这里开始可能会记录的更简略一些,时间紧张想迅速读完这本书的主要内容,可能有的部分不会自己上手做) 屏幕后处理通常指渲染完整个场景得到屏幕图像后,再对图像进行操作,抓取屏幕可以使用OnRenderI ...

  3. Unity Shader入门学习(5):基础屏幕后处理

    1.后处理基类 //屏幕后处理,顾名思义,通常指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效. //基类的作用有二:检测平台是否支持后处理效果,及创建一个用于处理渲 ...

  4. UnityShader24:最简单的屏幕后处理例子

    一.需要提前了解的 其实关于屏幕后处理(Screen Post-processing Effects)相关的知识,前面已经提过了不少: 这些是 OpenGL 渲染部分: OpenGL基础35:帧缓冲( ...

  5. [OpenGL] 屏幕后处理:景深效果

    开发环境:Qt, OpenGL 立方体纹理是Qt官方教程Cube里自带的纹理. 概念引入 景深是摄像中的术语.相机聚焦后,镜头前远近平面之间的物体能够清晰成像,这一段清晰成像的距离也就是景深,我们可以 ...

  6. unity屏幕后处理全家桶之color grading

    color grading color grading指的是对最终的游戏界面进行颜色和亮度的改变或矫正.你可以理解为增加滤镜. 屏幕后处理全家桶里的color grading是完全实时hdr工具,内部 ...

  7. unity 2020 怎么写shader使其接受光照?_Shader从入门到跑路:阶段性自我小测2(屏幕后处理、替换渲染、双Pass渲染)...

    以下是一些可供读者自我检测的问题,同上次一样,笔者不会提供答案,但如果实在想不明白依然可以私信笔者问思路.经某些读者建议,每题加上了分数,供各位自检. 练习1:使用第5章讲到的屏幕后处理效果,对屏幕颜 ...

  8. UnityShader屏幕后处理效果之碎屏效果

    前言:本篇是开始撰写的第一篇关于屏幕后处理效果的图片,所有的屏幕后处理效果其实就是对相机渲染得到的纹理再次处理,本质上都属于Image Processing(IP),即图像处理,包括之后会提到的各种滤 ...

  9. Unity中基于屏幕后处理的彩色与黑白渐变效果

    本文将介绍Unity屏幕后处理的基本方法与游戏角色死亡后的屏幕渐变到黑白效果的实现方法. 屏幕后处理是指整个场景每一帧渲染完毕后,再对得到的屏幕图像进行一系列处理并显示到屏幕上的过程.Unity中我们 ...

最新文章

  1. ImageMagick简单记录
  2. ==和equals的简单比较
  3. [转]DB2常用命令大全
  4. 深入理解 Vuejs 动画效果
  5. linux解决windows应用程序,关于Linux下使用Windows应用程序的尝试总结
  6. 【机器视觉】 set_fuzzy_measure算子
  7. 同步代码块解决线程安全
  8. learning to rank评价指标
  9. html5本地存储论坛,Web Storage--HTML5本地存储
  10. python中MySQLdb模块用法实例
  11. gplv3协议可以商用吗_协议离婚以后,可以变更原离婚协议的内容吗?
  12. HackTheBox You know racecar 格式化字符串漏洞pwn题目
  13. 制作背景为透明的图标
  14. echarts版中国地图
  15. QtCreator总是崩溃卡死的问题
  16. ZOJ3549 Little Keng(快速幂)
  17. Godot Shader:读屏着色器
  18. jbox弹窗_jbox很好的弹出层 很好的弹出层 - 下载 - 搜珍网
  19. ai如何旋转画布_ai中怎么使用旋转工具制作旋转对称图?ai中使用旋转工具制作旋转对称图的方法...
  20. CH340下载程序时DTR和RTS的电平变化分析

热门文章

  1. CxImage的编译及简单使用举例
  2. 【SVN】在阿里云上创建svn服务器
  3. java在己有的类创子类怎么创_如何使用Java创建自己的异常子类
  4. jquery text方法html,jquery text(),html()方法的区别
  5. 计算机专业看能力还是学校,【计算机专业论文】学校计算机专业学生实践能力的培养(共3502字)...
  6. mysql 行号_PQ获取TABLE的单一值作为条件查询MySQL返回数据
  7. springboot mysql行锁_SpringBoot基于数据库实现简单的分布式锁
  8. fabric 启动peer_编写 Fabric 链码的一般准则
  9. 【jsp】通过get和post传值的区别
  10. 读取本地照片 以流的形式进行显示