Now the fun begins.... In this lab, you will attempt to recreate the texture found on a real, live surface using procedural methods.
The texture which you will be recreating is a tile floor. An image of a sample of the floor is given below; a high-resolution version of this image is available. (This may be useful for getting a closer look when you start writing the shaders to simulate this surface.)
For those of you who have eaten at Crossroads, you may recognize this as the tile found throughout the eatery. This particular sample was taken from in front of the pizza/pasta station.
The area of this image which is outlined in black is the sample you will use as the base for your tile texture. For simplicity, you can assume that this pattern of tiles will repeat as one moves outside of the outlined region (unlike the floor in Crossroads, which doesn't repeat this pattern exactly).
In the second half of this week's lecture we built up a brick texture shader one feature at a time; you will be doing the same thing, building your tile shader from scratch in phases. Each phase should be an advancement and improvement over the previous. The phases of the shader will comprise the three parts of the lab:
BASIC: Basic coloring and tile division
INTERMEDIATE: Add bump mapping
ADVANCED: Use noise to modulate color
As brick shaders are the "Hello, World!" of procedural shaders, there are a multitude of sample versions available on the web and in books. Ceramic tile is another popular effect and, as such, sample shaders that implement a tile floor are also readily available. Although I encourage you to search out the the sample code for these shaders to use as a guide, I also request that you build your shader from scratch, fully commenting your logic and reasoning about the creation of the shader in the shader code.
I also encourage you to be creative in your shader design, in both definition of parameters as well as the final effect achieved, even if you find yourself deviating from the sample image above. The image is meant as more of a guideline rather than a requirement.
For each submission you should include the shader code and an example image which illustrates the effect. It should be clear that the later submissions are extensions of the code written for the earlier submissions of this lab.
As with the previous assignments, two ZIP archives have been provided for you:
lab4files.zip
expands into a folder named lab4 which contains "starter"
code for your GLSL and RenderMan®
implementations.
lab4results.zip
expands into a folder named lab4results which is a framework
into which you should place your solutions and resulting images.
As with previous assignments, please place your solutions in the
lab4results folder, as follows:
Place your source code (not object files or binaries) in the appropriate
subfolder (e.g., your GLSL basic source files in the
GLSL/Basic folder, your RenderMan intermediate source
files in the RenderMan/Intermediate folder, etc.).
Place your result images in the Results subfolder, with
names of the form
lang-task.suffix.
For lang, use glsl or
rman,
as appropriate; for task, use basic,
intermediate. or advanced;
suffix should match the type of the image file
you created (typically, tiff, png,
gif,
etc.
For example, the result image for the Basic RenderMan task might
be named rman-basic.tiff, and the Advanced GLSL task result
image might be named glsl-advanced.png.
Create a ZIP archive of your results folder by using the "Compress" entry of the right-click menu for the folder; to submit it, run the command
try wrc-grd shading-4 lab4results.zip
Part 1 involves definition of the basic subdivision of the tile surface. In short, given a point on the surface, the shader should determine whether the point is on the tile or in the grout, and color the point appropriately based on that assessment.
Use the sample image as a guide for tile placement. You can see that the overall pattern is comprised of 25 smaller square positions arranged in a 5x5 pattern; the pattern is completed using three 1x1 tiles, four 1x2 (one row, two column) tiles, five 2x1 tiles, and one 2x2 tile. Feel free to experiment with this pattern - your resulting tile pattern doesn't have to exactly match the sample image, but it should contain a variety of different tile sizes and orientations (e.g., using 25 1x1 tiles isn't acceptable).
Additionally, the tiles have varying base colors; in this sample, some tiles have a basic bluish color, and others have a tan or orangeish color. Feel free to experiment with this, as well; again, your resulting pattern doesn't have to use the same color distribution, but it should include tiles of different base colors. For this task, use a single color for each individual tile - you will be varying the color within tiles in the Advanced task.
In Part 2, procedural bump mapping is introduced. You are to add bump mapping to the texture. Bump mapping should be used:
In the grout area, thus creating a "groove" in which the grout sits.
On the tile itself. Unlike brick, the bumps in the tile are more of a "lumpy" noise rather than "grainy" noise. Feel feel to make use of noise at various frequencies to achieve the effect. Use of the turbulence or fBm function might be particularly helpful here.
A couple of good safety tips: First, remember that in order for bump mapping to be effective, your illumination model must somehow depend upon the normal. A simplified Phong model would suffice. Secondly, be careful with your coordinate spaces. Bump mapping should be applied in object space, so too, the parameter to the noise function (if a Point) should be in object coordinates.
Contrary to earlier experience, upon initial testing, it appears that the GLSL noise functions are indeed supported on the graphics cards in the ICL5 machines! Thus, for this lab, you should feel free to use the standard GLSL noise functions in your shaders. (If we run into trouble, there is an alternate noise implementation available for our use).
Note that bump mapping in GLSL should be done in tangent space.
In order to do this, you will need the tangent at the vertex point so that
you can transform the appropriate vectors needed for your illumination
calculation in your vertex shader.
A quick and dirty function named calculateTangent() has
been provided in bumpShader.vert to assist you in
obtaining the tangent vector given a normal vector.
In part 3, the color of the tile should be modulated using noise and turbulence. The color modifications can, if you wish, correspond to the tile area being bump mapped in Part 2, but this isn't required. Experiment, be creative, and have fun.