WebGL
Shader
WebGL
Børre Stenseth
Basis >Shading

Shading

Hva

Jeg har ingen ambisjoner om lage en komplett beskrivelse av verken OpenGL, OpenGL Shading Language eller sammenhengen mellom dem. Hensikten er å forsøke og framstille hovedprinsippene på en måte som kanskje kan gi mening for lesere som har erfaring med OpenGL og vil vite hva vi kan oppnå med Shading language og hvorfor det er interessant. Litt nyttig refreranse litteratur er RedBook [1], som er basisen for OpenGL, Yellow Book [2] som beskriver OpenGL Shading Language og OpenGL SuperBible [3] som dekker begge deler med eksempler.

En tilstandsmaskin

OpenGL beskrives ofte som en tilstandsmaskin. Med det forstår vi at vi fra vårt program spesifiserer en rekke egenskaper som projeksjon, transformasjoner, lys, farge, teksturer og en masse andre ting. Når dette er gjort, sender vi en rekke punkter gjennom denne tilstandsmaskinen maskinen og håper at dette manifesterer seg på skjermen i den formen vi forventer. I en viss forstand kan vi si at det eneste tegneprimitivet er et punkt. Tilstanden vi har satt spesifiserer om dette punktet skal være en del av en trekant, en firkant eller hva det måtte være.

En alt for enkel og naiv skisse kan se slik ut:

openglstrait

Grafikk prosessor

Når vi nå har tilgang til programmerbare grafikkprosessorer kan vi tenke slik:

openglshade

Dette innebærer at vi må skrive shaderprogrammet i et eget språk, Shading Language. Oppgavene til shaderprogrammet er å prosessere punkter (vertex) og fragmenter. Vi kan la OpenGL-programmet gi beskjeder om hvordan denne prosesseringen skal foregå, og vi kan implementere egne metoder for å oppnå ønskede effekter.

Et shaderprogram består av to deler, en vertex-shader og en fragment-shader. Vertex-shaderen involveres hver gang et punkt skal prosesseres. Fragment-shaderen tar seg av alle fragmenter, vi kan for enkelhets skyld si hvert pixel.

Vi kan f.eks implementere lyseffekter i en vertex-shader. Nedenfor et eksempel, en-vertex shader, tatt fra modulen En boks

// attributes to the vertex
attribute mediump vec3 aVertexNormal; 
attribute mediump vec3 aVertexPosition;
attribute vec4 aVertexColor;

// state of transformation matrices
uniform mediump mat4 uNormalMatrix;
uniform mediump mat4 uMVMatrix;
uniform mediump mat4 uPMatrix;

// values that will be passed on to the fragment shader
varying lowp vec4 vColor;
varying mediump vec3 vLighting;

void main(void) {
	// predefined variable
	// multiply with Projection-Matrix and ModelView-Matrix to find
	// correct position
	gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);

	// Apply lighting effect        
	mediump vec3 ambientLight = vec3(0.6, 0.6, 0.6);
	mediump vec3 directionalLightColor = vec3(0.5, 0.5, 0.75);
	mediump vec3 directionalVector = vec3(0.85, 0.8, 0.75);

	// normalize to get correct angle in dot-product below
	mediump vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0);
	mediump float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0);
	vLighting = ambientLight + (directionalLightColor * directional);

	vColor = aVertexColor;
}

Fragment-shaderen er slik i samme eksempel. Den blir svært enkel fordi vi har flater med homogen farge.

// received from the vertex shader
varying mediump vec3 vLighting;
varying lowp vec4 vColor;        
void main(void) {
  // predefined variable
  gl_FragColor = vec4(vColor.rgb * vLighting, vColor.a);
}
Referanser
  1. OpenGL Programming Guide : The Official Guide to Learning Opengl Shreiner, Dave , Woo, Mason, Neider, Jackie & Davis, Tom Addison-Wesley 0321481003 A Must have
  1. OpenGL Shading Language Shreiner, Dave Addison-Wesley 0321197895
  1. OpenGL SuperBible, 4.ed Wright,Richard S., Lipchak,benjamin & Haemel,Nicholas Addison-Wesley 0-321-49882-8
Basis >Shading