【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 AlwaysZWrite OffCull OffCGPROGRAM#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 * Bfixed _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}}
}

測試效果:
亮度:
在這里插入圖片描述
飽和度:
在這里插入圖片描述
對比度:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/19474.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/19474.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/19474.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用 C++ 在當前進程中獲取指定模塊的基址

C 實現 , 獲取指定模塊在該進程中的基址 1、流程: 獲取進程的所有模塊信息–>遍歷模塊列表 2、實現&#xff1a; // 我自己定義的 typedef struct moudle_date_ {HANDLE mhandle; // 句柄char mname[64]; // 名稱char* date; // 數據DWORD mdword; // 基址…

【機器學習】Adaboost: 強化弱學習器的自適應提升方法

&#x1f308;個人主頁: 鑫寶Code &#x1f525;熱門專欄: 閑話雜談&#xff5c; 炫酷HTML | JavaScript基礎 ?&#x1f4ab;個人格言: "如無必要&#xff0c;勿增實體" 文章目錄 Adaboost: 強化弱學習器的自適應提升方法引言Adaboost基礎概念弱學習器與強學習…

存儲器容量小才使用SRAM芯片,容量較大時使用DRAM芯片。為什么?

在計算機系統中&#xff0c;存儲器容量的選擇涉及到多種因素&#xff0c;包括成本、速度和復雜性。SRAM&#xff08;靜態隨機存取存儲器&#xff09;和DRAM&#xff08;動態隨機存取存儲器&#xff09;是兩種常見的內存類型&#xff0c;它們在設計和應用上有顯著的不同。以下是…

【藍橋杯嵌入式】 第六屆國賽

目錄 題目 配置 注意事項 代碼 - 默寫大師 EEPROM讀寫函數 LED驅動函數 ADC采集 上電初始化 LCD 按鍵 PWM互補輸出 全部代碼 hardware.c hardware.h control.c control.h main.c 題目 配置 注意事項 復制LCD的工程&#xff0c;先配置資源 --- 勾選完選項一…

CCIG 2024:合合信息文檔解析技術突破與應用前景

目錄 背景當前大模型訓練和應用面臨的問題訓練Token耗盡訓練語料質量要求高LLM文檔問答應用中文檔解析不精準 合合信息的文檔解析技術1. 具備多文檔元素識別能力2. 具備版面分析能力3. 高性能的文檔解析4. 高精準、高效率的文檔解析文檔多板式部分示例 文檔解析典型技術難點元素…

【代碼隨想錄Day23】|669.修建二叉搜索樹、108.將有序數組轉換為二叉搜索樹、538.把二叉搜索樹轉換為累加樹

669. 修剪二叉搜索樹 這題最開始的想法是復用刪除節點的那題的思路做&#xff0c;需要修改的部分就是要讓程序刪除完一個點后繼續遍歷&#xff0c;因為后續可能還有不符合條件的節點。但這樣想也做復雜了。 這類題其實不用想用什么序遍歷&#xff0c;用哪種方式只是為了更好的…

案例|開發一個美業小程序,都有什么功能

隨著移動互聯網的迅猛發展&#xff0c;美業連鎖機構紛紛尋求數字化轉型&#xff0c;以小程序為載體&#xff0c;提升服務效率&#xff0c;增強客戶體驗。 線下店現在面臨的困境&#xff1a; 客戶到店排隊時間過長&#xff0c;體驗感受差 新客引流難&#xff0c;老用戶回頭客…

基于EV54Y39A PIC-IOT WA的手指數量檢測功能開發(MPLAB+ADC)

目錄 項目介紹硬件介紹項目設計開發環境及工程參考總體流程圖硬件基本配置光照傳感器讀取定時器檢測邏輯 功能展示項目總結 &#x1f449; 【Funpack3-2】基于EV54Y39A PIC-IOT WA的手指數量檢測功能開發 &#x1f449; Github: EmbeddedCamerata/PIC-IOT_finger_recognition 項…

Flutter基礎 -- Dart 語言 -- 注釋函數表達式

目錄 1. 注釋 1.1 單行注釋 1.2 多行注釋 1.3 文檔注釋 2. 函數 2.1 定義 2.2 可選參數 2.3 可選參數 默認值 2.4 命名參數 默認值 2.5 函數內定義 2.6 Funcation 返回函數對象 2.7 匿名函數 2.8 作用域 3. 操作符 3.1 操作符表 3.2 算術操作符 3.3 相等相關的…

