首页 > 解决方案 > 在 Three.js 中将其他非动态贴图应用于 ShaderMaterial

问题描述

我正在尝试创建地球月球系统(或者将来可能是完整的太阳系)的可视化,并且我发现了这个惊人的着色器,它可以根据闪电动态地将昼夜纹理应用于地球部分。

该解决方案存在一个问题。我看不到任何方法可以应用其他贴图,例如凹凸贴图或高光贴图。

在应用着色器之前它们非常好,我真的希望它们回来。在研究该主题时,我发现您可以创建其他动态修改的地图。

我正在寻找一种方法来修改这些着色器以应用其他静态贴图,同时保持动态主贴图

顶点着色器

    varying vec2 vUv;
    varying vec3 vNormal;
    varying vec3 vSunDir;

    uniform vec3 sunDirection;

    void main() {
      vUv = uv;
      vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
      vNormal = normalMatrix * normal;
      vSunDir = mat3(viewMatrix) * sunDirection;
      gl_Position = projectionMatrix * mvPosition;
    }

片段着色器

    uniform sampler2D dayTexture;
    uniform sampler2D nightTexture;

    varying vec2 vUv;
    varying vec3 vNormal;
    varying vec3 vSunDir;

    void main(void) {
      vec3 dayColor = texture2D(dayTexture, vUv).rgb;
      vec3 nightColor = texture2D(nightTexture, vUv).rgb;

      float cosineAngleSunToNormal = dot(normalize(vNormal), normalize(vSunDir));

      cosineAngleSunToNormal = clamp(cosineAngleSunToNormal * 5.0, -1.0, 1.0);

      float mixAmount = cosineAngleSunToNormal * 0.5 + 0.5;

      vec3 color = mix(nightColor, dayColor, mixAmount);

      gl_FragColor = vec4(color, 1.0);
    }

材料设置

const earthmaterial = new THREE.ShaderMaterial({
  uniforms: {
    sunDirection: {
      value: new THREE.Vector3(1, 0, 0)
    },
    dayTexture: {
      value: earthtexture
    },
    nightTexture: {
      value: earthnighttexture,
    }
  },
  vertexShader: dayNightShader.vertex,
  fragmentShader: dayNightShader.fragment,
})

标签: three.jsshaderfragment-shadervertex-shader

解决方案


推荐阅读