three.js 入门六:向geometry中传入自定义的attribute属性, 在shader中访问此属性

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

环境:

  • three.js 0.159.0

正常情况下,我们使用BufferGeometry创建几何体后会向它里面写入:positionuvnormal甚至color属性,那么我们可不可以写入其他任意属性呢?

当然是可以的,比如:

//注意: 因为就3个顶点, 每个顶点一个数据所以是 [0.8, 0.8, 0.8]
geometry.setAttribute("testabc", new THREE.BufferAttribute(new Float32Array([0.8, 0.8, 0.8]), 1));

传入数据后我们就可以在shader中访问了:

const material = new THREE.ShaderMaterial({
     vertexShader: `
         attribute float testabc;
         varying float vTestabc;
         void main() {
             vTestabc = testabc;
             gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
         }
     `,
     fragmentShader: `
         varying float vTestabc;
         void main() {
             gl_FragColor = vec4(vTestabc, 0.0, 0.0, 1.0);
         }
     `
 });

这样就可以通过自定义参数控制shader中的代码对不同的物体有不同的效果,一个简单示例如下:
在这里插入图片描述
完整代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
    <script type="importmap">
        {
            "imports": {
                "three": "https://unpkg.com/three@0.159.0/build/three.module.js",
                "three/addons/": "https://unpkg.com/three@0.159.0/examples/jsm/"
            }
        }
    </script>
</head>

<body>
    <script type="module">

        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

        let camera, scene, renderer;
        //基础对象
        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100000);
        camera.position.set(500, 500, 500);
        camera.updateProjectionMatrix();
        renderer = new THREE.WebGLRenderer();
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.minDistance = 5;
        controls.maxDistance = 100000;
        controls.update()
        scene = new THREE.Scene();

        //坐标轴
        const axesHelper = new THREE.AxesHelper(200);
        scene.add(axesHelper);

        //物体1-几何体
        const geometry1 = new THREE.BufferGeometry();
        geometry1.setAttribute('position', new THREE.BufferAttribute(new Float32Array([
            0, 0, 0,
            100, 0, 0,
            100, 100, 0
        ]), 3));
        geometry1.setAttribute("testabc", new THREE.BufferAttribute(new Float32Array([0.2, 0.2, 0.2]), 1));

        //物体1-几何体
        const geometry2 = new THREE.BufferGeometry();
        geometry2.setAttribute('position', new THREE.BufferAttribute(new Float32Array([
            0, -100, 0,
            100, -100, 0,
            100, 0, 0
        ]), 3));
        geometry2.setAttribute("testabc", new THREE.BufferAttribute(new Float32Array([0.8, 0.8, 0.8]), 1));
        
        //共用一个shader材质
        const material = new THREE.ShaderMaterial({
            vertexShader: `
                attribute float testabc;
                varying float vTestabc;
                void main() {
                    vTestabc = testabc;
                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                }
            `,
            fragmentShader: `
                varying float vTestabc;
                void main() {
                    gl_FragColor = vec4(vTestabc, 0.0, 0.0, 1.0);
                }
            `
        });

        scene.add(new THREE.Mesh(geometry1, material));
        scene.add(new THREE.Mesh(geometry2, material));
        

        function animate() {
            requestAnimationFrame(animate);
            renderer.render(scene, camera);
        }
        animate();
    </script>
</body>

</html>

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackletter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值