碼農干貨系列【8】--世界上最簡單的3D渲染(no webgl)


rd3DPlane

簡介

進行上圖所示的3D格子地板的渲染,需要進行Canvas的像素級別操作,從視點連接屏幕(屏幕就是canvas)中的所有像素點,形成大量的射線,倘若射線與地板相交,把交點以及交點的顏色反饋給屏幕(canvas)。如下圖所示:

image

像素操作

在進行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!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM