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

31

30.03.2011, 14:44

So hab mal das ganze zum Fragment Shader hin erweitert:


(Link)


Sieht das so richtig aus? Mir kommts manchmal etwas komisch vor...

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

32

30.03.2011, 14:52

Ohne mehr Info is das schwer zu sagen ob das richtig aussieht. Interessant wär wie die Normalen und der Shader aussehen und wo sich das Licht befindet...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

33

30.03.2011, 14:54

Blickpunkt ist 0 0 0, Standpunkt 2 1 2, Licht kommt aus 0 0 -1

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Materialeigenschaften
            m_shaderProgram->sendUniform("material_ambient", 0, 0, 0, 0);
            m_shaderProgram->sendUniform("material_diffuse", 0.5, 0.5, 0.5, 0);
            m_shaderProgram->sendUniform("material_specular", 1, 1, 1, 0);
            m_shaderProgram->sendUniform("material_shininess", 100);

            // Lichtquelle
            m_shaderProgram->sendUniform("light0.ambient", 1, 1, 1, 0);
            m_shaderProgram->sendUniform("light0.diffuse", 1, 1, 1, 0);
            m_shaderProgram->sendUniform("light0.specular", 1, 1, 1, 0);
            m_shaderProgram->sendUniform("light0.constant_attenuation", 0.3f);
            m_shaderProgram->sendUniform("light0.linear_attenuation", 0.1f);
            m_shaderProgram->sendUniform("light0.quadratic_attenuation", 0.01f);
            m_shaderProgram->sendUniform("light0.position", 0, 0, -1, 0);


Der Rest ist so wie vorher.

Shader:

Quellcode

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
#version 130

precision highp float;

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
uniform mat3 normal_matrix; // Normalisierte Modelview Matrix

// Materialeigenschaften
uniform vec4 material_ambient; // Umgebungslicht
uniform vec4 material_diffuse; // Beleuchtung
uniform vec4 material_specular; // Highlight
uniform float material_shininess;

struct light{
    vec4 position;
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    
    float constant_attenuation;
    float linear_attenuation;
    float quadratic_attenuation;
};

uniform light light0; // Lichtquelle

in vec4 a_Vertex;
in vec2 a_TexCoord0;
in vec3 a_Normal;

out vec2 texCoord0;
out vec3 normal;
out vec3 lightDir;
out vec3 halfVector;

out vec4 vertDiffuse;
out vec4 vertAmbient;
out float dist;

void main(void){            
    normal = normalize(normal_matrix*a_Normal);
    vec3 lightPos = normalize(light0.position).xyz;
    vec4 pos = modelview_matrix*a_Vertex;
    lightDir = lightPos-pos.xyz;
    vec3 E = -(pos.xyz);
    
    dist = length(lightDir);
    lightDir = normalize(lightDir);         
    halfVector = normalize(lightPos+E);
    
    vertDiffuse = material_diffuse*light0.diffuse;
    vertAmbient = material_ambient*light0.ambient;
    
    texCoord0 = a_TexCoord0;
    gl_Position = projection_matrix*pos;    
}


Quellcode

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
#version 130

precision highp float;

uniform sampler2D texture0; // Textur

// Materialeigenschaften
uniform vec4 material_ambient; // Umgebungslicht
uniform vec4 material_diffuse; // Beleuchtung
uniform vec4 material_specular; // Highlight
uniform float material_shininess;

struct light{
    vec4 position;
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    
    float constant_attenuation;
    float linear_attenuation;
    float quadratic_attenuation;
};

uniform light light0;

in vec2 texCoord0;
in vec3 normal;
in vec3 lightDir;
in vec3 halfVector;

in vec4 vertDiffuse;
in vec4 vertAmbient;
in float dist;

out vec4 outColor;

void main(void){
    vec3 N = normalize(normal);
    float NdotL = max(dot(N, normalize(lightDir)), 0.0);    
    vec4 color = vec4(0.0, 0.0, 0.0, 0.0); // Hinten anfangen
    
    if(NdotL > 0.0){            
        color += vertDiffuse*NdotL;
        vec3 HV = normalize(halfVector);
        float NdotHV = max(dot(N, HV), 0.0);
        color += material_specular*light0.specular*NdotHV;  
    }
    
    float attenuation = 1.0/(light0.constant_attenuation+light0.linear_attenuation*dist+light0.quadratic_attenuation*dist*dist);        
    outColor = ((color*attenuation)+vertAmbient)*texture(texture0, texCoord0.st);       
}

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

34

30.03.2011, 15:02

Warum normalisierst du die Lichtposition? Liegt deine lightPos im Viewspace? Was ist die "Normalisierte Modelview Matrix"!?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (30.03.2011, 15:07)


DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

35

30.03.2011, 15:13

Im Buch steht das man die Matrizen und Vectoren für die Lichtkalkulation in "eye-space" bringen soll, bei dem Beispiel wird dies auch gemacht. Ich spiel später nochmal ein wenig damit rum.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

36

30.03.2011, 15:16

