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-25
    目录

    2. onBeforeCompile修改材质shader

    # .onBeforeCompile修改材质shader

    上节课给大家说过,你可以通过材质.onBeforeCompile方法查看材质的着色器代码,其实也可以通过函数参数shader获取顶点或片元着色器GLSL ES的字符串进行二次修改。

    const material = new THREE.MeshLambertMaterial();
    material.onBeforeCompile = function (shader) {
      console.log('顶点着色器', shader.vertexShader);
      console.log('片元着色器', shader.fragmentShader);
      //你可以增删shader.vertexShader字符串
      //你可以增删shader.fragmentShader字符串
    }
    

    本节课修改结果:

    const material = new THREE.MeshLambertMaterial({
        map: texture,
    });
    // 修改材质material默认的着色器shader代码
    material.onBeforeCompile = function (shader) {
        // console.log('片元着色器', shader.fragmentShader);
        // 在片元着色器main函数里面最后一行插入代码
        shader.fragmentShader = shader.fragmentShader.replace(
            '#include <dithering_fragment>',//一行代码字符串,你可以用单双引号
            //多行代码字符串,用模板字符串``更方便
            `
            #include <dithering_fragment>
            gl_FragColor.r = 0.0;
            gl_FragColor.g = 0.0;
            `
        )
    }
    

    # gl_FragColor多次执行

    在片元着色器主函数main中,内置变量gl_FragColor可以多次调用设置RGBA分量的值。

    // 片元着色器代码
    const fragmentShader = `
    void main() {
        gl_FragColor = vec4(0.0,1.0,1.0,1.0);
        //重新访问rgb属性赋值
        gl_FragColor.g = 0.0;
    }
    `
    
    // 片元着色器代码
    const fragmentShader = `
    void main() {
        gl_FragColor = vec4(0.0,1.0,1.0,1.0);
        //可以多次赋值
        gl_FragColor = vec4(1.0,0.0,0.0,1.0);
    }
    `
    

    # 查看材质MeshLambertMaterial片元着色器代码

    你可以直接去threejs官方文件包目录\src\renderers\shaders\ShaderLib,查看MeshLambertMaterial对应的shader文件meshlambert.glsl.js。

    meshlambert.glsl.js里面有两个字符串,一个是顶点着色器代码,一个片元着色器代码。

    const material = new THREE.MeshLambertMaterial();
    

    也可以直接浏览器控制台log打印

    material.onBeforeCompile = function (shader) {
        console.log('片元着色器', shader.fragmentShader);
    }
    

    因为threejs经常改变,不太稳定,所以这里强烈提醒,不同版本threejs,同一个材质的shader代码可能一样,也可能不一样,代码打印结果,以你使用的threejs版本为准,并不一定要和我视频完全一致。

    你可以确定下你当前threejs版本,MeshLambertMaterial片元着色器主函数main里面最后一行代码是什么,我这里是#include <dithering_fragment>。

    void main() {
        ...
        ...
        ...
        #include <dithering_fragment>
    }
    

    # .replace()方法介绍

    .replace()JavaScript语言处理字符串的一个方法,算是普通前端基础。如果你了解,可以跳过去,如果不熟悉,就跟着视频熟悉下。

    .replace()功能就是修改一串字符串,具体方式就是检索字符串是否包含参数1表示的字符串,去替换新的字符串。

    const str = '我爱加班';
    const newStr = str.replace('爱加班','不爱加班');
    console.log('改变后字符串', newStr);
    

    # 修改MeshLambertMaterial片元着色器代码

    目标:在MeshLambertMaterial片元着色器主函数main里面最后一行后面增加代码。

    void main() {
        ...
        ...
        ...
        #include <dithering_fragment>
        // 在这里增加代码
    }
    

    材质的片元着色器代码shader.fragmentShader本身就是一个字符串,所以我们可以用.replace()去修改替换shader.fragmentShader里面的部分代码。

    const material = new THREE.MeshLambertMaterial({
        map: texture,
    });
    // 修改材质material默认的着色器shader代码
    material.onBeforeCompile = function (shader) {
        // console.log('片元着色器', shader.fragmentShader);
        // 在片元着色器main函数里面最后一行插入代码
        shader.fragmentShader = shader.fragmentShader.replace(
            '#include <dithering_fragment>',//一行代码字符串,你可以用单双引号
            //多行代码字符串,用模板字符串``更方便
            `
            #include <dithering_fragment>
            gl_FragColor.r = 0.0;
            gl_FragColor.g = 0.0;
            `
        )
    }
    
    1. threejs材质的shader代码
    3. 修改材质shader(彩色图变灰度图)

    ← 1. threejs材质的shader代码 3. 修改材质shader(彩色图变灰度图)→

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