图像处理以及使用HTML5画布纹理映射? [英] Image manipulation and texture mapping using HTML5 Canvas?

查看:482
本文介绍了图像处理以及使用HTML5画布纹理映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个3D引擎我的工作我已经成功地设法绘制3D的立方体。填补了双方的唯一方法是使用一个纯色或渐变,据我而言。为了让事情变得更精彩,我真的很喜欢用一个简单的位图来实现纹理映射。

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.

的一点是,我很难找到对图像处理JavaScript中的问题的任何文章或code样本。此外,在HTML5画布图像支持似乎仅限于裁剪。

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.

我怎么能去拉伸位图,这样一个矩形位图可以填满一个不规则立方体的脸?在2D,预计正方体面,由于角度看,不是正方形,所以我不得不伸展它,使之在任何四边形适应。

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?

有没有人有使用JavaScript和HTML5的画布角度纹理映射(或图像处理的话)任何提示?

Does anyone have any tips on perspective texture mapping (or image manipulation at all) using JavaScript and HTML5 Canvas?

编辑:我得到了它的工作,这要归功于6502

I got it working, thanks to 6502!

这不过是,相当耗费CPU,所以我很乐意听到任何优化的想法。

It is, however, rather CPU intensive so I'd love to hear any optimization ideas.

结果用6502的技术 - 的Texture图像中使用

推荐答案

我想你永远无法得到一个准确的结果......我花了一些时间研究如何使用Canvas 2D上下文做3D图形,我发现它可行的做纹理映射洛德着色通过计算适当的2D梯度和矩阵:

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:

  • 实心多边形是当然容易
  • 在高氏充盈只能在一个组件(即你不能有一个三角形,每一个顶点是一个任意RGB充满了双线性插值,但你可以做到这一点灌装使用,例如单一颜色的三个任意色调)
  • 线性纹理映射,可以使用裁剪和图像绘制完成

我会用网格细分实现的角度来看,正确的纹理映射(如在PS1)。

I would implement perspective-correct texture mapping using mesh subdivision (like on PS1).

不过,我发现了很多问题......比如图像变换(用于纹理映射)是铬相当不准确的与基体图纸和国际海事组织这是不可能得到一个像素精确的结果;一般没有办法在画布上绘制时,关闭抗锯齿,这意味着在三角形细分的时候,你会得到看得见的透明线。我还发现,多路渲染工作对铬(可能是因为如何HW-呈现加速而实现)。

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).

在一般这种渲染无疑是网络浏览器,显然这些用例(奇怪的矩阵为例)应力未经测试非常好。我甚至能够得到火狐崩溃如此糟糕,它采取了整个X susbsystem在我的Ubuntu。

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.

您可以看到我的努力的结果,这里或视频的此处 ... IMO肯定是即时通讯pressing,这可以在浏览器不使用3D扩展来完成的,但我不认为目前的问题将固定在未来。

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.

反正使用使得4个角结束了在特定像素位置是绘制两个三角形,其每一个将使用双线性内插来绘制图像的基本思路。

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.

在以下code我假设你有一个图片对象纹理和4个角落每一个都是一个对象的字段 X, Y,U,V ,其中 X,Y 是像素坐标目标画布上和 U,V 的像素的坐标纹理

In the following code I assume you have a picture object texture and 4 corners each of which is an object with fields x,y,u,v where x,y are pixel coordinates on the target canvas and u,v are pixel coordinates on texture:

function textureMap(ctx, texture, pts) {
    var tris = [[0, 1, 2], [2, 3, 0]]; // Split in two triangles
    for (var t=0; t<2; t++) {
        var pp = tris[t];
        var x0 = pts[pp[0]].x, x1 = pts[pp[1]].x, x2 = pts[pp[2]].x;
        var y0 = pts[pp[0]].y, y1 = pts[pp[1]].y, y2 = pts[pp[2]].y;
        var u0 = pts[pp[0]].u, u1 = pts[pp[1]].u, u2 = pts[pp[2]].u;
        var v0 = pts[pp[0]].v, v1 = pts[pp[1]].v, v2 = pts[pp[2]].v;

        // Set clipping area so that only pixels inside the triangle will
        // be affected by the image drawing operation
        ctx.save(); ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(x1, y1);
        ctx.lineTo(x2, y2); ctx.closePath(); ctx.clip();

        // Compute matrix transform
        var delta = u0*v1 + v0*u2 + u1*v2 - v1*u2 - v0*u1 - u0*v2;
        var delta_a = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2;
        var delta_b = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2;
        var delta_c = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2
                      - v0*u1*x2 - u0*x1*v2;
        var delta_d = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2;
        var delta_e = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2;
        var delta_f = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2
                      - v0*u1*y2 - u0*y1*v2;

        // Draw the transformed image
        ctx.transform(delta_a/delta, delta_d/delta,
                      delta_b/delta, delta_e/delta,
                      delta_c/delta, delta_f/delta);
        ctx.drawImage(texture, 0, 0);
        ctx.restore();
    }
}

那些丑陋奇怪的公式,所有这些增量变量用于解决三个方程两个线性系统使用克莱默的方法和 Sarrus 以3x3的决定方案。

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.

更具体地讲,我们正在寻找 A B ... F ,使得下面的公式满足

More specifically we are looking for the values of a, b, ... f so that the following equations are satisfied

a*u0 + b*v0 + c = x0
a*u1 + b*v1 + c = x1
a*u2 + b*v2 + c = x2

d*u0 + e*v0 + f = y0
d*u1 + e*v1 + f = y1
d*u2 + e*v2 + f = y2

增量是矩阵的行列式

u0  v0  1
u1  v1  1
u2  v2  1

和例如 delta_a 是相同的矩阵,当你替换 X0的第一列行列式 X1 X2 。有了这些,你可以计算 A = delta_a /△

and for example delta_a is the determinant of the same matrix when you replace the first column with x0, x1, x2. With these you can compute a = delta_a / delta.

这篇关于图像处理以及使用HTML5画布纹理映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