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

1

01.12.2011, 22:31

Phong Shading #2

Hallo,

ich hab mich in letzter Zeit mal um das neustrukturieren in meine "Engine" gekümmert. Sie beinhaltet also alles was ich bisher so erstellt habe.
Nun möchte ich wieder Phong Shading einfügen, das hab ich aber jetzt schon länger nicht mehr gemacht und verstehe folgendes Ergebnis nicht:


(Link)


Die Position der Lichtquelle verändert sich nicht, trotzdem dreht der "Schatten" mit (das Object wird um die Y-Achse gedreht)?
Hier mal die Shader:

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
// VERTEX

#version 150

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

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

uniform vec4 material_ambient;
uniform vec4 material_diffuse;
uniform vec4 material_specular;
uniform float material_shininess;

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;

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);
    HV = normalize((lightPos+pos.xyz)/2);
    ambient = material_ambient*light0.ambient;
    diffuse = material_diffuse*light0.diffuse;
    
    texCoord = a_TexCoord;
    gl_Position = projection_matrix*pos;
}


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
// FRAGMENT

#version 150

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

uniform sampler2D texture0;

uniform vec4 material_ambient;
uniform vec4 material_diffuse;
uniform vec4 material_specular;
uniform float material_shininess;

uniform light light0;

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

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);

        color += diffuse*NdotL;
        //color += material_specular*light0.specular*pow(NdotHV, material_shininess);
    }
    
    outColor = color*texture(texture0, texCoord.st);
}


Rendermethode:

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
void BurningByte::render(unsigned int begin, unsigned int end){
    if(begin < 0 || end > m_objects.size() || m_objects.size() == 0){
        return;
    }

        // -----------------------------------
        Material mat = Material();
        mat.setAmbient(1);
        mat.setDiffuse(1);
        mat.setSpecular(1);
        mat.setShininess(100);
        Light lig = Light();
        lig.setPosition(vec3(0, 0, 5));
        lig.setAmbient(0.1);
        lig.setDiffuse(0.8);
        lig.setSpecular(1);
        //lig.setConstantAttenuation(0.0001);
        //lig.setLinearAttenuation(0.0002);
        //lig.setQuadraticAttenuation(0.0001);
        // -----------------------------------

    mat4 modelview, projection, cam_modelview;
        
    glClearColor(m_clearColor.r, m_clearColor.g, m_clearColor.b, m_clearColor.a);
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, m_width, m_height);

    projection = m_cameras[m_activeCamera]->getProjection();
    cam_modelview = m_cameras[m_activeCamera]->getModelview();
    m_cameras[m_activeCamera]->getPlanes(); // frustum culling
    
    glEnableVertexAttribArray(0); // Vertices
    glEnableVertexAttribArray(1); // TexCoords
    glEnableVertexAttribArray(2); // Normals
        
    // Objekte rendern
    for(unsigned int i = begin; i < end; i++){
        if(m_renderObject[i]){
            vec3 p = m_objects[i]->getPosition();
            vec3 *box = m_objects[i]->getBoundingBox();
            float r = m_objects[i]->getRadius();
            int cull = m_culling[i];    

            if(cull == BURNINGBYTE_NO_CULLING || (cull == BURNINGBYTE_BOX_CULLING && m_cameras[m_activeCamera]->testBox(p, box[0], box[1])) || (cull == BURNINGBYTE_SPHERE_CULLING && m_cameras[m_activeCamera]->testSphere(p, r))){            
                bbShader *shader = m_objects[i]->getShader();
                shader->bindShader();
                            
                modelview = m_objects[i]->getModelview(cam_modelview);

                shader->sendUniform("texture0", 0);
                shader->sendUniform4x4("modelview_matrix", modelview.getArray());
                shader->sendUniform4x4("projection_matrix", projection.getArray());

                    // -----------------------------------
                    shader->sendUniform("material_ambient", mat.ambient.r, mat.ambient.g, mat.ambient.b, mat.ambient.a);
                    shader->sendUniform("material_diffuse", mat.diffuse.r, mat.diffuse.g, mat.diffuse.b, mat.diffuse.a);
                    shader->sendUniform("material_specular", mat.specular.r, mat.specular.g, mat.specular.b, mat.specular.a);
                    shader->sendUniform("material_shininess", mat.shininess);
                
                    shader->sendUniform("light0.ambient", lig.ambient.r, lig.ambient.g, lig.ambient.b, lig.ambient.a);
                    shader->sendUniform("light0.diffuse", lig.diffuse.r, lig.diffuse.g, lig.diffuse.b, lig.diffuse.a);
                    shader->sendUniform("light0.specular", lig.specular.r, lig.specular.g, lig.specular.b, lig.specular.a);
                    shader->sendUniform("light0.position", lig.position.x, lig.position.y, lig.position.z, 0);
                    //shader->sendUniform("ligh0.constant_attenuation", lig.constant_attenuation);
                    //shader->sendUniform("ligh0.linear_attenuation", lig.linear_attenuation);
                    //shader->sendUniform("ligh0.quadratic_attenuation", lig.quadratic_attenuation);
    
                    mat4 normalMatrix = modelview;
                    normalMatrix.normalize();
                    shader->sendUniform3x3("normal_matrix", normalMatrix.getArray());
                    // -----------------------------------

                glBindTexture(GL_TEXTURE_2D, m_objects[i]->getTextureID());
            
                glBindBuffer(GL_ARRAY_BUFFER, m_objects[i]->getVertexBuffer()); 
                glVertexAttribPointer(GLint(0), 3, GL_FLOAT, GL_FALSE, 0, 0);
                glBindBuffer(GL_ARRAY_BUFFER, m_objects[i]->getTexCoordBuffer());
                glVertexAttribPointer(GLint(1), 2, GL_FLOAT, GL_FALSE, 0, 0);
                glBindBuffer(GL_ARRAY_BUFFER, m_objects[i]->getNormalBuffer()); 
                glVertexAttribPointer(GLint(2), 3, GL_FLOAT, GL_FALSE, 0, 0);

                glDrawArrays(GL_TRIANGLES, 0, m_objects[i]->getVerticesNumber());
            }
        }
    }
        
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
    
    glutSwapBuffers();
}


