【问题标题】:Three.js - Apply heatmap texture to pointcloudThree.js - 将热图纹理应用于点云
【发布时间】:2021-07-11 20:44:09
【问题描述】:

我想做的是将热图纹理应用于点云,这样当点云旋转时,纹理不会旋转。例如,红色需要始终 Z 向上,蓝色需要 Z 向下。

是否可以将纹理添加到 Points 对象并使其“锁定”到位,使其不随几何体旋转?或者我是否需要创建另一个对象,例如具有纹理的立方体,并以某种方式将其与点云混合?

是创建着色器还是将颜色属性放在顶点上是唯一的选择吗?

非常感谢所有 cmets 和建议!

【问题讨论】:

    标签: three.js 3d webgl


    【解决方案1】:

    一个非常粗略的选择,使用修改后的PointsMaterialBox3

    body{
      overflow: hidden;
      margin: 0;
    }
    <script type="module">
    console.clear();
    import * as THREE from 'https://threejs.org/build/three.module.js';
    
    import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';
    import { PCDLoader } from 'https://threejs.org/examples/jsm/loaders/PCDLoader.js';
    
    let camera, scene, renderer, clock, pcd;
    let box = new THREE.Box3();
    let size = new THREE.Vector3();
    let uniforms = {
      yMin: {value: 0},
      yMax: {value: 0}
    }
    
    init();
    
    function init() {
    
      renderer = new THREE.WebGLRenderer( { antialias: true } );
      renderer.setPixelRatio( window.devicePixelRatio );
      renderer.setSize( window.innerWidth, window.innerHeight );
      document.body.appendChild( renderer.domElement );
    
      scene = new THREE.Scene();
    
      camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 0.01, 40 );
      camera.position.set( 0, 0, 1 );
      scene.add( camera );
    
      const controls = new OrbitControls( camera, renderer.domElement );
      //controls.addEventListener( 'change', render ); // use if there is no animation loop
      controls.minDistance = 0.5;
      controls.maxDistance = 10;
    
      //scene.add( new THREE.AxesHelper( 1 ) );
    
      const loader = new PCDLoader();
      loader.load( 'https://threejs.org/examples/models/pcd/binary/Zaghetto.pcd', function ( points ) {
    
        points.geometry.center();
        points.geometry.rotateX( Math.PI );
        
        points.material.onBeforeCompile = shader => {
          shader.uniforms.yMin = uniforms.yMin;
          shader.uniforms.yMax = uniforms.yMax;
          shader.vertexShader = `
            varying vec4 worldPosition;
            ${shader.vertexShader}
          `.replace(
            `#include <worldpos_vertex>`,
            `
              worldPosition = vec4( transformed, 1.0 );
              worldPosition = modelMatrix * worldPosition;
            `
          );
          console.log(shader.vertexShader);
          shader.fragmentShader = `
            uniform float yMin;
            uniform float yMax;
            
            varying vec4 worldPosition;
            
            // https://www.shadertoy.com/view/4dsSzr
            vec3 ansiGradient(float t) {
              return mod(floor(t * vec3(8.0, 4.0, 2.0)), 2.0);
            }
            ${shader.fragmentShader}
          `.replace(
            `vec4 diffuseColor = vec4( diffuse, opacity );`,
            `
              float a = (worldPosition.y - yMin) / (yMax - yMin);
              vec3 col = ansiGradient(a);
              vec4 diffuseColor = vec4( col, opacity );
            `
          );
          console.log(shader.fragmentShader);
        
        }
        pcd = points;
        console.log(pcd);
        scene.add( points );
        
        const helper = new THREE.Box3Helper( box, 0xffff00 );
        scene.add( helper );
    
      } );
      
      clock = new THREE.Clock();
    
      window.addEventListener( 'resize', onWindowResize );
    
    }
    
    function onWindowResize() {
    
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
    
      renderer.setSize( window.innerWidth, window.innerHeight );
    
    }
    
    renderer.setAnimationLoop( _ => {
      let t = clock.getElapsedTime();
      if (pcd) {
        pcd.rotation.x = (Math.sin(t) * 0.5 + 0.5) * THREE.MathUtils.degToRad(-60);
        
        box.setFromObject(pcd);
        let yMin = box.min.y;
        let yMax = box.max.y;
    
        uniforms.yMin.value = yMin;
        uniforms.yMax.value = yMax;
      }
    
      renderer.render( scene, camera );
    
    });
    </script>

    【讨论】:

      猜你喜欢
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-17
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多