【Unity Shader入门精要 第12章】屏幕后处理效果(一)

1. 原理和过程

屏幕后处理是绑定摄像机的,通过抓取当前摄像机渲染的图像作为 SrcTextrue,然后按需依次调用处理接口,对 SrcTexture 进行处理,最后将处理完成的 DstTexture 显示到屏幕上,整个过程的调度通过 C# 脚本完成。

抓取摄像机当前渲染图像使用的接口如下:

OnRenderImage(RenderTexture _src, RenderTexture _dst)

其中:

  • _src为抓取到的当前绑定摄像机的渲染图像
  • _dst为处理结束时的目标纹理

调用的处理接口如下:

Graphics.Blit(Texture _src, RenderTexture _dst)
Graphics.Blit(Texture _src, RenderTexture _dst, Material _mat)
Graphics.Blit(Texture _src, Material _mat, int _passIndex = -1)

其中:

  • _src 为要处理的原始图像
  • _dst 为处理结束后存储到的目标纹理
  • _mat 为本次处理指定的材质,其主要作用是为本次处理提供使用的Shader,需要注意的是,_src会被赋值给该_mat所携带Shader的_MainTex变量,因此在实现Shader时,也需要声明对应名字的变量用于接收原始图像纹理
  • _passIndex 为本次处理指定使用的Pass索引,默认为-1,表示按照顺序依次执行Pass,否则为使用指定索引的Pass

2. 后处理脚本父类

我们可以建立一个后处理的父类,提供所有后处理脚本的基础功能,如检查效果可用性、初始化后处理所用材质等等。

脚本如下:

using UnityEngine;

[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class PostEffectBase : MonoBehaviour
{
    void Start()
    {
        CheckResource();
    }

    void CheckResource()
    {
        bool _supported = CheckDefaultSupported() && CheckSpecificSupported();
        if (!_supported) OnNotSurported();
    }

    /// <summary>
    /// 用于后处理模块通用设置
    /// 可被子类重写,因为可能存在某个子类不需要指定条件的情况
    /// </summary>
    /// <returns></returns>
    protected virtual bool CheckDefaultSupported()
    {
        return true;
    }

    /// <summary>
    /// 不同后处理子类可以分别实现各自特殊的检查
    /// </summary>
    /// <returns></returns>
    protected virtual bool CheckSpecificSupported()
    {
        return true;
    }

    /// <summary>
    /// 不满足后处理启用条件时禁用脚本
    /// </summary>
    void OnNotSurported()
    {
        enabled = false;
    }

    /// <summary>
    /// 初始化后处理使用的材质和Shader
    /// </summary>
    /// <param name="_shader"></param>
    /// <param name="_material"></param>
    /// <returns></returns>
    protected Material CheckShaderAndMaterial(Shader _shader, Material _material)
    {
        if (null == _shader || !_shader.isSupported) return null;
        if (null == _material || _material.shader != _shader)
        {
            _material = new Material(_shader);
            _material.hideFlags = HideFlags.DontSave;
        }
        return _material;
    }
}

3. 调整亮度、饱和度、对比度

下面的例子中,我们实现一个用于调整屏幕亮度、饱和度以及对比度的后处理效果。

首先,从Shader出发,考虑如何实现对于上述三项的调整:

  1. 对纹理(抓取的屏幕图像)进行采样,得到原始颜色
  2. 调整亮度:用原始颜色乘以亮度系数 _Brightness,即可得到调整后的处理颜色①
  3. 调整饱和度:通过 0.2125 * R + 0.7154 * G + 0.0721 * B 公式对原始颜色进行处理,得到纹理灰度值,然后按照饱和度系数 _Saturation 从灰度值到处理颜色①进行插值,即可得到增加了饱和度变化的处理颜色②
  4. 调整对比度:构建一个 (0.5, 0.5, 0.5) 的对比度为 0 的颜色,按照对比度系数 _Contrast 向处理颜色②进行插值,得到最终的颜色

然后,创建调用后处理的脚本,继承自上文后处理父类:

  1. 为脚本指定所需Shader
  2. 实现OnRenderImage方法,为Shader所需的 _Brightness、 _Saturation、_Contrast 赋值,并调用 Blit 方法执行后处理

测试脚本:

using UnityEngine;

public class PostEffect_BrightnessSaturationContrast : PostEffectBase
{
    public Shader BscShader;
    public Material BscMat;

    [Range(0.0f, 3.0f)]
    public float Brightness = 1;
    [Range(0.0f, 3.0f)]
    public float Saturation = 0.5f;
    [Range(0.0f, 3.0f)]
    public float Contrast = 0.5f;
    
    private void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        Material _mat = CheckShaderAndMaterial(BscShader, BscMat);
        if (null == _mat) Graphics.Blit(src, dest);
        else
        {
            _mat.SetFloat("_Brightness", Brightness);
            _mat.SetFloat("_Saturation", Saturation);
            _mat.SetFloat("_Contrast", Contrast);
            
            Graphics.Blit(src, dest, _mat);
        }


    }
}

