Three.js中文网 Three.js中文网
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • Three.js基础课程(旧版本) (opens new window)
  • 文章
WebGPU教程
  • WebGL教程
  • WebGL教程(旧版本) (opens new window)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原英文官网文档 (opens new window)
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • Three.js基础课程(旧版本) (opens new window)
  • 文章
WebGPU教程
  • WebGL教程
  • WebGL教程(旧版本) (opens new window)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原英文官网文档 (opens new window)
Web3D系统课程视频
  • 1.threejs Shader基础语法

  • 2.onBeforeCompile修改材质

    • 1. threejs材质的shader代码
    • 2. onBeforeCompile修改材质shader
    • 3. 修改材质shader(彩色图变灰度图)
    • 4. 顶点位置插值(设置片元颜色)
    • 5. 顶点位置插值(设置片元颜色)2
      • 6. 模型扫光效果(顶点位置插值)
      • 7. 模型扫光效果(颜色渐变)
    • Threejs Shader教程
    • 2.onBeforeCompile修改材质
    郭隆邦
    2023-10-28
    目录

    5. 顶点位置插值(设置片元颜色)2

    # 顶点位置插值(设置片元颜色)2

    接着2.4小节讲解,你可以尝试改变上节课模型mesh的y坐标或者进行旋转,看看光带的变化。

    // 分别测试下面的不同值
    mesh.position.y = 0;
    mesh.position.y = 25;
    mesh.position.y = 50;
    mesh.rotateZ(Math.PI / 6);
    

    模型位置改变的时候,光带对应的片元相对世界坐标系高度始终是20左右,不过如果以自身底部为参照点,光带高度位置是变化的。

    if(vPosition.y > 20.0 && vPosition.y < 21.0 ){
      gl_FragColor = vec4(1.0,1.0,0.0,1.0);
    }
    

    因为顶点插值计算时候,使用模型矩阵modelMatrix进行了变换,模型矩阵包含了模型的旋转缩放平移信息。

      shader.vertexShader = shader.vertexShader.replace(
        'void main() {',
        `
        varying vec3 vPosition;
        void main(){
          vPosition = vec3(modelMatrix * vec4( position, 1.0 ));
        `
      );
    

    # 不使用模型矩阵进行变换

    去掉模型矩阵对顶点坐标的影响,只根据几何体的顶点坐标来设置模型Mesh的片元的颜色。

    不考虑mesh的旋转缩放平移,仅仅根据mesh.geometry顶点位置插值坐标设置片元颜色。

    void main(){
      // vPosition = vec3(modelMatrix * vec4( position, 1.0 ));
      // 顶点位置坐标插值计算
      vPosition = position;//不考虑模型旋转缩放平移变换(modelMatrix)
    }
    

    这时候如果你想实现和上节课相似效果,精确控制光带相对模型自身的位置,就需要根据Geometry顶点分布特点设置代码。

    # 知识回顾:局部坐标系查看顶点位置

    你可以把辅助坐标轴AxesHelper作为mesh的子对象,就可以查看mesh的局部坐标系。

    通过mesh的局部坐标系,方便你查看mesh对应几何体mesh.geometry顶点位置分布状态。

    // 查看模型局部坐标系:判断几何体顶点坐标分布情况
    const axesHelper = new THREE.AxesHelper(100);
    mesh.add(axesHelper);
    

    你可以浏览器控制台查看几何体顶点位置坐标

    const geometry = new THREE.BoxGeometry(40, 100, 40);
    console.log('顶点位置', geometry.attributes.position);
    

    # 知识回顾:改变局部坐标系

    你可以再次改变mesh位置,局部坐标系相对世界坐标原点偏移,但是相对自身几何体mesh.geometry位置不变,也就是几何体的顶点坐标不受影响。

    mesh.position.x = 100;
    

    几何体平移,改变几何体顶点坐标,这时候局部坐标系原点相对geometry位置发生变化。

    geometry.translate(0,50,0);
    console.log('顶点位置', geometry.attributes.position);
    

    扩展:blender等建模软件中,建模的时候,也可以根据需要调整局部坐标系相对自身顶点坐标的位置。

    # 根据顶点坐标设置片元颜色

    position直接插值,不用modelMatrix变换,通过下面代码,在几何体高度y = 30.0位置设置光带。

    // 片元着色器代码
    void main(){
      if(vPosition.y > 30.0 && vPosition.y < 31.0 ){
        gl_FragColor = vec4(1.0,1.0,0.0,1.0);
      }
    }
    
    // 顶点着色器代码
    void main(){
      // vPosition = vec3(modelMatrix * vec4( position, 1.0 ));
      // 顶点位置坐标插值计算
      vPosition = position;//不考虑模型旋转缩放平移变换(modelMatrix)
    }
    

    在这种情况下,你再平移旋转缩放mesh,你会发现光带位置始终在mesh局部坐标系的高度y=30位置。

    mesh.position.y = 50;
    mesh.rotateZ(Math.PI / 6);
    

    你可以在渲染循环中,设置一个旋转动画,查看vPosition = position与vPosition = vec3(modelMatrix * vec4( position, 1.0 ));区别

    function render() {
        model.rotateZ(0.01)
        renderer.render(scene, camera);
        requestAnimationFrame(render);
    }
    render();
    
    

    # 顶点位置插值计算总结

    插值后获取,可以或获取每个片元对应的局部坐标

    void main(){
      // 布局坐标
      vPosition = position;//只考虑几何体的顶点位置xyz 
    }
    

    插值后获取,可以或获取每个片元对应的世界坐标

    void main(){
      // 世界坐标 
      vPosition = vec3(modelMatrix * vec4( position, 1.0 ));
    }
    

    # 外部三维模型

    提醒:三维建模软件,比如blender与threejs交互的时候,要注意blender中模型局部坐标系的设置对代码的影响。

    如果美术给你一个三维模型,你可以用辅助坐标系AxesHelper可视化查看顶点位置坐标分布。

    如果你用vPosition = position进行插值计算,来控制片元颜色,要注意局部坐标系坐标原点的设置。一般选择一个特殊的位置,没有固定要求,只要方便你写代码就行了。比如课程案例,是一个光带环绕长方体四周,这时候最好让局部坐标系的随便某个轴,沿着立方体高度方向,坐标原点与底部或中心重合。

    loader.load("../外部模型.glb", function (gltf) {
      model.add(gltf.scene);
      const mesh = model.getObjectByName('长方体');
      // 查看模型局部坐标系:判断几何体顶点坐标分布情况
      const axesHelper = new THREE.AxesHelper(200);
      mesh.add(axesHelper);
    })
    

    4. 顶点位置插值(设置片元颜色)
    6. 模型扫光效果(顶点位置插值)

    ← 4. 顶点位置插值(设置片元颜色) 6. 模型扫光效果(顶点位置插值)→

    Theme by Vdoing | Copyright © 2016-2025 豫ICP备16004767号-2
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式