HTML5.0キャンバスで3Dボールまたは球を描きたい。3D球の描画方法についてアルゴリズムを理解したい。誰がこれを私と共有できますか?
4 に答える
球をモデル化し、さまざまな色にする必要があります。これにより、球が回転するときに、それが球であるだけでなく、レンダリングされていることがわかります。
それ以外の場合、周囲に基準点がない空間内の球は、すべて 1 つの単色の場合、円のように見えます。
まず最初に、長方形で円を描いてみることをお勧めします。これが主なプリミティブです。
その方法、または Path メソッドを使用して三角形などの新しいプリミティブを作成し、円を作成する方法を理解したら、それを 3D に移動する準備が整います。
おそらく方程式によって生成されたモデルを取得し、どの部分が表示されるかを決定するときにモデルを平坦化し、表示するため、3D は単なるトリックです。
ただし、光源からの距離と、光源に対するその部分の角度に基づいて、三角形の色を変更する必要があります。
ここから最適化を開始できます。これをピクセルごとに行うと、レイトレーシングになります。大きなブロックと点光源があり、オブジェクトが回転しているが動き回っていない場合、三角形ごとに色がどのように変化するかを再計算できます。色を変更して回転をシミュレートするだけです。
アルゴリズムは、どのような単純化を行いたいかによって異なります。そのため、経験を積んだら、戻ってきて、これまでに行ったことを示して質問してください。
以下はその実行例で、以下に 3D 球体部分をコピーしましたが、記事全体を参照してください。
function Sphere3D(radius) {
this.point = new Array();
this.color = "rgb(100,0,255)"
this.radius = (typeof(radius) == "undefined") ? 20.0 : radius;
this.radius = (typeof(radius) != "number") ? 20.0 : radius;
this.numberOfVertexes = 0;
// Loop from 0 to 360 degrees with a pitch of 10 degrees ...
for(alpha = 0; alpha <= 6.28; alpha += 0.17) {
p = this.point[this.numberOfVertexes] = new Point3D();
p.x = Math.cos(alpha) * this.radius;
p.y = 0;
p.z = Math.sin(alpha) * this.radius;
this.numberOfVertexes++;
}
// Loop from 0 to 90 degrees with a pitch of 10 degrees ...
// (direction = 1)
// Loop from 0 to 90 degrees with a pitch of 10 degrees ...
// (direction = -1)
for(var direction = 1; direction >= -1; direction -= 2) {
for(var beta = 0.17; beta < 1.445; beta += 0.17) {
var radius = Math.cos(beta) * this.radius;
var fixedY = Math.sin(beta) * this.radius * direction;
for(var alpha = 0; alpha < 6.28; alpha += 0.17) {
p = this.point[this.numberOfVertexes] = new Point3D();
p.x = Math.cos(alpha) * radius;
p.y = fixedY;
p.z = Math.sin(alpha) * radius;
this.numberOfVertexes++;
}
}
}
}
コア webgl プログラミングから多くのコードを抽象化する three.js ライブラリを試すことができます。three.js libから three.js ライブラリを html に含めます。
u は、サファリ ブラウザーのキャンバス レンダラーを使用できます。webgl はクロムで動作します。
JS FIDDLE FOR SPHEREを見つけてください
var カメラ、シーン、マテリアル、メッシュ、ジオメトリ、レンダラー
function drawSphere() {
init();
animate();
}
function init() {
// camera
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(50, window.innerWidth / innerHeight, 1, 1000);
camera.position.z = 300;
scene.add(camera);
// sphere object
var radius = 50,
segments = 10,
rings = 10;
geometry = new THREE.SphereGeometry(radius, segments, rings);
material = new THREE.MeshNormalMaterial({
color: 0x002288
});
mesh = new THREE.Mesh(geometry, material);
//scene
;
scene.add(mesh);
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
mesh.rotation.x += .01;
mesh.rotation.y += .02;
renderer.render(scene, camera);
}
// fn callin
drawSphere();
更新:このコードはかなり古く、制限があります。現在、3D 球体を作成するためのライブラリがあります: http://techslides.com/d3-globe-with-canvas-webgl-and-three-js/
10 年以上前、私は Java アプレットを作成して、球の表面がシーン内のどこにあるかを実際に計算して (三角形を使用せずに)、テクスチャ付きの球をレンダリングしました。
キャンバス用に JavaScript で書き直しました。地球を球体としてレンダリングするデモがあります。
(出典: haslers.info )
私のマシンでは約 22 fps が得られます。これは、レンダリングに基づいた Java バージョンとほぼ同じくらい高速です。
Javaコードを書いてからずいぶん経ちますが、それは非常にわかりにくかったので、どのように動作するか正確には覚えていません。JavaScript に移植したところです。ただし、これはコードの遅いバージョンによるものであり、より高速なバージョンがピクセルを操作するために使用した Java メソッドの最適化によるものなのか、それともレンダリングするピクセルを計算するための計算の高速化によるものなのかはわかりません。テクスチャ。私は当時、私よりもはるかに高速な同様のアプレットを持っている誰かと連絡を取り合っていましたが、Java ライブラリに依存している可能性があるため、JavaScript で速度の改善が可能かどうかはわかりません。(私は彼らのコードを見たことがないので、彼らがどのようにそれをしたのかわかりません。)
そのため、速度が向上する可能性があります。しかし、これは概念実証としてうまく機能します。
JavaScript バージョンで速度が向上するかどうかを確認するために、高速バージョンをしばらく変換してみます。
球体の画像は常に画面上で円形になるため、重要なのはシェーディングだけです。これは、光源を配置する場所によって決まります。
アルゴリズムに関して言えば、レイ トレーシング<CANVAS>
は最も単純ですが、最も低速でもあります。そのため、 (特にその環境でグラフィックス アクセラレーションが利用できないことを考えると)非常に複雑なことを行うためにレイ トレーシングを使用したくないでしょう。単一の球体を作成したいだけなら十分速いかもしれません。