Shader für 3d - Licht, Lichtreflexion und Bumpmapping (Letzteres geht noch nicht)

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Shader für 3d - Licht, Lichtreflexion und Bumpmapping (Letzteres geht noch nicht)

    Hallöle,

    Anschließend an meinen letzten Thread präsentiere ich euch meine Arbeit der letzten Tage. Einen Shader mit dem es möglich ist mehr als nur 8 Lichtquellen zu verwenden.
    Außerdem wird das standart Vertexlighting im 3d Modus immer ignoriert wenn man einen Shader auf seine Modelle anwenden will, darum ist dieser Shader auch sinnvoll.

    Außerdem wollte ich unbedingt Bumpmapping können darum Hab ich die letzten Tage viel im Netz recharchiert und habe folgendes Tutorial gefunden:
    fabiensanglard.net/bumpMapping/index.php
    Zusammen mit dem Wissen das ich von Xor's Tutorials habe (kann ich jedem nur empfehlen) habe ich in viel Arbeit und mit leider zu wenigem mathematischem Verständnis diesen Shader "zusammen gebastelt". Teile davon hab ich nur ausm Netz kopert ohne sie ganz zu verstehen und da liegt glaub ich auch der Fehler.

    Wie gesagt, das Bumpmapping geht nicht. Das Problem ist glaube ich das ich den Tangentvektor von den Positionsvektor und den Normal Vektor brauche und den nicht korrekt berechne.
    Denn wenn ich das ric htig versteh (und davon geh ich nicht aus^^) dann muss man mehere Richtungsverktoren berechnen aber nicht für jedes Vertex sondern für jedes Pixel.

    Wer kann mir weiterhelfen?

    Der Shader darf frei verwendet werden und es ist auch kein Creditseintrag nötig. Ihr müsst nur ein paar Arrays erstellen und an den Shader übergeben. Wichtig ist, dass ihr die Richtungen für direktionales Licht mit degtorad ind Radians umwandelt. Wenn ihr keine Liochtreflexion braucht, dann lasst einfach das zweite gl_FragColor im Fragmentshader weg.

    Vertex Shader:

    GML-Quellcode

    1. attribute vec3 in_Position; // (x,y,z)
    2. attribute vec3 in_Normal; // (x,y,z)
    3. attribute vec4 in_Colour; // (r,g,b,a)
    4. attribute vec2 in_TextureCoord; // (u,v)
    5. varying vec2 v_vTexcoord;
    6. varying vec3 v_vNormal;
    7. varying vec3 v_vPosition;
    8. varying vec4 v_vColour;
    9. varying vec3 v_vLightVec;
    10. varying vec3 ldir;
    11. varying vec3 halfVec;
    12. varying vec3 eyeVec;
    13. uniform vec3 CamPos;
    14. uniform float LIGHTS;
    15. uniform float Lights_Kind[16];
    16. uniform float Lights_Direction[16];
    17. uniform float Lights_DirectionZ[16];
    18. uniform float Lights_Color_R[16];
    19. uniform float Lights_Color_G[16];
    20. uniform float Lights_Color_B[16];
    21. uniform float Lights_X[16];
    22. uniform float Lights_Y[16];
    23. uniform float Lights_Z[16];
    24. uniform float Lights_Range[16];
    25. uniform vec2 resolution;
    26. //diese Funktion is für direktionales Licht
    27. vec3 DoDirLightB(vec3 ws_normal, float dir, float dirz, float R, float G, float B)
    28. {
    29. //die Richtung wird mit zwei Radien angegeben
    30. //und da unten in einen Richtungsvektor umgerechnet
    31. float vx = cos(dir) * cos(dirz);
    32. float vy = sin(dir) * cos(dirz);
    33. float vz = sin(dirz);
    34. ldir = vec3(vx, vy, vz);
    35. float dotresult = dot(ws_normal, normalize(ldir)) * 0.5 + 0.5;
    36. vec3 diffusecolor = vec3(R, G, B);
    37. //hier wird die Farbe des Vertex an void main übergeben
    38. return dotresult * diffusecolor;
    39. }
    40. //diese Funktion ist für Pointlights (nicht getestet)
    41. vec3 DoPointLightB(vec3 pos, float posx,float posy,float posz, float range, float R, float G, float B)
    42. {
    43. ldir = vec3(posx, posy, posz) - pos;
    44. float attenuation = max( 1.0 - length(normalize(ldir))/range, 0.0);
    45. float lighting = (dot( normalize(v_vNormal), normalize(ldir)) * 0.5 + 0.5) * attenuation;
    46. vec3 diffusecol = vec3(R, G, B);
    47. return lighting * diffusecol;
    48. }
    49. //das ist die hauptfunktion für das Licht
    50. vec4 DoLightingB(vec4 vertexcolor, vec3 objectspacepos, vec3 objectspacenormal)
    51. {
    52. vec4 objectspacenormal4 = vec4(objectspacenormal, 1.0);
    53. vec3 ws_normal = normalize(objectspacenormal);
    54. vec3 accumcol = vec3(0.3, 0.3, 0.3);
    55. //hier werden alle Lichtinformation aus den Arrays gelesen
    56. //und an die Funktionen oben übergeben
    57. for(int i = 1; i <= int(LIGHTS); i++) {
    58. accumcol += abs(min(Lights_Kind[i], 0.0)) * DoDirLightB(ws_normal, Lights_Direction[i], Lights_DirectionZ[i], Lights_Color_R[i], Lights_Color_G[i], Lights_Color_B[i]);
    59. accumcol += max(Lights_Kind[i], 0.0) * DoPointLightB(objectspacepos, Lights_X[i], Lights_Y[i], Lights_Z[i], Lights_Range[i], Lights_Color_R[i], Lights_Color_G[i], Lights_Color_B[i]);
    60. }
    61. // das sccumcolor mit 0,5 multipliziert wird sorgt nur
    62. //dafür das das Endergebnis nicht zu hell ist. Dass ist
    63. //eigentlich schon ein Beweis dafür, dass meine Arbeit noch nicht ganz stimmt
    64. vec4 resultcolor = vec4(accumcol * 0.5, 1.0);
    65. return resultcolor;
    66. }
    67. void main()
    68. {
    69. //alles Ubliche
    70. vec4 object_space_pos = vec4( in_Position, 1.0);
    71. gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
    72. v_vTexcoord = in_TextureCoord;
    73. v_vNormal = in_Normal;
    74. v_vPosition = in_Position;
    75. v_vColour = in_Colour;
    76. //hier wird die Hauptfunktion für das Licht ausgeführt
    77. v_vColour = DoLightingB(v_vColour, v_vPosition, v_vNormal);
    78. // folgender Codeblock hab ich aus dem Internet und errechnet NormalMatrix
    79. // in GLSL gibt es die 3x3 Matrix gl_modelmatrix
    80. // das ist die modelviewmatrix nur umgestellt und invertiert
    81. // allerdings erkennt GMS diese nicht an obwohl sie rot geschrieben ist
    82. // Get upper left 3x3 matrix of ModelView:
    83. // | a b c |
    84. // | d e f |
    85. // | g h i |
    86. mat3 M = mat3(gm_Matrices[MATRIX_WORLD_VIEW]);
    87. // Get determinant of M = a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g
    88. float dtm;
    89. dtm = M[0][0]*M[1][1]*M[2][2]; // a*e*i
    90. dtm -= M[0][0]*M[2][1]*M[1][2]; // a*f*h
    91. dtm -= M[1][0]*M[0][1]*M[2][2]; // b*d*i
    92. dtm += M[1][0]*M[2][1]*M[0][2]; // b*f*g
    93. dtm += M[2][0]*M[0][1]*M[1][2]; // c*d*h
    94. dtm -= M[2][0]*M[1][1]*M[0][2]; // c*e*g
    95. // Transpose I:
    96. mat3 NormalMatrix;
    97. NormalMatrix[0][0] = (M[1][1] * M[2][2] - M[1][2] * M[2][1]);
    98. NormalMatrix[1][0] = (M[0][2] * M[2][1] - M[0][1] * M[2][2]);
    99. NormalMatrix[2][0] = (M[0][1] * M[1][2] - M[0][2] * M[1][1]);
    100. NormalMatrix[0][1] = (M[1][2] * M[2][0] - M[1][0] * M[2][2]);
    101. NormalMatrix[1][1] = (M[0][0] * M[2][2] - M[0][2] * M[2][0]);
    102. NormalMatrix[2][1] = (M[0][2] * M[1][0] - M[0][0] * M[1][2]);
    103. NormalMatrix[0][2] = (M[1][0] * M[2][1] - M[1][1] * M[2][0]);
    104. NormalMatrix[1][2] = (M[0][1] * M[2][0] - M[0][0] * M[2][1]);
    105. NormalMatrix[2][2] = (M[0][0] * M[1][1] - M[0][1] * M[1][0]);
    106. NormalMatrix /= dtm;
    107. //nun haben wir unsere normale Matrix
    108. //jetzt berechnen wir den Tangentvektor
    109. vec3 normal = vec3(1.0,1.0,0.0);
    110. vec3 tangent;
    111. vec3 t1 = cross( normal, in_Position);
    112. vec3 t2 = cross( normal, in_Normal);
    113. if (length(t1) > length(t2)) {
    114. tangent = t1;
    115. }
    116. else {
    117. tangent = t2;
    118. }
    119. // nun normalisieren wir unsere Vektoren im Verhältnis
    120. // zur NormalMatrix und errechnen den Kreuzpunkt
    121. // und nun geht meine Unwissenheit los :)
    122. // ich denke ab hier unten hab ich die meisten Fehler drin
    123. vec3 N = normalize(NormalMatrix * in_Normal);
    124. vec3 T = normalize(NormalMatrix * tangent);
    125. vec3 B = normalize(cross(N, T));
    126. vec3 v;
    127. v.x = dot(normalize(ldir), T);
    128. v.y = dot(normalize(ldir), B);
    129. v.z = dot(normalize(ldir), N);
    130. v_vLightVec = normalize(v); //Lichtvektor
    131. vec3 vertexPosition = normalize(NormalMatrix * in_Position);
    132. v.x = dot(vertexPosition, T);
    133. v.y = dot(vertexPosition, B);
    134. v.z = dot(vertexPosition, N);
    135. eyeVec = normalize(v);
    136. vertexPosition = normalize(vertexPosition);
    137. halfVec = normalize(vertexPosition + normalize(ldir));
    138. v.x = dot(halfVec, T);
    139. v.y = dot(halfVec, B);
    140. v.z = dot(halfVec, N);
    141. halfVec = v;
    142. }
    Alles anzeigen



    Fragment Shader:

    GML-Quellcode

    1. varying vec2 v_vTexcoord;
    2. varying vec3 v_vNormal;
    3. varying vec3 v_vPosition;
    4. varying vec4 v_vColour;
    5. varying vec3 v_vLightVec;
    6. varying vec3 ldir;
    7. varying vec3 halfVec;
    8. varying vec3 eyeVec;
    9. uniform vec3 CamPos;
    10. uniform float specStrength;
    11. uniform sampler2D bumpmap;
    12. void main()
    13. {
    14. vec3 normal = texture2D(bumpmap, v_vTexcoord).rgb; //die Bumpmap
    15. normal = normalize(normal);
    16. float lamberFactor = max(dot(v_vLightVec, normal), 0.1) * 4.0; //der Lamberfaktor
    17. vec4 finalFactor = vec4(vec3(lamberFactor), 1.0);
    18. // hier wird die Lichtreflexion berechnet
    19. vec3 EyeDirection_cameraspace = CamPos - v_vPosition;// Richtungsvektor der Kamera
    20. vec3 E = normalize(EyeDirection_cameraspace);
    21. vec3 R = reflect(-normalize(ldir), normalize(v_vPosition)); // die Lichtreflexion
    22. float cosAlpha = clamp( dot( E, R ), 0.0, 1.0 );
    23. vec3 specCol = vec3(0.5, 0.5, 1.0);
    24. vec4 Specular = cosAlpha * vec4( specCol, 1.0);
    25. float shininess = pow(max(dot(halfVec, normal), 0.0), 2.0);
    26. gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord) * finalFactor;
    27. gl_FragColor += Specular * shininess;
    28. }
    Alles anzeigen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Morpheus ()