Gut, dein Code da oben ist aber auch unter der Annahme dass light0.position im eye-space (== Viewspace) liegt nicht korrekt, eben z.B. wegen dieser Normalisierung. Damit berechnest du im Prinzip einen Richtungsvektor der vom Ursprung zur Lichtquelle zeigt und bildest dann die Differenz zwischen dieser Richtung und der Vertexposition. Was hat das deiner Meinung nach für einen Sinn!?

Und das mit der "Normalisierten Modelview Matrix" wär auch noch interessant wie du die genau berechnest, bzw. was du da genau drunter verstehst...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

37

30.03.2011, 17:18

Das mit dem normalisieren war ein Fehler (habs wohl gedankenlos hingeklatscht).

Zitat

Und das mit der "Normalisierten Modelview Matrix" wär auch noch interessant wie du die genau berechnest, bzw. was du da genau drunter verstehst...


Ist genau das gleiche wie beim Shader davor und ist einfach die aktuelle Modelview Matrix nur normalisiert.

So ich glaub das ist immer noch nicht so wie es aussehen soll:


(Link)


Vertex Shader:

a_Vertex ist natürlich ein vec3, hatte mich da vertan.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void main(void){            
    normal = normalize(normal_matrix*a_Normal);
    vec4 pos = modelview_matrix*vec4(a_Vertex, 1.0);
    
    vec3 lightPos = light0.position.xyz;
    lightDir = lightPos-pos.xyz;    
    dist = length(lightDir);
    lightDir = normalize(lightDir);         
    
    vec3 E = -(pos.xyz);
    halfVector = normalize(lightPos+E);
    
    vertDiffuse = material_diffuse*light0.diffuse;
    vertAmbient = material_ambient*light0.ambient;  
    texCoord0 = a_TexCoord0;
    gl_Position = projection_matrix*pos;    
}


Fragment Shader:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void main(void){
    vec3 N = normalize(normal);
    float NdotL = max(dot(N, normalize(lightDir)), 0.0);    
    vec4 color = vec4(0.0); // Hinten anfangen
    
    if(NdotL > 0.0){            
        color += vertDiffuse*NdotL;
        
        vec3 HV = normalize(halfVector);
        float NdotHV = max(dot(N, HV), 0.0);
        color += material_specular*light0.specular*pow(NdotHV, material_shininess); 
    }
    
    float attenuation = 1.0/(light0.constant_attenuation+light0.linear_attenuation*dist+light0.quadratic_attenuation*dist*dist);        
    outColor = ((color*attenuation)+vertAmbient)*texture(texture0, texCoord0.st);       
}

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

38

30.03.2011, 17:31

Das schaut ja so schlecht gar nicht aus. Trotzdem interessiert mich immer noch was für dich eine normalisierte Matrix ist, bzw. wie du die berechnest...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

39

30.03.2011, 17:43

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
static vector<float> normalizeMatrix(const float *matrix){
            vector<float> M(9);
            M[0] = matrix[0];
            M[1] = matrix[1];
            M[2] = matrix[2];
            M[3] = matrix[4];
            M[4] = matrix[5];
            M[5] = matrix[6];
            M[6] = matrix[8];
            M[7] = matrix[9];
            M[8] = matrix[10];

            float determinate = M[0]*M[4]*M[8]+M[1]*M[5]*M[6]+M[2]*M[3]*M[7];
            determinate -= M[2]*M[4]*M[6]+M[0]*M[5]*M[7]+M[1]*M[3]*M[8];
            float oneOverDet = 1/determinate;

            vector<float> N(9);
            N[0] = (M[4]*M[8]-M[5]*M[7])*oneOverDet;
            N[3] = (M[2]*M[7]-M[1]*M[8])*oneOverDet;
            N[6] = (M[1]*M[5]-M[2]*M[4])*oneOverDet;
            N[1] = (M[5]*M[6]-M[3]*M[8])*oneOverDet;
            N[4] = (M[0]*M[8]-M[2]*M[6])*oneOverDet;
            N[7] = (M[2]*M[3]-M[0]*M[5])*oneOverDet;
            N[2] = (M[3]*M[7]-M[4]*M[6])*oneOverDet;
            N[5] = (M[1]*M[6]-M[8]*M[7])*oneOverDet;
            N[8] = (M[0]*M[4]-M[1]*M[3])*oneOverDet;

            return N;
        }


Die Kanten (schwarz) kommen mir aber ziemlich hart vor...

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

40

30.03.2011, 17:48

Der Code schaut mir aus als würde er die Inverse der Matrix bilden!?

Für den allgemeinen Fall musst du den oberen 3x3 Teil der Inversen Transponierten der ModelViewMatrix nehmen. Für den gängigen Fall dass deine ModelViewMatrix orthogonal ist kannst du einfach direkt den oberen 3x3 Teil der ModelViewMatrix nehmen. Die Inverse allein ist in jedem Fall falsch.

EDIT: Ok ich vermute mal der Code transponiert auch gleich, damit stimmt das dann. Du berechnest dort nur eben die inverse Transponierte und nicht irgendeine "normalisierte" Matrix.

Was die schwarzen Kanten angeht: Render mal deine Normalen (als kurze Linien die auf den Vertices sitzen) und den Wireframe deines Modells. Das hilft sehr bei der Suche von Beleuchtungsbugs...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (30.03.2011, 17:58)


Werbeanzeige