使用 HTML5 Canvas 进行图像处理和纹理映射?
在我正在开发的 3D 引擎中,我成功地绘制了 3D 立方体。就我而言,填充侧面的唯一方法是使用纯色或渐变。为了让事情变得更令人兴奋,我真的很想使用简单的位图来实现纹理映射。
关键是我几乎找不到任何关于 JavaScript 图像处理主题的文章或代码示例。此外,HTML5 canvas 中的图像支持似乎仅限于裁剪。
我怎样才能拉伸位图,以便矩形位图可以填充不规则的立方体面?在 2D 中,由于透视原因,投影的方形立方体面不是正方形,因此我必须拉伸它以使其适合任何四边形。
希望这张图片能澄清我的观点。左面现在填充有白/黑渐变。在纹理映射后,如何用位图填充它?
有人对使用 JavaScript 和 HTML5 Canvas 进行透视纹理映射(或图像操作)有任何建议吗?
编辑:我成功了,感谢 6502!
然而,它是相当 CPU 密集型的,所以我很想听听任何优化的想法。
In a 3D engine I'm working on I've succesfully managed to draw a cube in 3D. The only method to fill the sides is using either a solid color or gradient as far as I'm concerned. To make things more exciting, I'd really love to implement texture mapping using a simple bitmap.
The point is that I can hardly find any articles or code samples on the subject of image manipulation in JavaScript. Moreover, image support in HTML5 canvas seems to be restricted to cropping.
How could I go about stretching a bitmap so that a rectangular bitmap can fill up a unregular cube face? In 2D, a projected square cube face is, due to perspective, not of a square shape, so I'll have to stretch it to make it fit in any quadrilateral.
Hopefully this image clarifies my point. The left face is now filled up with a white/black gradient. How could I fill it with a bitmap, after it has been texture-mapped?
Does anyone have any tips on perspective texture mapping (or image manipulation at all) using JavaScript and HTML5 Canvas?
Edit: I got it working, thanks to 6502!
It is, however, rather CPU intensive so I'd love to hear any optimization ideas.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为你永远不会得到准确的结果...我花了一些时间研究如何使用画布 2d 上下文来制作 3d 图形,我发现通过计算适当的 2d 梯度和矩阵来进行纹理映射 gouraud 着色是可行的:
我将使用网格细分来实现透视正确的纹理映射(就像在 PS1 上一样)。
然而我发现了很多问题......例如,使用矩阵变换(纹理映射所需)进行图像绘制在 Chrome 上非常不准确,并且 IMO 不可能获得像素精确的结果;一般来说,在画布上绘图时无法关闭抗锯齿功能,这意味着在细分三角形时您将获得可见的透明线。我还发现多通道渲染在 chrome 上工作得非常糟糕(可能是因为硬件加速渲染的实现方式)。
一般来说,这种渲染肯定会给网络浏览器带来压力,而且显然这些用例(例如奇怪的矩阵)没有经过很好的测试。我什至让 Firefox 严重崩溃,以至于导致我的 Ubuntu 上的整个 X susb 系统瘫痪。
您可以在此处或通过视频这里... IMO 确实令人印象深刻的是,这可以在浏览器中完成,而无需使用 3D 扩展,但我不这样做不要认为当前的问题将来会得到解决。
无论如何,用于绘制图像以使 4 个角最终位于特定像素位置的基本思想是绘制两个三角形,每个三角形都将使用双线性插值。
在下面的代码中,我假设您有一个图片对象
texture
和 4 个角,每个角都是一个带有字段x,y,u,v
的对象,其中x, y
是目标画布上的像素坐标,u,v
是纹理
上的像素坐标:所有这些“delta”变量的那些丑陋的奇怪公式用于使用 Cramer 方法和 Sarrus 3x3 行列式方案。
更具体地说,我们正在寻找
a
、b
、...f
的值,以便满足以下方程delta< /code> 是矩阵的行列式
,例如,当您将第一列替换为
x0
、x1
时,delta_a
是同一矩阵的行列式>,x2
。通过这些,您可以计算a = delta_a / delta
。I think you will never get an accurate result... I spent some time investigating how to do 3d graphics using canvas 2d context and I found it viable to do texture mapping gouraud shading by computing appropriate 2d gradients and matrices:
I would implement perspective-correct texture mapping using mesh subdivision (like on PS1).
However I found many problems... for example image drawing with a matrix transform (needed for texture mapping) is quite inaccurate on chrome and IMO it's impossible to get a pixel-accurate result; in general there is no way to turn off antialiasing when drawing on a canvas and this means you will get visible see-through lines when subdividing in triangles. I also found multipass rendering working really bad on chrome (probably because of how hw-accellerated rendering is implemented).
In general this kind of rendering is surely a stress for web browsers and apparently these use cases (strange matrices for example) are not tested very well. I was even able to get Firefox crashing so bad that it took down the whole X susbsystem on my Ubuntu.
You can see the results of my efforts here or as a video here... IMO is surely impressing that this can be done in a browser without using 3D extensions, but I don't think current problems will be fixed in the future.
Anyway the basic idea used to draw an image so that the 4 corners ends up in specific pixels position is to draw two triangles, each of which will use bilinear interpolation.
In the following code I assume you have a picture object
texture
and 4 corners each of which is an object with fieldsx,y,u,v
wherex,y
are pixel coordinates on the target canvas andu,v
are pixel coordinates ontexture
:Those ugly strange formulas for all those "delta" variables are used to solve two linear systems of three equations in three unknowns using Cramer's method and Sarrus scheme for 3x3 determinants.
More specifically we are looking for the values of
a
,b
, ...f
so that the following equations are satisfieddelta
is the determinant of the matrixand for example
delta_a
is the determinant of the same matrix when you replace the first column withx0
,x1
,x2
. With these you can computea = delta_a / delta
.