如何将 3D 坐标转换为 2D (X,Y) 以将文本 div 定位在 3d 游戏对象正下方
How to convert 3D coordinates into 2D (X,Y) for positioning text div just below the 3d game object
我需要在屏幕上将 DIVSet 定位在 3d 播放器正下方的正确 X、Y 位置,但我不确定如何将 x、y、z 转换为 x、y 坐标。
this.player = player => {
const pos = interpolate(player.position, player.movementVector)
resetDivSets()
calcViewMatrix()
mat4Translate(viewMatrix, -pos.x * glScale, -3.1 * glScale, pos.y * glScale)
mat4RotateY(viewMatrix, playerRotation(player, player.drawMovementVector))
gl.uniformMatrix4fv(uVmatrix, false, viewMatrix)
gl.uniform3f(uAmbientColor, 1, 1, 1)
gl.drawElements(gl.TRIANGLES, builtSprites.player.ibCount, gl.UNSIGNED_SHORT, builtSprites.player.ibStart * 2)
// compute a clipspace position
var clipspace = WHAT TO HAVE HERE??;
// divide X and Y by W just like the GPU does.
clipspace[0] /= clipspace[3];
clipspace[1] /= clipspace[3];
// convert from clipspace to pixels
var pixelX = (clipspace[0] * 0.5 + 0.5) * gl.canvas.width;
var pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;
addDivSet("Player Name under player object", pixelX , pixelY);
基本上
// compute a clipspace position
var modelRelativePosition = [0, 0, 0, 1]; // NOTE!! w = 1
var clipspace = m4.transformVector(uVmatrix, modelRelativePosition);
// divide X and Y by W just like the GPU does.
clipspace[0] /= clipspace[3];
clipspace[1] /= clipspace[3];
// convert from clipspace to pixels
var pixelX = (clipspace[0] * 0.5 + 0.5) * gl.canvas.width;
var pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;
// position the div
div.style.left = Math.floor(pixelX) + "px";
div.style.top = Math.floor(pixelY) + "px";
其中 transformVector 类似于
function transformVector(m, v, dst) {
dst = new Float32Array(4);
for (var i = 0; i < 4; ++i) {
dst[i] = 0.0;
for (var j = 0; j < 4; ++j) {
dst[i] += v[j] * m[j * 4 + i];
}
}
return dst;
}
如果您想在 2d 中进行偏移,只需在底部添加即可
div.style.left = Math.floor(pixelX + offsetX) + "px";
div.style.top = Math.floor(pixelY + offsetY) + "px";
const gl = document.createElement('canvas').getContext('webgl');
// use the identity matrix as a test
var uVmatrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
];
// compute a clipspace position
var modelRelativePosition = [0, 0, 0, 1]; // NOTE! w = 1
var clipspace = transformVector(uVmatrix, modelRelativePosition);
// divide X and Y by W just like the GPU does.
clipspace[0] /= clipspace[3];
clipspace[1] /= clipspace[3];
// convert from clipspace to pixels
var pixelX = (clipspace[0] * 0.5 + 0.5) * gl.canvas.width;
var pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;
// position the div
//div.style.left = Math.floor(pixelX) + "px";
//div.style.top = Math.floor(pixelY) + "px";
console.log(Math.floor(pixelX) + "px", Math.floor(pixelY) + "px");
function transformVector(m, v, dst) {
dst = new Float32Array(4);
for (var i = 0; i < 4; ++i) {
dst[i] = 0.0;
for (var j = 0; j < 4; ++j) {
dst[i] += v[j] * m[j * 4 + i];
}
}
return dst;
}
我需要在屏幕上将 DIVSet 定位在 3d 播放器正下方的正确 X、Y 位置,但我不确定如何将 x、y、z 转换为 x、y 坐标。
this.player = player => {
const pos = interpolate(player.position, player.movementVector)
resetDivSets()
calcViewMatrix()
mat4Translate(viewMatrix, -pos.x * glScale, -3.1 * glScale, pos.y * glScale)
mat4RotateY(viewMatrix, playerRotation(player, player.drawMovementVector))
gl.uniformMatrix4fv(uVmatrix, false, viewMatrix)
gl.uniform3f(uAmbientColor, 1, 1, 1)
gl.drawElements(gl.TRIANGLES, builtSprites.player.ibCount, gl.UNSIGNED_SHORT, builtSprites.player.ibStart * 2)
// compute a clipspace position
var clipspace = WHAT TO HAVE HERE??;
// divide X and Y by W just like the GPU does.
clipspace[0] /= clipspace[3];
clipspace[1] /= clipspace[3];
// convert from clipspace to pixels
var pixelX = (clipspace[0] * 0.5 + 0.5) * gl.canvas.width;
var pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;
addDivSet("Player Name under player object", pixelX , pixelY);
基本上
// compute a clipspace position
var modelRelativePosition = [0, 0, 0, 1]; // NOTE!! w = 1
var clipspace = m4.transformVector(uVmatrix, modelRelativePosition);
// divide X and Y by W just like the GPU does.
clipspace[0] /= clipspace[3];
clipspace[1] /= clipspace[3];
// convert from clipspace to pixels
var pixelX = (clipspace[0] * 0.5 + 0.5) * gl.canvas.width;
var pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;
// position the div
div.style.left = Math.floor(pixelX) + "px";
div.style.top = Math.floor(pixelY) + "px";
其中 transformVector 类似于
function transformVector(m, v, dst) {
dst = new Float32Array(4);
for (var i = 0; i < 4; ++i) {
dst[i] = 0.0;
for (var j = 0; j < 4; ++j) {
dst[i] += v[j] * m[j * 4 + i];
}
}
return dst;
}
如果您想在 2d 中进行偏移,只需在底部添加即可
div.style.left = Math.floor(pixelX + offsetX) + "px";
div.style.top = Math.floor(pixelY + offsetY) + "px";
const gl = document.createElement('canvas').getContext('webgl');
// use the identity matrix as a test
var uVmatrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
];
// compute a clipspace position
var modelRelativePosition = [0, 0, 0, 1]; // NOTE! w = 1
var clipspace = transformVector(uVmatrix, modelRelativePosition);
// divide X and Y by W just like the GPU does.
clipspace[0] /= clipspace[3];
clipspace[1] /= clipspace[3];
// convert from clipspace to pixels
var pixelX = (clipspace[0] * 0.5 + 0.5) * gl.canvas.width;
var pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;
// position the div
//div.style.left = Math.floor(pixelX) + "px";
//div.style.top = Math.floor(pixelY) + "px";
console.log(Math.floor(pixelX) + "px", Math.floor(pixelY) + "px");
function transformVector(m, v, dst) {
dst = new Float32Array(4);
for (var i = 0; i < 4; ++i) {
dst[i] = 0.0;
for (var j = 0; j < 4; ++j) {
dst[i] += v[j] * m[j * 4 + i];
}
}
return dst;
}