Javascript 我在使用RTC渲染技术渲染对象时遇到问题

Javascript 我在使用RTC渲染技术渲染对象时遇到问题,javascript,three.js,webgl,Javascript,Three.js,Webgl,我正在尝试使用相对中心技术渲染一个简单的平面。当你开始在gpu上处理非常大的数字时,比如6378137,地球的半径,由于gpu上的浮点计算精度错误,物体开始抖动。解决此问题的一种方法是渲染相对于对象中心的对象 基本思想是 确保位置缓冲区包含相对于几何体中心的顶点,默认情况下ThreeJS会这样做。例如,对于一个点,0,0,0 通过使用cpu/双精度将中心乘以modelview矩阵,将中心坐标转换为中心眼 前 (mv00、mv01、mv02、centerX、 mv10、mv11、mv12、cent

我正在尝试使用相对中心技术渲染一个简单的平面。当你开始在gpu上处理非常大的数字时,比如6378137,地球的半径,由于gpu上的浮点计算精度错误,物体开始抖动。解决此问题的一种方法是渲染相对于对象中心的对象

基本思想是

  • 确保位置缓冲区包含相对于几何体中心的顶点,默认情况下ThreeJS会这样做。例如,对于一个点,0,0,0

  • 通过使用cpu/双精度将中心乘以modelview矩阵,将中心坐标转换为中心眼

  • (mv00、mv01、mv02、centerX、

    mv10、mv11、mv12、centerY、

    mv20、mv21、mv22、centerZ、

    mv30、mv31、mv32、mv33)

  • 在着色器中使用该矩阵可避免任何双精度乘法(使矩阵中的值保持较小,并消除大多数对象的抖动)
  • 我知道我的modelview矩阵是正确的,因为我已经在没有RTC的着色器中使用它进行了测试,并简单地将我的x坐标转换为6378137

      <script id="vertex_shader" type="x-shader/x-vertex">
    uniform mat4 mv;
    void main() {
      gl_Position = projectionMatrix * mv * vec4(position, 1.0);
    }
    
    出于某种原因,这会渲染场景,使平面朝向错误的方向,因此看起来像一条直线


    *错误出现在matrix4的set()方法中,我只需要以列主格式读取modelview矩阵的值。我更新了代码,使其现在是正确的。

    *其他人回答了问题,然后删除了答案,但他们似乎非常接近,所以无论是谁发表了评论,我都会尝试给你评分。错误在matrix4的set()方法中,我只需要读取列major Format中modelview矩阵的值。答案是错误的,这就是为什么它被删除的原因。Three.js在元素12,13,14中存储具有位置的矩阵,但与Three.js中的许多不一致一样,
    Matrix4.set
    函数期望参数3,7,11中的位置好的,我将把这个留给任何需要它的人,以备将来参考,我想。。。对于其他人的参考,RTC可以减少抖动,精度高达1厘米,但您的对象不应超过约131071米的边界半径,这在大多数情况下是可以的。如果您需要更大的东西,您应该在cpu/gpu上查找相对于眼睛的渲染-来源:为了更好的精度,您应该考虑添加<代码>精度高浮点;<代码>在着色器的开头。
      <script id="fragment_shader" type="x-shader/x-fragment">
    void main() {
      gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );
    }
    
    var geometry = new THREE.PlaneBufferGeometry( 50, 50 );
    let material = new THREE.ShaderMaterial( {
      side:THREE.DoubleSide,
      wireframe:true,
      vertexShader: document.getElementById('vertex_shader').textContent,
      fragmentShader: document.getElementById('fragment_shader').textContent
    })
    material.uniforms.mv = {
      type:'m4',
      value: new THREE.Matrix4()
    }
    var plane = new THREE.Mesh( geometry, material );
    plane.onBeforeRender = (renderer, scene, camera, geometry, material) => {
      let mv = new THREE.Matrix4();
      //calculate modelview matrix w/ view x modelmatrix
      mv = mv.multiplyMatrices(camera.matrixWorldInverse, plane.matrixWorld);
      let center = new THREE.Vector4(6378137, 0.0, 0.0, 1.0);
      //multiply mv by center
      center.applyMatrix4(mv);
      let newMV = new THREE.Matrix4().set(mv.elements[0], mv.elements[4], mv.elements[8], center.x,
                                  mv.elements[1], mv.elements[5], mv.elements[9], center.y,
                                  mv.elements[2], mv.elements[6], mv.elements[10], center.z,
                                  mv.elements[3], mv.elements[7], mv.elements[11], mv.elements[15]);
    
      material.uniforms.mv.value = newMV;
    }
    scene.add( plane );