Environmental Bump Mapping mit GLSL Cube MapsErst mal das Programm: Die Texturen die in dieser Demo verwendet werden sind hier:
Die Museums-Ansicht stammt von http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/stereographics/stereopanoramic/, sie gehört Peter Murphy. Das Ergebnis sieht so aus: Programm BeschreibungUm eine reflektierende Kugel (mit wahlweise rauher Oberfläche) zu erzeugen, zeigen wir eine “Cube Map” auf der Oberfläche an. Welcher Punkt der sechs quadratischen Texturen an einer bestimmten Stelle der Kugel angezeigt wird, bestimmt der reflektierte Augen-Vektor. Diese Reflektionsberechnung wird durch die Oberflächen-Normale gesteuert - das ist damit auch die Stelle, wo wir einfach den Normalenvektor durch eine Bumpmap verändern können, wie im vorigen Beispiel gezeigt. Wir definieren die Taste “Z”, um die Bumpmap ein- und auszuschalten und die Tasten “N” und “B” (die auf der Tastatur praktischerweise nebeneinander liegen) um die Stärke des Effektes zu beeinflussen: elif symbol == key.Z: togglebump = not togglebump print 'Toggle Bump ', togglebump elif symbol == key.N: normalweight += 0.05 print 'Normal Weight = ', normalweight elif symbol == key.B: normalweight -= 0.05 print 'Normal Weight = ', normalweight Das Spiegelbild können wir optional durch eine ganz normale Textur “schmutzig” oder “zerkratzt” aussehen lassen - das steuern wir mit der “T”-Taste: elif symbol == key.T: print 'Texture toggle' textureon = not textureon Schliesslich wollen wir auch noch zoomen können(”+” und ”-” Taste): elif symbol == key.PLUS: dist += 0.5 print 'Distance now ', dist elif symbol == key.MINUS: dist -= 0.5 print 'Distance now ', dist Die Cube MapDie Cube Map belegt 6 hintereinander liegende Textur-Indizes, die wir in einem Schritt reservieren (nach den schon bisher belegten “texturecnt” Texturen). Wir teilen dem Shader Programm den Index der Reservierung mit: glActiveTexture(GL_TEXTURE0+texturecnt) glEnable(GL_TEXTURE_CUBE_MAP) glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap) shader.uniformi('my_cube_texture', texturecnt) und laden die Bilder: glEnable(GL_TEXTURE_CUBE_MAP) cubemap = GLuint() glGenTextures( 1, byref(cubemap)) cubemap = cubemap.value print "CubeTexture is bound to", cubemap glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) # GL_NEAREST) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) # GL_NEAREST) cubename = ['cube_map_positive_x.jpg', 'cube_map_negative_x.jpg', 'cube_map_negative_y.jpg', 'cube_map_positive_y.jpg', 'cube_map_negative_z.jpg', 'cube_map_positive_z.jpg'] for i in range (6): cubefile = cubename[i] print "Loading Cube Texture", cubefile cube = resource.texture(cubefile) # instance of class AbstractImage data = cube.get_image_data().get_data('RGBA', cube.width * 4) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, # texture.format, # 0, # format cube.width, cube.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data) glDisable(GL_TEXTURE_CUBE_MAP) Das Shader ProgrammWir deklarieren die Cube Map im Shader Programm durch: uniform samplerCube my_cube_texture; und verwenden sie (wieder unter Verwendung des Tangent Space Coordinate System - das macht die Berechnung erstaunlich einfach) wie folgt: vec3 refl = reflect(norm, eye); // in tangent space ! vec3 reflw = vec3( 1.0, -1.0, 1.0) * (TBNMatrix * refl); reflex = textureCube(my_cube_texture, reflw); if ( textureon > 0 ) gl_FragColor = mix( reflex, vec4(color, 1.0), smoothstep( 0.7, 1.5, length(color)) ); else gl_FragColor = reflex; Je heller der “color” Wert ist, desto mehr setzt sich diese Farbe gegenüber der “reflex” Farbe durch. Eine schwarze Textur ist also ein perfekter Spiegel, eine weisse Textur würde die Reflektion komplett überdecken (wie man an dem “pythonstuff”-Label im Bildschirm-Foto sieht). Und jetzt noch eines obendrauf: Beispiel 9 - Echtzeit-Video ! (auch schon Beispiel 7 - Anisotrope Reflexe gesehen ?) |