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

Unity3d 在Unity5中正确渲染半透明球体,unity3d,shader,alpha,Unity3d,Shader,Alpha,我正在Unity做一个太空探索游戏,我在半透明度方面有两个问题 每颗行星都由两个球体组成:一个是合并的表面和云层,另一个(半径稍大)通过剔除正面和向球体外缘淡入alpha来描绘地平线的“辉光”。这基本上可以正常工作,但存在以下两个问题: 1) 在我的自定义曲面着色器中,当我在#pragma定义中使用alpha关键字时,alpha会分解到渲染球体中,但“发光”球体会在几千个单位的距离处消失。如果不包括alpha关键字,球体不会向边缘淡入,但会在远处渲染 2) 尽管尝试了所有RenderType、Q

我正在Unity做一个太空探索游戏,我在半透明度方面有两个问题

每颗行星都由两个球体组成:一个是合并的表面和云层,另一个(半径稍大)通过剔除正面和向球体外缘淡入alpha来描绘地平线的“辉光”。这基本上可以正常工作,但存在以下两个问题:

1) 在我的自定义曲面着色器中,当我在#pragma定义中使用alpha关键字时,alpha会分解到渲染球体中,但“发光”球体会在几千个单位的距离处消失。如果不包括alpha关键字,球体不会向边缘淡入,但会在远处渲染

2) 尽管尝试了所有RenderType、Queue、ZWrite和ZDepth选项,但曲面球体和“发光”球体都是z-fighting;游戏似乎无法决定哪些多边形更近——尽管辉光球体上的近面应该被剔除。我甚至试着把发光球推离玩家相机,并以同样的比例扩大它的半径,但我仍然莫名其妙地得到了球之间的z-战斗

是否有我缺少的任何设置可以使“发光”球体始终绘制在曲面球体后面(鉴于我已经尝试了上面详述的ZWrite、ZDepth的所有组合),是否有方法使启用alpha的对象不会在远处消失

我似乎无法理解这一点,因此任何帮助都将不胜感激

编辑
下面是我的“发光球体”的着色器代码。正面将被剔除。我甚至尝试过使用Offset关键字将任何绘制的多边形“推”到离相机更远的地方。我已经尝试了我能找到的所有标签、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"
}

我在试图解决世界空间的“抖动”时,似乎偶然发现了这个问题的解决方案。。。 我正在开发的游戏使用大距离。我改变了远距离物体的定位方式(物体离摄像机越远,距离就越近),这解决了z-战斗和阿尔法消失的问题。
通过使用距离的平方根除以距离,再乘以物体的相对矢量3和比例,整个太阳系可以容纳大约300000公里。希望这些信息对某些人有用。

如果您使用alpha,则需要更改标记以在透明过程中渲染alpha。同时关闭ZWrite。并删除偏移量

我在一个空项目中测试了你的着色器,包括正向渲染和延迟渲染。经过这些调整,效果很好

首先绘制所有不透明几何体,然后完成alpha过程,并在场景中所有对象的顶部以透明度渲染所有对象。它需要这样做,否则它将无法混合alpha的颜色

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

您是否考虑过在另一个摄影机中以不同比例渲染大型对象以创建动态skybox?这肯定会解决z-战斗问题。 例如,您可以有两个摄影机—一个用于渲染范围为0.1-1000的对象,另一个用于渲染范围为1000到100000的对象。

额外的优化可以包括将环境从远处渲染到立方体天空盒,并且不是每一帧都这样做(除非可能是在从远处破坏行星的特殊情况下)。

还有另一个优化问题-你可以渲染一个围绕行星的平面环,旋转到面对相机的方向,以避免在实际行星表面上过度绘制。但这显然需要更复杂的照明计算。


另外,您是否在没有Skybox作为清除标志的摄影机上尝试了透明着色器?检查如何使用自定义skybox。

是否使用LOD?比如LOD 250?如果是,则删除它。不包括LOD。谢谢你的指针。你能在这里包括你的着色器代码吗?我想不出有什么会造成这种影响。此外,ZTest Off是一个有效的选项,尽管官方的统一手册中没有列出。即使增加了赏金也没有给出答案。有人有主意吗?我能提供更多信息吗?欢迎来到StackOverflow!下次,尝试发布一些示例代码作为您的答案,因为链接可能会变得无效