测试Shader:

Shader "MyShader/Chapter_12/Chapter_12_BSC_Shader"
{
    Properties
    {
        _MainTex("MainTex", 2D) = "white"{}
    }
    SubShader
    {
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            ZTest Always
            ZWrite Off
            Cull Off
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase
            #include "UnityCG.cginc"
            
            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
            
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed _Brightness;
            fixed _Saturation;
            fixed _Contrast;
            
            v2f vert(appdata_img v)
            {
               v2f o;
               o.pos = UnityObjectToClipPos(v.vertex);
               o.uv = v.texcoord;
               return o;
            }
            
            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 _samplerColor = tex2D(_MainTex, i.uv).rgb;
                fixed3 _finalColor = _samplerColor * _Brightness;
                _samplerColor *= _Brightness;
                //0.2125 * R + 0.7154 * G + 0.0721 * B
                fixed _luminance = 0.2125 * _samplerColor.r + 0.7154 * _samplerColor.g + 0.0721 * _samplerColor.b;
                _finalColor = lerp(float3(_luminance, _luminance, _luminance), _finalColor, _Saturation);
                _finalColor = lerp(float3(0.5, 0.5, 0.5), _finalColor, _Contrast);
                return fixed4(_finalColor, 1);
            }
            
            ENDCG
        }
    }
}

测试效果:
亮度:
在这里插入图片描述
饱和度:
在这里插入图片描述
对比度:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/663584.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

上弦外媒新闻发稿:2024年度国外主流新闻媒体和海外媒体软文分发平台有哪些?

2024年度主流海外媒体新闻发稿和海外媒体软文分发平台有很多&#xff0c;下面是一些常见的和广受认可的平台&#xff1a; 主流新闻媒体 CNN - 美国知名新闻网络&#xff0c;覆盖广泛的国际新闻。BBC - 英国广播公司&#xff0c;提供全球新闻和深入报道。纽约时报 - 美国主流报…

解决docker容器: bash: ping: command not found, 并制作镜像

一. 出现原因 从 dockerhub 拉下来的镜像都是最轻量级的, 不会安装各种工具, 所以使用 ping, vim 等命令, 会出现 command not found 二. 解决方式 2.1 安装工具包 进入到一个正在运行的容器内部, 执行命令: apt-get update 之后会发现, 容器正在更新软件包, 不过最终会由…

四川汇聚荣聚荣科技有限公司在市场评价好吗?

随着科技行业的迅猛发展&#xff0c;越来越多的科技公司如雨后春笋般涌现&#xff0c;其中不乏一些优秀的企业。四川汇聚荣聚荣科技有限公司便是其中的一员。那么&#xff0c;这家公司在市场上的评价如何呢?接下来&#xff0c;我们将从四个方面进行详细的阐述。 一、公司概况四…

画图工具帮助工作

processon的画图工具 https://www.processon.com/ PlantUML 支持的图 时序图 时序图的语法和功能PlantUML时序图的语法&#xff1a;你可以有几种类型的参与者&#xff08;演员等其他角色&#xff09;、箭头、备注、分组...改变字体和颜色也是可行的。https://plantuml.com/z…

Find My割草机|苹果Find My技术与割草机结合,智能防丢,全球定位

割草机是一种用于修剪草坪、植被等的机械工具&#xff0c;它是由刀盘、发动机、行走轮、行走机构、刀片、扶手、控制部分组成。效率比人工锄草提高8至10倍&#xff0c;伤苗率低&#xff0c;除苗清洁率高。节省了除草工人的作业时间&#xff0c;减少了大量的人力资源。在畜牧业机…

git使用流程与规范

原文网址&#xff1a;git代码提交流程与规范-CSDN博客 简介 本文git提交流程与规范是宝贵靠谱的经验&#xff0c;它能解决如下问题&#xff1a; 分支差距过大&#xff0c;导致合代码无数的冲突合完代码后发现代码丢失分支不清晰&#xff0c;无法追溯问题合代码耗时很长&…

PDF盖骑缝章

在PDF文件上加盖骑缝章&#xff0c;您可以采取以下几种方法之一&#xff1a; 使用Adobe Acrobat&#xff1a; 打开Adobe Acrobat软件&#xff0c;加载PDF文件。在工具栏选择“工具”选项&#xff0c;找到“骑缝章”或“印章”工具。选择或上传您的骑缝章图片&#xff0c;将其放…

DataCube 漏洞小结

