2016-10-30 37 views
1

你怎麼能這樣光線追蹤的點雲與three.js所定製的頂點着色器。 ,光線追蹤點雲用自定義的頂點着色器在three.js所

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:

這是我的頂點着色器

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; 
} 

在積分類,光線追蹤是這樣實現的不匹配屏幕上防止射線痕跡工作的頂點。

我們可以得到點從頂點着色器回來?

回答

2

我沒有潛入你的頂點着色器實際上做的,我認爲有充分的理由爲你做它的着色器,所以它可能是不可行的重新計算在JavaScript做射線敏感時鑄件。

一種方法可能是有某種估計的點在哪裏,使用那些預選和最接近於光線的點做一些更復雜的計算。

如果這樣做不起作用,那麼最好的辦法是呈現場景的查找圖,其中顏色值是在座標上呈現的點的ID(這也稱爲GPU例如here,here甚至一些圖書館here雖然這並不真正做你會需要的)。

要做到這一點,你需要渲染場景兩次:創建查找地圖在第一遍和第二遍定期對其進行渲染。 lookup-map將存儲每個像素的粒子在那裏渲染。

爲了獲取該信息,您需要設置一個THREE.RenderTarget(這可能會縮小到寬度/高度的一半以獲得更好的性能)和不同的材質。頂點着色器保持原樣,但片段着色器只會爲每個粒子(或任何可用於識別它們的物體)輸出一個唯一的顏色值。然後渲染場景(或更好:只將光線投射的目標的部分)到渲染目標:

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

渲染後,您可以使用​​- 方法獲得此查找紋理的內容:

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

(PixelData取出的佈局這裏是一樣的常規帆布imageData.data

一旦你的是,raycaster只需要查找一個座標,閱讀和解釋顏色值對象-id an d用它做點什麼。

+0

謝謝!我會在未來爲所有嘗試這個的人添加。在頂點着色器中,您可以設置一個變化的,然後您可以在片段着色器中使用它來設置頂點的顏色 – cjds