unity 半透明渲染技巧(3則)

2021-01-12 遊戲蠻牛
unity 半透明渲染技巧(1):固定深度法

半透明渲染排序問題 長期在各種3d引擎存在,這裡將一些針對性技巧。因為通用的解決方案 已經有各種OIT專業方案,比如 gpu 鍊表 和 depth peeling。但還是那個普遍規律越通用的性能就越不夠理想 因為他們不知道你資源的特殊性 可以做哪些極端的簡化。所以這裡只分享些個人針對一些具體開發積累的小小技巧(持續補充中...)。

對於 為什麼會出現這個問題本質原因還不清楚的 可以看這篇基礎說明(文章底部參考閱讀). 理解這個基礎原因很有好處,否則一堆美術問你為什麼max maya 沒問題 unity ue有問題的時候 你不知道怎麼回答。更直接的說是2個原因:

1 半透明混合的算法 是 srcAlpha oneMinusSrcAlpha 這個公式是 前後不對稱的 所以嚴重依賴渲染順序(這也是特效的翅膀半透明模型為什麼沒深度問題 特效大量用 one one混合 這是前後色對稱的 無關順序的);

2 引擎的半透明排序是逐對象的,離線渲染工具是逐像素的所以沒問題;

所以接下來針對這2個修改 實現些高性能方案。

深度寫入的alphaBlend(固定深度法)

案例:這是針對頭髮這種需求,大量中心部分不透明,邊緣透明。

原理:先在不透明區域繪製一遍不寫顏色的深度,來強制實行這些像素半透明材質的染順序正確(因為本被遮擋 有可能渲染到前面的半透明 因為這層深度寫入 會絕對剔除 不可能再有機會渲染到前面 產生亂序),因為這部分是模型的絕大部分區域 所以可以確保絕大部分區域的效果正確。但是半透明邊緣遮擋半透明邊緣的時候 就無法確保正確了 因為 上面這套深度圖 不包含這些區域,好在這些區域很小所以可接受 實際效果圖如下(為了簡化主題 剝離了頭髮專有的高光計算)。

全部alphatest效果 邊緣不柔和

全部 alpahblend效果 邊緣柔和但深度錯誤

該方案效果 深度大部分正確+邊緣柔和


Shader "Hidden/Advanced Hair Shader Pack/Aniso_Opaque" {  Properties{  _MainTex("Diffuse (RGB) Alpha (A)", 2D) = "white" {}  _Color("Main Color", Color) = (1,1,1,1)    _Cutoff("Alpha Cut-Off Threshold", float) = 0.95   }  SubShader{     Tags{ "Queue" = "AlphaTest"  "RenderType" = "TransparentCutout" }     Blend Off       Cull off    ZWrite on      colormask 0  
Pass { Name "OPAQUE" CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc"
struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; };
struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; };
sampler2D _MainTex; float4 _MainTex_ST; half4 _Color; half _Cutoff; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; }
fixed4 frag(v2f i) : SV_Target { fixed a = tex2D(_MainTex, i.uv).a*_Color.a; clip(a - _Cutoff); return 0; } ENDCG } } }Shader "Advanced Hair Shader Pack/Aniso_Transparent" { Properties{ _MainTex("Diffuse (RGB) Alpha (A)", 2D) = "white" {} _Color("Main Color", Color) = (1,1,1,1) _Cutoff("Alpha Cut-Off Threshold", float) = 0.95
} SubShader{ UsePass "Hidden/Advanced Hair Shader Pack/Aniso_Opaque/OPAQUE"
Cull off ZWrite off
Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "ForceNoShadowCasting" = "True" }
CGPROGRAM
#include "Lighting.cginc" #pragma surface surf Lambert alpha:auto #pragma target 3.0
struct Input { float2 uv_MainTex; float3 viewDir; }; sampler2D _MainTex; float _Cutoff; fixed4 _Color; void surf(Input IN, inout SurfaceOutput o) { fixed4 albedo = tex2D(_MainTex, IN.uv_MainTex); o.Albedo = albedo.rgb*_Color.rgb; o.Alpha = saturate(albedo.a / (_Cutoff + 0.0001)); clip(albedo.a - 0.0001); }
ENDCG
}

}


unity 半透明渲染技巧(2):預計算順序法


