0

I'm working on a ray tracer using C++ and OpenGL (glDrawPixels), and it is going well so far. However, my shading seems to be a bit off. I want my spheres to look a little smoother without having the blatant lines between intensities. At the moment, I am just trying to implement Lambertian shading, which is Intensity = Id * pd * (N dot L). I know how I need to calculate the (N dot L) by normalizing the normal vector and light vector, but what about the Id and pd (intensity diffuse and factor of proportionality)? I am just using a constant value of 2.5 to achieve the following:

(Here is a picture of what my shading looks like)

Obviously, 2.5 is completely arbitrary, and I'm only using it because my other attempts did not even resemble proper shading. The equation above seems to suggest that I should multiply the color by the intensity. This is my method:

Color simpleIlluminate(Vector3D normal, Vector3D light, Color color) {
    float intensity = dotProduct(normal, light)*2.5f;
    color = Color((unsigned int)intensity*color.r, (unsigned int)intensity*color.g, (unsigned int)intensity*color.b);
    return color;
}

Assume that the normal vector and the light vector are correct. Color is just a color struct I made that has an unsigned int for each of the RGB values. The parameter Color color is the color of the sphere I want to shade, e.g. red = Color(255,0,0). To modify the intensity of the color, I simply multiply each value by the intensity I calculated, but it doesn't look right when I run it.

Can someone explain what I am missing and show me what the correct function should look like given the vectors and sphere color? I've looked everywhere, but I can't find a good solution. I might also be doing my float to unsigned int conversion wrong, but I'm not sure. Any help is appreciated.

4

2 回答 2

3

我会删除 2.5 因子,因为它可能会影响结果,这很可能会产生条带,因为您将因子放大到 0 和 1 范围之外。

朗伯反射率也称为余弦反射率,实际上很容易理解。考虑一个平面,如果一束光垂直于该平面,那么所有的光都会落在表面上(100%,或因子 1.0)。如果一盏灯平行于该平面指向,那么 0 光将落在表面上(所有光线都是平行的,因此永远不会与平面相交,所以一个因子或 0)。

朗伯反射率只是光方向和表面法线之间夹角的余弦值,范围从 0(没有光射到平面)到 1.0(所有光射到平面)。注意余弦(90)= 1。余弦(0)= 0,因此称为余弦定律(朗伯反射率)。

于 2016-10-10T13:27:30.413 回答
0

我也可能将浮点数转换为无符号整数错误

发现。(unsigned int)intensity*color.r相当于((unsigned int)intensity)*color.r。因此,在乘以颜色之前,您的强度会呈现出离散的水平,从而产生这些线条。试试(unsigned int)(intensity*color.r)吧。

于 2016-10-10T13:27:19.100 回答