Подтвердить что ты не робот

Правильно визуализируйте полупрозрачную сферу в Unity5

Я делаю космическую разведку в Unity, и у меня две проблемы с полупрозрачностью.

Каждая планета состоит из двух сфер: одна представляет собой объединенный поверхностный и облачный слой, другой (с чуть большим радиусом) изображает "свечение" горизонта, отбраковывая передние грани и затухающую альфу по направлению к внешнему краю сферы, Это МОЩНО работает нормально, но со следующими двумя проблемами:

1) В моем настраиваемом шейдере поверхности, когда я использую альфа-ключевое слово в определении #pragma, альфа учитывается в визуализированной сфере, но сфера "свечения" исчезает на расстоянии нескольких тысяч единиц. Если я НЕ включаю альфа-ключевое слово, сфера не будет исчезать к краю, но она отображается на расстоянии.

2) Несмотря на то, что все параметры RenderType, Queue, ZWrite и ZDepth, сферическая сфера и "свечение" сфера - z-борьба; игра, похоже, не может решить, какие полигоны находятся ближе - несмотря на то, что грани поверхности на сфере свечения должны быть отбракованы. Я даже попытался оттолкнуть сферу свечения от камеры плеера и расширить его радиус на ту же пропорцию, но я ВСЕГО, необъяснимо, получаю z-сражение между сферами!

Есть ли какие-либо настройки, которые мне не хватает, что позволит шару "свечение" всегда рисовать в области поверхности (учитывая, что я пробовал ВСЕ комбинации ZWrite, ZDepth, как описано выше), и есть ли способ иметь объект с альфа-поддержкой НЕ исчезает на расстоянии?

Я не могу понять это, поэтому любая помощь будет хорошо оценена!

ИЗМЕНИТЬ
Вот шейдерный код для моей "сферы свечения". Передние поверхности отбракованы. Я даже пробовал ключевое слово Offset, чтобы "нажимать" любые вытянутые полигоны дальше от камеры. И я пробовал все параметры Tag, ZWrite и ZTest, которые мне удалось найти. Шейдер получает оттенок Color, плавучесть плотности атмосферы и вектор направления солнца...

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"
}
4b9b3361

Ответ 1

Кажется, я наткнулся на решение этой проблемы, пытаясь разрешить "дрожание" мирового пространства... Игра, которую я разрабатываю, использует большие расстояния. Я изменил способ размещения междугородних объектов (расстояние дотягивается дальше от объекта до объекта), и это разрешило z-сражение и альфа исчезает. Целая солнечная система вписывается во что-то вроде 300000 километров, используя квадратный корень из расстояния, деленного на расстояние, и умножая на него относительный Вектор3 и масштаб объекта. Надеюсь, эта информация может быть полезной для кого-то.

Ответ 2

Если вы используете альфа, вам нужно изменить теги, чтобы отобразить альфу в пропуске прозрачности. Также выключите ZWrite. И удалите смещение.

Я тестировал ваш шейдер в пустом проекте с визуализацией Forward и Deferred. Он отлично справился с этими настройками.

Сначала выполняется полная непрозрачная геометрия, затем выполняется альфа-проход и отображает все объекты с прозрачностью в TOP всех объектов в сцене. Это нужно сделать, иначе он не сможет смешивать цвета для альфы.

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

Ответ 3

Вы думали о том, чтобы создавать большие объекты в другом масштабе на другой камере для создания динамического skybox? Это, безусловно, решит проблемы z-боев. Например, у вас могут быть две камеры - одна, которая отображает объекты в диапазоне 0,1-1000 и другие, которые варьируются от 1000 до 100000.

Дополнительная оптимизация может включать среду рендеринга издалека в кубический skybox и делать это не каждый кадр (за исключением, может быть, особых случаев, когда вы уничтожаете планету издалека).

Существует еще одна проблема оптимизации - вы можете сделать плоское кольцо вокруг планеты, повернутое к камере, чтобы избежать перегрузки на реальной поверхности планеты. По-видимому, это потребует более сложных расчетов освещения.

Также вы пробовали свой прозрачный шейдер на камере, у которой нет Skybox как четких флагов? Проверьте этот ответ о том, как использовать пользовательский skybox.