Pixel shader tutorial - Hello World

So you're a programmer and own one of these vector computing monsters which we today still call graphic cards? Maybe you've always wanted to try out how it is to write code which runs on their pixel shader units. Because I am receiving lots of mails about this topic, and I'm tired of answering "buy and read a book about it", I've decided to write a small tutorial. And you'll see, it really is easy.
I'm using HLSL for this tutorial - a high level shader programming language. It works with Direct3D9, so this tutorial is windows only, but you could change this tutorial easily to OpenGL and GLSL if you like.
This tutorial also uses Irrlicht, because this will keep the code small and easy to understand, so we can focus on the pixel shader. So just download Irrlicht, paste this code and compile.
First, this hello world pixel shader just puts out a green pixel for every pixel drawn on the screen. The pixel shader is the red text in the beginning at the code. After you've compiled and run the program, play around with it. I'll explain things which may be unclear in the next part.
#include <irrlicht.h>
using namespace irr;

// This is our first pixel shader, written in HLSL.
// It simply puts out 'green' for every pixel drawn.
const char* pixelShader =

"sampler2D tex0; \
\
float4 pixelShader( float2 texCoord : TEXCOORD0,
\
float4 color : COLOR0 ) : COLOR0
\
{
\
return float4(0,1,0,0);
\
}
";

// now fire up Irrlicht, create a small scene with a cube and
// controllable camera and feed the gpu with our pixel shader

int main()
{
IrrlichtDevice* device = createDevice(
video::EDT_DIRECTX9, core::dimension2d<s32>(640, 480));

if (device == 0)
return 1; // could not create selected driver.

video::IVideoDriver* driver = device->getVideoDriver();
video::IGPUProgrammingServices* gpu =
driver->getGPUProgrammingServices();

s32 newMaterialType1 = 0;

if (gpu)
{
// create a new material for our pixel shader

newMaterialType1 = gpu->addHighLevelShaderMaterial(
0, 0, video::EVST_VS_1_1,
pixelShader, "pixelShader" );
}

// create a cube and set our created material with the pixel shader

scene::ISceneNode* node =
device->getSceneManager()->addTestSceneNode(50);
node->setMaterialTexture(0, driver->getTexture("data/wall.bmp"));
node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1);

// add a user controlled camera and disable the mouse cursor

scene::ICameraSceneNode* cam =
device->getSceneManager()->addCameraSceneNodeFPS(0, 100.0f, 100.0f);

cam->setPosition(core::vector3df(-100,50,100));
cam->setTarget(core::vector3df(0,0,0));
device->getCursorControl()->setVisible(false);

// draw everything

while(device->run())
{
driver->beginScene(true, true, video::SColor(255,0,0,0));
device->getSceneManager()->drawAll();
driver->endScene();
}

device->drop();
return 0;
}
The result will look like the following screenshot. Boring, right. But the green color is fully generated on the GPU (via the float4(0,1,0,0) line), a good point to start. We are going to improve the shader a bit in the next parts of the tutorial.


(Update: Follow this link directly to the 2nd part of the tutorial)

five comments, already:

nice tutorial,i was always wonder what is the easiest way to that
:-)
jugurdzija - 27 10 05 - 19:53

thanks! very helpful! i am looking forward to the next parts!
igor - 27 10 05 - 20:10

Just a note: hlsl and cg syntax are pretty much identical and cg is useable under opengl. Of course, Irrlicht doesn’t support cg, but it is (imo) the most flexible shader language
Electron - 27 10 05 - 22:19

Golly, he’s gone all Raymond Chen on us.. :)
Factory () - 27 10 05 - 23:19

hm :)
niko - 28 10 05 - 19:37


Name:  
Remember personal info?
yes
no
Email (optional):
URL (optional):
Enter "layered" (antispam):
Comment:Emoticons / Textile

  ( Register your username / Log in )

Notify: Yes, send me email when someone replies.  

Small print: All html tags except <b> and <i> will be removed from your comment. You can make links by just typing the url or mail-address.
Note: If you type in your email adress above, it will be visible to other visitors, although it will be hidden for bots using javaScript.