SlideShare a Scribd company logo
Working with Shaders (GLSL)
Timothy Kim

My project involved using different shaders to produce different effects in a bunny mesh.
I used the assignment 8 infrastructure as a base for my project.

1. The Lava Bunny

This effect involves animating lava on the bunny mesh.

I learned about animating textures in this tutorial by Jacobo Rodriguez Villar from Typhoon Labs:
http://www.opengl.org/sdk/docs/tutorials/TyphoonLabs/Chapter_3.pdf

First we apply a seamless lava texture to the bunny.
For the lava texture, we use a seamless 512x512 image called "lava2.ppm" in the project folder.
Credit for the image goes to Patrick Hoesly. His website is zooboing.com.
We enable the repeating of texture coordinates in the texture.
For the shaders, we use basic-gl3.vshader and bunny-gl3.fshader as bases.

Now to apply the texture to the bunny, we need some way of defining the texture coordinates a given
pixel of the bunny will use. We could started off by defining an in-attribute variable called aTexCoord.
However, since the texture is seamless and the repeating of texture coordinates is enabled, we don't
need to care about the texture coordinates as long as they are consistent. So we can use the vertex
positions as the texture coordinates.

Looking at basic-gl3.vshader, if we use vPosition as the texture coordinate in the fragment shader, we
will run into trouble because vPosition is multiplied by the ModelView matrix and the Projection
matrix. This results in the texture not being able to "stick on" to the bunny, and when we transform the
bunny, the texture acts like a fixed projection. To fix this problem, we use the in-variable aPosition,
which is vPosition without the matrices multiplied to it. We pass in the value of aPosition to the
fragment shader using a new out-variable called vPosition2.

To use the texture in the fragment shader, we need to define a new sampler2D uniform variable called
"uTexture." We can get the appropriate texel from the texture by writing:
vec4 texColor = texture(uTexture, vPosition2.xy * .25);
The multiplication of .25 helps enlarge the texture on the bunny.

Now to animate the lava on the bunny, we need to define a new uniform variable called "uTime" that
will hold a value that increases with time. We use a timer callback function called "lavaAnimate()"
(located in "final_project.h") that increases the value of uTime at a set interval. lavaAnimate can be
turned on by pressing the 'l' (lowercase "L") key.
We now add uTime as an offset to the texture coordinates:
vec4 texColor = texture(uTexture, vec2(vPosition2.x - uTime, vPosition2.y - uTime) * .25);
This has the effect of moving the lava texture diagonally up on the bunny.
Here are some pictures of the lava bunny:




The shaders for the lava bunny are called "lava-texture.vshader" and "lava-texture.fshader."


2. The Toon Bunny

This effect draws the bunny in a cartoony style.
Note that we will do not need to use a new vertex shader. It will remain as basic-gl3.vshader.
We use bunny-gl3.fshader as the base for the new fragment shader.

We can draw the bunny in a cartoony style by limiting the colors of the bunny to only 3 shades of its
original color. We can measure the intensity with which the lights in the environment hit a point on the
bunny. If the intensity is strong, we use the lightest of the 3 shades. If the intensity is moderate, we use
the 2nd lightest of the 3 shades. If the intensity is weak, we use the darkest of the 3 shades.

Credits to lighthouse3d.com for this first toon shading method.

We measure the intensity the lights hit a point by using the dot product of the normalized normal of the
point and the normalized vector from the point to a light. This dot products computes the cosine of the
angle between the normal of the point and the ray of light hitting the point. A cosine function is used
because it decreases as the angle increases from 0 to 90 degrees. A light ray parallel to the normal
should have a stronger effect than a light ray off from the normal. Luckily, this intensity is already
computed for us in the "diffuse" variable in bunny-gl3.fshader.

Here are the ways we separated the intensities:
if (diffuse > .91)
       diffuse = 1.0;
  else if (diffuse > .6)
    diffuse = .6;
  else
    diffuse = .4;
As you can see, only 3 shades of the bunny will be drawn.
This shader is called "toon1.fshader" in the project.