前一篇介紹了問題的原因和可入手的2點,這次依然從渲染順序入手,這裡是前一篇連結.

案例:上一個方案中不適合中間需要大量透明的效果否則邊緣很生硬看如下對比圖。

固定深度方案 遇到非邊緣區域大面積半透明 效果不好

本方案 預計算順序法 效果更好

原理:既然引擎只排序到逐對象級別,那麼對象內渲染順序是怎麼決定的呢?通過測試發現是 建模時候的頂點id順序決定的,那麼我們是否可以 預計算一些角度的排序數組,根據實時角度 進行切換呢?在很多情況下是可行的 比如 左右轉動的角色頭髮,甚至是遊戲內的頭髮 也能通過6-8-6 22個方向很精確的表達(赤道上8個方向,上下45度處 各6個方向)。以下是只預計算4個方向的效果。

默認半透明深度 各種角度錯誤

僅僅預計算4個方向的切換效果

代碼實現:

using System;using System.Collections;using System.Collections.Generic;using System.Diagnostics;using UnityEngine;
public class AlphaBakedOrder : MonoBehaviour{ class IndiceData : IComparable<IndiceData> { public int a; public int b; public int c; public float score;
public int CompareTo(IndiceData other){ return (int)((other.score - score) * 10000); } } public int[][] indicesDir; private int lastIndex; private int[] originIndices;
bool isReverse; Mesh mesh; Vector3 centerPt; void Awake(){ centerPt = transform.GetChild(0).localPosition; mesh = GetComponent<MeshFilter>().mesh; var indices = originIndices = mesh.GetIndices(0); var vertices = mesh.vertices; for (int i = 0; i < vertices.Length; i++) {
vertices[i] = transform.localToWorldMatrix.MultiplyPoint(vertices[i]);
}
indicesDir = new int[4][];
calculateDirIndices(out indicesDir[0], out indicesDir[2], indices, vertices, 0); calculateDirIndices(out indicesDir[1], out indicesDir[3], indices, vertices, 2);
}
private void calculateDirIndices(out int[] v1, out int[] v2, int[] indices, Vector3[] vertices, int dirCheck){
List<IndiceData> orderList = new List<IndiceData>(); for (int i = 0; i < indices.Length; i += 3) { IndiceData data = new IndiceData(); data.a = indices[i]; data.b = indices[i + 1]; data.c = indices[i + 2]; data.score = (vertices[data.a][dirCheck] + vertices[data.b][dirCheck] + vertices[data.c][dirCheck]);
orderList.Add(data); } orderList.Sort(); v1 = new int[indices.Length]; for (int i = 0; i < indices.Length; i += 3) { v1[i] = orderList[i / 3].a; v1[i + 1] = orderList[i / 3].b; v1[i + 2] = orderList[i / 3].c; } orderList.Reverse(); v2 = new int[indices.Length]; for (int i = 0; i < indices.Length; i += 3) { v2[i] = orderList[i / 3].a; v2[i + 1] = orderList[i / 3].b; v2[i + 2] = orderList[i / 3].c; }
} private void OnDisable(){ mesh.SetIndices(originIndices, MeshTopology.Triangles, 0); lastIndex = -1; }
void Update(){ if (Camera.main == null) return; var checkPos = Vector3.Normalize(Camera.main.transform.position - transform.localToWorldMatrix.MultiplyPoint3x4(centerPt)); var dotX = Vector3.Dot(transform.right, checkPos); var dotY = Vector3.Dot(transform.up, checkPos);
var index = 0; if (Mathf.Abs(dotY) < Mathf.Abs(dotX)) { index = dotX > 0 ? 2 : 0;
} else { index = dotY > 0 ? 1 : 3;
}
if (lastIndex != index) { mesh.SetIndices(indicesDir[index], MeshTopology.Triangles, 0); lastIndex = index; print(index); }

}}


unity 半透明渲染技巧(3):深度剝離法


DepthPeeling !沒錯 目前實時渲染最先進的OIT 技術之一 其他的我就知道只有Per-PixelLinkedLists 了,前者的優點是1顯存可以更小 ,2有限次數時候 丟棄的層對畫質影響更小,比如5層半透明後面就當看不見沒人察覺 。缺點是需要多次渲染 總的速度不如後者快,但穩定些。

效果圖對比

