2016-02-05 46 views
12

我在Unity中製作了一個太空探索遊戲,我遇到了半透明問題。在Unity5中正確渲染半透明球體

每個行星都由兩個球體組成:一個是組合表面和雲層,另一個(半徑稍大)通過剔除正面和衰落alpha到外邊緣來描述地平線'發光'領域。這主要是做工精細,但有以下兩個問題:

1)在我定製的表面材質,當我使用Alpha關鍵字在#pragma定義,阿爾法被計入呈現球面,但「光暈」球體在幾千個單位的距離消失。如果我不包含alpha關鍵字,則球體不會向邊緣褪色,但會在距離處呈現。 2)儘管嘗試所有的RenderType,Queue,ZWrite和ZDepth選項,表面球體和'發光'球體是z戰鬥;遊戲似乎無法確定哪個多邊形更近 - 儘管事實上發光球面上的近面應該被淘汰。我甚至試圖將發光球從球員相機中推開,並以相同的比例擴大其半徑,但我仍然莫名其妙地獲得了球體之間的z戰鬥!

有沒有辦法,我失蹤,這將使該「光暈」領域的任何設置總是被畫後面的表面球(因爲我已經試過ZWrite,ZDepth的所有組合如上所詳述),是有辦法有一個啓用alpha的對象不會在距離消失?

我似乎無法弄清楚這一點,所以任何幫助將不勝感激!

編輯
這裏是我的'輝光球'的着色器代碼。正面被剔除。我甚至嘗試使用Offset關鍵字將任何繪製的多邊形從相機中「推出」。我已經嘗試了所有我能找到的Tag,ZWrite和ZTest選項。着色器被傳遞色調的顏色,氣氛密度浮子和太陽方向矢量...

Shader "Custom/planet glow" { 
    Properties { 
     _glowTint ("Glow Tint", Color) = (0.5,0.8,1,1) 
     _atmosphereMix ("Atmosphere Mix", float) = 0 
     _sunDirection ("Sun Direction", Vector) = (0, 0, 0, 0) 
    } 
    SubShader { 
     Tags { "RenderType" = "Opaque" "Queue" = "Geometry" } 
     Cull Front // I want only the far faces to render (behind the actual planet surface) 
     Offset 10000, 10000 
     ZWrite On // Off also tried 
     ZTest LEqual // I have tried various other options here, incombination with changing this setting in the planet surface shader 

     CGPROGRAM 
     #pragma surface surf Lambert alpha 
     #pragma target 4.0 

     struct Input { 
      float3 viewDir; 
     }; 

     fixed4 _glowTint; 
     float _atmosphereMix; 
     float4 _sunDirection; 

     void surf (Input IN, inout SurfaceOutput o) { 
      _sunDirection = normalize(_sunDirection); 
      o.Albedo = _glowTint; 
      float cameraNormalDP = saturate(dot(normalize(IN.viewDir), -o.Normal) * 4.5); 
      float sunNormalDP = saturate(dot(normalize(-_sunDirection), -o.Normal) * 2); 
      o.Alpha = _atmosphereMix * sunNormalDP * (cameraNormalDP * cameraNormalDP * cameraNormalDP); // makes the edge fade 'faster'    
      o.Emission = _glowTint; 
     } 

     ENDCG 
    } 
    FallBack "Diffuse" 
} 
+0

你使用LOD嗎?像LOD 250一樣?如果是刪除它。 –

+0

不包含LOD。感謝指針,但。 – moosefetcher

+0

你可以在這裏包含着色器的代碼嗎?我想不出任何會導致這種影響的事情。另外,ZTest Off是一個有效的選擇,儘管沒有在官方的Unity手冊中列出。 – HalpPlz

回答

0

我似乎在解決這個問題都有所涉獵,而試圖解決世界空間「抖動」 .. 我正在開發的遊戲使用很遠的距離。我改變了長距離物體的定位方式(距離越來越近,物體距離相機越遠),這就解決了z戰鬥和alpha消失。 整個太陽系通過使用距離除以距離的平方根,乘以相對的Vector3和物體的比例尺,可以擬合成300000公里的距離。希望這些信息可能對某人有用。

0

如果您使用的是alpha,那麼您需要更改標籤以在透明度傳遞中呈現alpha。同時關閉ZWrite。並刪除偏移量。

我在一個空的項目中使用Forward和Deferred渲染測試了你的着色器。這些調整效果很好。

首先繪製所有不透明的幾何圖形,然後完成alpha通道並渲染場景中所有對象的TOP都具有透明度的所有對象。它需要這樣做,否則它將無法混合alpha的顏色。

Tags { "RenderType" = "Transparent" "Queue" = "Transparent" } 
ZWrite Off 
0

你有沒有想過在其他相機不同的比例繪製大型對象來創建動態天空體?這肯定會解決z戰鬥問題。 例如,您可以擁有兩個攝像頭 - 一個渲染範圍爲0.1-1000的對象,另一個攝像頭的範圍從1000到100000.

附加優化可以包括從遠處渲染環境到立方體天空框,然後執行此操作不是每一幀(除非你在遠方摧毀一顆行星時的特殊場合除外)。

另外還有一個優化問題 - 您可以在地球周圍繪製一個平坦的環,旋轉以面對相機,以避免在實際行星表面上透支。但顯然,這需要更復雜的照明計算。

另外,你有沒有試過你的透明着色器沒有Skybox作爲清除標誌的相機?請檢查this answer如何使用自定義天空盒。

+0

歡迎來到StackOverflow!下次嘗試發佈一些示例代碼作爲您的答案,因爲鏈接可能會失效 – cdomination

+0

Skybox代碼與此答案無關。 – mcfrei