一、绘制结果
如图所示,其中红色为x轴,绿色为y轴,蓝色为z轴,
二、代码
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);
}`