2016-10-30 19 views
1

3つの点でカスタム頂点シェーダを使用してポイントクラウドにトレースする方法はありますか。Three.jsのカスタム頂点シェーダを使用したポイントクラウドへのレイトレーシング

これは私の頂点シェーダポイントクラスで

void main() { 
    vUvP = vec2(position.x/(width*2.0), position.y/(height*2.0)+0.5); 
    colorP = vec2(position.x/(width*2.0)+0.5 , position.y/(height*2.0) ); 
    vec4 pos = vec4(0.0,0.0,0.0,0.0); 
    depthVariance = 0.0; 
    if ((vUvP.x<0.0)|| (vUvP.x>0.5) || (vUvP.y<0.5) || (vUvP.y>0.0)) { 
    vec2 smp = decodeDepth(vec2(position.x, position.y)); 
    float depth = smp.x; 
    depthVariance = smp.y; 
    float z = -depth; 
    pos = vec4((position.x/width - 0.5) * z * (1000.0/focallength) * -1.0,(position.y/height - 0.5) * z * (1000.0/focallength),(- z + zOffset/1000.0) * 2.0,1.0); 
    vec2 maskP = vec2(position.x/(width*2.0), position.y/(height*2.0) ); 
    vec4 maskColor = texture2D(map, maskP); 
    maskVal = (maskColor.r + maskColor.g + maskColor.b)/3.0 ; 
    } 
    gl_PointSize = pointSize; 
    gl_Position = projectionMatrix * modelViewMatrix * pos; 
} 

で次のように、レイトレーシングが実装されています

function testPoint(point, index) { 
    var rayPointDistanceSq = ray.distanceSqToPoint(point); 
    if (rayPointDistanceSq < localThresholdSq) { 
     var intersectPoint = ray.closestPointToPoint(point); 
     intersectPoint.applyMatrix4(matrixWorld); 
     var distance = raycaster.ray.origin.distanceTo(intersectPoint); 
     if (distance < raycaster.near || distance > raycaster.far) return; 
     intersects.push({ 
      distance: distance, 
      distanceToRay: Math.sqrt(rayPointDistanceSq), 
      point: intersectPoint.clone(), 
      index: index, 
      face: null, 
      object: object 
     }); 
    } 
} 

var vertices = geometry.vertices; 
for (var i = 0, l = vertices.length; i < l; i ++) { 
     testPoint(vertices[ i ], i); 
} 

しかし、私は、geometry.verticesを頂点シェーダを使用していますので、レイトレースが機能しないように、画面上の頂点までマッチしないでください。

頂点シェーダからポイントを戻すことはできますか?

答えて

2

あなたの頂点シェーダが実際に何をしているのかはわかりませんでした。シェーダでそれを行うのがよい理由があると仮定しています。したがって、レイアウエアを実行するときにjavascriptで計算をやり直すことは、鋳造。

1つのアプローチは、ポイントがどこにあるかについての何らかの評価をし、それらを事前選択のために使用し、レイに最も近いポイントについてより複雑な計算を行うことができる。

これでうまくいかない場合は、シーンのルックアップマップをレンダリングすることをお勧めします。ここで、カラー値は座標にレンダリングされるポイントのIDです(これはGPU例をherehereとさらにいくつかのライブラリhereでも、あなたが必要とするものは実際にはありません)。

シーンを2回レンダリングする必要があります。最初のパスでルックアップマップを作成し、2回目のパスでルックアップマップを定期的にレンダリングします。ルックアップマップは、そこにレンダリングされたすべてのピクセルを格納します。

この情報を取得するには、THREE.RenderTarget(パフォーマンス向上のために幅/高さの半分に縮小されている可能性があります)と異なる素材をセットアップする必要があります。頂点シェーダはそのままのままですが、フラグメントシェーダは各パーティクル(またはそれらを識別するために使用できるもの)ごとに単一の固有のカラー値を出力します。その後、シーンをレンダリング(またはより良い:レイキャスト、ターゲットされなければならない部品のみ)レンダーターゲットへ:

var size = renderer.getSize(); 
var renderTarget = new THREE.WebGLRenderTarget(size.width/2, size.height/2); 
renderer.render(pickingScene, camera, renderTarget); 

をレンダリングした後、あなたが​​-methodを使用して、このルックアップテクスチャの内容を取得することができます。

var pixelData = new Uint8Array(width * height * 4); 
renderer.readRenderTargetPixels(renderTarget, 0, 0, width, height, pixelData); 

(ここではピクセルデータのレイアウトは、通常のキャンバスimageData.dataと同じです)

あなたはraycasterは唯一のオブジェクトとしての色値を読み、解釈し、単一の座標を検索する必要があるでしょう、ということしたら-idそれと何かする。

+0

ありがとうございます!私は将来これを試みる人のために追加します。頂点シェーダでは、さまざまな値を設定できます。これをフラグメントシェーダで使用すると、頂点の色を設定できます – cjds

関連する問題