threejs加载高度图渲染点云,不支持tiff

问题点

使用的point来渲染高度图点云,大数据图片无效渲染点多(可以通过八叉树过滤掉无效点增加效率,这个太复杂),但是胜在简单能用

效果图

img

在这里插入图片描述

code

代码可运行,无需npm

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js Heightmap Visualization</title>
    <style>
        body {
      margin: 0; }
        canvas {
      display: block; }
    </style>
</head>
<body>
    <button id="loadImageButton">Load Image</button>
    <!-- 引入Three.js和OrbitControls -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/three@v0.149.0/build/three.module.js" type="module"></script> -->
    <script src="https://seikichi.github.io/tiff.js/tiff.min.js"></script>
    <script src="orb.js"></script>
    <script type="module">
        import * as THREE from "https://cdn.jsdelivr.net/npm/three@v0.149.0/build/three.module.js";
        console.log(THREE)
        var {
     OrbitControls, MapControls} = Orb(THREE.EventDispatcher,
        THREE.MOUSE,
            THREE.Quaternion,
            THREE.Spherical,
            THREE.TOUCH,
            THREE.Vector2,
            THREE.Vector3)
        // 设置基本的Three.js场景、相机和渲染器
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
        // const OrbitControls = threeTsorbitControls;
        // 创建 OrbitControls 控件,并绑定到相机和渲染器
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true; // 启用阻尼感(惯性效果)
        controls.dampingFactor = 0.25; // 阻尼系数
        controls.screenSpacePanning = true; 
        controls.maxPolarAngle = Math.PI; 

        camera.position.set(100, 100, 500);  // 设置相机位置
        camera.lookAt(0, 0, 0);

        // 加载高度图
        // const textureLoader = new THREE.TextureLoader();
        // textureLoader.load('https://threejsfundamentals.org/threejs/resources/images/heightmap-96x64.png', );

        const createGeometryFn = (texture) => {
     
            const img = texture.image;
            const canvas = document.createElement('canvas');
            canvas.width = img.width;
            canvas.height = img.height;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0);

            const imgData = ctx.getImageData(0, 0, img.width, img.height).data;

            const geometry = new THREE.BufferGeometry();
            const positions = [];
            const colors = [];

            for (let y = 0; y < img.height; y++) {
     
                for (let x = 0; x < img.width; x++) {
     
                    // 获取像素的灰度值作为高度
                    const index = (y * img.width + x) * 4;
                    const height = imgData[index] / 255 * 50; // 0-255映射为高度范围
                    
                    // 设置每个点的位置 (x, y, height)
                    positions.push(x - img.width / 2, y - img.height / 2, height);

                    // 颜色映射,越高越鲜艳
                    const color = new THREE.Color(`hsl(${
       (height / 50) * 240}, 100%, 50%)`);
                    colors.push(color.r, color.g, color.b);
                }
            }

            // 将位置和颜色数据添加到BufferGeometry中
            geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
            geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

            // 创建点材质,启用顶点颜色
            const material = new THREE.PointsMaterial({
     
                size: 1.5,
                vertexColors: true
            });

            // 创建点云对象
            const points = new THREE.Points(geometry, material);
            scene.add(points);

            // 渲染循环
            function animate() {
     
                requestAnimationFrame(animate);

                // 更新OrbitControls状态
                controls.update();

                // 渲染场景
                renderer.render(scene, camera);
            }

            animate();
        }

        const createGeometryTiffFn = (canvas) => {
     
            const img = texture.image;
            canvas.width = img.width;
            canvas.height = img.height;
            const ctx = canvas.getContext('2d');


            const imgData = ctx.getImageData(0, 0, img.width, img.height).data;

            const geometry = new THREE.BufferGeometry();
            const positions = [];
            const colors = [];

            for (let y = 0; y < img.height; y++) {
     
                for (let x = 0; x < img.width; x++) {
     
                    // 获取像素的灰度值作为高度
                    const index = (y * img.width + x) * 4;
                    const height = imgData[index] / 255 * 50; // 0-255映射为高度范围
                    
                    // 设置每个点的位置 (x, y, height)
                    positions.push(x - img.width / 2, y - img.height / 2, height);

                    // 颜色映射,越高越鲜艳
                    const color = new THREE.Color(`hsl(${
       (height / 50) * 240}, 100%, 50%)`);
                    colors.push(color.r, color.g, color.b);
                }
            }

            // 将位置和颜色数据添加到BufferGeometry中
            geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
            geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

            // 创建点材质,启用顶点颜色
            const material = new THREE.PointsMaterial({
     
                size: 1.5,
                vertexColors: true
            });

            // 创建点云对象
            const points = new THREE.Points(geometry, material);
            scene.add(points);

            // 渲染循环
            function animate() {
     
                requestAnimationFrame(animate);

                // 更新OrbitControls状态
                controls.update();

                // 渲染场景
                renderer.render(scene, camera);
            }

            animate();
        }

        Tiff.initialize({
     TOTAL_MEMORY: 16777216 * 10});

        function loadFile(){
     
            const inputElement = document.createElement('input');
            inputElement.type = 'file';
            inputElement.accept = 'image/*';

            inputElement.addEventListener('change', (event) => {
     
                const file = event.target.files[0];
                const reader = new FileReader();
                console.log(file.name)
                reader.onload = function(e) {
     
                    let fname = file.name
                    if(fname.includes('tif')){
     //todo 我这里没有调试成功
                        const buffer = new Uint8Array(e.target.result);
                        var tiff = new Tiff({
     buffer: buffer});
                        console.log(tiff)
                        var canvas = tiff.toCanvas();
                        createGeometryTiffFn(canvas)
                    }else{
     
                        const img = new Image();
                        img.src = e.target.result;
                        
                        img.onload = function
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值