在这里分享一下通过拖取 DataCube 代码审计后发现的一些漏洞&#xff0c;包括前台的文件上传&#xff0c;信息泄露出账号密码&#xff0c;后台的文件上传。当然还有部分 SQL 注入漏洞&#xff0c;因为 DataCube 采用的是 SQLite 的数据库&#xff0c;所以SQL 注入相对来说显得就…

tomcat-请求url初始化

tomcat启动时会调用Lifecycle的start()方法&#xff0c;MapperListener.java中的方法startInternal()会被调用&#xff0c;此时开始了请求url映射到容器的初始化之路。首先看下private final Mapper mapper;属性&#xff0c;这个属性包含了请求url到容器的所有映射关系&#xf…

珠宝首饰AR虚拟3D试戴增强企业商品营销效果

在西安这座古老与现代交织的城市中&#xff0c;VRAR软件开发公司相比其他城市也略多一些&#xff0c;作为专业的西安AR软件开发公司&#xff0c;我们正凭借着前沿的AR增强现实/VR虚拟现实技术&#xff0c;为客户打造独一无二的互动体验。 专业团队&#xff0c;定制开发 我们拥有…

轻松入门:HTML网页制作指南 进阶篇

一.表格标签 1.1表格的主要作用 表格不是用来布局页面的,而是用来展示数据的。 1.2基本语法 <table><tr><td>单元格内的文字</td>...</tr>...</table>说明&#xff1a; 1.<table> </table> 是用于定义表格的标签。 2.<t…

服务器数据恢复—异常断电导致ESXi虚拟机无法启动的数据恢复案例

服务器数据恢复环境&#xff1a; 某大厂PS4000服务器&#xff0c;服务器上部署VMware ESXi虚拟化平台。 服务器故障&#xff1a; 机房断电&#xff0c;重启后服务器中的某台虚拟机不能正常启动。管理员查看虚拟机配置文件&#xff0c;发现无法启动的虚拟机的配置文件除了磁盘文…

vivado原语使用

首先介绍一下原语&#xff1a;其英文名字为Primitive。原语是Xilinx针对其器件特征开发的一系列常用模块的名字&#xff0c;用户可以将其看成Xilinx公司为用户提供的ip&#xff0c;是芯片中的基本元件&#xff0c;代表FPGA中实际拥有的硬件逻辑单元&#xff0c;如LUT&#xff0…

freertos初体验 - 在stm32上移植

1. 说明 freertos内核 非常精简&#xff0c;代码量也很少&#xff0c;官方也针对主流的编译器和内核准备好了移植文件&#xff0c;所以 freertos 的移植是非常简单的&#xff0c;很多工具&#xff08;例如CubeMX&#xff09;点点鼠标就可以生成一个 freertos 的工程&#xff0…

【Qt知识】Qt中的对象树是什么?

在深入Qt编程的世界时&#xff0c;你会频繁遇到一个核心概念——对象树&#xff08;Object Tree&#xff09;。这个概念是Qt框架管理内存、处理事件和组织用户界面元素的基础。 什么是Qt对象树&#xff1f; 如果你的Qt应用程序就像一片茂盛的森林&#xff0c;而这片森林中的每…

【linux深入剖析】进程间通信

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1.进程间通信目的2. 什么…

大语言模型应用与传统程序的不同

大语言模型&#xff08;LLM&#xff09; 被描述的神乎其神&#xff0c;无所不能&#xff0c;其实&#xff0c;大语言模型只是一个模型&#xff0c;它能够理解和生成自然语言&#xff0c;唯有依靠应用程序才能够发挥作用。例如&#xff0c;基于大模型可以构建一个最简单的会话机…

搜狐视频专访神工坊创始人任虎:以先进计算技术为引擎,引领新一代CAE革新之路

搜狐视频采访 神工坊&#xff08;无锡&#xff09;数字技术有限公司&#xff0c;源自国家超级计算无锡中心&#xff08;始于2016年&#xff09;&#xff0c;于2022年8月在无锡成立&#xff0c;是一家以高性能计算等先进计算技术推动新一代CAE技术革新的公司。 在全国科技工作者…

[Algorithm][动态规划][子序列问题][最长递增子序列][摆动序列]详细讲解

目录 0.子序列 vs 子数组1.最长递增子序列1.题目链接2.算法原理详解3.代码实现 2.摆动序列1.题目链接2.题目链接3.代码实现 0.子序列 vs 子数组 子序列&#xff1a; 相对顺序是跟源字符串/数组是一致的但是元素和元素之间&#xff0c;在源字符串/数组中可以是不连续的一般时间…

python绘制piper三线图

piper三线图 Piper三线图是一种常用于水化学分析的图表&#xff0c;它能够帮助我们理解和比较水样的化学成分。该图表由三个部分组成&#xff1a;两个三角形和一个菱形。两个三角形分别用于显示阳离子和阴离子的相对比例&#xff0c;而菱形部分则综合显示了这些离子比例在水样…