【发布时间】:2020-03-08 14:53:18
【问题描述】:
我目前正在制作一个基于殖民行星的游戏,我想知道如何在球体上重叠地球的光照贴图纹理,但仅限于受着色图中阴影影响的位置。 我正在使用 unity 2020.1.0a25 和 通用渲染管道。
【问题讨论】:
我目前正在制作一个基于殖民行星的游戏,我想知道如何在球体上重叠地球的光照贴图纹理,但仅限于受着色图中阴影影响的位置。 我正在使用 unity 2020.1.0a25 和 通用渲染管道。
【问题讨论】:
光线在球体上的分布最基本的水平是由表面法线和朝向光线的矢量之间的点积决定的。这称为朗伯着色。在着色器语言中,它会这样写:
float NdotL = dot(normal, lightDir);
我们可以以类似的方式将其合并到自定义函数中。创建一个自定义函数,其中包含两个名为 Normal 和 WorldPos 的输入变量,以及一个名为 Shadow 的输出变量。将此代码粘贴到其中:
#if SHADERGRAPH_PREVIEW
Shadow = 1 - saturate(dot(float3(0.707, 0.707, 0), Normal));
#else
Light mainLight = GetMainLight();
float lightAmount = saturate(dot(mainLight.direction, Normal));
#ifdef _ADDITIONAL_LIGHTS
uint pixelLightCount = GetAdditionalLightsCount();
for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
{
Light light = GetAdditionalLight(lightIndex, WorldPos);
lightAmount += saturate(dot(light.direction, Normal));
}
#endif
Shadow = saturate(1 - lightAmount);
#endif
此函数的作用是将主光和所有附加光的光贡献相加,并返回其倒数。因为点积产生一个介于 -1 和 1 之间的值,所以首先使用 saturate() 将其限制在 [0, 1] 范围内。
注意——你从这个函数中得到的本质上是一个梯度,从终点的 0 到太阳对面的点的 1。您可能希望以某种方式重新映射此值以获得更清晰的边界,例如,您可以将其乘以 100 并将其钳制为 [0, 1],或使用平方根。