happyfire

Forum Replies Created

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • in reply to: 作业3 OpenCV 避坑 – texture mapping 运行时 #11034 Score: 0
    happyfire
    Participant
    4 pts

    这地方确实有bug,参考我这个post:
    Reply To: 作业3:小牛正面或背面正对镜头时出现缝隙

    in reply to: 作业3:小牛正面或背面正对镜头时出现缝隙 #11032 Score: 0
    happyfire
    Participant
    4 pts

    找到原因了,作业3框架Texture类getColor方法有bug:

    Eigen::Vector3f getColor(float u, float v)
    {
    auto u_img = u * width;
    auto v_img = (1 – v) * height;
    auto color = image_data.at<cv::Vec3b>(v_img, u_img);
    return Eigen::Vector3f(color[0], color[1], color[2]);
    }

    uv坐标转像素坐标的时候,不能直接乘width和height。这是因为uv坐标的范围是[0,1],而像素坐标的范围是[0,width-1]和[0,height-1]。如果直接乘width,height。那么uv为1的时候,坐标就会越界。但是作业框架使用的库对于越界的像素坐标并不会crash或报错,而是返回一个透明值,因此小牛uv为1的地方就没有颜色了。
    正确的方法是:

    auto u_img = u * (width-1);
    auto v_img = (1 – v) * (height-1);

    另外打个广告,以GAMES101的理论为基础,在Unity平台上实现了一个光栅化渲染器,同时支持多核和GPGPU加速
    https://github.com/happyfire/URasterizer

    Attachments:
    You must be logged in to view attached files.
    in reply to: 作业7eval函数问题 #9148 Score: 0
    happyfire
    Participant
    4 pts

    能说一下吗?我觉得应该是eval(wi,wo,N),因为wi才是光线进入的方向,wo是反射方向。但是貌似顺序不影响结果。另外作业pdf上说wo的含义和课程是反的,我不知道他说的反的是什么意思。wo难道不是反射方向吗?一开始从camera生成的光线其实是最终的wo,只是生成的是camera_to_sample,而wo是sample_to_camera。然后路径逆着追踪,每次的-wi是下次的wo

    in reply to: 关于作业三的dispalcement map #8875 Score: 0
    happyfire
    Participant
    4 pts

    感觉作业里面的displacement mapping简化了,真正的位移贴图确实需要在光栅化之前就移动顶点的位置,作业里面已经到了fragment shader了,此时已经光栅化结束了,因此也就没法再移动顶点了,作业里面只是使用移动后的view_pos去计算光照而已。

    in reply to: 关于代码框架中代码的一点疑问 #8874 Score: 0
    happyfire
    Participant
    4 pts

    可以参考一下我在这个帖子里面的回复:

    作业3 关于深度值问题自己踩的坑和一些想法

    in reply to: 作业3 关于深度值问题自己踩的坑和一些想法 #8873 Score: 2
    happyfire
    Participant
    4 pts

    需要说明的是,以上对于z值问题的分析是基于课程推导投影矩阵时的约定,即:
    view为右手系,camea看向-z;NDC为右手系;矩阵中的n和f是坐标值,即为负值。
    但是根据作业2框架给的函数参数,get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)。调用时传入的zNear和zFar分别为0.1和50, 而这个写法和OpenGL很接近,因此也可以推断作业框架使用了OpenGL的约定,即view为右手系,camea看向-z;NDC为左手系;矩阵中的n和f是距离值,即为正值。如果按照这个约定去推导投影矩阵并计算z值,得到的结果就和我之前分析的不一样了。此时就不会存在上面的问题。因此,可能框架也没问题吧,但是应该在pdf里面指出使用的约定,否则就容易引起误会,造成不必要的困扰。

    This post has received 2 votes up.
    in reply to: 作业3 关于深度值问题自己踩的坑和一些想法 #8872 Score: 1
    happyfire
    Participant
    4 pts

    很高兴你也注意到了w==1这个问题,其实作业2,作业3的框架都有问题,他们公共的问题是光栅化取三角形顶点坐标时使用了 auto v = t.toVector4(); 这样w肯定是1了。然后作业2错误更多些,在透视除法里面使用了vec /= vec.w();造成w为1。然后作业3修复了这一点,只对x,y,z除了w。但是没有用啊,因为toVector4。

    然后项目框架里面的w应该是什么含义呢?按照课程的约定,NDC使用了和ViewSpace一样的右手系,所以投影矩阵的最后一行是(0,0,1,0),这样w=Z_view。所以课程3框架的注释里面说:v[i].w() is the vertex view space depth value z. 并没有问题。而在网上找的关于OpenGL的文章里面,推导出来w=-Z_view,那是因为OpenGL的约定中,NDC为左手坐标系(near为-1,far为+1)。

    然后我们看下z插值的问题,作业2框架中这么写(作业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;
    

    由于w为1,因此上面的w_reciprocal就是1.0/(alpha+beta+gamma),而alpha+beta+gamma==1,因此w_reciprocal为1。
    因为w为1,z_interpolated 其实就是直接使用重心坐标进行插值了(没有透视校正的效果),最后一步z_interpolated *= w_reciprocal也没有作用。最终z_interpolated 就是三个顶点的z值的插值。
    那么这个地方三个顶点的z值是什么呢?在draw中:

    
    float f1 = (50 - 0.1) / 2.0;
    float f2 = (50 + 0.1) / 2.0;
    vert.z() = vert.z() * f1 + f2;
    

    f1,f2是什么意思?因为框架中的near是0.1,far是50.(这儿near,far都是距离值,是正值。我只能这么理解吧),所以f1,f2的作用就是把clip space的z值变换到[near,far]的范围中。我LOG了一下,第一个三角形的clip space z为 -0.975379,变换后为0.714285;第二个三角形从-0.983968变换到0.50002。因为框架中一直使用的是右手坐标系,且view space的view方向为-z。因为第一个三角形的z值-0.97xx大于第二个三角形的-0.98xxx,离camera更近,所以第一个三角形应该挡住第二个三角形。但是真正做深度测试的时候,使用的是变换到[0.1,50]范围的z值。这样第一个三角形的0.7xxx由于大于第二个三角形的0.5xxx,因此如果直接使用z_interpolated 并且按照小值离camera近的逻辑去比较就会得到第二个三角形挡住第一个三角形的错误结果。为了得到正确的结果,简单的取个负修正一下确实可以,但这里面的逻辑确实搞错了。根源就在于作业2的pdf里面说的:为了方便同学们写代码,我们将 z 进行了反转,保证都是正数,并且越大表示离视点越远。
    按照我上面的分析,反转后的正数z并不是越大离视点越远,而是正好相反。所以作业3牛画反的同学应该明白了吧,并不是你的问题。框架本身就有问题。。这个地方转成正数后反而不能用<去测试了,有点画蛇添足的感觉。

    This post has received 1 vote up.
    in reply to: 透视投影转换为正交投影中的n、f是正是负? #8789 Score: 1
    happyfire
    Participant
    4 pts

    因为他给出的参数zNear和zFar就是正数啊,那么只能是距离值了,人家又没说是坐标。你设置坐标时取一下负就行。
    当然了,因为老师课上讲的时候都是用的坐标,这个地方给距离值我感觉是有点会误导。我想这个主要是遵循一些习惯罢了,比如OpenGL的同款函数的参数都是距离值(正数)

    This post has received 1 vote up.
    in reply to: 平移矩阵为什么不能写出来 #8788 Score: 0
    happyfire
    Participant
    4 pts

    思路清奇。。矩阵是用来变换向量的,你把向量写到矩阵里了,请问矩阵怎么构造出来?

    in reply to: 重心坐标插值属性问题? #8787 Score: 0
    happyfire
    Participant
    4 pts

    你想一想需要插值的场景,是光栅化之后进行Fragment shader计算的时候,此时已经是屏幕空间了,所以要在屏幕空间插值。而且插值也就是为了每个像素(片段)获取属性值。
    如果在视图空间插值,插值的颗粒度是啥?3D空间并没有离散的量,你只能自己定义一个,比如0.1单位插值一次?但这样也没有意义,因为你怎么离散都不一定能对应到像素。况且你真离散了,插值完了得传多少varying进shader啊。
    当然屏幕空间插值也有问题,就是老师讲的重心坐标投影后会变的问题,所以有个技术叫透视投影校正

    in reply to: [作业1]关于PCSS边界明显的Tip #8259 Score: 0
    happyfire
    Participant
    4 pts

    了解了,你应该是用了透视投影,然后你的zReceiver和zBlocker都不是线性的,所以你需要转到线性吧。这没问题。
    我是跟着课程走的,计算penumbra就是用的一个简单的相似三角形,当然用的是正交投影,所以zReceiver和zBlocker都是线性的,因此这么计算:
    float penumbra = (zReceiver – zBlocker) * LIGHT_WIDTH / zBlocker;
    应该没有物理上不正确吧

    in reply to: [作业1]关于PCSS边界明显的Tip #8207 Score: 0
    happyfire
    Participant
    4 pts

    Sorry,看成PCF了,不过意思一样的。(这个帖子不能编辑吗?没找到EDIT..)
    findBlocker和PCF里面都是用的一样的z,可能你修改了findBlocker,不过这个函数真的是改一点东西影响都很大,所以你改了z应该就是会有不同的效果。但是我觉得应该和linear depth没关系的,请批评指正!

    in reply to: [作业1]关于PCSS边界明显的Tip #8206 Score: 0
    happyfire
    Participant
    4 pts

    请问能说清楚一些吗?最好能上代码。
    PCF里面比较的是shadowmap中的深度和当前片段在LightSpace中的深度。这两个深度都是正交投影计算出来的吧,而且使用的都是LightMVP矩阵。
    区别只是shadowmap中的深度是从gl_FragCoord.z读取出来的,这个值是range到了0~1(默认)。而用来和shadowmap比较的深度计算是vPositionFromLight = uLightMVP * vec4(aVertexPosition, 1.0);
    这个就是clip space的,当然对于正交投影,w=1,因此就是NDC的。因此范围是[-1,1],因此只要转换到[0,1]就可以和shadow map解压出来的深度比较了。
    如果我分析的没问题的话,这里面找不到需要变换到线性深度(eye space z,范围[n,f])的地方呀?而且用的都是一样的矩阵,即便不是正交投影,是透视投影,应该也没问题吧?

    另外最终出的效果和采样数,filterSize都有关系,你确定其他参数都没变?

Viewing 13 posts - 1 through 13 (of 13 total)