Toon Shading
Toon Shading
Toon Shading
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
C A R L<br />
V O N<br />
O S S I E T Z K Y<br />
<strong>Toon</strong> <strong>Shading</strong><br />
Johannes Diemke<br />
Übung im Modul OpenGL mit Java<br />
Wintersemester 2010/2011
<strong>Toon</strong> <strong>Shading</strong><br />
Grundlagen<br />
Gelegentlich auch Cel <strong>Shading</strong> genannt<br />
Verfahren zum nicht-fotorealistischen Rendern<br />
Imitiert Zeichenstil von Comics<br />
Charakteristika<br />
◮ Fette Außenlinien<br />
◮ Wenige Schattierungsstufen<br />
Verwendung in Zeichentrickfilmen und Computerspielen<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 2/12
<strong>Toon</strong> <strong>Shading</strong><br />
The Legend of Zelda: The Wind Waker<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 3/12
<strong>Toon</strong> <strong>Shading</strong><br />
Team Fortress 2 (<strong>Toon</strong> <strong>Shading</strong> Mod)<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 4/12
<strong>Toon</strong> <strong>Shading</strong><br />
Umsetzung<br />
Mehrere alternative Vorgehensweisen<br />
◮ Von trivial bis anspruchsvoll<br />
◮ Trade-off zwischen Komplexität und visueller Qualität<br />
Ein mögliches Vorgehen<br />
1 Zeichnen der Back-Faces mit fetten Linien<br />
2 Berechnung des <strong>Shading</strong><br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 5/12
<strong>Toon</strong> <strong>Shading</strong><br />
Schritt 1: Zeichnen der Back-Faces<br />
Zeichnen der Back-Faces<br />
Verwendung von fetten schwarzen Linien<br />
// setup<br />
gl.glEnable(GL2.GL_CULL_FACE);<br />
...<br />
// first renderpass<br />
gl.glLineWidth(3.0f);<br />
gl.glColor3f(0.0f, 0.0f, 0.0f);<br />
// render back faces using lines<br />
gl.glFrontFace(GL2.GL_CW);<br />
gl.glPolygonMode(GL2.GL_FRONT, GL2.GL_LINE);<br />
// render object<br />
deathstar.draw(gl);<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 6/12
<strong>Toon</strong> <strong>Shading</strong><br />
Schritt 2: Berechnung des <strong>Shading</strong><br />
Beleuchtungsberechnung wie bei diffuser Komponente<br />
Danach Abbildung auf wenige Schattierungsstufen<br />
Umsetzung mittels eines Shader-Programms<br />
// second renderpass<br />
// render front faces using a shader<br />
gl.glFrontFace(GL2.GL_CCW);<br />
gl.glPolygonMode(GL2.GL_FRONT, GL2.GL_FILL);<br />
shader.activate(gl);<br />
// render object<br />
deathstar.draw(gl);<br />
shader.deactivate(gl);<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 7/12
<strong>Toon</strong> <strong>Shading</strong><br />
Schritt 2: Berechnung des <strong>Shading</strong> (Forts.)<br />
Vertex-Shader<br />
◮ Transformiert Vertex in den Clipspace<br />
◮ Berechnet Eyespace-Normale<br />
◮ Übergibt Eyespace-Normale an den Fragment-Shader<br />
varying vec3 eyeSpaceNormal;<br />
void main() {<br />
}<br />
eyeSpaceNormal = gl_NormalMatrix * gl_Normal;<br />
gl_Position = ftransform();<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 8/12
<strong>Toon</strong> <strong>Shading</strong><br />
Schritt 2: Berechnung des <strong>Shading</strong> (Forts.)<br />
Fragment-Shader<br />
◮ Pro-Fragment-Berechnung des <strong>Shading</strong><br />
◮ Beleuchtungsberechnung wie bei diffuser Komponente<br />
◮ Berechnet Kosinus des Winkels zwischen Normale und Lichtvektor<br />
(Directional Light)<br />
varying vec3 eyeSpaceNormal;<br />
void main() {<br />
vec3 normal = normalize(eyeSpaceNormal);<br />
}<br />
float intensity = dot(normalize(gl_LightSource[0].position.xyz), normal);<br />
gl_FragColor = toonify(intensity);<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 9/12
<strong>Toon</strong> <strong>Shading</strong><br />
Schritt 2: Berechnung des <strong>Shading</strong> (Forts.)<br />
Fragment-Shader (Forts.)<br />
◮ Abbildung auf wenige Schattierungsstufen über toonify()<br />
vec4 toonify(in float intensity) {<br />
}<br />
if(intensity > 0.95)<br />
return vec4(0.5, 1.0, 0.5, 1.0);<br />
else if(intensity > 0.5)<br />
return vec4(0.3, 0.6, 0.3, 1.0);<br />
else if(intensity > 0.25)<br />
return vec4(0.2, 0.4, 0.2, 1.0);<br />
else<br />
return vec4(0.1, 0.2, 0.1, 1.0);<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 10/12
Literatur<br />
<br />
<br />
<br />
<br />
Dave Shreiner<br />
OpenGL Programming Guide<br />
http://www.opengl-redbook.com/<br />
Richard S. Wright, Benjamin Lipchak und Nicholas Haemel<br />
OpenGL SuperBibel<br />
http://www.starstonesoftware.com/OpenGL/<br />
Randi J. Rost<br />
OpenGL <strong>Shading</strong> Language<br />
http://www.3dshaders.com/<br />
Tomas Akenine-Möller, Eric Haines und Naty Hoffman<br />
Real-Time Rendering<br />
http://www.realtimerendering.com/<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 11/12
Literatur<br />
<br />
<br />
<br />
Edward Angel<br />
Interactive Computer Graphics<br />
http://www.cs.unm.edu/˜angel/<br />
Gerald Farin und Dianne Hansford<br />
Practical Linear Algebra<br />
http://www.farinhansford.com/books/pla/<br />
Fletcher Dunn und Ian Parberry<br />
3D Math Primer for Graphics and Game Development<br />
www.gamemath.com/<br />
Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 12/12