alpha blend的 常見錯亂

6層剝離的效果

需求

前面寫了2種技巧 但都有限制 方案1 只能邊緣半透明,而且多人的邊緣半透明疊加時候深度依然錯誤。方案2 有時候需要預計算很多方向,且最高也就三角形級別的精確。做不到像素級別。所以 實現了這版 除了消耗點性能 通用性和精確度都很高

原理

引擎默認是之渲染離相機最近的一層depth,和color。這種始終對無序半透明渲染是信息不足的,我們想 如果 每一處遮擋 都可以保留遮擋後面的最近的顏色 那麼我們自然就能 對這些顏色 一起混合。就像做ui 拿到5張從前到後的圖片 計算他們透明疊加就很簡單了。那麼怎麼獲得這些顏色呢?一個比較簡單的方案是這樣:首先常規渲染depth 離相機最近的一層,然後把這個depth 設置給shader 下次渲染採樣。下次渲染的時候 遇到比這個depth更接近或一樣近 相機的 fragment 就discard。這樣就渲染出 第二層接近相機的depth和 color,那麼再渲染一次 又會得到第三層 以此類推。

最後我們把得到的幾層 從後完全混合 常用的算法就是back.rgb(1-col.a)+col.rgb*col.a; 這樣就實現了

每一層的深度圖

優化

這種簡單的實現方便理解原理,但是比較佔顯存。因為 從前往後渲染多次 但從後往前混合 所以需要同時保存這些顏色 就需要用rendertexutre array 保存好幾張。這方面優化的方案有2個 一個是 從後往前拍 同時混合。只要一張rendertexutre 不斷混合。一個是 還是從前往後拍 但也 只用一張rendertexutre 不斷混合。從前往後的混合 我根據基礎的物理光穿透計算 大致是這樣 col.rgb=col.rgb*(col.a)+back.rgb*(1-col.a);
col.a=1-(1-col.a)*(1-back.a); 不是完全準確但效果我測過很接近可以省5,6張屏幕大小RT 有時候很划算

還有一種優化是一次性寫入同一個fragment不同深度的各種顏色 做個原子累加 不同次數的顏色 寫入到RWStructedBuffer 不同offset。我想到這裡時就被及時的告知 這可能就是 Per-PixelLinkedLists了

代碼講解與連結

renderTexture 創建與作用

因為同時渲染出color和depth,這裡採用MRT渲染,後續會嘗試優化層 普通渲染+camera深度圖獲取

rts 為 MRT渲染目標 其中rts[0]存放深度 rts[1]存放顏色

finalClips 為存儲每個rts[1]的數組 最後對他每個圖進行半透明混合

rtTemp 是臨時從rts[0]拷貝出來 給下一次渲染的時候做深度比對的 但還不清楚為什麼 不能直接用rts[0] 我之前是猜測讀寫不能同時 所以這樣拷貝一次 沒想到被我猜中這樣就成功了

        finalClipsMat = new Material(finalClipsShader);        rts = new RenderTexture[2]        {            new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, 0, RenderTextureFormat.RFloat),            new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, 0, RenderTextureFormat.Default)        };                 rts[0].Create();        rts[1].Create();        finalClips = new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, 0,            RenderTextureFormat.Default);
finalClips.dimension = TextureDimension.Tex2DArray; finalClips.volumeDepth = 6; finalClips.Create();
Shader.SetGlobalTexture("FinalClips", finalClips); rtTemp = new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, 0, RenderTextureFormat.RFloat); rtTemp.Create();
Shader.SetGlobalTexture("DepthRendered", rtTemp);


多次渲染

for (int i = 0; i < depthMax; i++)        {            Graphics.Blit(rts[0], rtTemp);            Shader.SetGlobalInt("DepthRenderedIndex", i);            tempCamera.RenderWithShader(MRTShader, "");            Graphics.CopyTexture(rts[1], 0, 0, finalClips, i, 0);        }
if (showFinal == false) { Graphics.Blit(rts[rt.GetHashCode()], destination); } else { Graphics.Blit(null, destination, finalClipsMat); }

mrt 渲染shader

DepthRendered 是上一次渲染的深度 所以和他對比 比他靠近相機就是渲染過的 直接discard,因為DepthRendered是屏幕空間的 所以需要 用screenPos採樣,i.uv是模型uv不能直接用,最後輸出2個目標 深度和顏色

