Shading


Processing 2.0

In Processing 2.0 basiert die Rendering Engine auf GLSL Shadern. D.h. bei jeder Darstellung auf dem Bildschirm wird von Processing automatisch ein geeigneter Shader gewählt. Der Vorteil dabei liegt darin, dass die Programme zu einem größeren Teil von der GPU ausgeführt werden. Außerdem entfällt der Datentransfer vom RAM in den Grafikspeicher. All das führt zu einer mehr oder weniger starken Beschleunigung der Programme.

Es kommen immer 2 Shader zum Einsatz:

  • Vertex Shader
    • Manipuliert die Geometrie der dargestellten Objekte.
    • Z.B. zum Verändern der Perspektive
    • Er kann keine Objekte hinzufügen, oder entfernen!
  • Fragment Shader
    • Wandelt die 2D Objekte in ein Pixel-Array um –> Rasterization
    • Berechnet Blending und Licht
    • Das Resultat ist die endgültige Pixelfarbe

     

Wie schon gesagt, wendet Processing einen geeigneten Shader für die jeweilige Aufgabe aus. Diese Aufgaben können folgendermaßen eingeteilt werden:

  1. gefärbte Polygone ohne Licht und Textur
  2. gefärbte Polygone mit Licht, aber ohneTextur
  3. gefärbte Polygone ohne Licht, aber mit Textur
  4. gefärbte Polygone mit Licht und Textur
  5. Linien
  6. Punkte

Jeder dieser verschiedenen Shader erwartet bestimmte In- und Outputs.

Beinhaltet ein draw() Durchlauf verschiedene dieser Elemente, kommen die entsprechenden Shader (immer bestehend aus einem Vertex– und einem FragmentShader) zum Einsatz.

Will man nun einen eigenen Shader anwenden, kann man entweder beide default Shader, oder nur den Fragment-Shader ersetzen. Dadurch werden die default Shader aber nur deaktiviert und können jederzeit wieder aktiviert werden.

Beispiel: Default Shader für 1.

shader

In diesem Beispiel schauen wir uns an, wie man die default Shader von Processing durch eigene ersetzen kann und wie diese Shader aufgebaut sind.

Zuerst einmal brauchen wir einen Vertex-Shader. Dieser gleicht dem default Shader in Processing.


uniform mat4 projmodelviewMatrix;

attribute vec4 inVertex;
attribute vec4 inColor;

varying vec4 vertColor;

void main() {
gl_Position = projmodelviewMatrix * inVertex;

vertColor = inColor;
}

Was macht nun dieser Vertex Shader? Er bekommt von Processing die projmodelviewMatrix übergeben und für jeden Punkt die Variablen inVertex und inColor. In void main()  wird dann das eigentliche C-Programm platziert. In unserem Fall werden nur inVertex mit der projmodelviewMatrix verrechnet und in gl_Position gespeichert, und der Wert inColor wird in vertColor gespeichert.

Die Variable vertColor wird dann an den Fragment Shader weitergereicht und in dessen Programmteil verarbeitet. Die Definitionen am Beginn des Shaders sind aus Kompatibilitätsgründen notwendig.

Hier jetzt der gesamte Fragment Shader.

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

varying vec4 vertColor;

void main() {
// Outputting pixel color (interpolated across triangle)
gl_FragColor = vertColor;
}

Diese beiden Shader (vertex.glsl und fragment.glsl) müssen nun im Unterordner /data im Sketchordner platziert werden. Der Einsatz dieser Shader wird in Processing mit der PShader Klasse kontrolliert. Mit loadShader(„fragment.glsl“, „vertex.glsl“) werden die Shader geladen. Es kann auch nur ein Fragment Shader als Parameter übergeben werden. Ist der Shader erst einmal geladen, wird er mit shader(basic) aktiviert und mit resetShader() deaktiviert.

/** Copyright 2012 Thomas Koberger
*/

// https://lernprocessing.wordpress.com/
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* MOUSE LEFT          : Shader ein/aus
*/

PShader basic;

boolean enabled = false;

void setup() {
size(640, 360, P3D);
basic = loadShader("fragment.glsl", "vertex.glsl");
}

void draw() {
background(0);
fill(255);
if (enabled == true) {
shader(basic);
println("shader");
}

translate(width/2, height/2, -200);
sphere(200);
//println(frameRate);
}

void mousePressed() {
enabled = !enabled;
if (!enabled == true) {
resetShader();
}
}

Um zu beweisen, dass die Shader auch aktiv sind, kann man die folgende Zeile in das Programm des Fragment Shaders statt der Originalzeile einfügen:

gl_FragColor = vertColor*vec4(0.1,0.6,0.8,1.0);

Speichert man dann und lässt das Programm laufen, ändert sich die Farbe des Objekts.

Advertisements

2 Kommentare

  1. Pingback: Processing – Über dieses Weblog « processing – tutorial

  2. Besten Dank für die gute und leicht verständliche Erklärung!

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: