キャンバスなし

おそらく「I am PR」または「JavaScript」に転送することをお勧めします(提案は受け入れられます)。 または、そのままにしておく必要があります。 しかし...



JavaScriptでZバッファー、サブピクセル精度、Guroライティングを使用した3Dですか? はい、誰でもキャンバスを使用してこれ行うことができます



キャンバスの長所を長く美味しいもので説明することはできますが、この記事はそれについてではありません。 それほど面白くない

キャンバスが悪い理由をご覧ください。





それで何?





私は非常にクレイジーな ブログを持っています。そこでは、キャンバスを使用しないJavaScriptでさまざまなエフェクトやゲームを作成することについて定期的に書いていきます。



シードに関する小さな異端記事-キャンバスを使用して3D + Zバッファー+サブピクセル+グラウドシェーディング作成する方法



ステップ0


始めるには、Chrome Frameの形式でcanvasタグのサポートを提供することでIEユーザーの世話をする必要があります: メタを登録し、Googleスクリプトを接続し、 非キャンバスブロックを作成し、Google iframeのスタイルを編集します(デフォルトではページの中央に表示されます)

< head > <br> < meta http-equiv ="X-UA-Compatible" content ="chrome=1" /> <br> < style type ="text/css" media ="screen" > <br>.chrome-install {<br> position: relative;<br> margin: 0;<br> padding: 0;<br> top: 0;<br> left: 0;<br>}<br> </ style > <br> < script type ="text/javascript" src ="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js" ></ script > <br> </ head > <br> < body onload ="main()" > <br> < div id ="no-canvas" style ="display:none;" > <br> < h2 > &lt; canvas &gt; support required. </ h2 > <br> < div id ="chrome-install-placeholder" ></ div > <br> </ div > <br> < div id ="canvas-enabled" > <br> < canvas id ="canvas" width ="384" height ="384" ></ canvas > <br> </ div > <br> </ body > <br><br> * This source code was highlighted with Source Code Highlighter .





メイン関数(タイムアウトによって呼び出されます。それ以外の場合、chrome(開発版)は本体の背景を最後まで描画しないことがあります):

function main()<br>{<br> canvas = document .getElementById( 'canvas' );<br><br> if ( typeof (canvas.getContext) == 'function' )<br> {<br> ctx = canvas.getContext( '2d' );<br> setTimeout(init, 100);<br> }<br> else <br> {<br> document .getElementById( 'canvas-enabled' ).style.display = 'none' ;<br> document .getElementById( 'no-canvas' ).style.display = '' ;<br><br> CFInstall.check({<br> node: 'chrome-install-placeholder' ,<br> className: 'chrome-install' ,<br> destination: window.location.href<br> });<br> }<br>}<br> <br> * This source code was highlighted with Source Code Highlighter .





ステップ1


すべてのレンダリングは128x128バッファーで行われ、3倍に増加して表示されます( putImageDataを使用)。