fout frag(v2f i)  {     float depth = i.pos.z / i.pos.w;     fixed shadow = SHADOW_ATTENUATION(i);                 half4 col=tex2D(_MainTex,i.uv)*_Color*shadow;                 col.rgb *=i.color;                 clip(col.a-0.001);                 float renderdDepth=tex2D(DepthRendered,i.screenPos.xy/i.screenPos.w).r;                 if(DepthRenderedIndex>0&&depth>=renderdDepth-0.000001) discard;           fout o;     o.rt0=depth;     o.rt1=col;           return o;  }

FinalClip 最終混合shader

        fixed4 col =0;  fixed4 top=0;  for(int k=0;k<DepthRenderedIndex+1;k++){                             fixed4 front=  UNITY_SAMPLE_TEX2DARRAY(FinalClips, float3(i.uv, DepthRenderedIndex-k));         col.rgb=col.rgb*(1-front.a)+front.rgb*front.a;         col.a=1-(1-col.a)*(1-front.a);         top=col;     }    col.a=saturate(col.a);        col.rgb= col.rgb+top.rgb*(1-col.a);    return col;

代碼連結

github.com/jackie2009/depthPeeling

題外話

做這個系列有很巧的事情發生,就是一開始我想了一個很蠢的辦法,就是根據不同的距離 做不同範圍的多次渲染 也得到了 多次切片顏色 我叫他clipColor,比如一個頭髮看成0.1米厚的立方體 第一次渲染頭髮的0到0.01處 第二次0.01-0.02處。。。這樣切10片渲染。這樣雖然也能實現正確排序但非常低效。然後我就想能不能根據深度圖來推進渲染位置,於是跑到樂樂女神TA群問下這樣做可行性 結果有大佬秒回我 depthpeeling。一看思路幾乎絲毫不差。但他成熟專業的多 還 提出 雙向渲染 減少一半次數等。做完想優化的時候 想出方式一討論又被告知 就是 Per-PixelLinkedLists。這種感覺很久沒有了,上一次印象深刻還是 2003年自己想出的 尋路 和A*驚人相近。說了這麼多巧合 我想表達 有一種人就是屬於:書看得太少 但腦子想得太多——



參考閱讀:

透明渲染:渲染模型時控制它的透明通道(Alpha Channel)



對不透明(opaque)物體,由於深度緩衝(depth buffer,z-buffer),不考慮渲染順序也能得到正確的排序效果。

深度緩衝:渲染一個片元時,把它的深度值(視錐空間中距離攝像機的距離,範圍0-1)和深度緩衝中的值進行比較(如開啟深度測試ZTest),通過測試(深度值距離攝像機),則這個片元應該覆蓋掉此時顏色緩衝中的像素值,並更新它的深度值到深度緩衝(如果開啟了深度寫入)。(不開的話,深度緩衝中的值就是只讀的)。


關閉深度寫入原因:否則測試成功就會寫入顏色緩衝區,不進行顏色混合。


渲染順序:A(黃色)是半透明物體,B(紫色)是不透明物體

透明與不透明物體之間:不透明物體渲染完之後再渲染半透明物體。

半透明物體之間:從後往前


渲染引擎一般都會先對物體進行排序,再渲染。

常用方法:

1、先渲染所有不透明物體,開啟它們的深度測試和深度寫入。

2、把半透明物體按它們距離攝像機的遠近進行排序,按照從後往前的順序渲染,開啟它們的深度測試,關閉深度寫入。


但循環重疊的半透明物體會無法得到正確的半透明效果。

這裡的問題是:如何排序?

紅色點分別標明了網格上距離攝像機最近的點、最遠的點以及網格中點,每個點的深度值可能都不同,選擇哪個深度值在某些情況下半透明物體之間一定會出現錯誤的遮擋問題,解決方法:分割網格。

為減少錯誤排序的情況,儘可能讓模型是凸面體,將複雜的模型拆分成可以獨立排序的多個子模型。就算排序錯誤結果也不會非常糟糕。如果不想分割網格,可以試著讓透明通道更加柔和,使穿插看起來並不是那麼明顯。也可以使用開啟了深度寫入的半透明效果來近似模擬物體的半透明。

