Shader Programming Guides

Shaders | Thursday 9 October 2008 5:16 pm

Here are some links to a couple of quick guides and references that’s useful when writing shaders.

The OpenGL GLSL shader language Quick Reference Guide.
http://www.opengl.org/sdk/libs/OpenSceneGraph/glsl_quickref.pdf

The full specification of GLSL 1.20.8.
http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.20.8.pdf

The full specification of GLSL 1.30.08
http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.30.08.pdf

GPU Programming guide from Nvidia for both OpenGL and DirectX.
http://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide.pdf

Guide to write shaders in DirectX9 in HLSL
http://msdn.microsoft.com/en-us/library/bb944006(VS.85).aspx

Guide to write shaders in DirectX10 in HLSL
http://msdn.microsoft.com/en-us/library/bb509703(VS.85).aspx

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks

Lerp

Math | Sunday 5 October 2008 6:57 pm

Lerp is the procedure to interpolate between two vectors with a specified weight. An example below

float weight; // the weight for lerping
 
vec2 input1, input2; // the inputs to lerp between
 
vec2 lerpResult = input1(1.0-weight)+input2(weight);

In GLSL it’s named mix( genType, genType, float ) instead of lerp which can be misleading. But when testing, it actually works to use lerp instead of mix in GLSL shaders when running them on a Nvidia GeForce 8800GTS although it’s not recommended.

Here’s the OpenGL GLSL quick reference guide which contains all functions you can use inside of a shader (and much more).
 http://www.opengl.org/sdk/libs/OpenSceneGraph/glsl_quickref.pdf

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks

Bilinear Interpolation

Filtering | Sunday 5 October 2008 5:18 pm

When sampling a texel from a texture that has been re-sized (which is nearly always the case in 3D rendering) you need to use some kind of filter to select what result you should get. Bilinear interpolation uses the four nearest neighbors to interpolate an average texel value.

Bilinear Interpolation

This is a built in filter in OpenGL and to activate it you set the following lines when setting up a texture:

// set the minification filter
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
// set the magnification filter
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

If you for some reason wants to do bilinear interpolation manually in a shader then the function to do so looks like the following in GLSL. Note that in vertex shaders you have to do manual bilinear interpolation between texture samples.

const float textureSize = 512.0; //size of the texture
const float texelSize = 1.0 / textureSize; //size of one texel 
 
vec4 texture2DBilinear( sampler2D textureSampler, vec2 uv )
{
    // in vertex shaders you should use texture2DLod instead of texture2D
    vec4 tl = texture2D(textureSampler, uv);
    vec4 tr = texture2D(textureSampler, uv + vec2(texelSize, 0));
    vec4 bl = texture2D(textureSampler, uv + vec2(0, texelSize));
    vec4 br = texture2D(textureSampler, uv + vec2(texelSize , texelSize));
    vec2 f = fract( uv.xy * textureSize ); // get the decimal part
    vec4 tA = mix( tl, tr, f.x ); // will interpolate the red dot in the image
    vec4 tB = mix( bl, br, f.x ); // will interpolate the blue dot in the image
    return mix( tA, tB, f.y ); // will interpolate the green dot in the image
}

Here’s a magnification of a texture using using three different types of filters. The texture is mapped on a sphere and the viewport has been zoomed in on a small part of it.

Nearest Neigbour  (OpenGL fixed function implementation)

Nearest Neigbor filter

Bilinear Interpolation (OpenGL fixed function implementation)

Bilinear Interpolation OpenGL

Bilinear Interpolation (GLSL implementation, the code above)

Bilinear Interpolation GLSL

Some information about OpenGL texture mapping and how to set the filtering properties:
http://www.nullterminator.net/gltexture.html

Here’s some discussion why you should not always use bilinear interpolation:
http://gregs-blog.com/2008/01/14/how-to-turn-off-bilinear-filtering-in-opengl/

Link to a bilinear interpolation function for DirectX:
http://www.catalinzima.com/?page_id=85

Article on GameDev.net about bilinear filtering:
http://www.gamedev.net/reference/articles/article669.asp

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks

Screen Space

Cameras | Sunday 5 October 2008 12:10 pm

The last step of transformations (world to screen) when rendering is to get the rendered objects to screen space. This is a 2D space with the origin in the middle of the screen. After the vertex shader but before the fragment shader the fragments will be normalized device coordinates and will automatically be transformed to screen space. The fragments x,y coordinates will be mapped to the x and y coordinates on the screen (the exact mapping is set by viewportbounds). And the z coordinates will be mapped to the depth buffer (z-buffer) as the following [-1] -> [near clip plane limit] and [1] -> [far clip plane limit].

The viewport mapping is the following [-1,1] in X is mapped to the left to right of the viewport range. The [-1,1] in Y is mapped to the bottom to top of the viewport range

Framents will automatically be transformed to screen space before the fragment shader, you just need to set the viewport mapping with the following OpenGL call.

glViewport(0, screenHeight/2, screenWidth/2, screenHeight/2);

You can access the current fragment depth in a fragment shader with the variable gl_FragDepth which in default is the same as gl_FragCoord.z. The screen coordinates can be accessed in the variable gl_FragCoord.xy.

Information about pixel shaders in DirectX (most is the same in OpenGL):
http://www.gamedev.net/columns/hardcore/dxshader3/

A quick reference guide to GLSL:
http://www.opengl.org/sdk/libs/OpenSceneGraph/glsl_quickref.pdf

Description of the mapping in DirectX:
http://msdn.microsoft.com/en-us/library/bb219690.aspx

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks
« Previous PageNext Page »