Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用光线跟踪(webgl,three.js)将三维场景转换为二维图像_Javascript_Three.js_Webgl_Raytracing - Fatal编程技术网

Javascript 使用光线跟踪(webgl,three.js)将三维场景转换为二维图像

Javascript 使用光线跟踪(webgl,three.js)将三维场景转换为二维图像,javascript,three.js,webgl,raytracing,Javascript,Three.js,Webgl,Raytracing,如上所述,我希望使用光线跟踪在2D平面上渲染3D场景。最终,我想用它来进行体绘制,但我在这里的基础知识方面遇到了困难。我有一个3.js场景,其中观察平面连接到相机(当然在它前面) 设置: 然后(在着色器中)我从摄影机通过平面中的每个点(250x250)拍摄光线。平面后面是41x41x41体积(基本上是一个立方体)。如果光线穿过立方体,则光线穿过的观察平面中的点将渲染为红色,否则该点将渲染为黑色。不幸的是,只有从前面看立方体时,这才有效。下面是一个例子: 如果你试着从不同的角度看立方体(你可以用

如上所述,我希望使用光线跟踪在2D平面上渲染3D场景。最终,我想用它来进行体绘制,但我在这里的基础知识方面遇到了困难。我有一个3.js场景,其中观察平面连接到相机(当然在它前面)

设置:

然后(在着色器中)我从摄影机通过平面中的每个点(250x250)拍摄光线。平面后面是41x41x41体积(基本上是一个立方体)。如果光线穿过立方体,则光线穿过的观察平面中的点将渲染为红色,否则该点将渲染为黑色。不幸的是,只有从前面看立方体时,这才有效。下面是一个例子:

如果你试着从不同的角度看立方体(你可以用鼠标移动相机),那么我们不会像我们希望的那样将立方体渲染到观察平面上,而是得到一个侧面有一些奇怪像素的正方形

这是光线跟踪的代码:

顶点着色器:

bool inside(vec3 posVec){
        bool value = false;

        if(posVec.x <0.0 ||posVec.x > 41.0 ){
            value = false;
        }
        else if(posVec.y <0.0 ||posVec.y > 41.0 ){
            value = false;
        }
        else if(posVec.z <0.0 ||posVec.z > 41.0 ){
            value = false;
     }
     else{
        value = true;
     }
     return value;
    }





float getDensity(vec3 PointPos){

    float stepsize = 1.0;
    float emptyStep = 15.0;

    vec3 leap;
    bool hit = false;
    float density = 0.000;
    // Ray direction from the camera through the current point in the Plane
    vec3 dir = PointPos- camera;
    vec3 RayDirection = normalize(dir);
    vec3 start = PointPos;   

    for(int i = 0; i<STEPS; i++){

         vec3 alteredPosition = start;
         alteredPosition.x += 20.5;
         alteredPosition.y += 20.5;
         alteredPosition.z += 20.5;

        bool insideTest = inside(alteredPosition);

        if(insideTest){


         // advance from the start position
        start = start + RayDirection * stepsize;

          hit = true;

     }else{
        leap = start + RayDirection * emptyStep;
        bool tooFar = inside(leap);
        if(tooFar){
            start = start + RayDirection * stepsize;
        }else{
            start = leap;
        }
     }

    }
    if(hit){
        density = 1.000;
    }

    return density; 
}


        void main() {


    PointIntensity = getDensity(position);
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;

}
完整代码:

相同的代码但正在运行:

如果有人知道我做错了什么,我会很高兴的

编辑:

我用Mark Lundin提出的更改更新了示例,但不幸的是,在移动相机时,我仍然只得到了一个红色的正方形(虽然侧面没有奇怪的像素):

inverseProjectionMatrix是作为统一属性传递给着色器的Three.js camera属性ProjectionMatrix。然后对视图平面中的每个点及其uv坐标调用Unject函数

新代码如下:

在这里跑步:


要查看摄影机是否实际移动,可以按x、y、z以获取当前摄影机的x、y、z坐标。

之所以看到的是正方形,而不是3D体积,是因为光线跟踪方法没有考虑摄影机方向或投影。当你用轨迹球移动相机时,它的方向会改变,因此这应该包括在你的计算中。其次,还应使用摄像机的投影矩阵将平面坐标投影到三维空间。您可以通过以下方式实现这一点:

vec3 unproject( vec2 coord ){
    vec4 screen = vec4( coord, 0, 1.0 );
    vec4 homogenous = uInvMVProjMatrix * 2.0 * ( screen - vec4( 0.5 )  );
    return homogenous.xyz / homogenous.w;
}

其中,
coord
是平面的二维坐标,
uInvMVProjMatrix
是模型视图投影矩阵的逆矩阵。这将返回一个
vec3
,您可以使用它来测试交叉点。

之所以看到正方形而不是三维体积,是因为光线跟踪方法没有考虑相机方向或投影。当你用轨迹球移动相机时,它的方向会改变,因此这应该包括在你的计算中。其次,还应使用摄像机的投影矩阵将平面坐标投影到三维空间。您可以通过以下方式实现这一点:

vec3 unproject( vec2 coord ){
    vec4 screen = vec4( coord, 0, 1.0 );
    vec4 homogenous = uInvMVProjMatrix * 2.0 * ( screen - vec4( 0.5 )  );
    return homogenous.xyz / homogenous.w;
}

其中,
coord
是平面的二维坐标,
uInvMVProjMatrix
是模型视图投影矩阵的逆矩阵。这将返回一个
vec3
,您可以使用它对交叉口进行测试。

请问您到底想实现什么?你不是在找一台正交摄影机吗?或者渲染目标?另外,在你的例子中,控制对我来说似乎不起作用。我可以问一下你到底想要实现什么吗?你不是在找一台正交摄影机吗?或者渲染目标?另外,在你的示例中,控件似乎对我不起作用。谢谢你花时间回答,但似乎不起作用。谢谢你花时间回答,但似乎不起作用
vec3 unproject( vec2 coord ){
    vec4 screen = vec4( coord, 0, 1.0 );
    vec4 homogenous = uInvMVProjMatrix * 2.0 * ( screen - vec4( 0.5 )  );
    return homogenous.xyz / homogenous.w;
}