不知道错哪了
来源:6-3 透视投影
小小奥
2022-12-14
{
function initShader(gl: WebGLRenderingContext, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE) {
// 创建着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER)!
// 创建片元着色器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)!
gl.shaderSource(vertexShader, VERTEX_SHADER_SOURCE) // 指定 着色器的源码
gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE) // 指定 片元着色器的源码
// 编译着色器
gl.compileShader(vertexShader)
gl.compileShader(fragmentShader)
// 创建一个程序对象
const program = gl.createProgram()!
// 指定 着色器
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
gl.useProgram(program)
return program
}
const ctx = document.getElementById('canvas') as HTMLCanvasElement
const gl = ctx.getContext('webgl')!
/** 顶点着色器 */
const VERTEX_SHADER_SOURCE = `
attribute vec4 aColor;
varying vec4 vColor;
attribute vec4 aPosition;
uniform mat4 mat;
void main() {
gl_Position = mat * aPosition;
vColor = aColor;
}
`
/* 片元着色器 */
const FRAGMENT_SHADER_SOURCE = `
precision lowp float;
varying vec4 vColor;
void main() {
// vec4() => 将 vec3 的数据 转换为 vec4
gl_FragColor = vColor;
}
`
const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition')
const aColor = gl.getAttribLocation(program, 'aColor')
const mat = gl.getUniformLocation(program, 'mat')
function getTranslateMatrix(x = 0, y = 0, z = 0) {
return new Float32Array([
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1
])
}
// 创建顶点数据
// 给 attribute vec4 aPosition 变量赋值
const points = new Float32Array([
0.75, 1.0, 0.6, 1.0, 0.0, 0.0,
0.25, -1.0, 0.6, 1.0, 0.0, 0.0,
1.0, -1.0, 0.6, 1.0, 0.0, 0.0,
0.75, 1.0, 0.5, 0.0, 1.0, 0.0,
0.25, -1.0, 0.5, 0.0, 1.0, 0.0,
1.0, -1.0, 0.5, 0.0, 1.0, 0.0,
0.75, 1.0, 0.4, 0.0, 0.0, 1.0,
0.25, -1.0, 0.4, 0.0, 0.0, 1.0,
1.0, -1.0, 0.4, 0.0, 0.0, 1.0,
-0.75, 1.0, 0.6, 1.0, 0.0, 0.0,
-0.25, -1.0, 0.6, 1.0, 0.0, 0.0,
-1.0, -1.0, 0.6, 1.0, 0.0, 0.0,
-0.75, 1.0, 0.5, 0.0, 1.0, 0.0,
-0.25, -1.0, 0.5, 0.0, 1.0, 0.0,
-1.0, -1.0, 0.5, 0.0, 1.0, 0.0,
-0.75, 1.0, 0.4, 0.0, 0.0, 1.0,
-0.25, -1.0, 0.4, 0.0, 0.0, 1.0,
-1.0, -1.0, 0.4, 0.0, 0.0, 1.0,
])
// 创建缓冲区 对象
const buffer = gl.createBuffer()
const BYTES = points.BYTES_PER_ELEMENT
// 绑定缓冲区 对象
gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW)
gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, BYTES * 6, 0)
gl.enableVertexAttribArray(aPosition)
gl.vertexAttribPointer(aColor, 3, gl.FLOAT, false, BYTES * 6, BYTES * 3)
gl.enableVertexAttribArray(aColor)
gl.drawArrays(gl.TRIANGLES, 0, 3 * 6)
/** 创建 透视投影矩阵 */
// fov 视角
// aspect 宽高比
// far 块
function getPerspective(fov, aspect, far, near) {
fov = fov * Math.PI / 100
return new Float32Array([
1/(aspect*Math.tan(fov/2)), 0, 0, 0,
0, 1/(Math.tan(fov/2)), 0, 0,
0, 0, -(far + near)/(far - near), -(2*far*near)/(far-near),
0, 0, -1, 0
])
}
let eyex = 0.0
let eyey = -0.1
let eyez = 0.2
function draw() {
const vm = getViewMatrix(eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 0.6, 0.0)
console.log('vm', vm)
const perspective = getPerspective(150, ctx.width / ctx.height, 100, 1)
console.log('perspective', perspective)
gl.uniformMatrix4fv(mat, false, maxMatrix(vm, perspective))
gl.drawArrays(gl.TRIANGLES, 0, 3 * 6)
// requestAnimationFrame(draw)
}
draw()
document.onkeydown = function (e) {
switch(e.keyCode) {
case 37:
eyex += 0.01
break
case 38:
eyex -= 0.01
break
case 39:
eyey += 0.01
break
case 40:
eyey -= 0.01
break
}
draw()
}
// 归一化 函数
function normalized(arr: Float32Array) {
let sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i] * arr[i]
}
// 返回 目标数字的 平方根 => 4 -> 2 9 -> 3
const middle = Math.sqrt(sum)
for (let i = 0; i < arr.length; i++) {
arr[i] = arr[i] / middle
}
}
// 叉积函数, 获取法向量
function cross(a, b) {
return new Float32Array([
a[1] * b[2] - a[2] * b[1],
a[2] * b[0] - a[0] * b[2],
a[0] * b[1] - a[1] * b[0]
])
}
// 实现点积 函数, 获取 投影长度
function dot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
}
// 向量差
function minus(a, b) {
return new Float32Array([
a[0] - b[0],
a[1] - b[1],
a[2] - b[2]
])
}
// 视图 矩阵获取
function getViewMatrix(eyex, eyey, eyez, lookAtx, lookAty, lookAtz, upx, upy, upz) {
// 视点
const eye = new Float32Array([eyex, eyey, eyez])
// 目标点
const lookAt = new Float32Array([lookAtx, lookAty, lookAtz])
// 上方向
const up = new Float32Array([upx, upy, upz])
// z 轴的向量差 通过 视点 和 目标点 确定
const z = minus(eye, lookAt)
normalized(z)
normalized(up)
// 确定 x 轴
const x = cross(z, up)
normalized(x)
// 确定 y 轴
const y = cross(x, z)
return new Float32Array([
x[0], y[0], z[0], 0,
x[1], y[1], z[1], 0,
x[2], y[2], z[2], 0,
-dot(x, eye), -dot(y, eye), -dot(z, eye), 1
])
}
// 获取 正射投影矩阵
function getOrtho(l, r, t, b, n, f) {
return new Float32Array([
2 / (r - l), 0, 0, 0,
0, 2 / (t - b), 0, 0,
0, 0, -2 / (f - n), 0,
- (r + l) / (r - l), -(t + b) / (t - b), -(f + n)/(f - n), 1
])
}
function maxMatrix(A, B) {
const result = new Float32Array(16)
for (let i = 0; i < 4; i++) {
result[i] = A[i] * B[0] + A[i + 4] * B[1] + A[i + 8] * B[2] + A[i + 12] * B[3]
result[i + 4] = A[i] * B[4] + A[i + 4] * B[5] + A[i + 8] * B[6] + A[i + 12] * B[7]
result[i + 8] = A[i] * B[8] + A[i + 4] * B[9] + A[i + 8] * B[10] + A[i + 12] * B[11]
result[i + 12] = A[i] * B[12] + A[i + 4] * B[13] + A[i + 8] * B[14] + A[i + 12] * B[15]
}
return result
}
}
6个三角形 没有渲染出来, 不知道错哪了
老师你能不能把最新的代码 提交一下, 我看着视频对比 代码 有点难受
写回答
2回答
-
points里的坐标出现了问题,z坐标是负的就可以看到图形了。像这种
,,-, ,,, ,-,-, ,,, , -,-, ,,, ,,-, ,,, ,-,-, ,,, , -,-, ,,, ,,-, ,,, ,-,-, ,,, , -,-, ,,, -,,-, ,,, -,-,-, ,,, -, -,-, ,,, -,,-, ,,, -,-,-, ,,, -, -,-, ,,, -,,-, ,,, -,-,-, ,,, -, -,-, ,,,
-0.6, -0.5,-0.4
代码已经上传上去了,可以在代码库里重新拉一下022022-12-15 -
yancy
2022-12-14
好的,我传下代码。过会儿我看下问题出在哪儿了
00
相似问题