Unity Vision VR/AR Summit來到中國了(http://www.bagevent.com/event/197605?bag_track=http://www.bagevent.com/event/197605 ),最近也關注了一下Unity的VR開發。
git
相關連接:
- 官方帖子:http://steamcommunity.com/games/250820/announcements/detail/604985915045842668
- GitHub下載:https://github.com/ValveSoftware/the_lab_renderer
- Unity Asset Store下載:https://www.assetstore.unity3d.com/en/#!/content/63141github
從GitHub下載了The Lab Renderer以後,粗略的瀏覽一遍,內容很少,主要是幾個組件的C#代碼和一些Shader。接下來就看看它的主要特性是怎麼實現的。算法
The Lab Renderer使用Forward Rendering的緣由主要是爲了MSAA(MultiSampling Anti-Aliasing)和效率。然而Unity默認的Forward Rendering使用了Multi-Pass來渲染全部燈光(每一個物體的每一個動態燈要多一個Pass來渲染它的光照),The Lab Renderer提供了一個單Pass渲染多個燈光的解決方案。
數組
#define MAX_LIGHTS 18 ... float4 g_vLightColor[ MAX_LIGHTS ]; float4 g_vLightPosition_flInvRadius[ MAX_LIGHTS ]; float4 g_vLightDirection[ MAX_LIGHTS ];
而後使用一個for循環,一次性計算全部燈光的光照:markdown
LightingTerms_t ComputeLighting( float3 vPositionWs ...) { [ loop ] for ( int i = 0; i < g_nNumLights; i++ ) {} }
接下來就是在C#層來處理燈光信息了。app
而後,須要在Main Camera對象上添加「ValveCamera.cs」腳本。在class ValveCamera.UpdateLightConstants()成員函數中,會計算全部的燈光相關的參數,並設置到Shader的常量中。函數
以上就是The Lab Renderer的Single-Pass Forward Rendering這個特性的實現思路。oop
The Lab Renderer還接管了陰影的渲染。須要在Unity的Quality->Shadows settings 中選擇「Disable Shadows」來關閉Unity默認的陰影。
ui
上述算法的流程控制,在ValveCamera.cs腳本中實現。首先它須要一個從燈光角度渲染的Camera、一個RenderTexture用作Shadow Map,還須要一個Shader來進行Shadow Map渲染(Resources/vr_cast_shadows.shader)。spa
[ExecuteInEditMode] [RequireComponent( typeof( Camera ) )] public class ValveCamera : MonoBehaviour { ... [NonSerialized] private Camera m_shadowCamera = null; [NonSerialized] public RenderTexture m_shadowDepthTexture = null; [NonSerialized] public Shader m_shaderCastShadows = null; ... }
在ValueCamera.OnPreCull()腳本回調函數中會調用ValueCamera.ValveShadowBufferRender()來渲染Shadow Buffer。如上圖的Shadow所示,The Lab把全部燈光渲染到了一個總體的Shadow Buffer之中,把每一個燈光Shadow Buffer對應的區域,存儲到Shader參數「g_vShadowMinMaxUv」之中。這樣在前面講的Single-Pass Forward Rendering過程當中,就能夠在一個Pass實現全部燈光的光影計算了。
至於vr_cast_shadows.shader的內容,就很簡單了,它核心就是一個Vertex Shader,用來計算Projection以後的Position座標就好,UV啊什麼之類的均可以省略掉了。
在燈光渲染的Shader中(vr_lighting.cginc)經過ComputeShadow_PCF_3x3_Gaussian()函數來計算陰影。所謂的PCF就是Percentage Closer Filter,爲的是產生陰影的邊緣柔滑效果。在這個函數中,它纔算有了高斯過濾來對目標點周圍的3x3範圍進行計算。
對於VR來講,幀速率是很是重要的,因此Valve的大牛就添加了這個特性:動態調節渲染質量,達到穩定的搞效率,這是他在GDC 2016上的一個演講:https://www.youtube.com/watch?v=eIlb688pUu4 這部分主要涉及到什麼時候去調節質量,調節哪些地方(哪些是不能隨便調的),具體的邏輯都在ValveCamera.UpdateAdaptiveQuality()這個函數裏了。