Matrix 在WebGL中,我可以使用矩阵在屏幕空间中绘制对象偏移吗?

Matrix 在WebGL中,我可以使用矩阵在屏幕空间中绘制对象偏移吗?,matrix,3d,webgl,Matrix,3d,Webgl,我有一个简单的对象,它在0,0,0处绘制一个3d gizmo。如果摄影机以0、0、0为中心,则它会在屏幕中心绘制gizmo 我想“提起”这个小控件,并在屏幕坐标系下在屏幕的右下角渲染它,而不旋转它。基本上,我希望gizmo显示屏幕中心的旋转,而不阻塞视图,也不必聚焦于特定点。所以我想去掉模型矩阵之类的东西 通过转换投影矩阵,我得到了以下结果: 但gizmo已旋转到其新位置。红线仍应指向下方和左侧,因为这是屏幕中心正X轴的方向。另外,数字5和3是任意的,我不认为它们在不同的缩放或相机位置工作

我有一个简单的对象,它在0,0,0处绘制一个3d gizmo。如果摄影机以0、0、0为中心,则它会在屏幕中心绘制gizmo

我想“提起”这个小控件,并在屏幕坐标系下在屏幕的右下角渲染它,而不旋转它。基本上,我希望gizmo显示屏幕中心的旋转,而不阻塞视图,也不必聚焦于特定点。所以我想去掉模型矩阵之类的东西

通过转换投影矩阵,我得到了以下结果:

但gizmo已旋转到其新位置。红线仍应指向下方和左侧,因为这是屏幕中心正X轴的方向。另外,数字5和3是任意的,我不认为它们在不同的缩放或相机位置工作


有没有一种方法可以指定一个矩阵变换,它占据屏幕的中心并在屏幕空间中进行转换?

一种方法是在渲染该对象时更改视口

// size of area in bottom right
const miniWidth = 150;
const miniHeight = 100;
gl.viewport(gl.canvas.width - miniWidth, gl.canvas.height - miniHeight, miniWidth, miniHeight);

// now draw. you'll need to zoom in, like set the camera closer
// or move the object closer or add a scale matrix after the projection
// matrix as in projection * scale * view * ...
您需要一个与新视口的纵横比相匹配的投影矩阵,并且您需要缩放对象、将相机靠近或在投影矩阵和视图矩阵之间添加二维比例。 记住将视口放回完整画布以渲染场景的其余部分

const vs=`
属性向量4位置;
均匀mat4 u_世界视图投影;
void main(){
gl_位置=u_世界视图投影*位置;
}
`;
常数fs=`
精密中泵浮子;
void main(){
gl_FragColor=vec4(vec3(0),1);
}
`
const gl=document.querySelector(“canvas”).getContext(“webgl”);
const programInfo=twgl.createProgramInfo(gl[vs,fs]);
const bufferInfo=twgl.createBufferInfoFromArrays(gl{
职位:[
-1, -1, -1,
1, -1, -1,
1,  1, -1,
-1,  1, -1,
-1, -1,  1,
1, -1,  1,
1,  1,  1,
-1,  1,  1,
],
指数:{
NUM组件:2,
数据:[
0, 1,
1, 2,
2, 3,
3, 0,
4, 5,
5, 6,
6, 7,
7, 4,
0, 4,
1, 5,
2, 6,
3, 7,
],
},
});
函数渲染(时间){
时间*=0.001;
twgl.resizeCanvasToDisplaySize(总图画布);
总图视口(0,0,总图画布宽度,总图画布高度);
常数fov=90*Math.PI/180;
常数zNear=0.5;
常数zFar=100;
const projection=mat4.perspective(mat4.create(),
fov,gl.canvas.clientWidth/gl.canvas.clientHeight,zNear,zFar);
常数眼=[0,0,10];
常量目标=[0,0,0];
const up=[0,1,0];
const view=mat4.lookAt(mat4.create(),眼睛,目标,向上);
drawCube([-8,0,0],投影,视图);
drawCube([-4,0,0],投影,视图);
drawCube([0,0,0],投影,视图);
drawCube([4,0,0],投影,视图);
drawCube([8,0,0],投影,视图);
常数iconAreaWidth=100;
常数iconAreaHeight=75;
总图视口(
gl.canvas.width-图标宽度,0,
iconAreaWidth,iconAreaHeight);
const iconproject=mat4.perspective(mat4.create(),
视野、图像宽度/图像高度、zNear、zFar);
//计算缩放大小,使之成为SNG
常量比例=gl.canvas.clientHeight/iconAreaHeight;
mat4.比例(图标投影,图标投影,[比例,比例,1]);
drawCube([0,0,0],图标投影,视图);
函数drawCube(平移、投影、视图){
const viewProjection=mat4.multiply(mat4.create(),projection,view);
常量世界=mat4.5倍(
mat4.create(),
mat4.fromTranslation(mat4.create(),translation),
mat4.fromRotation(mat4.create(),time[0.42,0.56,0.70]);
const worldViewProjection=mat4.multiply(mat4.create(),viewProjection,world);
总账使用程序(programInfo.program);
twgl.setBuffersAndAttributes(总帐、程序信息、缓冲信息);
twgl.设置制服(程序信息{
世界视图投影:世界视图投影,
});
twgl.drawBufferInfo(总帐,bufferInfo,总帐行);
}
请求动画帧(渲染);
}
请求动画帧(渲染)
body{margin:0;}
画布{宽度:100vw;高度:100vh;显示:块;背景:#CDE;}

我使用了修改后的视口。虽然我需要一个更近的相机/视图矩阵和一个新的方形透视矩阵,但这是一个非常简单的解决方案!结果是:谢谢。
// size of area in bottom right
const miniWidth = 150;
const miniHeight = 100;
gl.viewport(gl.canvas.width - miniWidth, gl.canvas.height - miniHeight, miniWidth, miniHeight);

// now draw. you'll need to zoom in, like set the camera closer
// or move the object closer or add a scale matrix after the projection
// matrix as in projection * scale * view * ...