Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

11

04.12.2011, 12:06

Ich glaube ich hab noch nicht ganz verstanden wie ich jetzt daraus ein Pointlight bekomme:


(Link)


Wie man hier sieht ist der "Lichtfleck" nicht an der Position des Lichts (gelbe Kugel). Außerdem verschiebt sich das Licht komisch wenn ich die Kugel (also das Licht) bewege (in einem "V" quer über die Fläche, niemals parallel zur X bzw. Z Achse).

Shader sind:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// VERTEX

// [...]

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
uniform mat3 normal_matrix;

uniform vec3 camera_position;
uniform Material material0;
uniform Light light0;

in vec3 a_Vertex;
in vec2 a_TexCoord;
in vec3 a_Normal;

out vec2 texCoord;
out vec3 N, L, HV; // Normale, Lichtrichtung, halfway vector
out vec4 ambient, diffuse;
out float attenuationDistance;

void main(void){        
    vec4 pos = modelview_matrix*vec4(a_Vertex, 1.0);
    N = normalize(normal_matrix*a_Normal);
    
    vec3 lightPos = light0.position.xyz;
    L = normalize(lightPos-pos.xyz);
    HV = normalize(camera_position-pos.xyz)+L*0.5;
    attenuationDistance = length(lightPos-pos.xyz);

    ambient = material0.ambient*light0.ambient;
    diffuse = material0.diffuse*light0.diffuse;
    
    texCoord = a_TexCoord;
    gl_Position = projection_matrix*pos;
}

// FRAGMENT

// [...]

uniform sampler2D texture0;
uniform Material material0;
uniform light light0;

in vec2 texCoord;
in vec3 N, L, HV;
in vec4 ambient, diffuse;
in float attenuationDistance;

out vec4 outColor;

void main(void){    
    vec4 color = ambient;
    vec3 n = normalize(N);
    float NdotL = max(dot(n, normalize(L)), 0.0);
    
    if(NdotL > 0.0){
        float NdotHV = max(dot(n, normalize(HV)), 0.0);
        float attenuation = 1.0/(light0.constant_attenuation+ 
                                 light0.linear_attenuation*attenuationDistance+ 
                                 light0.quadratic_attenuation*attenuationDistance*attenuationDistance);
                                                                             
        color += attenuation*diffuse*NdotL+material0.specular*light0.specular*pow(NdotHV, material0.shininess);
    }
    
    outColor = color*texture(texture0, texCoord.st);
}


An [...] kommt nur das Material und das Light struct, sowie #version 150.
Gelesen dazu habe ich übrigens mein Buch, sowie:

http://www.lighthouse3d.com/tutorials/gl…ight-per-pixel/
(Link verloren)

Und ich erkenne nicht direkt den Unterschied zum directionalen...

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

12

04.12.2011, 12:19

Die Lichtposition liegt auch im Viewspace vor?

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

13

04.12.2011, 12:32

Dazu muss ich was tun?

Übergeben wird die Position so:

C-/C++-Quelltext

1
shader->sendUniform("light0.position", light.position.x, light.position.y, light.position.z, 1);


Wie dann damit gerechnet wirst du oben.

[EDIT]

*modelview, kann das sein?


(Link)


Sort aber für komische Kanten die da nicht hingehören (unten in rot).

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

14

04.12.2011, 12:35

Deine Vertexposition liegt im Viewspace vor. Deine Lichtposition muss also auch im Viewspace vorliegen, sonst machen all diese Berechnungen keinen Sinn. Falls sie das nicht tut, musst du sie eben entsprechend transformieren!?

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

15

04.12.2011, 13:22

Nee, irgendwie nicht:


(Link)


Die roten "Flecken" sollten jawohl nicht da sein.

Vertex Shader:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void main(void){        
    vec4 pos = modelview_matrix*vec4(a_Vertex, 1.0);
    N = normalize(normal_matrix*a_Normal);
    
    vec3 lightPos = vec3(modelview_matrix*light0.position); // MAL MODELVIEW GERECHNET
    L = normalize(lightPos-pos.xyz);
    HV = normalize((camera_position-pos.xyz+L)*0.5);
    attenuationDistance = length(light0.position.xyz-pos.xyz);

    ambient = material0.ambient*light0.ambient;
    diffuse = material0.diffuse*light0.diffuse;
    
    texCoord = a_TexCoord;
    gl_Position = projection_matrix*pos;
}


[EDIT]

Hier nochmal etwas deutlicher was ich meine:


(Link)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

16

04.12.2011, 13:24

Die ModelView Matrix ist ja wohl auch in die falsche Matrix. Oder liegt dein Licht im Objectspace?

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

17

04.12.2011, 13:30

Ich finde nirgendswo das man die Lichtposition in Eyespace oder Objectspace umrechnen müsste. Also woher soll ich das wissen? Und mit projection sieht das ganze so aus (immer noch falsch):


(Link)


C-/C++-Quelltext

1
2
3
4
vec4 lightPos = projection_matrix*light0.position;
    L = normalize(lightPos-pos).xyz;
    HV = normalize((camera_position-pos.xyz+L)*0.5);
    attenuationDistance = length(lightPos-pos);

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

18

04.12.2011, 13:37

Ich finde nirgendswo das man die Lichtposition in Eyespace oder Objectspace umrechnen müsste.

Dann erklär mir mal was genau du denkst, dass du hier tust:

Quellcode

1
L = normalize(lightPos-pos).xyz;



Und mit projection sieht das ganze so aus (immer noch falsch)

Um ja, wie kommst du auch auf Projection!? Ich hab das Gefühl du solltest dir vielleicht nochmal genau anschauen was für Koordinatensysteme du da eigentlich so hast und wie sie zusammenhängen, anstatt einfach alle möglichen Kombinationen auszuprobieren, bis mal irgendwas rauskommt das einigermaßen richtig aussieht...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

19

04.12.2011, 13:44

Ok, ich sollte vielleicht mal was anderes machen, also was ganz anderes. Konzentration lässt doch gerade stark nach ^^
Dann fang ich mit dem Shader nochmal "von vorne" an.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

20

04.12.2011, 15:19

So, ich glaube ich bin dem ganzen ein Stück näher gekommen:


(Link)


C-/C++-Quelltext

1
2
3
4
vec3 lightDir = (light_matrix*light0.position).xyz-pos.xyz;
    L = normalize(lightDir);
    attenuationDistance = length(lightDir);
    HV = normalize((camera_position-pos.xyz+lightDir)/2);


Wie man sieht hat die Lichtquelle jetzt ihre eigene Matrix ( = camera_modelview transformiert mit Position der Lichtquelle). Da durch bewegt sich das Licht schonmal auf den richtigen Achsen. Allerdings, wie man rechts sieht, bewegt sich die Lichtquelle "schneller" als die Kugel, obwohl die Kugel jedes Frame an die Position der Lichtquelle gesetzt wird. Rechts wurde die Lichtquelle +(2; 0; 2) bewegt. Aber die Lichtquelle ist irgendwo weiter.
Hier nochmal die Matrixberechnung:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
// in Render Methode:
shader->sendUniform4x4("light_matrix", m_lights[m_objectLight[i]]->getModelview(cam_modelview).getArray());

// Methode der Lichtquelle:
mat4 bbLight::getModelview(mat4 modelview){
    modelview.translate(m_information.position.x, m_information.position.y, m_information.position.z);

    return modelview;
}


So, hab ich das Problem schonmal richtig verstanden dot?

Werbeanzeige