我正在使用 Three.JS 在 WebGL 中创建一个地球,到目前为止,我有一个具有昼夜纹理和大气的地球。现在要完成它,我想在我的地球上添加一个仅在水部分显示的高光。现在,我已经有了一个高光贴图,但我似乎无法将它全部拼凑起来。
由于地球/夜晚/大气的原因,我在自定义着色器中做所有事情,并且我读到我还必须在这个等式中包含镜面反射计算,因为 Three.JS 不能堆叠多个着色器。
这是我的着色器,我只停留在镜面反射部分:
<script id="earthFragmentShader" type="x-shader/x-fragment">
uniform sampler2D dayTexture;
uniform sampler2D nightTexture;
uniform sampler2D specularTexture;
uniform vec3 sunDirection;
varying vec3 vNormal;
varying vec2 vUv;
void main() {
// Textures for day and night:
vec3 dayColor = texture2D( dayTexture, vUv ).xyz;
vec3 nightColor = texture2D( nightTexture, vUv ).xyz;
// compute cosine sun to normal so -1 is away from sun and +1 is toward sun.
float cosineAngleSunToNormal = dot(normalize(vNormal), sunDirection);
// sharpen the edge beween the transition
cosineAngleSunToNormal = clamp( cosineAngleSunToNormal * 3.0, -1.0, 1.0);
// convert to 0 to 1 for mixing
float mixAmount = cosineAngleSunToNormal * 0.5 + 0.5;
// Atmosphere:
float intensity = 1.09 - dot( vNormal, vec3( 0.0,0.0, 1.0 ) );
vec3 atmosphere = vec3( 1,1,1) * pow( intensity, 2.0 );
// Select day or night texture based on mixAmount.
vec3 color = mix( nightColor, dayColor + atmosphere, mixAmount );
// Specular:
vec3 specularAmount = texture2D( specularTexture, vUv ).xyz;
vec3 specularColor = vec3(1,1,1) * specularAmount;
color = mix(color, specularColor, mixAmount);
// Set the color
gl_FragColor = vec4(color, 1.0);
}
</script>
到目前为止,它只是将高光贴图添加为地球上的纹理,但就像我提到的,我想使用这张 BW 图像来显示某种高光。谁能指出我正确的方向?
编辑:
好吧,我用以下代码实现了整个映射:
// Specular:
vec3 specularAmount = texture2D( specularTexture, vUv ).xyz;
vec3 specularColor = vec3(1,1,1);
float c = 0.35;
float p = 3.0;
float mixAmountSpecular = pow(c * dot(normalize(vNormal), sunDirection), p) * specularAmount.z;
// Select day or night texture based on mixAmount.
vec3 color = mix(dayColor, specularColor, mixAmountSpecular);
color = mix( nightColor, color + atmosphere, mixAmount );
现在剩下的唯一事情是如何使高光点变小......对此有什么想法吗?
编辑2:
好的,我终于通过调整一些参数来实现它:
float c = 0.035;
float p = 30.0;
float mixAmountSpecular = pow(c * dot(normalize(vNormal), specularDirection), p) * (specularAmount.z * 0.5);
作为参考,我的 sunDirection 是 -2, 0.8, 1,我的 specularDirection 是 -15, 10, 22.5。