issue with importance sampling I was trying to do importance sampling on lambertian surface.At first I uniformly choose direction from unit sphere.
vec3 direction = camera-&gt;genDirection();
...
direction = random_in_unit_sphere();
float cosine = dotp(direction,surfaceNormal);
/*
float dotp(float val){
val = dot(val);
if(val&gt;0.0001f) return val;
else return 0.0001f;
}
*/
vec3 brdf_result = material-&gt;baseColor/Pi;//lambertian
vec3 pdf = 1.0f/(2.0f*Pi);
throughput = throughput * brdf_result * cosine / pdf;

With 10 samples per pixel,yields:
then I choose random direction from the unit hemisphere above the surface
direction = random_in_unit_hemisphere(surfaceNormal);
float cosine = dotp(direction,surfaceNormal);
vec3 brdf_result = material-&gt;baseColor/Pi;
vec3 pdf = 1.0f/(1.0f*Pi);
throughput = throughput * brdf_result * cosine / pdf;

the result is very similar,except for less noise

and then I use the importance sampling method from (http://in1weekend.blogspot.com/)
    class onb {
public:
    vec3 operator[](int i)const { return axis[i]; }
    vec3 u()const { return axis[0]; }
    vec3 v()const { return axis[1]; }
    vec3 w()const { return axis[2]; }
    vec3 local(float a, float b, float c) { return a * u() + b * v() + c * w(); }
    vec3 local(const vec3&amp; a) { return a.x * u() + a.y * v() + a.z * w(); }
    void buildFromNormal(const vec3&amp; n) {
        axis[2] = normalize(n);
        vec3 a;
        if (std::abs(w().x) &gt; 0.9f)
            a = vec3(0.0f, 1.0f, 0.0f);
        else
            a = vec3(1.0f, 0.0f, 0.0f);
        axis[1] = normalize(cross(w(), a));
        axis[0] = cross(w(), v());
    }


private:
    vec3 axis[3];
};
vec3 randCosDir() {
    float r1 = randFloat01();
    float r2 = randFloat01();
    float z = sqrt(1.0f - r2);
    float phi = 2.0f * Pi * r1;
    float x = cos(phi) * 2.0f * sqrt(r2);
    float y = sin(phi) * 2.0f * sqrt(r2);
    return vec3(x, y, z);
}

,
onb uvw;
uvw.buildFromNormal(surfaceNormal);
direction = normalize(uvw.local(randCosDir()));
float cosine = dotp(direction,surfaceNormal);
vec3 brdf_result = material-&gt;baseColor/Pi;
vec3 pdf = dotp(uvw.w(), direction)/Pi;
throughput = throughput * brdf_result * cosine / pdf;

however the result is different:

The baseColor of the wall is vec3(0.8f,0.8f,0.8f),and the color of the dome light is vec3(1.0f,1.0f,1.0f).
In some tutorial the cosine item is inside the lambertian brdf,and some are in the render equation,and in
http://in1weekend.blogspot.com/ &quot;weekend one&quot; there is no cosine item at all.I really get messed with those concepts.Is there any one help me?thanks so much.
another rendering with baseColor = vec3(1.0f,1.0f,1.0f) and dome color = vec3(0.5f,0.5f,0.5f)  (importance sampling)
the average color of the final image over all pixels is vec3(0.470884f,0.470884f,0.470884f).

10,000 samples per pixel with uniform hemisphere sampling:
I just found that if I use pdf = 1.0f/(4.0f * Pi) in unit sphere sampling or pdf = 1.0f/(2.0f * Pi) in unit hemisphere sampling,the result are almost the same as the importance sampling one(I also get the same result when set the baseColor to vec3(0.4f,0.4f,0.4f),the half of vec3(0.8f,0.8f,0.8f).
And the surface area of a unit sphere is just 4.0f * Pi(I forget why I use 2.0f * Pi before).I HAVE to come to two conclusions:
1: the importance sampling one is correct!
2: I'm too stupid!!!!!!