3

我有一个关于在 HTML5/Canvas/Javascript 中伪造 3d 的问题...

<canvas>基本上,我在using上绘制了一个 2d 图像drawImage()
我想做的是绘制图像,然后置换球体上的纹理以看起来......类似球体......

为了清楚起见,请参见下图:

Javascript 中的球体

有任何想法吗?

我已经在谷歌上搜索到自己濒临死亡,它也不能是 WebGL,因为它必须在手机上工作......有没有办法做到这一点?

4

2 回答 2

5

您可以在此处检查工作原型:http: //jsbin.com/ipaliq/edit

我敢打赌,优化和更好/更快的算法还有很多空间,但我希望这个概念证明能为您指明正确的方向。

基本算法遍历原始图像的每个像素,如果它受到球面变形,则计算其新位置。

结果如下:

领域

代码:

var w = 150, h = 150;
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
    ctx.fillStyle="red";
    ctx.fillRect(0,0,w,h);

//-- Init Canvas
var initCanvas = function()
{
  var imgData=ctx.getImageData(0,0,w,h);
  for (i=0; i<imgData.width*imgData.height*4;i+=4)
  {
    imgData.data[i]=i%150*1.5;
    imgData.data[i+1]=i%150*1.5;
    imgData.data[i+2]=(i/imgData.width)%150*1.5;
    imgData.data[i+3]=255;
  }
  ctx.putImageData(imgData,0,0);
};
initCanvas();

var doSpherize = function()
{
    var refractionIndex = 0.5; // [0..1]
        //refraction index of the sphere
    var radius = 75;
    var radius2 = radius * radius;
    var centerX = 75; 
    var centerY = 75; 
        //center of the sphere
    var origX = 0;
    var origY = 0;


    for (x=0; x<w;x+=1)
    for (y=0; y<h;y+=1)
    {
        var distX = x - centerX;
        var distY = y - centerY;

        var r2 = distX * distX + distY * distY;

        origX = x;
        origY = y;

        if ( r2 > 0.0 && r2 < radius2 )
        {
            // distance
            var z2 = radius2 - r2;
            var z = Math.sqrt(z2);

            // refraction
            var xa = Math.asin( distX / Math.sqrt( distX * distX + z2 ) );
            var xb = xa - xa * refractionIndex;
            var ya = Math.asin( distY / Math.sqrt( distY * distY + z2 ) );
            var yb = ya - ya * refractionIndex;

            // displacement
            origX = origX - z * Math.tan( xb );
            origY = origY - z * Math.tan( yb );
        }

      // read
      var imgData=ctx.getImageData(origX,origY,1,1);
      // write
      ctx.putImageData(imgData,x+w,y+h);
    }
};
doSpherize();

笔记

我建议不要在没有 webGL 像素着色器的情况下由前端处理如此密集的操作。这些都非常优化,将能够利用 GPU 加速。

于 2012-06-25T21:38:24.257 回答
0

你绝对可以做这样的事情。我不确定质量和速度是否足够好,尤其是在移动设备上。

你会想要getImageData像素,对它们执行一些我目前无法想到的数学变换,然后将putImageData它们返回。

它可能看起来有点模糊或像素化(你可以尝试插值,但这只会让你到目前为止)。而且您可能必须大幅优化您的 javascript 才能在合理的时间内在移动设备上完成它。

转换可能类似于逆方位角投影。

于 2012-06-25T14:16:14.077 回答