2016-02-05 52 views
12

Tworzę kosmiczną grę eksploracyjną w Unity i mam dwa problemy z półprzezroczystością.Prawidłowo wyrenderować półprzezroczystą sferę w Unity5

Każda planeta składa się z dwóch sfer: Jedna to połączona warstwa powierzchni i chmur, druga (o nieco większym promieniu) przedstawia "poświatę" horyzontu poprzez ubożenie przednich ścian i zanikanie alfa w kierunku zewnętrznej krawędzi kula. Jest to NAJBARDZIEJ działające, ale z dwoma następującymi problemami:

1) W moim niestandardowym shaderze powierzchniowym, gdy używam słowa kluczowego alpha w definicji #pragma, alfa jest uwzględniana w renderowanej kuli, ale "blask" Kula znika w odległości kilku tysięcy jednostek. Jeśli NIE dodaję słowa kluczowego alfa, sfera nie zblaknie w kierunku krawędzi, ale będzie renderować z odległości.

2) Pomimo wypróbowania wszystkich opcji RenderType, Queue, ZWrite i ZDepth, sfery powierzchni i sfery "świecącej" są walkami z; gra nie może wydawać się decydować, które wielokątów są bliżej - pomimo faktu, że bliskie twarze w sferze świecą powinny zostać uśpione. Próbowałem nawet wypchnąć kulę jarzeniową z kamery gracza i rozszerzyć jej promień o tę samą proporcję, ale STILL, w niewytłumaczalny sposób, dostaję z-walki pomiędzy kulami!

Czy jest jakieś ustawienie, którego mi brakuje, które pozwoli na ciągłe wyrysowywanie sfery "poświata" ZA KULA NARZĘDZI (biorąc pod uwagę, że wypróbowałem WSZYSTKIE kombinacje ZWrite, ZDepth jak wyszczególniono powyżej) i czy istnieje sposób aby obiekt z obsługą alfa NIE zniknął z odległości?

Nie mogę tego zrozumieć, więc każda pomoc zostanie doceniona!

EDYTOWANIE
Oto kod modułu cieniującego dla mojej "sfery poświaty". Przednie twarze są poddawane ubojowi. Próbowałem nawet słowa kluczowego Przesunięcie, aby "wypchnąć" dowolne wyciągnięte wielokąty z aparatu. Wypróbowałem wszystkie opcje Tag, ZWrite i ZTest, które udało mi się znaleźć. Shader zostanie przeniesiony do koloru odcień, gęstość pływaka atmosfera i kierunek wektora Sun ...

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

Czy używasz LOD? Jak LOD 250? Jeśli tak, usuń go. –

+0

Brak uwzględnienia LOD. Dzięki za wskaźnik. – moosefetcher

+0

Czy możesz podać tutaj swój kod cieniowania? Nie mogę wymyślić niczego, co mogłoby spowodować ten efekt. ZTest Off jest również ważną opcją, mimo że nie jest wymieniony w oficjalnym Podręczniku Unity. – HalpPlz

Odpowiedz

0

I wydaje się, że natknął się na rozwiązanie tego problemu, starając się rozwiązać światowej przestrzeni „drgania” .. Gra, którą rozwijam, używa dużych odległości. Zmieniłem sposób, w jaki ustawiane są obiekty dalekosiężne (odległości zostają zakontraktowane, im dalej obiekt pochodzi z kamery), co rozwiązało problem z-walki i znikania alfa. Cały układ słoneczny mieści się w około 300 000 kilometrów, używając pierwiastka kwadratowego odległości dzielonego przez odległość i mnożąc względny Vector3 i skalę obiektu przez to. Mam nadzieję, że informacje mogą być przydatne dla kogoś.

0

Jeśli używasz alfa, musisz zmienić znaczniki, aby renderować alfa w przejściu przezroczystości. Wyłącz także ZWrite. I usuń przesunięcie.

Przetestowałem twój moduł cieniujący w pustym projekcie z renderowaniem zarówno przekazywanym, jak i odroczonym. Z tymi poprawkami działało dobrze.

Cała nieprzezroczysta geometria jest narysowana jako pierwsza, a następnie przechodzi alfa i renderuje wszystkie obiekty z przezroczystością na górze wszystkich obiektów w scenie. Musi to zrobić, w przeciwnym razie nie będzie w stanie mieszać kolorów alfa.

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

Czy myślałeś o renderowaniu dużych obiektów w innej skali w innym aparacie, aby stworzyć dynamiczny skybox? To z pewnością rozwiąże problemy z z-walkami. Możesz mieć na przykład dwie kamery - jedną, która renderuje obiekty w zakresie 0.1-1000, i inne, które obejmują zakres od 1000 do 100000.

Dodatkowa optymalizacja może obejmować renderowanie środowiska z daleka do skyboxa kostki i robienie tego nie każda klatka (może poza wyjątkowymi okazjami, kiedy zniszczysz planetę z daleka).
Istnieje również inny problem związany z optymalizacją - można obrócić płaski pierścień wokół planety, obracając go tak, aby był skierowany w stronę kamery, aby uniknąć przeciążenia na rzeczywistej powierzchni planety. Będzie to jednak wymagało bardziej złożonych obliczeń oświetlenia.
Czy próbowałeś też swojego przezroczystego modułu cieniującego w kamerze, która nie ma Skyboksa jako przezroczystych flag? Sprawdź, this answer, jak korzystać z niestandardowego skybox.

+0

Witamy w StackOverflow! Następnym razem spróbuj opublikować przykładowy kod jako odpowiedź, ponieważ linki mogą stać się nieważne. – cdomination

+0

Kod Skybox nie ma związku z tą odpowiedzią. – mcfrei