在GPU上执行的矩阵操作可能很难调试,因为GPU操作实际上不允许控制台日志。
我已经写了一个为实时2D渲染引擎设计的程序,它基于一种非常简单的形式,我猜这可以称为射线投射,并且在弄清楚它出了什么问题时遇到了麻烦(它会输出[0,0,0,255,0,0,0,255,...]
填充颜色)。
this.thread.x
是要操作的矩阵中当前单位(颜色通道)的索引。
scene
是一个由6个单位的块组成的缓冲区,每个值依次包含:
实体的类型,在这种情况下,始终为{sprite}的1
。
子画面ID,对应于this.constants.textures
中包含实体子画面缓冲区的索引。
X偏移量,精灵的左边缘
Y偏移量,精灵的上边缘
子画面的宽度
精灵的高度
bufferWidth
是渲染区域的宽度乘以4个通道。
this.constants.textures
是一个数组,其中包含scene
中的精灵ID所引用的每个精灵的缓冲区。
注意:对于那些好奇的人,这是通过GPU.js完成的,这是一个JavaScript库,可将JS函数转换为GLSL代码以通过WebGL运行。
function(scene, sceneLength, bufferWidth) {
var channel = this.thread.x % 4;
if (channel === 3) {
return 255;
}
var x = this.thread.x % bufferWidth;
var y = Math.floor(this.thread.x / bufferWidth);
for (let i1 = 0; i1 < sceneLength; i1 += 6) {
var id = scene[i1 + 1];
var x1 = scene[i1 + 2];
var y1 = scene[i1 + 3];
var w1 = scene[i1 + 4];
var h1 = scene[i1 + 5];
var r1 = scene[i1 + 6];
var offsetX1 = x1 - x;
if (offsetX1 > 0 && offsetX1 < w1) {
var offsetY1 = y1 - y;
if (offsetY1 > 0 && offsetY1 < h1) {
var c1 = offsetY1 * w1 * 4 + offsetX1 * 4;
var c1R = c1 - (c1 % 4);
var c1A = c1R + 3;
if (this.constants.textures[id][c1A] != 0) {
return this.constants.textures[id][c1];
}
}
}
}
return 0;
}
我要实现的概念的解释:
使用矩阵运算时,如果要在整个渲染区域上执行传递操作,则要绘制精灵时,您要做的工作将远远超出必要。如果将渲染区域分解成块,并且仅更新正在绘制的精灵中涉及的部分,那将是一个相当不错的方法。对于实时游戏渲染肯定足够了。这将是一种多遍方法,其中一次渲染一个精灵。
或者,对于我来说似乎是最最佳的方法,相反,我们可以使用单遍方法对整个渲染区域执行单个矩阵运算,并为每个颜色通道评估基于对场景中的每个精灵以及该精灵中的相关像素执行非常基本的碰撞检测形式。
答案 0 :(得分:1)
您正在向后计算Sprite偏移,计算应为:
var offsetX1 = x - x1;
和
var offsetY1 = y - y1;
偏移量应随x和y的增加而增加(假设子图形坐标与屏幕坐标具有相同的坐标系),因此您不应减去x和y。