Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 实施Blinn&x2013的问题;Phong着色模型_Java_Graphics_3d_Vector Graphics - Fatal编程技术网

Java 实施Blinn&x2013的问题;Phong着色模型

Java 实施Blinn&x2013的问题;Phong着色模型,java,graphics,3d,vector-graphics,Java,Graphics,3d,Vector Graphics,我做了这个非常简单、完美的实现(目前还没有实现任何氛围,但现在这并不困扰我)。功能应该是自我解释的 /** * Implements the classic Phong illumination Model using a reflected light * vector. */ public class PhongIllumination implements IlluminationModel { @RGBParam(r = 0, g = 0, b = 0) publ

我做了这个非常简单、完美的实现(目前还没有实现任何氛围,但现在这并不困扰我)。功能应该是自我解释的

/**
 * Implements the classic Phong illumination Model using a reflected light
 * vector.
 */
public class PhongIllumination implements IlluminationModel {

    @RGBParam(r = 0, g = 0, b = 0)
    public Vec3 ambient;

    @RGBParam(r = 1, g = 1, b = 1)
    public Vec3 diffuse;

    @RGBParam(r = 1, g = 1, b = 1)
    public Vec3 specular;

    @FloatParam(value = 20, min = 1, max = 200.0f)
    public float shininess;

    /*
     * Calculate the intensity of light reflected to the viewer .
     * 
     * @param P = The surface position expressed in world coordinates.
     * 
     * @param V = Normalized viewing vector from surface to eye in world
     * coordinates.
     * 
     * @param N = Normalized normal vector at surface point in world
     * coordinates.
     * 
     * @param surfaceColor = surfaceColor Color of the surface at the current
     * position.
     * 
     * @param lights = The active light sources in the scene.
     * 
     * @return Reflected light intensity I.
     */
    public Vec3 shade(Vec3 P, Vec3 V, Vec3 N, Vec3 surfaceColor, Light lights[]) {
        Vec3 surfaceColordiffused = Vec3.mul(surfaceColor, diffuse);
        Vec3 totalintensity = new Vec3(0, 0, 0);
        for (int i = 0; i < lights.length; i++) {
            Vec3 L = lights[i].calcDirection(P);
            N = N.normalize();
            V = V.normalize();
            Vec3 R = Vec3.reflect(L, N); // reflection vector
            float diffuseLight = Vec3.dot(N, L);
            float specularLight = Vec3.dot(V, R);
            if (diffuseLight > 0) {
                totalintensity = Vec3.add(Vec3.mul(Vec3.mul(
                        surfaceColordiffused, lights[i].calcIntensity(P)),
                        diffuseLight), totalintensity);
                if (specularLight > 0) {

                    Vec3 Il = lights[i].calcIntensity(P);

                    Vec3 Ilincident = Vec3.mul(Il, Math.max(0.0f, Vec3
                            .dot(N, L)));

                    Vec3 intensity = Vec3.mul(Vec3.mul(specular, Ilincident),
                            (float) Math.pow(specularLight, shininess));

                    totalintensity = Vec3.add(totalintensity, intensity);
                }

            }
        }
        return totalintensity;
    }
}
这些微小的变化应该已经起作用了(可能强度不正确,但基本上应该是正确的)。但结果是错误的

这里有两张图片。左边是它应该如何正确渲染,右边是它如何渲染

如果我降低光泽度系数,您可以在右上角看到一点镜面反射光:

虽然我了解Phong照明的概念,也了解blinn Phong简化的更高性能的适应性,但我已经尝试了好几天,只是无法让它工作。任何帮助都是值得的

编辑:

我意识到一个错误,在计算H时,我用
|L+V |
而不是除以它。我改为使用偏差:

Vec3 H = Vec3.mul(Vec3.add(L.normalize(), V), 1/Vec3.add(L.normalize(), V).length());
不幸的是,这没有多大变化。结果如下所示:

如果我提高镜面反射常数,降低光泽度,你可以以一种微笑的错误方式更清楚地看到效果:

然而,这种划分只是正常化

我想我错过了一步。因为这样的公式对我来说毫无意义

如果你看这张图片:

H到N的投影远小于V到R。如果你想象改变图片中的矢量V,当观察矢量在“左侧”时,角度是相同的。向右走的时候会变得越来越不一样

我悲观地将整个投影乘以2,得到类似的结果(孔点是为了避免计算R)。虽然我没有读到任何关于这个的东西,但是我要试试这个

结果:镜面反射光的强度太大(白色区域),位置仍然错误

我想我把其他事情搞糟了,因为这些反射只是在错误的地方。但是什么呢


编辑:现在我在维基百科上的注释中读到,N/H的角度实际上接近V/R的一半。为了补偿这一点,我应该将我的亮度指数乘以4,而不是我的投影。如果我这样做,我就没有可见的镜面反射光。

当计算
H
时,你似乎是将
L+V
乘以它的范数,比如:
H=(L+V)*| L+V |
(假设
Vec3.mul(V,x)
V
乘以
x
)。相反,你应该除以标准值,
H=(L+V)/| L+V |

算出了


我不得不否定查看向量。

谢谢。不幸的是,这并没有太大改变。。。你能看到我编辑过的答案吗?我只做了两个3D项目,两次都搞砸了+1.
Vec3 H = Vec3.mul(Vec3.add(L.normalize(), V), 1/Vec3.add(L.normalize(), V).length());