ssloy/tinyrenderer

Confuse about lesson 6

Closed this issue · 1 comments

virtual bool fragment(const vec3 bar, TGAColor &gl_FragColor) const {
    vec3 bn = normalized(bar * varying_nrm); // per-vertex normal interpolation
    vec2 uv = bar * varying_uv;              // tex coord interpolation

    mat<3,3> AI = mat<3,3>{ {view_tri[1] - view_tri[0], view_tri[2] - view_tri[0], bn} }.invert(); // for the math refer to the tangent space normal mapping lecture
    vec3 i = AI * vec3{varying_uv[1].x - varying_uv[0].x, varying_uv[2].x - varying_uv[0].x, 0};   // https://github.com/ssloy/tinyrenderer/wiki/Lesson-6bis-tangent-space-normal-mapping
    vec3 j = AI * vec3{varying_uv[1].y - varying_uv[0].y, varying_uv[2].y - varying_uv[0].y, 0};
    mat<3,3> B = mat<3,3>{ { normalized(i), normalized(j), bn } }.transpose();

    vec3 n = normalized(B * model.normal(uv));          // transform the normal from the texture to the tangent space
    vec3 r = normalized(n * (n * uniform_l)*2 - uniform_l); // reflected light direction, specular mapping is described here: https://github.com/ssloy/tinyrenderer/wiki/Lesson-6-Shaders-for-the-software-renderer
    double diff = std::max(0., n * uniform_l);                                       // diffuse light intensity
    double spec = std::pow(std::max(-r.z, 0.), 5+sample2D(model.specular(), uv)[0]); // specular intensity, note that the camera lies on the z-axis (in view), therefore simple -r.z

    TGAColor c = sample2D(model.diffuse(), uv);
    for (int i : {0,1,2})
        gl_FragColor[i] = std::min<int>(10 + c[i]*(diff + spec), 255); // (a bit of ambient light, diff + spec), clamp the result
    return false; // do not discard the pixel
}

Normal from tangent space to world space. This is my deduction:

Image

I don't think A is needed to be inverted.

It depends on how you define what the tangent and bitangent are.
I guess that in my code they are rotated 90° w.r.t yours. I'll update it in the v2 of the series I am writing.