Now, we can stop here and we would have a decent toon shader, but one thing is missing: outlines.
We could compute the outlines by making a 4th shade in the toon shader, where when the light
intensity of a point is really low, we just color it black.
However, we run into a problem if we use a light intensity as the measure of when to color a point
black. Since the light intensity of a point is measured with respect to the ray of light hitting the point, if
we change our view of the bunny, the light ray will not change. This means the outline on the bunny
will not move with respect to the viewer. So if we change our view to see an area of the bunny that is
not hit strongly by the light, we will see areas of black on the bunny and not an appropriate outline.

What we really need to do is create the outline with respect to the viewer (or the camera).
We can compute the "intensity" with which the camera views a point on the bunny using the dot
product of the normal with the vector from the point to the camera (everything should be normalized of
course). If this intensity is low, we color the point black.
Since in our shaders we are working in eyespace, the position of the camera will always be (0,0,0).
This means that the vector from a point (with eyespace coordinate vector vPosition) to the camera will
be -vPosition.
Here's what this looks like in code:
vec3 toCamera = normalize(-vPosition);
float cameraHit = max(0.0, dot(normal, toCamera));

if (cameraHit < .4)
  intensity = vec3(0, 0, 0);
"intensity" here does not refer to the camera view intensity. It is a variable from bunny-gl3.fshader that
represents the final color output of a point. "cameraHit" represents the camera view intensity.

*This method for computing an outline was original and not taken from another source.

For our other 3 shades, we would still want them to be colored with respect to the light intensity.
Thus we only need to add a few lines of code to toon1.fshader.
The new toon shader is called "toon2.fshader" in the project folder.

Here are some pictures of the toon bunny:




The 1st picture shows the effect from our 1st toon shader. The 2nd picture shows us the problem we
can get if we use light intensity to compute the outlines. The 3rd and 4th picture are examples using the
corrected, 2nd toon shader.


3. The Eroding Bunny

This effect makes the bunny gradually crumble and disappear.

Credits to 3Dlabs (3dshaders.com) for the idea for this effect. I looked at the source code for the
shaders they used to make the erode effect. I only really used one of their coding ideas, but the
implementation of the effect into my project was original. Also, the texture used was original.
The vertex shader for this effect is "lava-texture.vshader."
The fragment shader for this effect used "lava-texture.fshader" as its base.

To make the bunny gradually disappear, we can use a texture. A texture is not only useful for applying
an image onto another object. It can be used as data as well.
We create a texture that only consists of black, white, and shades of gray in between. We can use these
texture values to represent the time at which a certain point on the bunny will disappear. To make the
disappearing smooth, we need to make sure that there are appropriate transitions of gray between black
and white points in the texture. So basically all we need to do is draw an image that has black dots on a
white background, and use a smudge tool to create the transitions between the black and white.

The texture we use is called "erosion_map.ppm" in the project folder.

With that texture in place, we can have a uniform variable "uTime" in the fragment shader that
increases with time through a timer callback function (this callback function is called
"erosionAnimate()" in "final_project.h").
After getting the color of a point on the texture in the fragment shader, we measure the darkness of that
point and compare it to a value. If the measured darkness is less than the value, we discard the
associated fragment (lighter values are higher than darker values). This comparison value should
increase with time to let lighter fragments get discarded.
Here's what this looks like in code:
vec4 texColor = texture(uTexture, vPosition2.xy);

if (texColor.r < 0 + uTime)
  discard;
As you can see, the uTime variable increases the comparison value.

We can turn on the eroding animation by pressing the 'e' key.
We also disable backface culling so that the eroding parts of the back of the bunny can be seen.

Here are some pictures of the eroding bunny:




You can see the bunny gradually disappearing. The last picture is a picture of the texture we used.

