three.js 中shader 的几种呈现方式

three.js 中shader 的几种呈现方式

这里以改变box的颜色为例。
three.js 中shader 的几种呈现方式_第1张图片

方式1-使用three.js 内置的shader
// 改变颜色-方式1: 通过顶点属性修改, 使用three.js自带shader 
addColorBox1(size) {
    var geometry = new THREE.BoxBufferGeometry(size, size, size);
    var material = new THREE.MeshBasicMaterial({
        vertexColors: THREE.VertexColors
    })
    var cube = new THREE.Mesh(geometry, material);
    this.stage.scene.add(cube)

    const color = new THREE.Color();
    color.setRGB(0, 255, 0);
    const numVerts = geometry.getAttribute('position').count;
    const itemSize = 3;  // r,g,b
    const colors = new Uint8Array(itemSize * numVerts);
    const normalized = true;
    const colorAttrib = new THREE.BufferAttribute(colors, itemSize, normalized);
    geometry.addAttribute('color', colorAttrib);
    window.aaa = geometry
    for ( var i = 0; i < numVerts; i ++ ) {
        colorAttrib.setXYZ( i,color.r, color.g, color.b );
    }
}
方式2-使用自定义shader

自定义shader:

export default = {
  vertexShader: `
    attribute vec3 cusotomColor;
    varying vec3 color;

    void main() {
      color = cusotomColor;
      gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
  `,
  fragmentShader: `
    varying vec3 color;
    void main() {
      gl_FragColor = vec4(color, 1.);
    }
  `,
}
// 改变颜色-方式2: 通过顶点属性修改,使用自定义shader
addColorBox2(size) {
    var geometry = new THREE.BoxBufferGeometry(size, size, size);
    var material = new THREE.ShaderMaterial({
        vertexShader: BoxShader.vertexShader,
        fragmentShader: BoxShader.fragmentShader,
    });
    var cube = new THREE.Mesh(geometry, material);
    this.stage.scene.add(cube)

    const color = new THREE.Color();
    color.setRGB(0, 0, 255);
    const numVerts = geometry.getAttribute('position').count;
    const itemSize = 3;  // r,g,b
    const colors = new Uint8Array(itemSize * numVerts);
    const normalized = true;
    const colorAttrib = new THREE.BufferAttribute(colors, itemSize, normalized);
    geometry.addAttribute('cusotomColor', colorAttrib);
    window.aaa = geometry
    for ( var i = 0; i < numVerts; i ++ ) {
        colorAttrib.setXYZ( i,color.r, color.g, color.b );
    }
}
方式3-自定义+three.js 内置

原理与方式2相同。

 // 改变颜色-方式3: 通过顶点属性修改,使用组合方式写shader(自定义+three.js 内置)
addColorBox3(size) {
    var geometry = new THREE.BoxBufferGeometry(size, size, size);
    var material = new THREE.MeshBasicMaterial( {vertexColors: THREE.VertexColors});
    const vertexShaderReplacements = [
        {
        from: '#include ',
        to: `
        attribute vec3 cusotomColor;
        varying vec3 myColor;
        #include 
        `,
        },
        {
        from: '#include ',
        to: `myColor = cusotomColor;`,
        },
    ]

    const fragmentShaderReplacements = [
        {
        from: '#include ',
        to: `varying vec3 myColor;`,
        },
        {
        from: '#include ',
        to: `diffuseColor.rgb *= myColor;`,
        },
    ]

    material.onBeforeCompile = (shader) => {
        vertexShaderReplacements.forEach((rep) => {
        shader.vertexShader = shader.vertexShader.replace(rep.from, rep.to);
        });

        fragmentShaderReplacements.forEach((rep) => {
        shader.fragmentShader = shader.fragmentShader.replace(rep.from, rep.to);
        });
    };

    material.onAfterCompile = shader=>{
        console.error(shader.fragmentShader)
    }

    var cube = new THREE.Mesh(geometry, material);
    this.stage.scene.add(cube)

    const color = new THREE.Color();
    color.setRGB(0, 0, 255);
    const numVerts = geometry.getAttribute('position').count;
    const itemSize = 3;  // r,g,b
    const colors = new Uint8Array(itemSize * numVerts);
    const normalized = true;
    const colorAttrib = new THREE.BufferAttribute(colors, itemSize, normalized);
    geometry.addAttribute('cusotomColor', colorAttrib);
    window.aaa = geometry
    for ( var i = 0; i < numVerts; i ++ ) {
        colorAttrib.setXYZ( i,color.r, color.g, color.b );
    }
}
小结
  • 方式3可以使用three.js 内置封装好的代码块,避免重复开发

你可能感兴趣的:(Threejs-Shader,three.js,shader)