質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Three.js

Three.jsはWebGLをサポートしているJavaScriptの3D描画用ライブラリです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

Q&A

0回答

1274閲覧

Three.jsにおいて複数Rendererで適切にclippingを動作させたい

MistletoeNaoko

総合スコア15

Three.js

Three.jsはWebGLをサポートしているJavaScriptの3D描画用ライブラリです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

0グッド

0クリップ

投稿2019/09/23 19:26

編集2019/09/23 20:16

Three.jsで複数rendererで、一つのsceneを複数のカメラで描画する時に、clippingが正しく動作しないことについて伺いたく投稿させていただきました。
clippingPlaneをTHREE.Vector3(0, 0, -1)に設定して、オブジェクトの手前側を描画しないようにしています。カメラはOrbitControlsで動かせるようになっています。以下にgifの動作イメージを添付しました。z軸方向負側を描画しないようにしたいだけなので、OrbitControlsでカメラをまわりこませてもz軸方向正側は描画していて欲しいのです。rendererが一つの時はこのように想定する通りに動作しています。
正しい動作イメージ
しかし、rendererを増やすと以下のgifのように、カメラの位置が動くと正しくclippingされません。白い軸状のものや円形の線はきちんとclippingされているようですので、チューブだけの問題のようです。カメラをチューブ状のオブジェクトの真横に移動させると手前側が全て見えなくなってしまうので、イメージとしては、clipping planeが固定されているような感じです。
誤った描画
カメラを真横に移動させたイメージ
なぜrendererを増やすとこのような動作になるのか検討もつきません。
【追記】clippingは二個目のrendererの方では正しく動作しているようです。
なお、rendererを増やしたのはmulti viewsを実現したかったからです。multi viewsのコードはthree.jsのサンプルを参考にいたしました。
Multi views
チューブに関してはシェーダーで色を決めたりclippingしたりしています。シェーダーにおけるclippingに関してはこちらを参考にいたしました。
Add clipping to THREE.ShaderMaterial

以下に該当すると思われる部分のコードを添付いたします。
お力をいただけると幸いです。よろしくお願いいたします。
githubのレポジトリはGitHub
該当すると思われるチューブ描画に関するコードはDraw Tube
シェーダーはShader
に置いてあります。
rendererの初期化

JavaScript

1componentDidMount() { 2 const width = this.mount.clientWidth; 3 const height = this.mount.clientHeight; 4 this.scene = new THREE.Scene(); 5 6 this.setCameras(width, height); 7 8 this.renderer = new THREE.WebGLRenderer(); //{ antialias: true } 9 this.renderer.setClearColor("#000000"); 10 this.renderer.setSize(width, height); 11 this.renderer.localClippingEnabled = true; 12 this.renderer.domElement.id = 'TimeTubes_viewport_' + this.id; 13 this.renderer.domElement.className = 'TimeTubes_viewport'; 14 this.initQBEView(); 15 16 this.mount.appendChild(this.renderer.domElement); 17 18 this.renderScene(); 19 this.start(); 20 21 以下略 22}

もう一つのRendererの初期化

JavaScript

1initQBEView() { 2 this.QBECamera = new THREE.PerspectiveCamera(45, 1, 0.1, 2000); 3 this.QBECamera.position.z = 50; 4 this.QBERenderer = new THREE.WebGLRenderer(); 5 this.QBERenderer.setSize(500, 500); 6 this.QBERenderer.setClearColor("#000000"); 7 this.QBERenderer.localClippingEnabled = true; 8 this.QBERenderer.domElement.id = 'QBE_viewport_' + this.id; 9 this.QBERenderer.domElement.className = 'TimeTubes_viewport'; 10}

チューブのマテリアル

JavaScript

1let tubeMaterial = new THREE.ShaderMaterial({ 2 vertexShader: this.vertex, 3 fragmentShader: this.fragment, 4 uniforms: { 5 lightPosition: {value: new THREE.Vector3(-20, 40, 60)}, 6 shade: {value: true}, 7 texture: {value: this.texture}, 8 minmaxH: {value: new THREE.Vector2(this.data.meta.min.H, this.data.meta.max.H)}, 9 minmaxV: {value: new THREE.Vector2(this.data.meta.min.V, this.data.meta.max.V)}, 10 flagH: {value: true}, 11 flagV: {value: true} 12 }, 13 side: THREE.DoubleSide, 14 transparent: true, 15 clipping: true, 16 clippingPlanes: [this.clippingPlane] 17});

Vertex shader

GLSL

1precision mediump float; 2attribute vec3 colorData; 3attribute float selected; 4varying vec3 vNormal; 5varying vec3 vWorldPosition; 6varying vec3 vColor; 7varying float vSelected; 8#include <clipping_planes_pars_vertex> 9void main() { 10 #include <begin_vertex> 11 vNormal = normalMatrix * normal; 12 vec4 worldPosition = modelMatrix * vec4(position, 1.0); 13 vWorldPosition = worldPosition.xyz; 14 vColor = colorData; 15 vSelected = selected; 16 gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 17 vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); 18 #include <clipping_planes_vertex>

Fragment Shader

precision mediump float; varying vec3 vNormal; varying vec3 vWorldPosition; varying vec3 vColor; varying float vSelected; uniform vec3 lightPosition; uniform sampler2D texture; uniform int tubeNum; uniform bool shade; uniform vec2 minmaxH; uniform vec2 minmaxV; uniform bool flagH; uniform bool flagV; #include <clipping_planes_pars_fragment> void main() { #include <clipping_planes_fragment> vec3 lightDirection = normalize(lightPosition - vWorldPosition); vec2 T; if (flagH) T.x = (vColor.x - minmaxH.x) / (minmaxH.y - minmaxH.x); else T.x = 0.5; if (flagV) T.y = (vColor.y - minmaxV.x) / (minmaxV.y - minmaxV.x); else T.y = 0.5; vec4 resultColor = texture2D(texture, T); float c = max(0.0, dot(vNormal, lightDirection)) * 0.3; float opacity = vColor.z; gl_FragColor = vec4(resultColor.r + c, resultColor.g + c, resultColor.b + c, opacity); else gl_FragColor = vec4(resultColor.r, resultColor.g, resultColor.b, opacity); if (vSelected != 0.0) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問