【Unity Shader】渲染纹理实现镜子效果
1 基本概念
1.1 什么是渲染到紋理?
全稱是Render To Texture,《入門精要》好像又把渲染目標紋理,即Render Target Texture也叫做RTT,但我認為《入門精要》的RTT更多的是“中間緩沖區”這個緩沖區,而Render To Texture這個RTT更多的是指渲染到紋理這一個操作,為了避免混亂接下來我說的RTT都是指Render To Texture這個渲染操作。
在我們學習渲染過程基礎的時候,一個Camera的渲染結果通常會說“輸出并儲存在顏色緩沖中”,再等待最后出現在屏幕上。當然,這也是常規的渲染操作。至于為什么會是渲染到紋理?有時候渲染會想要實現一些特效,那么此時RTT也像常規渲染操作一樣渲染一個場景,但這次并不是儲存在幀緩沖(雙緩沖則是儲存在后緩沖)中,而是渲染出一張紋理并在之后進行使用。
關于RTT更專業點的敘述:現代圖形處理單元(GPU)允許我們將3D場景先渲染到中間緩沖區中,也就是說不會直接到達默認的幀緩沖或者后緩沖(關于各種緩沖我在【技術美術圖形部分】圖形渲染管線3.0-光柵化和像素處理階段末尾有做簡單的介紹)。
1.2 什么是渲染紋理?
全稱Render Texture,簡稱RT,也就是上述提到的渲染出的那張紋理,這是Unity為渲染目標紋理專門定義的一種紋理類型。
1.3?RTT的應用范圍
上面說了,是為了實現一些特效效果。一般是在游戲的攝像機進行設置,使得攝像機渲染的結果能存到Render Texture中。
1.4 什么是多重渲染目標?
Multiple Render Target, 簡稱MRT,也叫做多目標渲染,是一個意思。多重渲染目標允許我們同時把場景渲染到多個渲染目標紋理中,不用再是渲染整個場景后才儲存。在【技術美術圖形部分】關于前向渲染和延遲渲染中我在Unity實現延遲渲染中,提到了“RT0、RT1、RT2、RT3”這四個渲染紋理,就是延遲渲染使用到MRT的體現。
2 模擬鏡子效果
2.1 原理
就是創建除了MainCamera之外的另一個Camera:用于渲染鏡子想要反射的場景,同時這個Camera的Render Target選擇創建的一個Render Texture,這樣的話選中的Camera渲染的場景將不會到屏幕上,而是存到的選中的渲染紋理RT中。同時要注意,既然是鏡像效果,畫面肯定是要反轉一下。
2.2?效果展示
這里我為了練習自己搜索紋理的能力沒有用《入門精要》提供的一些紋理圖片,而是在網上搜索(推薦一個免費的紋理貼圖網站:Texture Ninja,如果有更好的歡迎分享!)自己想要效果的紋理圖片當作Texture,然后在PS里獲得Texuture的法線圖,再分別給場景中的Wall、Sphere、Cube們賦予想要的材質。?
2.3?實現過程
2.3.1 準備場景
首先是搭建場景,創建6個立方體把MainCamera包圍住,場景中放置一些物體,再加上3個Point Light,賦予對應的材質,Shader用的是標準光照Shader。
2.3.2 創建RT/Camera/“鏡子”
Project視圖下右鍵,Create -> Render Texture創建一個MirrorTexture渲染紋理;
Scene視圖下右鍵,創建一個Camera,并將Render Target選中剛才創建的RT:
我們的鏡子就用一個Quad平面代替,還需要創建MirrorMat材質以及MirrorShader。
2.3.3 用于“鏡子”平面的Shader
這個Shader輸入的texture是剛才創建的RenderTexuture,整個結構非常簡單,這里就直接貼上代碼了:
Shader "Unity Shaders Book/Chapter 10/Mirror" {Properties{_MainTex ("Texture", 2D) = "white" {}}SubShader{Pass{Tags {"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment fragsampler2D _MainTex;struct a2v {//必不可少的,object->clipspacefloat4 vertex : POSITION;//要使用uv?那要先存著float4 texcoord : TEXCOORD0; };struct v2f {float4 pos : SV_POSITION;float2 uv : TEXCOORD0; };v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.texcoord; //什么都不需要做,就是獲取個紋理而已//還需要左右翻轉一下,關于x=0.5對稱:o.uv.x = 1 - o.uv.x;return o;}fixed4 frag(v2f i) : SV_Target {return tex2D(_MainTex, i.uv);}ENDCG}}FallBack OFF }2.4 特點及應用
2.4.1 “鏡子”清晰度與什么有關?
清晰度完全取決于這個Render Texture的分辨率,上述效果中我的分辨率選擇的是默認的256x256,看上去會比較模糊,如果改成1024x1024,則會清晰很多,但會消耗更多的性能,必要時注意清晰度和性能二者的取舍:
2.4.2 應用
游戲里的鏡子是怎么做出來的? - 知乎 (zhihu.com)
想了解更多可以自行搜索“游戲中怎么做鏡子效果”等等,這里我只是貼了一個知乎的問題,16年的時候就有人回答了用渲染紋理實現鏡子效果的方法。
總結
以上是生活随笔為你收集整理的【Unity Shader】渲染纹理实现镜子效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何把excel中的多行数据按行数拆分成
- 下一篇: 线上编辑器推荐