2016-02-05 11 views
12

Ich mache ein Weltraumexplorationsspiel in Unity und habe zwei Probleme mit Semi-Transparenz.Halbtransparente Kugel in Unity5 richtig rendern

Jeder Planet besteht aus zwei Kugeln: Die eine ist die kombinierte Oberfläche und Wolkendecke, die andere (mit einem etwas größeren Radius) stellt den Horizont 'Glühen' dar, indem Frontflächen und verblassendes Alpha zum äußeren Rand der Kugel. Dies funktioniert meist gut, aber mit den folgenden zwei Problemen:

1) In meinem benutzerdefinierten Oberfläche Shader, wenn ich das Alpha-Schlüsselwort in der # Pragma-Definition verwenden, ist Alpha in die gerenderten Kugel, sondern die 'Glow' faktoriert Kugel verschwindet in einer Entfernung von einigen tausend Einheiten. Wenn ich das Schlüsselwort alpha nicht verwende, verblasst die Kugel nicht zum Rand hin, sondern rendert in der Entfernung.

2) Obwohl alle RenderType, Queue, ZWrite und ZDepth Optionen getestet wurden, sind die Oberflächenkugel und die "Glow" Kugel z-fighting; das Spiel kann scheinbar nicht entscheiden, welche Polygone näher sind - trotz der Tatsache, dass nahe Gesichter auf der Leuchtkugel ausgemustert werden sollten. Ich habe sogar versucht, die Leuchtkugel von der Kamera des Spielers wegzuschieben und ihren Radius um das gleiche Verhältnis zu vergrößern, aber ich bin immer noch unerklärlicherweise dabei, den Z-Kampf zwischen den Sphären zu bekommen!

Gibt es irgendeine Einstellung, die ich vermisse, die es ermöglicht, die "Leuchtkugel" immer HINTER der Oberflächensphäre zu zeichnen (vorausgesetzt, ich habe ALLE Kombinationen von ZWrite, ZDepth wie oben beschrieben) und gibt es einen Weg ein Alpha-fähiges Objekt NICHT in der Entfernung verschwinden zu lassen?

Ich kann nicht scheinen, das herauszufinden, so wird jede Hilfe gut geschätzt werden!

EDIT
Hier ist der Shader-Code für meine 'glow Kugel'. Frontflächen sind geköpft. Ich habe sogar das Offset-Schlüsselwort ausprobiert, um gezeichnete Polygone weiter von der Kamera wegzuschieben. Und ich habe alle Optionen Tag, ZWrite und ZTest ausprobiert, die ich gefunden habe. Der Shader wird eine Tönung Farbe, eine Atmosphäre Dichte Schwimmer und eine Sonnenrichtungsvektor ...

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" 
} 
bestanden
+0

Verwenden Sie LOD? Wie LOD 250? Wenn ja, entfernen Sie es. –

+0

Keine LOD enthalten. Danke für den Zeiger. – moosefetcher

+0

Kannst du den Code deiner Shader hier einfügen? Ich kann mir nichts vorstellen, was diesen Effekt verursachen würde. Außerdem ist ZTest Off eine gültige Option, obwohl sie nicht im offiziellen Unity-Handbuch aufgeführt ist. – HalpPlz

Antwort

0

Ich scheine auf eine Lösung für dieses Problem gestoßen zu haben, bei dem Versuch, Weltraum ‚jittering‘ zu lösen .. Das Spiel, das ich entwickle, benutzt große Entfernungen. Ich änderte die Art und Weise, wie Fernobjekte positioniert werden (die Entfernungen werden immer enger, je weiter ein Objekt von der Kamera entfernt ist) und das hat den Z-Kampf und das Alpha-Verschwinden gelöst. Ein ganzes Sonnensystem passt in etwa 300000 Kilometer, indem es die Quadratwurzel der Entfernung dividiert durch die Entfernung verwendet und damit den relativen Vektor3 und die Größe des Objekts multipliziert. Hoffentlich kann diese Information für jemanden nützlich sein.

0

Wenn Sie Alpha verwenden, müssen Sie die Tags ändern, um das Alpha im Transparenzdurchlauf darzustellen. Schalte auch ZWrite aus. Und entferne den Offset.

Ich habe Ihren Shader in einem leeren Projekt mit Vorwärts- und Deferred-Rendering getestet. Es hat mit diesen Anpassungen gut funktioniert.

Alle undurchsichtigen Geometrien werden zuerst gezeichnet, dann wird der Alpha-Durchgang ausgeführt und alle Objekte mit Transparenz werden auf alle Objekte in der Szene gerendert. Es muss dies tun, sonst wird es nicht in der Lage sein, die Farben für das Alpha zu mischen.

0

Haben Sie darüber nachgedacht, große Objekte in einem anderen Maßstab in einer anderen Kamera zu rendern, um eine dynamische Skybox zu erstellen? Das wird sicherlich Z-Kampfprobleme lösen. Sie können zum Beispiel zwei Kameras haben - eine, die Objekte im Bereich 0,1-1000 rendert, und andere, die von 1000 bis 100000 reicht.

Die zusätzliche Optimierung kann Rendering-Umgebung aus der Ferne in die Cube Skybox aufnehmen und tun nicht jeden Rahmen (außer vielleicht besondere Anlässe, wenn du einen Planeten aus der Ferne zerstörst).

Es gibt noch eine weitere Optimierungsfrage - Sie könnten einen flachen Ring um den Planeten herum drehen, der so gedreht ist, dass er der Kamera gegenübersteht, um Überziehungen auf der tatsächlichen Planetenoberfläche zu vermeiden. Aber das wird anscheinend komplexere Beleuchtungsberechnungen erfordern.

Haben Sie auch Ihren transparenten Shader auf einer Kamera versucht, die keine Skybox als Clear Flags hat? Überprüfen Sie this answer wie benutzerdefinierte skybox verwendet wird.

+0

Willkommen bei StackOverflow! Versuchen Sie es beim nächsten Mal, einen Beispielcode als Antwort einzugeben, da die Links ungültig werden können – cdomination

+0

Der Skybox-Code ist für diese Antwort nicht relevant. – mcfrei