上海亞商投顧:滬指沖高回落 兩市成交金額僅剩7000億

上海亞商投顧前言&#xff1a;無懼大盤漲跌&#xff0c;解密龍虎榜資金&#xff0c;跟蹤一線游資和機構資金動向&#xff0c;識別短期熱點和強勢個股。 一.市場情緒 三大指數昨日沖高回落&#xff0c;午后一度集體翻綠&#xff0c;臨近尾盤小幅回升。光伏產業鏈再度走強&#…

aws 在ecs外部實例上運行gpu負載

參考資料 https://docs.amazonaws.cn/zh_cn/AmazonECS/latest/developerguide/ecs-gpu.htmlhttps://docs.amazonaws.cn/AWSEC2/latest/UserGuide/accelerated-computing-instances.html#gpu-instanceshttps://docs.amazonaws.cn/AWSEC2/latest/UserGuide/install-nvidia-drive…

LeetCode 63.不同路徑Ⅱ

思路&#xff1a; 在有障礙物的地方增加一個判斷即可 class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int dp[105][105];int mobstacleGrid.size();int nobstacleGrid[0].size();for(int i0;i<m;i){for(int j0…

K8s集群之 存儲卷 PV PVC

目錄 默寫 1 如何將pod創建在指定的Node節點上 2 污點的種類(在node上設置) 一 掛載存儲??????? 1 emptyDir存儲卷 2 hostPath存儲卷 ①在 node01 節點上創建掛載目錄 ② 在 node02 節點上創建掛載目錄 ③ 創建 Pod 資源 ④ 在master上檢測一下&#xff1a;…

C++ vector 模擬實現

vector的底層也是一個動態數組&#xff0c;他與 string 的區別就是&#xff0c;string 是專門用來存儲字符類數據的&#xff0c;為了兼容C語言&#xff0c;使用C語言的接口&#xff0c;在string的動態數組內都會都開一塊空間用來存 \0 &#xff0c;而vector則不會。 首先我們要…

【Linux多線程】認識多線程創建線程

文章目錄 什么是多線程為什么稱linux下的線程是輕量級進程呢&#xff1f; 線程的優點線程的缺點線程異常線程和進程創建線程1.pthread_create2.pthread_self 什么是多線程 進程是正在運行的程序的實例&#xff0c;而線程&#xff08;thread&#xff09;是進程中的一個執行路線…

python 刪除pdf 空白頁

環境 python 3.10 PyPDF2 3.0.1 安裝 pip install PyPDF2流程 將空白頁和內容頁讀取出來&#xff0c;看看內部結構有什么不同以此為依據&#xff0c;遍歷整個PDF 文件&#xff0c;標記處有內容的頁面&#xff0c;寫入到另外一個PDF文件。 python 代碼 # 每一個頁都是一個…

Springboot郵件發送配置

Springboot郵件發送配置 pom.xml依賴&#xff1a; <dependency><groupId>org.eclipse.angus</groupId><artifactId>jakarta.mail</artifactId><version>2.0.3</version> </dependency> <dependency><groupId>or…

跨域的解決方案

1. 計算機更改跨域 1.C盤->Windows->System32->drivers->etc 2.修改hosts 文件2. Chrome瀏覽器的跨域設置 操作步驟&#xff1a;1.打開我的電腦——C盤 新建一個文件夾&#xff0c;命名為MyChromeDevUserData2.右鍵——Chrome——快捷方式——目標&#xff0c;在…

ChatGPT成知名度最高生成式AI產品,使用頻率卻不高

5月29日&#xff0c;牛津大學、路透社新聞研究所聯合發布了一份生成式AI&#xff08;AIGC&#xff09;調查報告。 在今年3月28日—4月30日對美國、英國、法國、日本、丹麥和阿根廷的大約12,217人進行了調查&#xff0c;深度調研他們對生成式AI產品的應用情況。 結果顯示&…

ElementUI之el-table標題列中顯示el-tooltip

ElementUI之el-table標題列中顯示el-tooltip 文章目錄 ElementUI之el-table標題列中顯示el-tooltip1. el-table標題列中顯示el-tooltip2. 實現代碼3. 展示效果 1. el-table標題列中顯示el-tooltip 在el-table-column標簽內添加具名插槽v-slot:header 在el-tooltip標簽中使用具…