Viewing 1 reply thread
  • Author
    Posts
    • #6359 Score: 0
      oxine
      Participant
      6 pts

      在作业3中计算插值的代码如下:

      float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
      float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
      z_interpolated *= w_reciprocal;

      其中v是view space下的坐标,w_reciprocal是插值后的z_view

      我暴力的手推了一下,发现最终的z_interpolated的确是z_ndc,正是我们所需要的。

      但是这个式子,后两行的这个代码是怎么来的呢?我始终想不通如何从数学上推出这个代码。但我按这个式子列了一下,算到最后,知道他是正确的。

      另外假设从view space变换到ndc,我们有

      auto z_correct_ndc = (zfar+znear)/(zfar-znear) + 2*zfar*znear/ ((zfar - znear) *w_reciprocal );
      auto z_correct = 1 / w_reciprocal ;

      可以看到实际上影响到深度值的部分就是z_correct, 我们直接使用1 / w_reciprocal,也就是1/z_view来做depth test就可以了,那么再把插值后的z_view变换到z_ndc是否还有必要?在多出了部分运算量后,这样做有什么好处?

      以及在draw()函数中的vert.z() = vert.z() * f1 + f2;这个我手推出来是n+f+nf/z_view,我并不清楚这步的意义,在插值计算时我也完全没有使用传入rasterize_triangle()函数中三角形的这个z分量,我想知道原本这个设计是用来做什么的。

      最后是一个关于插值理解的问题,我发现如果要对depth或者其他的属性做插值的话,我现在是这样做的,先在屏幕空间计算出贡献分量,然后回到view space去做关于1/z_view的线性插值。有没有不使用viewspace坐标或者说不把z_ndc变换到z_view,直接使用z_ndc的插值方法?

      恳请各位大佬赐教!!

    • #6693 Score: 0
      lumixraku
      Participant

      同样的疑问, 我更加不懂的是,按照课上特别强调右手坐标系应该是离的远Z比较小,离得近反而Z大。
      但是深度缓冲计算时却不是这样,每次有更小的z 就更新深度缓冲。这是为什么呢?

      • #8380 Score: 0
        Yijie Li
        Participant

        这是因为框架中为了简便起见把z进行了反转,作业2文件中有说明。

Viewing 1 reply thread
  • You must be logged in to reply to this topic.