2016-11-13 2 views
2

Ich habe Probleme, das Beleuchtungsmodell für meine Sphären zu korrigieren. Genauer gesagt kann ich die Glanzlichter für Kugeln nicht korrekt erhalten. Hier ist, was ich zu sehen bin, wenn ich Sphären Raytracing:
Wrong specular highlightsSphere Raytracing - Glanzlichter

Nun ist die Glanzlichter ein wenig mehr wie diese aussehen sollen:
Correct specular highlights

Wie ich verstehe, das Beleuchtungsmodell (für diese diffusen Sphären) sieht wie folgt aus:
Lighting model

Wo c r die Farbe der Kugel ist, c ein ist die Ambie nt-Komponente von Licht, c l ist die Farbe des Lichts, n die Normale an dem Schnittpunkt auf der Kugel ist, ist l die Richtung des Lichts, c p wird die Farbe des Glanzlichtes, e ist Auge/Look From, r ist der Reflexionsvektor von der Oberfläche der Kugel, und im Exponenten bezieht sich auf die Phong Konstante/Exponent (wie eng/lose das Licht ist).

Hier ist mein Prozess:

public Color calculateIlluminationModel(Vector normal, Scene scene) 
{ 
    //c = cr * ca + cr * cl * max(0, n \dot l)) + cl * cp * max(0, e \dot r)^p 
    Vector lightSourceColor = getColorVector(scene.getLight().getLightColor()); //cl 
    Vector diffuseReflectanceColor = getColorVector(getMaterialColor()); //cr 
    Vector ambientColor = getColorVector(scene.getLight().getAmbientLightColor()); //ca 
    Vector specularHighlightColor = getColorVector(getSpecularHighlight()); //cp 
    Vector directionToLight = scene.getLight().getDirectionToLight(); //l 
    Vector reflectionVector = normal.multiply(2).multiply(normal.crossProduct(directionToLight)).subtract(directionToLight); //r = 2n(n \dot l) - l 

    Vector ambientTerm = diffuseReflectanceColor.multiply(ambientColor); 
    double angleBetweenLightAndNormal = directionToLight.dotProduct(normal); 
    Vector diffuseTerm = diffuseReflectanceColor.multiply(lightSourceColor).multiply(Math.max(0, angleBetweenLightAndNormal)); 
    Vector phongTerm = lightSourceColor.multiply(specularHighlightColor).multiply(Math.pow(Math.max(0, scene.getCameraSettings().getLookFrom().dotProduct(reflectionVector)), (double) getPhongConstant())); 
    return getVectorColor(ambientTerm.add(diffuseTerm).add(phongTerm)); 
} 

Beachten Sie, dass das Auge Komponente für den phong Begriff in diesem Fall die Optik der Kamera ist aus, das ist (0, 0, 1), und die Richtung des Licht ist (1, 0, 0).

Irgendwelche Ideen, warum meine specular Highlights auf der Spitze der Kugeln sind, anstatt in die Richtung des Lichts zu sehen?

Lassen Sie mich wissen, wenn ich irgendwelche wichtigen Details herauslassen, die Sie mir helfen müssen.

+0

Warum ist Ihre Kamera Look-von immer (0, 0, 1)? Sollte das nicht variieren, abhängig davon, welches Pixel du gerade zeichnest? –

+0

Mein Verständnis war, dass das Auge/Ursprung des Strahls nicht ändert, nur die Richtung des Strahls. –

Antwort

1

Das Problem ist mit dieser Zeile:

Vector reflectionVector = normal.multiply(2).multiply(normal.crossProduct(directionToLight)).subtract(directionToLight); //r = 2n(n \dot l) - l 

Statt des Punktprodukts zwischen der normalen und der Richtung auf das Licht nehmen, werden Sie stattdessen normal.crossProduct(directionToLight) nehmen, die Quer Produktion, die Sie würde einen Vektor senkrecht zu dem einen, den Sie wollen, geben Sie den Fehler, den Sie oben sehen.

Also statt, sollten Sie

Vector reflectionVector = normal.multiply(2).multiply(normal.dotProduct(directionToLight)).subtract(directionToLight); //r = 2n(n \dot l) - l 
1

Der Reflexionsvektor sollte basierend auf der Oberflächennormalen und eintreffenden Strahlrichtung berechnet werden, nicht auf Lichtrichtung, wie Sie es jetzt tun.

+0

Das machte die Dinge viel schlimmer. Bist du dir da sicher? Von dem, was ich gesehen habe, ist der Reflexionsvektor "r = 2n (n \ dot l) - l", wobei "l" die Richtung zum Licht ist. –

+0

Denken Sie nur darüber nach - hängt die Form Ihrer Reflexion in einem Spiegel von der Position naher Lichter ab? –

+1

Ich habe einige Dinge geändert, und es scheint ein paar Probleme behoben zu haben. Aber das eigentliche Problem war, dass ich das Cross-Produkt genommen habe, als ich das Dot-Produkt nehmen wollte. –

Verwandte Themen