2016-10-30 40 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