Lambertian着色器仍无法正常工作

时间:2015-04-11 15:03:20

标签: java shader raytracing

昨天我发布了这个:

Lambertian Shader not working

我的着色器仍无法正常工作,我已经做了一些调试,试图找到原因。当我运行我的程序并点击一个球体时,调用shader.shade(renderable.colour)并运行此代码:

public Colour shade(Intersection intersection, Light light){
    Vector3D lightDirection =  light.location.subtract(intersection.point);
    lightDirection.normalise();
    Normal normal = intersection.normal;
    normal.normalise();

    Colour finalColour = new Colour();
    float lambCoef = (float) normal.dot(lightDirection);

    if(lambCoef>0){
        finalColour.r = Math.max(0.0f, diffuseColour.r * lambCoef * light.intensity.r);
        finalColour.g = Math.max(0.0f, diffuseColour.g * lambCoef * light.intensity.g);
        finalColour.b = Math.max(0.0f, diffuseColour.b * lambCoef * light.intensity.b);


    }
    return finalColour;

}

我每次都得到lambCoef的不同值,但不是非常多,例如红色球体,对于彼此垂直约20个像素的像素,我得到: 0.9446402 0.94463843 0.9446326 0.94462925 为了获得我使用的球体的法线:

public Normal getNormalAt(Vector3D point) {

    Normal normal = new Normal(point);
    normal = normal.subtract(center);
    normal = normal.multiply(-1);
    normal.normalise();
    return normal;

}

似乎有用。 然后我使用点和交叉代码:

public double dot(Vector3D vector){
    return x*vector.x + y*vector.y +z*vector.z;
}

public double dot(Point3D point){
    return x*point.x + y*point.y +z*point.z;
}

public double dot(Normal normal){
    return x*normal.x + y*normal.y +z*normal.z;
}

public Vector3D cross(Vector3D vector) {

    Vector3D crossedVector =  new Vector3D();

    crossedVector.x = y*vector.z - z*vector.y;
    crossedVector.y = z*vector.x - x*vector.z;
    crossedVector.z = x*vector.y - y*vector.x;

    return crossedVector;

}

这似乎也是正确的。 任何帮助都会非常感激,如果需要,我很乐意提供更多信息。

我现在得到这种形象:

enter image description here

哪种有意义,因为飞机与球体的角度要小得多。但它仍然是错误的。

1 个答案:

答案 0 :(得分:0)

+1,用于使用离散的NormalPointVector类。在你的shade()方法中,它并不像我在考虑光源到交叉点的距离那样。基本上,您希望距离给定光线更远的交叉点比接近光线的点接收更少的光线。您可以通过将intensity系数c / (distance * distance)调整为c,将distance调整为点光源,其中finalColour是经验确定的亮度修正系数(从1开始然后向上调整,如果结果太暗了)light.intensity是点光源和交叉点之间的距离。当我说调整时,我的意思是将该字词添加到1/d*d计算中,而不是实际更改String的值。

一旦你开始工作,你可能想要考虑用PDF来取样光源,而不是使用DateTime黑客。