Ich hoffe das war jetzt nicht schon wieder zu viel ^^
Später werden die Lichtquellen natürlich dynamisch hinzufügbar sein und nicht hard coded in der render Funktion stehen.
Das ganze soll übrigens Directional sein.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

2

02.12.2011, 17:17

Könnte es wohl daran liegen das Blender die Normalen falsch ins PLY File schreibt?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

02.12.2011, 17:29

Wohl eher nicht. Sonst wäre die Beleuchtung von vornherein Müll.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

02.12.2011, 17:34

Kann es sein, dass du die Normalen mit der Kameramatrix transformierst?
Das ist natürlich Quatsch, es sei denn du tust das gleiche auch mit der Lichtquelle.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

5

02.12.2011, 18:51

Jup, das wars... Danke.

Falls jemand kurz Lust hat, stimmt das soweit? Ich bin mir bei dem halfway vector nie sicher ^^

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
// Vertex Shader:

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(lightPos);
    ambient = material_ambient*light0.ambient;
    diffuse = material_diffuse*light0.diffuse;
    
    texCoord = a_TexCoord;
    gl_Position = projection_matrix*pos;
}

// Fragment Shader:

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);

        color += diffuse*NdotL+material_specular*light0.specular*pow(NdotHV, material_shininess);
    }
    
    outColor = color*texture(texture0, texCoord.st);
}

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

02.12.2011, 19:10

Nein, ich glaube da ist was falsch. Du benutzt in Deiner Rechnung L gar nicht, sondern normalisierst nur den Vektor zwischen dem Vertex und der Lichtquelle. Es müsste aber der Vektor aus (normalize(camera-pos) + normlize(light-pos))*0.5) sein, oder?

C-/C++-Quelltext

1
2
3
    vec3 lightPos = light0.position.xyz;
    L = normalize(lightPos-pos.xyz);
    HV = normalize(lightPos);
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »BlueCobold« (02.12.2011, 19:17)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

02.12.2011, 19:35

Das ist schon richtig so, er rechnet die Beleutung im Viewspace, wo die Kamera im Ursprung liegt ;)

EDIT: Sry, nicht genau genug gelesen...

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »dot« (02.12.2011, 19:53)


DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

8

02.12.2011, 19:37

Hmm, ja, ich glaube das wars:


(Link)


C-/C++-Quelltext

1
HV = (normalize(camera_position-pos.xyz)+L)*0.5;

(links neu, rechts alt)

Nochmal zu Problem 1: Es war noch nicht die Lösung des Schatten Fehlers David. Wenn ich die Lichtquelle drehe tritt der gleiche Fehler immer noch auf. So sende ich die normal Matrix:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
// so wie ich es vorher hatte:

mat4 normalMatrix = modelview;
normalMatrix.normalize();
shader->sendUniform3x3("normal_matrix", normalMatrix.getArray());

// so wie es jetzt ist (ebenfalls falsch):

mat4 normalMatrix = mat4();
normalMatrix.setIdentity();
normalMatrix.normalize();
shader->sendUniform3x3("normal_matrix", normalMatrix.getArray());


Im oberen Bild sende ich übriegens wieder die "alte" normal Matrix, sonst wirkt das Ergebnis komplett Falsch.
Wenn ich die Normalen in Blender übrigens drehe wird alles was jetzt Schatten ist hell und andersrum, dreht sich auch mit.
Weiß einer wie ich die Normalen in Blender sehen kann?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

02.12.2011, 19:52

Man sollte vielleicht auch noch drauf hinweisen, dass das kein richtiges Phong Shading ist, sondern eigentlich ein Blinn-Phong. Richtiges Phong-Shading benutzt nicht den Half-Vector, sondern rechnet den richtigen Reflektionsvektor aus.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

10

02.12.2011, 20:22

Zitat

Man sollte vielleicht auch noch drauf hinweisen, dass das kein richtiges Phong Shading ist, sondern eigentlich ein Blinn-Phong. Richtiges Phong-Shading benutzt nicht den Half-Vector, sondern rechnet den richtigen Reflektionsvektor aus.


Ja ich weiß ;)

Werbeanzeige