在Unity5中正确渲染半透明球体

moo*_*her 14 shader alpha unity-game-engine

我在Unity制作太空探索游戏,我有两个半透明的问题.

每个行星由两个球体组成:一个是组合的表面和云层,另一个(半径略大)通过剔除前面和向球体外缘褪色α来描绘地平线"发光".这一切工作得非常好,但有以下两个问题:

1)在我的自定义表面着色器中,当我在#pragma定义中使用alpha关键字时,alpha会被分解到渲染的球体中,但是'glow'球体会在几千个单位的距离内消失.如果我不包含alpha关键字,则球体不会向边缘渐变,但会在距离处呈现.

2)尽管尝试了所有RenderType,Queue,ZWrite和ZDepth选项,表面球体和'发光'球体都是z-fighting; 游戏似乎无法决定哪个多边形更接近 - 尽管事实上应该剔除发光球体上的近面.我甚至试图从播放器相机推辉光球,距离同比例扩大半径,但我仍然,莫名其妙地,让球在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"
}
Run Code Online (Sandbox Code Playgroud)

moo*_*her 0

我似乎在尝试解决世界空间“抖动”时偶然发现了这个问题的解决方案......我正在开发的游戏使用了很大的距离。我改变了远距离物体的定位方式(物体离相机越远,距离就越短),这解决了 z-fighting 和 alpha 消失的问题。通过使用距离的平方根除以距离并乘以相对 Vector3 和物体的尺度,整个太阳系的长度大约为 300000 公里。希望这些信息对某人有用。