私はthree.jsで水を作るに取り組んでいるとこれまでのところ、してください私は反射と屈折の両方を実装するthree.js内の任意の水の例を見ていないが、あなたがしなければリンク。 はSlayvin によって私はMirror.jsの上に構築で働いている瞬間https://threejs.org/examples/webgl_mirror.html行列演算(三のJS)
で私の計画は、反射と同様の方法でrefractiontextureをレンダリングするために第2のレンダーターゲットを使用していたし、その後に2つのテクスチャをブレンドシェイダー。
今私はブレンドに使用する一時的な屈折レンダリングターゲットを持っています。これは機能します。しかし、テクスチャに正しい行列乗算を適用していないので、この一時的な屈折はひどく歪んでいます。それは私が思うミラーよりも簡単なはずですが、これは私が思ったようにはうまくいかないのです。最初のテクスチャマトリックスをどのように設定すべきかを知るにはどうすればよいですか?
this.updateMatrixWorld();
this.camera.updateMatrixWorld();
// Update the texture matrix
this.textureMatrixRefraction.set(0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
0.0, 0.0, 0.5, 0.5,
0.0, 0.0, 0.0, 1.0);
this.textureMatrixMirror.multiply(this.camera.projectionMatrix);
this.textureMatrixMirror.multiply(this.camera.matrixWorldInverse);
は、私は非常に重要な何かが欠けておりますので、ミラーのための行列演算がどのように機能するかを把握しようとしています。私はこれより簡単なバージョンを作成しようとしましたが、それは上記のコードです。コード内の帽子のコメントは私のものなので、あなたが私の質問票のいくつかを説明できるなら、それは素晴らしいでしょう。
THREE.Water.prototype.updateTextureMatrixMirror = function() {
//UPDATE TO CURRENT WORLD AND CAMERA FOR MIRROROBJECT
this.updateMatrixWorld();
this.camera.updateMatrixWorld();
//COPY VALUES FROM WORLD AND CAMERA, GETTING TRANSFORMATIONS IN WORLD
this.mirrorWorldPosition.setFromMatrixPosition(this.matrixWorld);
this.cameraWorldPosition.setFromMatrixPosition(this.camera.matrixWorld);
this.rotationMatrix.extractRotation(this.matrixWorld);
//SET NORMAL AND APPLY ROTATION
this.normal.set(0, 0, 1);
this.normal.applyMatrix4(this.rotationMatrix);
//CREATE NEW CAMERA VIEW, THIS IS ONLY RELEVANT FOR THE REFLECTION
var view = this.mirrorWorldPosition.clone().sub(this.cameraWorldPosition);
view.reflect(this.normal).negate(); //tHIS IS NOT NEEDED FOR REFRACTION?
view.add(this.mirrorWorldPosition);
this.rotationMatrix.extractRotation(this.camera.matrixWorld);
//SET LOOKAT... NOT REALLY GRASPING WHAT IT CHANGES?
this.lookAtPosition.set(0, 0, -1);
this.lookAtPosition.applyMatrix4(this.rotationMatrix);
this.lookAtPosition.add(this.cameraWorldPosition);
//TARGET, ALSO TROUBLY UNDERSTANDING WHAT IT CHANGES
var target = this.mirrorWorldPosition.clone().sub(this.lookAtPosition);
target.reflect(this.normal).negate(); //WHAT HAPPENS HERE??
target.add(this.mirrorWorldPosition);
this.up.set(0, -1, 0); //CHANGING TO NEG Y
this.up.applyMatrix4(this.rotationMatrix);
this.up.reflect(this.normal).negate(); // IS THIS NEEDED?
//MIRRORCAMERA COPIES THE GENERATED VALUES AND UPDATES
this.mirrorCamera.position.copy(view);
this.mirrorCamera.up = this.up;
this.mirrorCamera.lookAt(target);
this.mirrorCamera.updateProjectionMatrix();
this.mirrorCamera.updateMatrixWorld();
this.mirrorCamera.matrixWorldInverse.getInverse(this.mirrorCamera.matrixWorld); // IS THIS NEEDED FOR REFRACTION?
//THIS IS WHERE THE MAGIC HAPPENS, TEXTURE MATRIX IS UPDATED
// Update the texture matrix
this.textureMatrixMirror.set(0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
0.0, 0.0, 0.5, 0.5,
0.0, 0.0, 0.0, 1.0);
//USE THE GENERATED MIRRORCAMERA TO GET MATRIX MULTIPLICATIONS
this.textureMatrixMirror.multiply(this.mirrorCamera.projectionMatrix);
this.textureMatrixMirror.multiply(this.mirrorCamera.matrixWorldInverse);
// AS I UNDERSTAND, THIS PART DEALS WITH THE CLIPPING USING OBLIQUE FRUSTUMS
// Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
// Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
this.waterPlane.setFromNormalAndCoplanarPoint(this.normal, this.mirrorWorldPosition);
this.waterPlane.applyMatrix4(this.mirrorCamera.matrixWorldInverse);
this.clipPlane.set(this.waterPlane.normal.x, this.waterPlane.normal.y, this.waterPlane.normal.z, this.waterPlane.constant);
var q = new THREE.Vector4();
var projectionMatrix = this.mirrorCamera.projectionMatrix;
q.x = (Math.sign(this.clipPlane.x) + projectionMatrix.elements[ 8 ])/projectionMatrix.elements[ 0 ];
q.y = (Math.sign(this.clipPlane.y) + projectionMatrix.elements[ 9 ])/projectionMatrix.elements[ 5 ];
q.z = - 1.0;
q.w = (1.0 + projectionMatrix.elements[ 10 ])/projectionMatrix.elements[ 14 ];
// Calculate the scaled plane vector
var c = new THREE.Vector4();
c = this.clipPlane.multiplyScalar(2.0/this.clipPlane.dot(q));
// Replacing the third row of the projection matrix
projectionMatrix.elements[ 2 ] = c.x;
projectionMatrix.elements[ 6 ] = c.y;
projectionMatrix.elements[ 10 ] = c.z + 1.0 - this.clipBias;
projectionMatrix.elements[ 14 ] = c.w;
更新:だから私は半分降下視覚的な結果を得ることができた、しかし、いくつかのバグがあると私は私が障害のため、マトリックス変換の適切屈折テクスチャを作成していない」知っています。また、私は実装したdudv-mapのオフセットに素敵な流れを得るのに苦労していますが、私は正弦関数を使っていますが、これは揺れ動く動きにつながり、非常に不自然に見えます。 rippleMoveFactorを除算値のままでループする "ジャンプカット"。ここではいくつかの説明があるDemo