【发布时间】:2016-02-05 13:11:20
【问题描述】:
我正在使用 Unity 制作太空探索游戏,但在半透明方面遇到了两个问题。
每个行星都由两个球体组成:一个是地表和云层的组合,另一个(半径稍大)通过剔除正面和向球体外边缘衰减 alpha 来描绘地平线“发光” .这大部分工作正常,但存在以下两个问题:
1) 在我的自定义表面着色器中,当我在#pragma 定义中使用 alpha 关键字时,alpha 会被计入渲染球体,但“发光”球体会在几千个单位的距离处消失。如果我不包含 alpha 关键字,则球体不会向边缘淡化,但会在远处呈现。
2) 尽管尝试了所有 RenderType、Queue、ZWrite 和 ZDepth 选项,但表面球体和“发光”球体是 z-fighting;游戏似乎无法确定哪些多边形更接近 - 尽管事实上应该剔除发光球体上的近面。我什至尝试将发光球体推离玩家相机并将其半径扩大相同的比例,但我仍然莫名其妙地在球体之间进行 z-fighting!
是否有任何我遗漏的设置可以使“发光”球体始终绘制在表面球体后面(鉴于我已经尝试了 ZWrite、ZDepth 的所有组合,如上所述)并且有没有办法启用 alpha 的对象不会在远处消失吗?
我似乎无法弄清楚这一点,因此我们将不胜感激任何帮助!
编辑
这是我的“发光球”的着色器代码。正面被剔除。我什至尝试使用 Offset 关键字将任何绘制的多边形“推”离相机更远。我已经尝试了所有能找到的 Tag、ZWrite 和 ZTest 选项。着色器传递了一个 tint 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"
}
【问题讨论】:
-
你使用LOD吗?喜欢 LOD 250?如果是,请将其删除。
-
不包括细节层次。不过感谢您的指点。
-
您能在此处包含您的着色器代码吗?我想不出任何会导致这种效果的东西。此外,ZTest Off 是一个有效的选项,尽管官方 Unity 手册中没有列出。
-
即使添加赏金也没有产生答案。有人有想法吗?我可以提供更多信息吗?