Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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
C++ 路径跟踪器不显示阴影_C++_Rendering_Shader_Shadow_Raytracing - Fatal编程技术网

C++ 路径跟踪器不显示阴影

C++ 路径跟踪器不显示阴影,c++,rendering,shader,shadow,raytracing,C++,Rendering,Shader,Shadow,Raytracing,为了研究的目的,我尝试实现一个梯度域路径跟踪器。为了实现这一步,我首先需要一个工作路径跟踪器。到目前为止,我一直在创建一个,但结果是错误的,我将向您解释原因。一些概念: 我正在处理采样之前生成的路径。我的意思是,我的算法的第一步是计算某个像素(x,y)的路径。此路径将在场景中执行一些反弹,如果终止于灯光,则视为有效 首先:以下是结构的定义(稍后将声明和初始化),其中包含将光线从摄影机投射到场景中所需的一些场景信息 struct RenderData { vec3 E; vec3

为了研究的目的,我尝试实现一个梯度域路径跟踪器。为了实现这一步,我首先需要一个工作路径跟踪器。到目前为止,我一直在创建一个,但结果是错误的,我将向您解释原因。一些概念:

我正在处理采样之前生成的路径。我的意思是,我的算法的第一步是计算某个像素(x,y)的路径。此路径将在场景中执行一些反弹,如果终止于灯光,则视为有效

首先:以下是结构的定义(稍后将声明和初始化),其中包含将光线从摄影机投射到场景中所需的一些场景信息

struct RenderData
{
    vec3 E;
    vec3 p1;
    vec3 dx;
    vec3 dy;
};
它在InitializeScene方法中初始化:

void InitializeScene(){ // setup virtual screen plane
  vec3 E( 2, 8, -26 ); //Eye position
  vec3 V( 0, 0, 1 ); //LookAt vector
  float d = 0.5f, ratio = SCRWIDTH / SCRHEIGHT, focal = 18.0f;
  vec3 p1(E + V * focal + vec3(-d * ratio * focal, d * focal, 0)); // top-left screen corner in SCREEN SPACE
  vec3 p2(E + V * focal + vec3(d * ratio * focal, d * focal, 0)); // top-right screen corner
  vec3 p3(E + V * focal + vec3(-d * ratio * focal, -d * focal, 0)); // bottom-left screen corner
  mat4 M = rotate( mat4( 1 ), r, vec3( 0, 1, 0 ) );
  p1 = vec3(M * vec4(p1, 1.0f)); //rotating the above points
  p2 = vec3(M * vec4(p2, 1.0f));
  p3 = vec3(M * vec4(p3, 1.0f));
  renderData.dx = (p2 - p1) / (float)SCRWIDTH;
  renderData.dy = (p3 - p1) / (float)SCRHEIGHT;
  renderData.E = vec3(M * vec4(E, 1.0f));
  renderData.p1 = p1;
}
上面的代码是为了让您了解我是如何初始化场景的。 我还使用结构来存储有关路径的信息:

struct PathVert {
   vec3 p; vec3 n; //hit point and normal of the surface hit 
};

struct Path {
   PathVert verts[MAX_DEPTH]; //maxDepth is 15 for now
   int vertCount;
   int x, y; //which pixel this path is referring to
};
因此,我开始考虑像素后像素。

for (int y = 0; y < SCRHEIGHT; y++) for (int x = 0; x < SCRWIDTH; x++)
{     
   Path path;
   if(generatePath(x,y, path)){
      Sample(path);
   }
}
如前所述,光是一个曲面,但恰好是一个正方形曲面,其4个角度为:

Vec P1 = Vec(lightPos.x - 20, lightPos.y, lightPos.z + 20);
Vec P2 = Vec(lightPos.x + 20, lightPos.y, lightPos.z + 20);
Vec P3 = Vec(lightPos.x + 20, lightPos.y, lightPos.z - 20);
Vec P4 = Vec(lightPos.x - 20, lightPos.y, lightPos.z - 20);
相当大,我知道,所以第一个问题依赖于这方面,有这么大的光是正确的吗

但是让我们来看看主要的方法。在此您可以看到GeneratePath方法:

bool GeneratePath(int x, int y, Path &path){
   path.x = x;
   path.y = y;
   path.vertCount = 0;

   vec3 P = renderData.p1 + renderData.dx * ((float)(x) + Rand(1)) +  renderData.dy * ((float)(y) + Rand(1));
   vec3 O = renderData.E + vec3(Rand(0.4f) - 0.2f, Rand(0.4f) - 0.2f, Rand(0.4f) - 0.2f);
   vec3 D = normalize(P - O); //direction of the first ray, the one from the camera towards the pixel we are considering

   for (int depth = 1; depth <= MAXDEPTH; depth++){
    float t;
    Vec hitLightPoint;
    PathVert vert;
    if (!checkIfRayIntersectSomething(t)){
        //we didn't find any object.. but we still may have found the light which is an object non represented in the scene
        //the depth check avoids me rendering the light as a white plane
        if (depth > 1 && checkRayLightIntersection(O, D, hitLightPoint)){
            //update the vertex since we realized it's the light
            vert.p = hitLightPoint;
            vert.n = Vec(0, -1, 0);//cause the light is pointing down
            path.verts[depth - 1] = vert;
            path.vertCount++;
            return true; //light hit, path completed    
        }
        return false; //nothing hit, path non valid
    }
    //otherwise I got a hit into the scene
    vert.p = O + D * t; //reach the hitPoint
    vert.n = methodToFindTheNormal();
    vert.color = CalculateColor(vert.p); //according to the material properties (only diffuse objects so far)
    path.verts[depth - 1] = vert;
    path.vertCount++;

    //since I have the light, and a path terminates when it hits the light, I have to check out also if my ray hits this light,
    //and if does, I have to check whether it first hits the light or the object just calculated above
    //moreover with the "depth > 1" check, I avoid again rendering the light which otherwise would be visible as a white plane

    if (depth > 1 && checkRayLightIntersection(O, D, hitLightPoint)){
        float distFromObj = length(vert.p);
        float distFromLight = length(hitLightPoint);
        if (distFromLight < distFromObj){
            //update the vertex since we realized it's the light
            vert.p = hitLightPoint;
            vert.n = Vec(0, -1, 0);
            vert.color = Vec(1, 1, 1);// TODO light color? or light emission?

            path.verts[depth - 1] = vert;
            return true; //light hit, path completed
        }
    }
    if (depth == MAXDEPTH) return false;
       Vec newDir = BSDFDiffuseReflectionCosineWeighted(vert.n, D);//explained later
       D = newDir;
       O = vert.p;
   }
   return false;
}
bool GeneratePath(整数x、整数y、路径和路径){
路径x=x;
路径y=y;
path.vertCount=0;
vec3 P=renderData.p1+renderData.dx*((float)(x)+Rand(1))+renderData.dy*((float)(y)+Rand(1));
vec3o=renderData.E+vec3(Rand(0.4f)-0.2f,Rand(0.4f)-0.2f,Rand(0.4f)-0.2f);
vec3d=规格化(P-O);//第一条光线的方向,即从相机到我们正在考虑的像素的方向
对于(int depth=1;depth 1&&checkRaylight交叉点(O、D、hitLightPoint)){
浮动距离OBJ=长度(垂直p);
浮动距离灯光=长度(hitLightPoint);
if(distFromLight
BSDFDiffuseReflectionCosNewWarghted()只需计算新方向,并进行测试和工作。最后剩下的是计算像素最终颜色的采样方法

Vec Sampling(Path &path){

   Vec color(1, 1, 1);

   for (int vert = 0; vert < path.vertCount - 1; vert++) { //considers the last vertex as the light
      const PathVert &currVert = path.verts[vert];
      const PathVert &nextVert = path.verts[vert + 1];
      Vec wo = (nextVert.p - currVert.p).norm();
      double cosTheta = fabs(wo.dot(currVert.n));
      float PDF = cosTheta/PI;
      if (cosTheta <= 1e-6) return Vec();
      //considering only DIFFUSE objects
      color = color.mult(currVert.color * (cosTheta / M_PI) / PDF);
   }
   return color.mult(Vec(10.0f, 10.0f, 10.0f)); //multiplication for the light emission?
}
Vec采样(路径和路径){
Vec颜色(1,1,1);
对于(int vert=0;vert如果(cosTheta)缺少哪些阴影?是否有作为“目标渲染”的参考图像?@molbdnilo使用目标参考图像编辑了描述。对于从摄影机射入对象的每条光线,必须将一条光线从命中点传递到场景中的所有灯光。该点上的亮度由光线遮挡的光线的比率决定。@codetiger,这称为下一个事件估计,用于减少e方差。阴影应该在没有该方差的情况下出现。我的理解是,如果你正在进行光子贴图(光线从灯光开始并到达摄影机),那么你不必单独计算阴影。如果你正在进行常规光线跟踪(光线从摄影机开始),那么你必须使用阴影光线计算阴影(光线从点击点到灯光开始,以查看是否有任何其他对象遮挡)缺少哪些阴影?是否有作为“目标渲染”的参考图像?@molbdnilo使用目标参考图像编辑了描述。对于从摄影机射入对象的每条光线,必须将一条光线从命中点传递到场景中的所有灯光。该点上的亮度由光线遮挡的光线的比率决定。@codetiger,这称为下一个事件估计,用于减少e方差。阴影应该在没有该方差的情况下出现。我的理解是,如果你正在进行光子贴图(光线从灯光开始并到达摄影机),那么你不必单独计算阴影。如果你正在进行常规光线跟踪(光线从摄影机开始),那么你必须使用阴影光线计算阴影(光线从命中点到灯光开始,以查看是否有任何其他对象遮挡)
Vec Sampling(Path &path){

   Vec color(1, 1, 1);

   for (int vert = 0; vert < path.vertCount - 1; vert++) { //considers the last vertex as the light
      const PathVert &currVert = path.verts[vert];
      const PathVert &nextVert = path.verts[vert + 1];
      Vec wo = (nextVert.p - currVert.p).norm();
      double cosTheta = fabs(wo.dot(currVert.n));
      float PDF = cosTheta/PI;
      if (cosTheta <= 1e-6) return Vec();
      //considering only DIFFUSE objects
      color = color.mult(currVert.color * (cosTheta / M_PI) / PDF);
   }
   return color.mult(Vec(10.0f, 10.0f, 10.0f)); //multiplication for the light emission?
}