2023-03-22---webgl绘制坐标轴和视锥体

352 阅读1分钟

一、绘制结果

如图所示,其中红色为x轴,绿色为y轴,蓝色为z轴,

  • 原点位于地球表面,地球也向里偏移一个地球半径\color{orange}{原点位于地球表面,地球也向里偏移一个地球半径}
  • 白色为视锥体,其中视锥体已向里偏移一个地球半径\color{orange}{白色 为视锥体,其中视锥体已向里偏移一个地球半径}
  • 地球也向里偏移一个地球半径,这样视锥体与包围球图示的相交关系与不偏移\color{orange}{地球也向里偏移一个地球半径,这样视锥体与包围球图示的相交关系与不偏移} 算出的相交关系是一致的\color{orange}{算出的相交关系是一致的} image.png

二、代码

2.1、绘制三个轴

export class AxisGeometry extends BufferGeometry {
  constructor() {
    super()

    this.initGeometry()
  }


  initGeometry() {
    const positions = [
      0, 0, 0, earthRadius * 2, 0, 0,
      0, 0, 0, 0, earthRadius * 2, 0,
      0, 0, 0, 0, 0, earthRadius * 2
    ]

    const colors = [
      1, 0, 0, 255, 0, 0,
      0, 1, 0, 0, 1, 0,
      0, 0, 1, 0, 0, 1
    ]
    this.create({
      positions, colors
    }, gl.LINES)
  }

}

着色器:



export const originVS =/*glsl*/`
    attribute vec3 a_Position;
    attribute vec3 a_PositionHigh;
    attribute vec3 a_PositionLow;
    attribute vec3 a_Color;
    attribute vec2 a_Uv;
    uniform mat4 u_ModelMatrix;
    uniform mat4 u_ViewMatrix;
    uniform mat4 u_ProjectMatrix;
    uniform float u_LogDepthConst;
    uniform vec3 u_RefCenter;
    uniform vec3 u_RefCenterHigh;
    uniform vec3 u_RefCenterLow;
     uniform vec2 u_Frust;
    varying vec2 v_Uv;
    varying vec3 v_Color;



    void main(){
      mat4 mvpMatrix=u_ProjectMatrix*u_ViewMatrix*u_ModelMatrix;
      vec4 clip_Position=mvpMatrix*vec4(a_PositionHigh+a_PositionLow,1.0);
      v_Color=a_Color;
      gl_Position=clip_Position;
    }
  `


export const originFS =/*glsl*/`
  #ifdef GL_ES
  precision mediump float;
  #endif
  uniform vec3 u_Color;
  uniform float u_Alpha;
  
  varying vec2 v_Uv;
  varying vec3 v_Color;
  void main(){
  
      
      gl_FragColor=vec4(v_Color,u_Alpha);
  
  }`

2.2、绘制视锥体

import { BufferGeometry } from "./BufferGeometry.js";
import { toRadian } from "../Math/common.js";

export class FrustGeometry extends BufferGeometry {
  constructor({
    near,
    far,
    aspect,
    fovy,
    inverseViewMatrix
  }) {
    super()
    this._far = far
    this._near = near
    this._aspect = aspect
    this._fovy = fovy
    this._inverseViewMatrix = inverseViewMatrix
    this.initGeometry()
  }


  initGeometry() {
    const topFar = this._far * Math.tan(toRadian((this._fovy - 0.1) / 2))
    const bottomFar = -topFar
    const rightFar = this._aspect * topFar
    const leftFar = -rightFar

    const topNear = this._near * Math.tan(toRadian((this._fovy - 0.1) / 2))
    const bottomNear = -topNear
    const rightNear = this._aspect * topNear
    const leftNear = -rightNear

    //计算视图坐标中的
    const positions = [
      0, 0, 0,
      rightNear, topNear, -this._near,
      rightNear, bottomNear, -this._near,
      leftNear, topNear, -this._near,
      leftNear, bottomNear, -this._near,
      rightFar, topFar, -this._far,
      rightFar, bottomFar, -this._far,
      leftFar, topFar, -this._far,
      leftFar, bottomFar, -this._far,
    ]
    //转为世界坐标
    // for (let i = 0; i < positions.length; i += 3) {
    //   const vector = { elements: [positions[i], positions[i + 1], positions[i + 2], 1.0] }
    //   const worldVector = this._inverseViewMatrix.multiplyVector4(vector)
    //   positions[i] = worldVector.elements[0]
    //   positions[i + 1] = worldVector.elements[1]
    //   positions[i + 2] = worldVector.elements[2]
    // }
    // console.log(positions)
    const indexes = [
      0, 5, 0, 6, 0, 7, 0, 8,//四个棱
      1, 3, 3, 4, 4, 2, 2, 1,//近平面线
      5, 7, 7, 8, 8, 6, 6, 5 //远平面线
    ]

    this.create({
      positions, indexes: indexes
    }, gl.LINES)
  }

}

着色器代码



export const frustVS =/*glsl*/`
    attribute vec3 a_Position;
    attribute vec3 a_PositionHigh;
    attribute vec3 a_PositionLow;
    attribute vec2 a_Uv;
    uniform mat4 u_ModelMatrix;
    uniform mat4 u_ViewMatrix;
    uniform mat4 u_InverseViewMatrix;
    uniform mat4 u_ProjectMatrix;
    uniform float u_LogDepthConst;
    uniform vec3 u_RefCenter;
    uniform vec3 u_RefCenterHigh;
    uniform vec3 u_RefCenterLow;
     uniform vec2 u_Frust;
    varying vec2 v_Uv;



    void main(){
      mat4 mvpMatrix=u_ProjectMatrix;
      
      vec4 clip_Position=mvpMatrix*vec4(a_Position.xy,a_Position.z-6378137.0,1.0);
      v_Uv=a_Uv;
      gl_Position=clip_Position;
    }
  `


export const frustFS =/*glsl*/`
  #ifdef GL_ES
  precision mediump float;
  #endif
  uniform vec3 u_Color;
  uniform float u_Alpha;
  
  varying vec2 v_Uv;

  void main(){
  
      
      gl_FragColor=vec4(u_Color,u_Alpha);
  
  }`