Javascript 如何在模型视图转换后在webgl上获取为命中测试绘制的对象的二维尺寸

Javascript 如何在模型视图转换后在webgl上获取为命中测试绘制的对象的二维尺寸,javascript,html,css,node.js,webgl,Javascript,Html,Css,Node.js,Webgl,我遵循webgl基础知识,绘制2d对象,并使用矩阵缩放顶点和渲染 在渲染之前,我将通过设置为顶点以渲染四边形的width/height。这定义了对象的大小。但在顶点着色器中,我将变换应用于这些顶点,如下所示: in vec2 aPosition; in vec2 aTexCoord; out vec2 vQuadCoord; uniform mat3 uMatrix; void main() { vec2 position = (uMatrix * vec3(aPosition, 1

我遵循webgl基础知识,绘制2d对象,并使用矩阵缩放顶点和渲染

在渲染之前,我将通过设置为顶点以渲染四边形的
width/height
。这定义了对象的大小。但在顶点着色器中,我将变换应用于这些顶点,如下所示:

in vec2 aPosition;
in vec2 aTexCoord;

out vec2 vQuadCoord;

uniform mat3 uMatrix;

void main() {

  vec2 position = (uMatrix * vec3(aPosition, 1)).xy;

  vQuadCoord = aTexCoord;

  gl_Position = vec4(position, 0, 1);

}

此矩阵控制对象的平移/旋转/缩放。渲染后,我想知道这个对象的边界。但特别是在缩放之后,我不知道边界。如果我在
x,y
平移这个对象(用矩阵),它的位置是已知的,但是如果我缩放这个对象,x会向左移动,移动量未知。webgl基础知识没有提到这个主题,什么是检测对象边界和精确变换的好方法?因为我也有轴的问题,我可能会问另一个问题。

您需要将鼠标坐标转换为剪辑空间,然后将它们乘以矩阵的倒数。这将为您提供相对于
aPosition
值的鼠标坐标

之后就看你了。如果输入到
aPosition
的值(顶点)是一个矩形,则您只需对照该矩形检查变换点即可。如果它们是一个更复杂的形状,如星形,则需要创建自己的函数来执行
星形点
三角形点
,并检查每个三角形,但至少在转换后,鼠标位置位于相对于顶点的坐标中。您还可以在初始化时计算顶点的边界框,并使用该边界框对变换点进行测试

函数main(){
const gl=document.querySelector('canvas').getContext('webgl2');
如果(!gl){
返回警报(“需要WebGL2”);
}
const vs=`#版本300 es
在vec2位置;
均匀mat3-uMatrix;
void main(){
vec2位置=(uMatrix*vec3(位置,1)).xy;
gl_位置=vec4(位置,0,1);
}
`;
常数fs=`#版本300 es
精密中泵浮子;
vec4颜色均匀;
外显vec4外显色;
void main(){
outColor=颜色;
}
`;
const programInfo=twgl.createProgramInfo(gl[vs,fs]);
//创建一个从0,0开始、宽20个单位、高10个单位的四边形
const bufferInfo=twgl.createBufferInfoFromArrays(gl{
位置:{
NUM组件:2,
数据:[
0, 0,
0, 10,
20, 0,
20, 0,
0, 10,
20, 10,
],
}
});
const vao=twgl.createVAOFromBufferInfo(gl,programInfo,bufferInfo);
让mouseClipX=0;
让mouseClipY=0;
const infoElem=document.querySelector('info');
函数渲染(时间){
t=时间/1000;
twgl.resizeCanvasToDisplaySize(总图画布);
总图视口(0,0,总图画布宽度,总图画布高度);
总账使用程序(programInfo.program);
bindVertexArray总帐(vao);
设mat=m3.投影(总图画布宽度、总图画布高度);
mat=m3.1(
垫子,
150+数学sin(t*0.1)*100,
75+数学系数(t*0.2)*50);
mat=m3.旋转(mat,t*0.3);
mat=m3.1刻度(
垫子,
2+数学sin(t*0.4)*0.5,
2+数学cos(t*0.5)*0.5);
//将clipspace鼠标转换为位置相对值
//“mat”接受一个位置并转换为剪辑空间
//所以“mat”的倒数将占用剪辑空间和
//转换回位置空间。
常数invMat=m3.逆(mat);
常数p=m3.transformPoint(invMat,[mouseClipX,mouseClipY]);
//现在检查位置空间。它是一个20x10的矩形,从0,0开始
常量收件箱=p[0]>=0&&p[0]<20&&
p[1]>=0&&p[1]<10;
twgl.设置制服(程序信息{
uMatrix:mat,
颜色:收件箱?[1,0,0,1]:[0,0,1,1],
});
twgl.drawBufferInfo(总账,bufferInfo);
infoElem.textContent=inbox?'mouse in rect':'no hit';
请求动画帧(渲染);
}
请求动画帧(渲染);
gl.canvas.addEventListener('mousemove',(事件)=>{
//将画布相对鼠标坐标转换为剪辑空间
mouseClipX=(event.offsetX/gl.canvas.clientWidth)*2-1;
mouseClipY=(event.offsetY/gl.canvas.clientHeight)*-2+1;//注意我们翻转Y
});
}
main()
canvas{边框:1px纯黑;}


一种解决方案是根本不进行缩放,并在初始时间更改对象的宽度和高度。此解决方案存在一些问题,请看“有问题”是什么意思?关于上述解决方案?它对我有效,对你无效?