Unity中的渲染排序(Unity已經提供了很好地渲染順序解決方案,我們拿來用就行了~)

Unity提供了渲染隊列(render queue)解決渲染順序的問題。SubShader的Queue標籤決定模型歸於哪個渲染隊列。

Unity內部用一系列整數索引來表示每個渲染隊列,越小表示越早被渲染。

Unity提前定義了5個渲染隊列(也可以自定義)。

Unity內部用一系列整數索引來表示每個渲染隊列,越小表示越早被渲染透明度測試代碼透明度混合代碼:自定義渲染隊列索引,相當於2000+1。在所有的非透明物體之後渲染。


來源知乎專欄:遊戲技術輪子

相關焦點

  • Unity高級知識點總結:性能優化與圖形渲染進階
    比如我們常聽人說AlphaTest性能低,如果更進一步了解Early-Z、HSR、TBDR之後,就可以理解為什麼Unity要先渲染不透明物體,再渲染半透明物體。我們常聽人說Drawcall影響性能,更進一步了解渲染管線,知道什麼是Drawcall,什麼是渲染狀態,就會更進一步了解SetPassCalls是什麼東東。  理解本文中列舉的幾個關鍵知識點,也就可以對渲染優化有一定的概念了。
  • Unity 最新版本迎來260項功能改進,高清渲染管線HDRP升級
    最新上線的Unity 2019.3版本帶來了超過260項功能改進,其中的高清渲染管線(HDRP)功能可在高端遊戲主機和PC上解鎖高清精美畫質的無限潛能。高清渲染管線在2019.3中經過驗證幾近純熟,帶來了全新的功能和藝術創作工具,可用於製作高保真圖像。
  • Unity用戶手冊-正向渲染和延遲渲染
    正向渲染 & 延遲渲染 一、Forward Rendering(正向渲染) 發生在渲染管線的頂點處理階段,會計算所有的頂點的光照。全平臺支持。
  • 2021新年匯總:Unity項目原型快速開發資源,看這一篇就夠
    資源商店中模板項目搜索結果: https://assetstore.unity.com/templates Bolt (可視化編程工具) : https://assetstore.unity.com/packages/tools/visual-scripting/bolt-163802
  • Unity項目開發過程中常見的問題,你遇到過嗎?
    最近看到有朋友問一個unity遊戲開發團隊,需要掌握哪些知識之類的問題。
  • 博主營地 | Unity3D 實用技巧 - 理論知識庫(一)
    參考:  http://www.unitymanual.com/3821.html  注意:C#中有lock這個關鍵字,以確保只有一個線程可以在特定時間內訪問特定的對象。  Unity3D的協程和C#線程之間的區別是什麼?
  • Unity 實用技巧 - 物理系統初識
    官方文檔:https://docs.unity3d.com/Manual/PhysicsSection.html01  Rigidbody(剛體)/ Rigidbody2D(2D剛體)在使用文檔連結:https://docs.unity3d.com/cn/current/Manual/PhysicsDebugVisualization.html最後,小編特別推薦一些其他大神分享的內容。
  • 哪些材質有半透明屬性?
    有規律的散亂表現就是各向異性;透明是光線進入物體後,發生偏折而射出,折射率越大光偏折就越大;次表面散射是光線進入物體後,在內部的反彈和吸收,再有很少部分光線從表面射出,呈現一種半透明效果。從物理的角度來說,光與材質的交互包括兩個方面:散射(Scattering)和吸收(Absorption)。
  • Unity 2018.3 Beta版發布
    直播課程:Facial AR Remote面部捕捉解決方案課程(第一期)直播地址:https://connect.unity.com/events/unitychina-facialarUnity官方教師培訓報名火熱進行中Unity將在10月22-26日,舉辦為期5天的專業的Unity官方教師培訓課程,誠邀廣大教師與
  • Unity粒子系統小技巧X1
    下面我們就來學幾個跳出去又跳回來的小技巧放心,不會被人打的哈哈哈哈首先我們來看看效果圖幾個方法都是用unity粒子系統裡面的Velocity over lifetime(不知道這是什麼的去學基礎課)第一個方法
  • 【厚積薄發】Unity Batches與glDrawElements的關係
    CullingGroup.onStateChanged事件綁定,通過事件觸發調整傳入DrawMeshInstanced的Matrix順序和渲染數量。代碼如下:    Vector3 midVe1   = obj.transform.position;    Vector2 viewPose = worldCamera.WorldToViewportPoint(midVe1 + new Vector3(0, 2, 0));    viewPose.x
  • 使用unity製作RPG遊戲3——2D精靈
    context=%7B%22nid%22%3A%22news_9564882242542237691%22%2C%22sourceFrom%22%3A%22bjh%22%2C%22url_data%22%3A%22bjhauthor%22%7D下面需要利用Tiled2Unity把01地圖導入unity下載Tiled2Unity,在根目錄下打開可執行文件進入unity。
  • 就是一門實時渲染的藝術!
    因為不同平臺下的性能不同,支持的程式語言也不盡相同,所以針對不同平臺下的流行的遊戲引擎也是不同的(方括號裡面是特別推薦的,基於開源性、易用性、性能與效果等方面的綜合水平推薦): windows或遊戲主機:【Unreal】、寒霜、CE3 蘋果ios:【unity3D】、【cocos2d-ObjC】、【Unreal】、sparrow
  • 在unity中用C#連接資料庫步驟
    所以本文就介紹一下unity連MySQL資料庫所遇到的一些坑。unity連接資料庫,首先你需要導入如圖所示的五個數據連結庫。在本圖中,歐陽講他們放到了Mysql文件夾下,在這裡歐陽強調一下――最好將他們放到Plugins文件夾下,不然會出現莫名其妙的問題哦。
  • Unity漸進式光照貼圖烘焙詳解|unity
    支持Unity的哪些渲染管線?硬體要求:1. 至少需要一塊支持OpenCL 1.2的顯卡2. 至少2GB的顯存3. CPU支持SSE4.1指令支持的渲染管線:1.內置渲染管線(Built-in Render Pipeline):支持Baked Indirect,Subtractive和Shadowmask光照模式。2. 通用渲染管線(Universal Render Pipeline,簡稱URP):支持Baked Indirect,Subtractive和Shadowmask光照模式。3.
  • unity什麼意思
    unity什麼意思uni前綴,只包含一個的,更多例子還有:uniform, unique, unilateral, etc. 發音類似於有你,整個世界中有你就夠了,不需要別人,也就是只包含一個的。unity,聯合、統一、團結、和睦。學單詞,只記住意思可不行,會用才行,小夥伴們可以在評論區造句,我們一起學習哦!我先來:造句:Unity is strength. (團結就是力量)
  • 遊戲美術技巧 – 光場與公告板
    ,在ZB裡隨便拉個體塊,然後放進Houdini變成雲,多光線角度渲染一下就行了輸入參數lmax是最大階數,比如0階返回1個float,0-1階總共4個,0-2階是9個,0-3階是16個等等。噫,之前見過的很多技巧就這麼串起來了。3 八面體公告板這是一種從多角度記錄物體材質信息並用於遠景公告板的方法,這樣從不同角度讀取不同幀,就能還原這個角度看到的物體。
  • U3D實時渲染|角色頭髮各向異性表達 第一章(下)
    1目錄這個系列主要分為三個部分:1.頭髮的渲染2.皮膚的渲染3.眼睛的渲染2正文每個分為2個文章,第一篇講基礎理論,第二篇講實際操作。這裡讀者必須要理解幾個概念:深度寫入顏色寫入深度測試渲染隊列渲染排序這裡沒法花很大的篇幅講解,具體直接看樂樂入門書的第8章只能簡單的概括一下,對於半透的東西,渲染排序是很嚴謹的。透明物體的渲染一直是圖形學方面比較蛋疼的地方。
  • 王者榮耀是怎樣煉成的(三)unity組件與腳本
    上回書王者榮耀是怎樣煉成的(二)《王者榮耀》unity安裝及使用的小白零基礎入門 說到了unity的基本操作。
  • Unity推出的AR Foundation能幫助使用者解決AR開發過程中遇到的難題
    AR Foundation AR Foundation 的初始版本將為大多數AR應用的核心功能提供支持: 平整表面檢測 表示為點雲的深度數據 高效的pass-thru渲染 有助於將虛擬對象錨定到物理世界的參考點 估計平均色溫和亮度 追蹤物理空間中的設備位置和方向 在AR中正確縮放內容的實用程序