Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

questing about shadowbuffer in lesson 7 #54

Open
whyaysd opened this issue Aug 30, 2020 · 0 comments
Open

questing about shadowbuffer in lesson 7 #54

whyaysd opened this issue Aug 30, 2020 · 0 comments

Comments

@whyaysd
Copy link

whyaysd commented Aug 30, 2020

In lesson 7, we use a shadow buffer to determine whether a point is lit or not.

In my opinion, if a point is lit, then the depth should equal to than in the shadow buffer. However, this shadow buffer is an array, we need to round the point into an integer. As a result, there is some errors between the shadow buffer(from DepthShader) and the depth recovered by the Shader.

In your wiki, you use:
float shadow = .3+.7*(shadowbuffer[idx]<sb_p[2]+43.34);

Then, both cases will be ok.

However, I compare those two value in my code:

struct Shader : public IShader {
    mat<4,4,float> uniform_M;   //  Projection*ModelView
    mat<4,4,float> uniform_MIT; // (Projection*ModelView).invert_transpose()
    mat<4,4,float> uniform_Mshadow; // transform framebuffer screen coordinates to shadowbuffer screen coordinates
    mat<2,3,float> varying_uv;  // triangle uv coordinates, written by the vertex shader, read by the fragment shader
    mat<3,3,float> varying_tri; // triangle coordinates before Viewport transform, written by VS, read by FS
    mat<3,3,float> vert; // triangle coordinates before Viewport transform, written by VS, read by FS

    mat<4,4,float> uniform_M0shadow; // transform framebuffer screen coordinates to shadowbuffer screen coordinates

    Shader(Matrix M, Matrix MIT, Matrix MS, Matrix MS0) :
        uniform_M(M), uniform_MIT(MIT), uniform_Mshadow(MS), varying_uv(), varying_tri(), vert(), uniform_M0shadow(MS0) {}

    virtual Vec4f vertex(int iface, int nthvert) {
        varying_uv.set_col(nthvert, model->uv(iface, nthvert));
        Vec4f gl_Vertex = Viewport*Projection*ModelView*embed<4>(model->vert(iface, nthvert));
        varying_tri.set_col(nthvert, proj<3>(gl_Vertex/gl_Vertex[3]));
        vert[nthvert] =  model->vert(iface, nthvert);
        return gl_Vertex;
    }

    virtual bool fragment(Vec3f bar, TGAColor &color) {
        Vec4f sb_p = uniform_Mshadow*embed<4>(varying_tri*bar); // corresponding point in the shadow buffer
        sb_p = sb_p/sb_p[3];
        int idx = int(sb_p[0]) + int(sb_p[1])*width; // index in the shadowbuffer array
      
        // ==========================================
        static int x1, x2;
        if(std::abs(shadowbuffer[idx]-sb_p[2]) < 10){
            if (shadowbuffer[idx] > sb_p[2])
                x1 ++;
            else
                x2 ++;
            std::cout << x1 << " " << x2 << std::endl;
        }
        // ==========================================

        float shadow = .3+.7*(shadowbuffer[idx] < sb_p[2]); // magic coeff to avoid z-fighting
        Vec2f uv = varying_uv*bar;                 // interpolate uv for the current pixel
        Vec3f n = proj<3>(uniform_MIT*embed<4>(model->normal(uv))).normalize(); // normal
        Vec3f l = proj<3>(uniform_M  *embed<4>(light_dir        )).normalize(); // light vector
        Vec3f r = (n*(n*l*2.f) - l).normalize();   // reflected light
        float spec = pow(std::max(r.z, 0.0f), model->specular(uv));
        float diff = std::max(0.f, n*l);
        TGAColor c = model->diffuse(uv);
        for (int i=0; i<3; i++) color[i] = std::min<float>(20 + c[i]*shadow*(1.2*diff + .6*spec), 255);
        return false;
    }
};


results:

...
4644 35330
4644 35331
4644 35332
4645 35332
4645 35333
4645 35334
4645 35335
4645 35336
4645 35337
4645 35338
4645 35339
4645 35340
4645 35341
4645 35342
4645 35343
4645 35344
4645 35345
4645 35346
4645 35347
4645 35348
4645 35349
4645 35350
4645 35351
4645 35352
4645 35353

And this turns out that most of the time shadowbuffer[idx] < sb_p[2]

I can not understand it. I think, if a point is lit by light, the depth from DepthShader and Shader should be much close. And this result indicates there are some systematic errors between them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant