在球体上的两个纹理之间交叉淡入淡出

时间:2013-06-07 13:04:51

标签: opengl glsl textures texture-mapping

我有一个只有一个球体的3D场景,我有两个纹理 - 一个用于夜晚,一个用于这个星球的一天。 另外我在我的场景中有一个(15,15,15)的lightSource。对于球体上的每个顶点,我也有法线。

现在我想在两种纹理之间进行混合,以便白天和黑夜之间的淡化似乎是现实的。 因此,我使用点积来计算法线和光线之间的角度,但是如果我检查角度是否大于此值,我会得到硬交叉。 0(这将是白天)。 我需要根据角度混合纹理,这是一个软交叉。

任何人都可以帮助我如何混合纹理吗?到目前为止我的代码:

float angle = dot(L,N);
vec4 texture = texture2D(day, textureCoord);         

texture = texture2D(night,textureCoord) * (1-angle)  +  texture * angle;
vec4 light = vec4(ambientTerm + diffuseTerm + specularTerm , 1);

if(angle > 0) {
    color = light * texture;
} else if(angle >= -0.25) {
    color = texture2D(night,textureCoord)*(angle-1) + texture * (angle);
} else if( angle < -0.25) {
    color = texture2D(night,textureCoord);
}

1 个答案:

答案 0 :(得分:2)

您可以使用smoothstep function将连续值转换为0/1决策,并在其间进行小的平滑过渡。所以基本上你定义了一个过渡范围,让我们只需要[-0.25,0.25],这个角度范围大约是75到105度(对于更大的过渡区域,需要更大的值,但要尽量使其对称,因此,人们在黄昏时开启他们的灯,因此居中于90度左右;))。然后我们使用

转换[-1,1]单调余弦
angle = smoothstep(-0.25, 0.25, angle)

这将导致angle(尽管该名称有点不幸被选中,因为它不是一个角度并且与实际角度成反比)如果它是{{1} 0如果它是< -0.25,则1,如果介于两者之间,则为平滑过渡。并且整个纹理看起来像是(从奇怪的内容中清除并使用内置mix function):

> 0.25

或者,为了完整性的乐趣和更精简的

float angle = dot(N, L);
vec4 nightColor = texture2D(night, textureCoord);
vec4 dayColor = texture2D(day, textureCoord);
color = light * mix(nightColor, dayColor, smoothstep(-0.25, 0.25, angle));