var scr = [];<br> var zbuf = [];<br> var WDT = 128;<br> var HGT = 128;<br><br> function blit()<br>{<br> var cd = ctx.createImageData(canvas.width, canvas.height);<br> var data = cd.data;<br> var ind = 0;<br><br> for ( var y = 0; y < HGT; y++)<br> {<br> var line = scr[y];<br><br> for ( var x = 0; x < WDT; x++)<br> {<br> data[ind++] = line[x][0]; data[ind++] = line[x][1]; data[ind++] = line[x][2]; data[ind++] = 255;<br>....<br> }<br><br> ctx.putImageData(cd, 0, 0);<br>}<br> <br> * This source code was highlighted with Source Code Highlighter .





ステップ2


Figureをオブジェクトとして表現し、チート関数boxを記述します 。これにより、法線を持つキューブがすぐに作成されます。

{<br> points: [<br> {x: point_x, y: point_y, z: point_z, n: { x: point_normal_x, y: point_normal_y, z: point_normal_z } },<br> ....<br> ],<br> faces: [<br> [point_1, point_2, point_3, { x: face_normal_x, y: face_normal_y, z: face_normal_z }],<br> ....<br> ],<br> color: object_color,<br> rot: [rot_x, rot_y, rot_z]<br>}<br><br> function box(size, cl, rot)<br>{<br> var norm = 1 / Math.sqrt(3);<br><br> return {<br> points: [<br> { x: -size, y: size, z: -size, n: { x: -norm, y: norm, z: -norm } },<br> ....<br> ],<br> faces: [<br> [ 0, 1, 2, { x: 0, y: 1, z: 0 } ],<br> ....<br> ],<br> color: cl,<br> rot: rot<br> };<br>}<br> <br> * This source code was highlighted with Source Code Highlighter .





ステップ3


すべての黒の仕事をしましょう-オブジェクトを(法線と一緒に-再び法線を読み取るよりも高速です)2Dで投影します(通常は光のレベルを数えるのが面倒だったので、魔法の式と魔法の係数を見つけるために科学的な突く方法 tmを使用しまし 0.7および3)

function project(pt, rm)<br>{<br> var rot = {<br> x: (pt.x*rm.oxx + pt.y*rm.oxy + pt.z*rm.oxz),<br> y: (pt.x*rm.oyx + pt.y*rm.oyy + pt.z*rm.oyz),<br> z: (pt.x*rm.ozx + pt.y*rm.ozy + pt.z*rm.ozz + ZPOS)<br> };<br><br> var l = 1 - (Math.cos(pt.nx*rm.ozx + pt.ny*rm.ozy + pt.nz*rm.ozz) - 0.7) * 3;<br> l = Math.max(0, Math.min(1, l));<br><br> return {<br> x: ((WDT / 2) + rot.x * (WDT / 2 - 1) / rot.z),<br> y: ((HGT / 2) + rot.y * (HGT / 2 - 1) / rot.z),<br> z: rot.z,<br> l: l<br> };<br>}<br><br> function draw_object(obj)<br>{<br> var ax = (tm * obj.rot[0]);<br> var ay = (tm * obj.rot[1]);<br> var az = (tm * obj.rot[2]);<br><br> var s1 = Math.sin(ax); var s2 = Math.sin(ay); var s3 = Math.sin(az);<br> var c1 = Math.cos(ax); var c2 = Math.cos(ay); var c3 = Math.cos(az);<br><br> var rm = {<br> oxx: (c2 * c1),<br> oxy: (c2 * s1),<br> ....<br> };<br><br> var pr = [];<br><br> for ( var i = 0; i < obj.points.length; i++) {<br> pr.push(project(obj.points[i], rm));<br> }<br><br> for ( var i = 0; i < obj.faces.length; i++)<br> {<br> var face = obj.faces[i];<br> var fz = (face[3].x*rm.ozx + face[3].y*rm.ozy + face[3].z*rm.ozz);<br><br> if (fz <= 0) {<br> triangle(pr[face[0]], pr[face[1]], pr[face[2]], obj.color);<br> }<br> }<br>}<br> <br> * This source code was highlighted with Source Code Highlighter .





ステップ4


水平線(最適ではない)と三角形(スピードチャンピオンでもない)を描画する手順を記述します。

function hline(y, xl, xr, cl, ll, lr, zl, zr)<br>{<br> // - , <br> // , <br> // <br> xl -= 0.5;<br> xr += 0.5;<br> ....<br>}<br><br> // ** ** <br> function triangle(a, b, c, cl)<br>{<br> .... ....<br><br> var dxl = (cx - ax) / (cy - ay);<br> var dxr = (bx - ax) / (by - ay);<br> ....<br> var y = ay;<br><br> while (y < by)<br> {<br> // (y - ay) - <br> // <br> xl = sx + dxl * (y - ay);<br> xr = sx + dxr * (y - ay);<br> ....<br> hline(y, xl, xr, cl, ll, lr, zl, zr);<br> y++;<br> }<br><br> ....<br>}<br> <br> * This source code was highlighted with Source Code Highlighter .





ステップ5


ループ関数を記述し、setIntervalを介して実行します。

function loop()<br>{<br> tm = (( new Date()).valueOf() - st) / 1.5;<br><br> draw_scene();<br> blit();<br>}<br> <br> * This source code was highlighted with Source Code Highlighter .





エピローグ


完全なスクリプトはhttp://zame-dev.org/projects/nocanvas/0000/index.htmlで入手できます(ページのソースコードをご覧ください)



ブログを読む @ RSSを購読する




All Articles