
簡介
進行上圖所示的3D格子地板的渲染,需要進行Canvas的像素級別操作,從視點連接屏幕(屏幕就是canvas)中的所有像素點,形成大量的射線,倘若射線與地板相交,把交點以及交點的顏色反饋給屏幕(canvas)。如下圖所示:
像素操作
在進行3D渲染之前,必須了解Canvas的像素操作相關概念。在給定了width和height的canvas上,在坐標(x ,y)上的像素的index構成如下。
var data=getImageData(0, 0, canvas.width, canvas.height);
紅色index:((width * y) + x) * 4 像素值:data[((width * y) + x) * 4]
綠色index:((width * y) + x) * 4 + 1 像素值:data[((width * y) + x) * 4+1]
藍色index:((width * y) + x) * 4 + 2 像素值:data[((width * y) + x) * 4+2]
透明度index:((width * y) + x) * 4 + 3 像素值:data[((width * y) + x) * 4+3]
修改了任何像素的紅、綠、藍和alpha值之后,可以通過第二個函數來更新canvas上的顯示,那就是context.putImageData(imagedata, dx, dy)。
尋找交點
怎么找到射線與地板的交點?可以先列出已知的條件:
視點坐標A、屏幕上的點坐標B、交點P的Y坐標(y=0),向量AP,BP共線。
根據上面的條件,利用兩兩向量共線(Ax-Px/Bx-Px = Ay-Py/By-Py = Az-Pz/Bz-Pz) 可以推導出交點的坐標。
格子材質
找到交點后,還剩下的問題就是根據z的坐標渲染格子材質,如下面代碼所示:
(Math.ceil(cv.x / sideLength) + Math.ceil(cv.z / sideLength)) % 2 === 0
上面的cv為交點坐標,sideLength為地板格子編程,根據上面的true和false返回相應的顏色值。
在線演示
修改代碼里面的變量值點擊run again試試!
Have Fun!