Three.js材质方法.onBeforeCompile()(修改内置材质着色器代码)

通过Three.js引擎自定义着色器GLSL代码不一定要全部自己编写,也可以在threeejs内置的MeshLambertMaterialMeshPhongMaterial等材质基础上,通过.onBeforeCompile()方法二次开发,在内置材质的顶点和片元着色器代码中插入新的着色器代码。

通过材质基类Material.onBeforeCompile()方法可以修改threejs内置材质的顶点和片元着色器代码。

threejs官方案例资源利用

examples目录下全文检索关键词.onBeforeCompile(),可以看到一些使用过.onBeforeCompile()方法的相关案例。

内置phong材质修改案例-增加灰度图功能

Threejs通过下面代码修改phong材质的片元材质着色器代码,对渲染效果进行灰度处理。

    //替换phong网格材质片元着色器代码中的部分语句
    material.onBeforeCompile = function(shader) {
      shader.fragmentShader = shader.fragmentShader.replace(
        'gl_FragColor = vec4( outgoingLight, diffuseColor.a );',
        'float luminance = 0.299*outgoingLight.r+0.587*outgoingLight.g+0.114*outgoingLight.b;' +
        'gl_FragColor = vec4(luminance,luminance,luminance,diffuseColor.a);'
      );
    };

上面代码是通过字符串换行编写,也可以通过数组形式编写,然后通过.join()方法把数组元素合并为字符串。

    material.onBeforeCompile = function(shader) {
      shader.fragmentShader = shader.fragmentShader.replace(
        'gl_FragColor = vec4( outgoingLight, diffuseColor.a );',
        [ // 计算RGB三个分量光能量之和,也就是亮度
          'float luminance = 0.299*outgoingLight.r+0.587*outgoingLight.g+0.114*outgoingLight.b;',
          // 逐片元赋值,RGB相同均为亮度值,用黑白两色表达图片的明暗变化
          'gl_FragColor = vec4(luminance,luminance,luminance,diffuseColor.a);',
          // .join()把数组中多个字符串合称为一个字符串,转义字符'\n'表示换行
        ].join('\n')
      )
    };