Resources:
1. The GLSL tutorials from lighthouse3d.com, Clockworkcoders
(http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/ ), and Typhoon Labs
(http://www.opengl.org/sdk/docs/tutorials/TyphoonLabs/Chapter_3.pdf)
2. The shaders demo and source code from 3dshaders.com.

More Related Content

PDF
Forcedamp2
PPT
Disjoint sets
PDF
Multi degree of freedom systems
PPTX
Disjoint set
PDF
10.30 k5 d sullivan
PPTX
Restricted Boltzman Machine (RBM) presentation of fundamental theory
PPT
Approximate Methods
PPTX
Lecture 6 disjoint set
Forcedamp2
Disjoint sets
Multi degree of freedom systems
Disjoint set
10.30 k5 d sullivan
Restricted Boltzman Machine (RBM) presentation of fundamental theory
Approximate Methods
Lecture 6 disjoint set

What's hot (18)

PDF
Radiation Physics Laboratory – Complementary Exercise Set
PDF
07. disjoint set
PDF
PPT
Data miningpresentation
PPTX
Machine Learning - Neural Networks - Perceptron
PPTX
K MEANS CLUSTERING
PPTX
Customer Segmentation using Clustering
PPT
L5 determination of natural frequency & mode shape
PDF
K-means Clustering Algorithm with Matlab Source code
PPT
K means Clustering Algorithm
PPTX
Statistica theromodynamics
PPTX
New chm 151_unit_4_power_points
PPT
K mean-clustering
PDF
Convolution
DOCX
Neural nw k means
PDF
Back propderiv
DOCX
One particle to_onepartlce_scattering_18052020
Radiation Physics Laboratory – Complementary Exercise Set
07. disjoint set
Data miningpresentation
Machine Learning - Neural Networks - Perceptron
K MEANS CLUSTERING
Customer Segmentation using Clustering
L5 determination of natural frequency & mode shape
K-means Clustering Algorithm with Matlab Source code
K means Clustering Algorithm
Statistica theromodynamics
New chm 151_unit_4_power_points
K mean-clustering
Convolution
Neural nw k means
Back propderiv
One particle to_onepartlce_scattering_18052020
Ad

Viewers also liked (7)

PPTX
Crime And Mental Illness
PPTX
Mental illness
DOC
Crime
PPTX
Mental illness and crime
PPTX
Crime & Mental Disorders
PPTX
Criminal psychology
PPT
Biological Theories of Crime
Crime And Mental Illness
Mental illness
Crime
Mental illness and crime
Crime & Mental Disorders
Criminal psychology
Biological Theories of Crime
Ad

Similar to Shaders project (20)

PDF
201707 SER332 Lecture 21
PDF
iOS Visual F/X Using GLSL
PPTX
Opengl texturing
PPT
Topic 6 Graphic Transformation and Viewing.ppt
PDF
Mixing Path Rendering and 3D
PPT
OpenGL Texture Mapping
PDF
Texture Mapping
PPT
CS 354 Texture Mapping
PPTX
Trident International Graphics Workshop 2014 5/5
PDF
OpenGL L05-Texturing
PPTX
Approaching zero driver overhead
PDF
OpenGL ES on Android
PPTX
Texture mapping in_opengl
PDF
Open gl
PDF
reflective bump environment mappings.pdf
PDF
The Ring programming language version 1.9 book - Part 190 of 210
PPT
CS 354 Programmable Shading
PPT
Order Independent Transparency
PDF
Introduction of openGL
201707 SER332 Lecture 21
iOS Visual F/X Using GLSL
Opengl texturing
Topic 6 Graphic Transformation and Viewing.ppt
Mixing Path Rendering and 3D
OpenGL Texture Mapping
Texture Mapping
CS 354 Texture Mapping
Trident International Graphics Workshop 2014 5/5
OpenGL L05-Texturing
Approaching zero driver overhead
OpenGL ES on Android
Texture mapping in_opengl
Open gl
reflective bump environment mappings.pdf
The Ring programming language version 1.9 book - Part 190 of 210
CS 354 Programmable Shading
Order Independent Transparency
Introduction of openGL

Recently uploaded (20)

PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Machine Learning_overview_presentation.pptx
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Big Data Technologies - Introduction.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
The AUB Centre for AI in Media Proposal.docx
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Machine Learning_overview_presentation.pptx
Digital-Transformation-Roadmap-for-Companies.pptx
NewMind AI Weekly Chronicles - August'25-Week II
Assigned Numbers - 2025 - Bluetooth® Document
Chapter 3 Spatial Domain Image Processing.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Advanced methodologies resolving dimensionality complications for autism neur...
Programs and apps: productivity, graphics, security and other tools
Mobile App Security Testing_ A Comprehensive Guide.pdf
MYSQL Presentation for SQL database connectivity
Big Data Technologies - Introduction.pptx
Unlocking AI with Model Context Protocol (MCP)
Reach Out and Touch Someone: Haptics and Empathic Computing
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
The Rise and Fall of 3GPP – Time for a Sabbatical?

Shaders project

  • 1. Working with Shaders (GLSL) Timothy Kim My project involved using different shaders to produce different effects in a bunny mesh. I used the assignment 8 infrastructure as a base for my project. 1. The Lava Bunny This effect involves animating lava on the bunny mesh. I learned about animating textures in this tutorial by Jacobo Rodriguez Villar from Typhoon Labs: http://www.opengl.org/sdk/docs/tutorials/TyphoonLabs/Chapter_3.pdf First we apply a seamless lava texture to the bunny. For the lava texture, we use a seamless 512x512 image called "lava2.ppm" in the project folder. Credit for the image goes to Patrick Hoesly. His website is zooboing.com. We enable the repeating of texture coordinates in the texture. For the shaders, we use basic-gl3.vshader and bunny-gl3.fshader as bases. Now to apply the texture to the bunny, we need some way of defining the texture coordinates a given pixel of the bunny will use. We could started off by defining an in-attribute variable called aTexCoord. However, since the texture is seamless and the repeating of texture coordinates is enabled, we don't need to care about the texture coordinates as long as they are consistent. So we can use the vertex positions as the texture coordinates. Looking at basic-gl3.vshader, if we use vPosition as the texture coordinate in the fragment shader, we will run into trouble because vPosition is multiplied by the ModelView matrix and the Projection matrix. This results in the texture not being able to "stick on" to the bunny, and when we transform the bunny, the texture acts like a fixed projection. To fix this problem, we use the in-variable aPosition, which is vPosition without the matrices multiplied to it. We pass in the value of aPosition to the fragment shader using a new out-variable called vPosition2. To use the texture in the fragment shader, we need to define a new sampler2D uniform variable called "uTexture." We can get the appropriate texel from the texture by writing: vec4 texColor = texture(uTexture, vPosition2.xy * .25); The multiplication of .25 helps enlarge the texture on the bunny. Now to animate the lava on the bunny, we need to define a new uniform variable called "uTime" that will hold a value that increases with time. We use a timer callback function called "lavaAnimate()" (located in "final_project.h") that increases the value of uTime at a set interval. lavaAnimate can be turned on by pressing the 'l' (lowercase "L") key. We now add uTime as an offset to the texture coordinates: vec4 texColor = texture(uTexture, vec2(vPosition2.x - uTime, vPosition2.y - uTime) * .25); This has the effect of moving the lava texture diagonally up on the bunny.
  • 2. Here are some pictures of the lava bunny: The shaders for the lava bunny are called "lava-texture.vshader" and "lava-texture.fshader." 2. The Toon Bunny This effect draws the bunny in a cartoony style. Note that we will do not need to use a new vertex shader. It will remain as basic-gl3.vshader. We use bunny-gl3.fshader as the base for the new fragment shader. We can draw the bunny in a cartoony style by limiting the colors of the bunny to only 3 shades of its original color. We can measure the intensity with which the lights in the environment hit a point on the bunny. If the intensity is strong, we use the lightest of the 3 shades. If the intensity is moderate, we use the 2nd lightest of the 3 shades. If the intensity is weak, we use the darkest of the 3 shades. Credits to lighthouse3d.com for this first toon shading method. We measure the intensity the lights hit a point by using the dot product of the normalized normal of the point and the normalized vector from the point to a light. This dot products computes the cosine of the angle between the normal of the point and the ray of light hitting the point. A cosine function is used because it decreases as the angle increases from 0 to 90 degrees. A light ray parallel to the normal should have a stronger effect than a light ray off from the normal. Luckily, this intensity is already computed for us in the "diffuse" variable in bunny-gl3.fshader. Here are the ways we separated the intensities: if (diffuse > .91) diffuse = 1.0; else if (diffuse > .6) diffuse = .6; else diffuse = .4; As you can see, only 3 shades of the bunny will be drawn. This shader is called "toon1.fshader" in the project. Now, we can stop here and we would have a decent toon shader, but one thing is missing: outlines. We could compute the outlines by making a 4th shade in the toon shader, where when the light intensity of a point is really low, we just color it black. However, we run into a problem if we use a light intensity as the measure of when to color a point black. Since the light intensity of a point is measured with respect to the ray of light hitting the point, if
  • 3. we change our view of the bunny, the light ray will not change. This means the outline on the bunny will not move with respect to the viewer. So if we change our view to see an area of the bunny that is not hit strongly by the light, we will see areas of black on the bunny and not an appropriate outline. What we really need to do is create the outline with respect to the viewer (or the camera). We can compute the "intensity" with which the camera views a point on the bunny using the dot product of the normal with the vector from the point to the camera (everything should be normalized of course). If this intensity is low, we color the point black. Since in our shaders we are working in eyespace, the position of the camera will always be (0,0,0). This means that the vector from a point (with eyespace coordinate vector vPosition) to the camera will be -vPosition. Here's what this looks like in code: vec3 toCamera = normalize(-vPosition); float cameraHit = max(0.0, dot(normal, toCamera)); if (cameraHit < .4) intensity = vec3(0, 0, 0); "intensity" here does not refer to the camera view intensity. It is a variable from bunny-gl3.fshader that represents the final color output of a point. "cameraHit" represents the camera view intensity. *This method for computing an outline was original and not taken from another source. For our other 3 shades, we would still want them to be colored with respect to the light intensity. Thus we only need to add a few lines of code to toon1.fshader. The new toon shader is called "toon2.fshader" in the project folder. Here are some pictures of the toon bunny: The 1st picture shows the effect from our 1st toon shader. The 2nd picture shows us the problem we can get if we use light intensity to compute the outlines. The 3rd and 4th picture are examples using the corrected, 2nd toon shader. 3. The Eroding Bunny This effect makes the bunny gradually crumble and disappear. Credits to 3Dlabs (3dshaders.com) for the idea for this effect. I looked at the source code for the shaders they used to make the erode effect. I only really used one of their coding ideas, but the implementation of the effect into my project was original. Also, the texture used was original.
  • 4. The vertex shader for this effect is "lava-texture.vshader." The fragment shader for this effect used "lava-texture.fshader" as its base. To make the bunny gradually disappear, we can use a texture. A texture is not only useful for applying an image onto another object. It can be used as data as well. We create a texture that only consists of black, white, and shades of gray in between. We can use these texture values to represent the time at which a certain point on the bunny will disappear. To make the disappearing smooth, we need to make sure that there are appropriate transitions of gray between black and white points in the texture. So basically all we need to do is draw an image that has black dots on a white background, and use a smudge tool to create the transitions between the black and white. The texture we use is called "erosion_map.ppm" in the project folder. With that texture in place, we can have a uniform variable "uTime" in the fragment shader that increases with time through a timer callback function (this callback function is called "erosionAnimate()" in "final_project.h"). After getting the color of a point on the texture in the fragment shader, we measure the darkness of that point and compare it to a value. If the measured darkness is less than the value, we discard the associated fragment (lighter values are higher than darker values). This comparison value should increase with time to let lighter fragments get discarded. Here's what this looks like in code: vec4 texColor = texture(uTexture, vPosition2.xy); if (texColor.r < 0 + uTime) discard; As you can see, the uTime variable increases the comparison value. We can turn on the eroding animation by pressing the 'e' key. We also disable backface culling so that the eroding parts of the back of the bunny can be seen. Here are some pictures of the eroding bunny: You can see the bunny gradually disappearing. The last picture is a picture of the texture we used. Resources: 1. The GLSL tutorials from lighthouse3d.com, Clockworkcoders (http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/ ), and Typhoon Labs (http://www.opengl.org/sdk/docs/tutorials/TyphoonLabs/Chapter_3.pdf) 2. The shaders demo and source code from 3dshaders.com.