问题如图所示,点击中间的白柱子,结果高亮的构件在下方。 "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250107/1bf52f8636a53878cc5144ea77b51026.png) 我说一下我写的方法: 1、因为我只是浅调整了高度,所以通过调整"element.position.y",给模型进行了高度偏移,这里是向上偏移了2.5,所以,position打印出来是"{x: 0, y: 2.5, z: 0}",我知道这里是更改了模型的原点。 2、然后,我给光线投射raycaster增加了改动变量,"raycaster.ray.origin.add(finalPosition);",这里的finalPosition的值就是"{x: 0, y: 2.5, z: 0}",因为原先的原点是0,0,0,所以这里用"raycaster.ray.origin.add"或者"raycaster.ray.origin.set",我看渲染出来是一样的。 3、再然后,因为是要做模型分层的,所以我就没有直接使用scene.children,而是整了另一个数据集合models来做参考。"raycaster.intersectObjects(models);" (因为单纯的将visible设置为false,鼠标还是可以点击到的,所以要整一个新的数据集合来进行数据的清理) 目前看来,感觉是第三步出了问题,就好像模型都向上移动了2.5,结果光线投射这里的参考数据models还是在0,0,0。可是我打印models的时候,看到position也是0,2.5,0,甚至我后来给里面的所有构件都加上了偏移量,都是0,2.5,0。结果还是一样......实在是想不出到底问题出在哪里了啊,求教~~~~~ ~
如下图所示: 我想实现的是,点击一个构件的时候,标签弹窗会出现在构件上方,与构件是在一个平面上;如果我转到模型的另一面,再点击一个构件,也是在一个平面上,跟构件一个朝向。 想要的效果是这样: "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250108/3864616737e54cc66c6293da9dc1cd00.png) 但是,实际上,总是会出现各种角度偏转: "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250108/787fb9abf3c2b2516f96cbc4362f2756.png)"image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250108/6eea1630cbf97187139ac3ae03469830.png)"image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250108/c2174919aabfbf43a74de7a354cd38f7.png) 实在是搞不懂怎么实现了... 之前是用2D去实现的,但是会出现缩放的时候,弹窗大小比例不正确、弹窗与构件之间的距离有误等问题,所以,尝试多次后还是决定用3D来实现,没想到碰到这个问题,这如何解决? 补充问题: lookAt的方法我是使用过的,但是会出现这样的奇葩情况 "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250108/f25e93196d974dd172ad559571a4a139.png) 弹窗下面的指示线乱指,标签的角度也是很奇怪...
//创建纹理加载器 let textureLoader = new THREE.TextureLoader() //加载纹理 let texture = textureLoader.load('./textures/parvers/worn_patterned_pavers_diff_4k.jpg') // let texture = textureLoader.load('./textures/covers/Sewer-0793.jpg') //设置sRGB纹理的颜色空间 texture.colorSpace = THREE.SRGBColorSpace gui.add(texture, 'colorSpace', { sRGB: THREE.SRGBColorSpace, Linear: THREE.LinearSRGBColorSpace }).onChange((val) => { console.log('change',val) console.log(texture) console.log(texture.colorSpace) texture.needsUpdate = true }) 输出的内容显示,texture对象的colorSpace已经改变了,但是页面没有重新渲染。 即便在使用后,texture.needsUpdate = true 后,仍然没有效果。 值得注意的是,当我不设置texture的颜色空间,即texture.colorSpace = THREE.LinearSRBColorSpace 或者 THREE.NoColorSpace的时候,可以实现页面从linear-srgb到srgb的转换,但是不能实现srgb到linear-srgb的转换。 这是什么情况导致的?该如何实现GUI控制纹理的颜色空间的转变? 补充1: https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20241225/33ab8b5ed06b3ea7995269e67302d04e.png 根据官方文档,只要改变颜色空间,就需要将材质的needsUpdate设置为true就可以重新编译了,但是,即使我在onchange中的回调函数中加上material.needsUpdate = true也并没有什么改变
我拿到一段代码片段: const i = this._shouldRender(); if (i) { this._renderRequested = !1; // 将当前对象的 _renderRequested 属性设置为 false(注意:在JavaScript中 !1 等同于 false)。这可能意味着渲染请求已经被处理,或者不再需要渲染。 const i = r.Math.incrementWrap(t.frameNumber, 15e6, 1); // 这行代码再次声明了一个常量 i(这会覆盖之前声明的 i),并调用了 r.Math.incrementWrap 方法,传入了三个参数:t.frameNumber(当前的帧编号)、15e6(可能是帧编号的最大值,这里使用的是1500万)、1(增量)。incrementWrap 方法可能是用来增加帧编号,并在达到最大值时将其环绕(wrap)回到起始值。 this.updateFrameNumber(i, e), // 这行代码调用当前对象的 updateFrameNumber 方法,更新帧编号。它传入了新的帧编号 i 和另一个参数 e t.newFrame = !0 // 将某个对象 t 的 newFrame 属性设置为 true(在JavaScript中 !0 等同于 true)。这可能意味着标记了一个新的渲染帧的开始。 } // 综合来看,这段代码的作用是检查是否应该渲染新的一帧,如果是,则取消渲染请求标志,更新帧编号,并标记新帧的开始。这是典型的在游戏或者图形应用中用于控制帧更新和渲染的逻辑。 这段代码是用来判断是否渲染新的一帧的,这个我理解。但是,不太理解的是,为啥要给数据打上一个帧编号"t.frameNumber",并对应的进行更新。这个"t.frameNumber"在整个帧更新中的作用是什么? 难道是当前帧数与帧编号相同的就进行渲染更新?还是...?
// 引入threejs import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 1.创建一个三维场景scene const scene = new THREE.Scene(); const geometry = new THREE.BoxGeometry(100, 100, 100); // * 添加光照 // ! MeshBasicMaterial 不受光材质 // ! MeshLambertMaterial 漫反射 受光材质 const material = new THREE.MeshLambertMaterial({color: 0x0000ff}); // 2。创建网格模型 const mesh = new THREE.Mesh(geometry, material); // mesh.position.set(0, 0, 0); // * 集合体的位置 默认原点 scene.add(mesh); // * 创建一个三维坐标轴 const axesHelper = new THREE.AxesHelper(250); scene.add(axesHelper); // * 创建一个光源 const light = new THREE.PointLight(0xffffff, 1); light.position.set(100, 100, 30); // * 设置光源位置 scene.add(light); // * 添加光源 const pointLightHelper = new THREE.PointLightHelper(light, 10); scene.add(pointLightHelper); // 3.用来设置canvas的宽高 const sizes = { width: 1200, height: 800, }; // 4.透视相机设置 const camera = new THREE.PerspectiveCamera( 45, sizes.width / sizes.height, 1, 30000, ); // * 改变相机位置 camera.position.set(400, 400, 400); // * 斜对角位置 camera.lookAt(0, 0, 0); // 5.创建渲染器 const renderer = new THREE.WebGLRenderer(); renderer.setSize(sizes.width, sizes.height); // 设置渲染区域尺寸 renderer.render(scene, camera); // 把结果canvas画布添加到网页上 document.getElementById('main').appendChild(renderer.domElement); const orbitControls = new OrbitControls(camera, renderer.domElement); orbitControls.addEventListener('change', () => { renderer.render(scene, camera); }); Document { "imports": { "three": "../../build/three.module.js", "three/addons/": "../../jsm/" } } .mainCanvas { width: 100%; height: 100%; } https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241008/d9b6c71d75829ed7bbc977f2abf9f7e2.png 把PointLight改成平行光就可以显示出来。
如图所示,渲染的时候,有时候会出现下面的两种情况: 图一,就是随机出现不规则的面,有时候过一会儿会消失,有时候不会。使用光线投射点击它的时候,并没有获取到什么信息,例如,点击草地区域上面的不规则面的时候,会返回的是草地mesh的信息。 图二,直接就是整个场景都变成了纯色并且一堆的噪点,这种情况就不会消失,只能刷新页面重新渲染。 这两个都是因为什么才出现的状况啊?如何解决? 图一(两个图): "不规则面" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240918/58aa3a167c5bbb751b8f0fe838aea2d6.png) "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240918/405e82b25ca8ad18966e3efad551a24c.png) 图二: "全场景噪点" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240918/8f2dc2737723e54c0ac38efae43d50b8.png)
原需求是将模型与地图进行结合渲染,结合的问题解决了。 但是,甲方提出一个需求说是希望使用地理坐标系的模型,这样可以方便后续的一些操作,虽然一时没有想明白,但是还是要做。 我的想法是: 1、模型在给到前端的时候,就已经是从地理坐标系转成了适用的右手坐标系。(这当然是最好的了) 2、在渲染前,可以对three进行一些配置,让其识别地理坐标系。 3、或者在添加到场景前先对所有构件进行坐标的转换。 ... 2和3,哪种有可执行的地步呢?亦或是有更好的办法?
背景: 对threejs的官方文档入门相关的知识熟悉了一遍之后,想通过示例,更好地直观地熟悉threejs的使用,更贴近实际业务需求。有没有什么好的threejs示例供参考、学习?
threejs如何获取一个几何体其中一个面的形状? "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241010/0bd26e85ff02209f9bf51c91d839c611.png) const waterGeometry = this.scene.getObjectByName('小河'); let position = waterGeometry.geometry.attributes.position; //拿到顶点坐标,然后创建曲线
threejs 柱状图如何实现渐变色,比如从红色变成蓝色 "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241002/689f682c086c26c223273e6e24441c62.png)