Bücher online kostenlos Kostenlos Online Lesen
Erfolgreiche Spieleentwicklung

Erfolgreiche Spieleentwicklung

Titel: Erfolgreiche Spieleentwicklung
Autoren: Alexander Rudolph
Vom Netzwerk:
Render-Buffer-Objekt erzeugen, das die Funktion des z-Buffers übernimmt (Listing 2.2).
    // Render-Buffer erzeugen und als z-Buffer verwenden:
glGenRenderbuffers(1, &PrimaryScreenRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, PrimaryScreenRenderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, g_screenwidth, g_screenheight);

// Frame-Buffer erzeugen und Render-Targets (Texturen) binden:
glGenFramebuffers(1, &PrimaryScreenFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, PrimaryScreenFrameBuffer);

// In Render-Target 1 wird später die 3D-Szene gezeichnet:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, PrimaryScreenTexture->TextureID, 0);
// In Render-Target 2 wird später das Tiefenabbild der
// 3D-Szene gezeichnet:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, CameraViewDepthTexture->TextureID, 0);

// Den Render-Buffer in seiner Funktion als z-Buffer an den
// Frame-Buffer binden:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, PrimaryScreenRenderBuffer);
    Listing 2.2: Render und Frame Buffer erzeugen, zwei Render Targets binden
    Deferred Lighting
    Deferred Lighting gehört zu den interessantesten Einsatzmöglichkeiten des Post Processings. Getreu der Maxime „Beleuchtungsberechnungen nur für diejenigen Szenenpixel durchzuführen, die auch wirklich sichtbar sind“, bleiben die Lichteinflüsse anders als beim klassischen Forward Rendering im Rahmen der Geometrieverarbeitung unberücksichtigt. Der für die Beleuchtung erforderliche Rechenaufwand pro Lichtquelle ist lediglich proportional zur Bildschirmauflösung, nicht jedoch abhängig von der Komplexität der Szenengeometrie. Als Folge davon lassen sich deutlich mehr Lichtquellen berücksichtigen als beim Forward Rendering. Selbstverständlich können die für das Deferred Lighting benötigten Szeneninformationen auch für weitere Post-Processing-Effekte verwendet werden (z. B. für Screen-Space-Ambient-Occlusion-Berechnungen).
    Bevor die Beleuchtungsberechnungen durchgeführt werden können, müssen die hierfür benötigten geometrischen Informationen zunächst in eine Reihe von Texturen gerendert werden, die allesamt an einen als G-Buffer (Geometry-Buffer) bezeichneten Framebuffer gebunden sind. Verschaffen wir uns eine Übersicht über die benötigten Render Targets:
Textur 1: Kameraraum-Positionen und Tiefenwerte der sichtbaren Szenenpixel
Textur 2: Kameraraum-Normalen der sichtbaren Szenenpixel
Textur 3: die texturierten, jedoch nicht beleuchteten sichtbaren Szenenpixel
Textur 4: Reflektionsvermögen (Farbe und Intensität) der sichtbaren Szenenpixel
Textur 5: selbstleuchtende Szenenpixel (z. B. mittels Light Map beleuchtet)
    Während man für die Texturen 2, 3, 4 und 5 mit 8 Bit pro Farbkanal auskommt (GL_RGBA8), werden zum Speichern der Kameraraum-Positionen und der Tiefenwerte 32 Bit pro Farbkanal benötigt (GL_RGBA32F). Der prinzipielle Aufbau eines Deferred Lighting Fragment Shaders ist in Listing 2.3 dargestellt. Bevor wir uns mit den zugrunde liegenden Beleuchtungsmodellen befassen, konzentrieren wir uns zunächst auf die notwendigen Fallunterscheidungen, die den eigentlichen Beleuchtungsberechnungen vorausgehen:
Überprüfen, ob Lichtquellen eingeschaltet sind (andernfalls das unbeleuchtete Szenenpixel rendern)
Überprüfen, ob einem Szenenpixel eine Normale zugeordnet ist (andernfalls das unbeleuchtete Szenenpixel rendern)
Alle Lichtquellen durchgehen und das betreffende Szenenpixel entsprechend des Lichtquellentyps (direktionales Licht oder Punktlicht) beleuchten
    in vec4 gs_TexCoord[8];
out vec4 gs_FragColor;

uniform sampler2D ScreenTexture;
uniform sampler2D EmissiveTexture;
uniform sampler2D NormalTexture;
uniform sampler2D SpecularTexture;
uniform sampler2D CameraSpacePositionTexture;

uniform vec3 ViewDirection;

#define NumLightsMax 20
uniform vec4 LightCameraSpacePosAndRange[NumLightsMax];
uniform vec4 LightColor[NumLightsMax];
uniform vec3 NegLightDir[NumLightsMax];

uniform int NumLightsUsed;

void main()
{
// keine Lichtquelle eingeschaltet:
if(NumLightsUsed == 0)
gs_FragColor = texture2D(ScreenTexture, gs_TexCoord
[0].st) + texture2D(EmissiveTexture, gs_TexCoord[0].st);

// mindestens eine aktive Lichtquelle
else
{
vec3 Normal = texture2D(NormalTexture, gs_TexCoord[0].st).rgb;

// Pixel kann nicht beleuchtet werden, da diesem
// keine Normale für die Durchführung der
// Berechnungen zugeordnet ist:
if(Normal.r < 0.01 &&
Vom Netzwerk:

Weitere Kostenlose Bücher