From 7028cbe09c688437910a25623098762bf0fa592d Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 28 Mar 2016 22:28:34 +1000 Subject: Move Irrlicht to src/others. --- .../examples/10.Shaders/tutorial.html | 566 +++++++++++++++++++++ 1 file changed, 566 insertions(+) create mode 100644 src/others/irrlicht-1.8.1/examples/10.Shaders/tutorial.html (limited to 'src/others/irrlicht-1.8.1/examples/10.Shaders/tutorial.html') diff --git a/src/others/irrlicht-1.8.1/examples/10.Shaders/tutorial.html b/src/others/irrlicht-1.8.1/examples/10.Shaders/tutorial.html new file mode 100644 index 0000000..05c4f08 --- /dev/null +++ b/src/others/irrlicht-1.8.1/examples/10.Shaders/tutorial.html @@ -0,0 +1,566 @@ + + +Irrlicht Engine Tutorial + + + + +
+ + + + + + + + +
+
+
Tutorial 10. Shaders
+
+
+
+

This tutorial shows how to use shaders for D3D8, D3D9 and OpenGL with + the engine and how to create new material types with them. It also shows + how to disable the generation of mipmaps at texture loading, and how + to use text scene nodes.

+

This tutorial does not explain how shaders work. I would recommend + to read the D3D or OpenGL documentation, to search a tutorial, or to + read a book about this.

+

The program which is described here will look like this:

+


+

+
+
+
+ + + + + + + +
Lets start!
+
+

At first, we need to include all headers and do the stuff we always + do, like in nearly all other tutorials:

+ + + + +
#include <irrlicht.h>
#include <iostream>

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")
+

Because we want to use some interesting shaders in this tutorials, + we need to set some data for them to make them able to compute nice + colors. In this example, we'll use a simple vertex shader which will + calculate the color of the vertex based on the position of the camera. + For this, the shader needs the following data: The inverted world + matrix for transforming the normal, the clip matrix for transforming + the position, the camera position and the world position of the object + for the calculation of the angle of light, and the color of the light. + To be able to tell the shader all this data every frame, we have to + derive a class from the IShaderConstantSetCallBack interface and override + its only method, namely OnSetConstants(). This method will be called + every time the material is set.
+ The method setVertexShaderConstant() of the IMaterialRendererServices + interface is used to set the data the shader needs. If the user chose + to use a High Level shader language like HLSL instead of Assembler + in this example, you have to set the variable name as parameter instead + of the register index.

+ + + + +
IrrlichtDevice* device = 0;
bool UseHighLevelShaders = false;

class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public: +
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();

// set inverted world matrix
// if we are using highlevel shaders (the user can select this when
// starting the program), we must set the constants by name.

core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD);
invWorld.makeInverse();

if (UseHighLevelShaders)
services->setVertexShaderConstant("mInvWorld", &invWorld.M[0], 16);
else
services->setVertexShaderConstant(&invWorld.M[0], 0, 4);

// set clip matrix
core::matrix4 worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);

if (UseHighLevelShaders)
services->setVertexShaderConstant("mWorldViewProj", &worldViewProj.M[0], 16);
else
services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4);

// set camera position
core::vector3df pos = device->getSceneManager()->
getActiveCamera()->getAbsolutePosition();

if (UseHighLevelShaders)
services->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&pos), 3);
else
services->setVertexShaderConstant(reinterpret_cast<f32*>(&pos), 8, 1);

// set light color
video::SColorf col(0.0f,1.0f,1.0f,0.0f);

if (UseHighLevelShaders)
services->setVertexShaderConstant("mLightColor", reinterpret_cast<f32*>(&col), 4);
else
services->setVertexShaderConstant(reinterpret_cast<f32*>(&col), 9, 1);

// set transposed world matrix
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
world = world.getTransposed();

if (UseHighLevelShaders)
services->setVertexShaderConstant("mTransWorld", &world.M[0], 16);
else
services->setVertexShaderConstant(&world.M[0], 10, 4);
}
};
+

The next few lines start up the engine. Just like in most other + tutorials before. But in addition, we ask the user if he wants this + example to use high level shaders if he selected a driver which is + capable of doing so.

+ + + + +
int main()
{
// let user select driver type

video::E_DRIVER_TYPE driverType = video::EDT_DIRECTX9;

printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");

char i;
std::cin >> i;

switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}

// ask the user if we should use high level shaders for this example
if (driverType == video::EDT_DIRECT3D9 ||
driverType == video::EDT_OPENGL) + {
printf("Please press 'y' if you want to use high level shaders.\n");
std::cin >> i;
if (i == 'y')
UseHighLevelShaders = true;
}

// create device

device = createDevice(driverType, core::dimension2d<s32>(640, 480));

if (device == 0)
{
printf("\nWas not able to create driver.\n"\
"Please restart and select another driver.\n"
);
getch();
return 1;
}

video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* gui = device->getGUIEnvironment();
+

Now for the more interesting parts. If we are using Direct3D, we + want to load vertex and pixel shader programs, if we have
+ OpenGL, we want to use ARB fragment and vertex programs. I wrote the + corresponding programs down into the files d3d8.ps, d3d8.vs, d3d9.ps, + d3d9.vs, opengl.ps and opengl.vs. We only need the right filenames + now. This is done in the following switch. Note, that it is not necessary + to write the shaders into text files, like in this example. You can + even write the shaders directly as strings into the cpp source file, + and use later addShaderMaterial() instead of addShaderMaterialFromFiles().

+ + + + +
	c8* vsFileName = 0; // filename for the vertex shader
c8* psFileName = 0; // filename for the pixel shader

switch(driverType)
{
case video::EDT_DIRECT3D8:
psFileName = "../../media/d3d8.psh";
vsFileName = "../../media/d3d8.vsh";
break;
case video::EDT_DIRECT3D9:
if (UseHighLevelShaders)
{
psFileName = "../../media/d3d9.hlsl";
vsFileName = psFileName; // both shaders are in the same file
}
else
{
psFileName = "../../media/d3d9.psh";
vsFileName = "../../media/d3d9.vsh";
}
break;
case video::EDT_OPENGL:
if (UseHighLevelShaders)
{
psFileName = "../../media/opengl.frag";
vsFileName = "../../media/opengl.vert";
}
else
{
psFileName = "../../media/opengl.psh";
vsFileName = "../../media/opengl.vsh";
}
break;
}
+
+

In addition, we check if the hardware and the selected renderer + is capable of executing the shaders we want. If not, we simply set + the filename string to 0. This is not necessary, but useful in this + example: For example, if the hardware is able to execute vertex shaders + but not pixel shaders, we create a new material which only uses the + vertex shader, and no pixel shader. Otherwise, if we would tell the + engine to create this material and the engine sees that the hardware + wouldn't be able to fullfill the request completely,
+ it would not create any new material at all. So in this example you + would see at least the vertex shader in action, without the pixel + shader.

+
+ + + + +
	if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
{
device->getLogger()->log("WARNING: Pixel shaders disabled "\
"because of missing driver/hardware support.");
psFileName = 0;
}

if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
{
device->getLogger()->log("WARNING: Vertex shaders disabled "\
"because of missing driver/hardware support.");
vsFileName = 0;
}
+

Now lets create the new materials.
+ As you maybe know from previous examples, a material type in the Irrlicht + engine is set by simply changing the MaterialType value in the SMaterial + struct. And this value is just a simple 32 bit value, like video::EMT_SOLID. + So we only need the engine to create a new value for us which we can + set there. To do this, we get a pointer to the IGPUProgrammingServices + and call addShaderMaterialFromFiles(), which returns such a new 32 bit + value. That's all.
+ The parameters to this method are the following: First, the names of + the files containing the code of the vertex and the pixel shader.
+ If you would use addShaderMaterial() instead, you would not need file + names, then you could write the code of the shader directly as string. + The following parameter is a pointer to the IShaderConstantSetCallBack + class we wrote at the beginning of this tutorial. If you don't want + to set constants, set this to 0. The last paramter tells the engine + which material it should use as base material.
+ To demonstrate this, we create two materials with a different base material, + one with EMT_SOLID and one with EMT_TRANSPARENT_ADD_COLOR.

+ + + + +
	// create materials

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

s32 newMaterialType1 = 0;
s32 newMaterialType2 = 0;

if (gpu)
{
MyShaderCallBack* mc = new MyShaderCallBack();
+ // create the shaders depending on if the user wanted high level
// or low level shaders:


if (UseHighLevelShaders)
{
// create material from high level shaders (hlsl or glsl)

newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_SOLID);

newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_TRANSPARENT_ADD_COLOR);
}
else
{
// create material from low level shaders (asm or arb_asm)

newMaterialType1 = gpu->addShaderMaterialFromFiles(vsFileName,
psFileName, mc, video::EMT_SOLID);

newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName,
psFileName, mc, video::EMT_TRANSPARENT_ADD_COLOR);
}

mc->drop();
}
+

Now its time for testing out the materials. We create a test cube + and set the material we created. In addition, we add a text scene node + to the cube and a rotatation animator, to make it look more interesting + and important.

+ + + + +

+	// create test scene node 1, with the new created material type 1
+
+	scene::ISceneNode* node = smgr->addCubeSceneNode(50);
+	node->setPosition(core::vector3df(0,0,0));
+	node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
+	node->setMaterialFlag(video::EMF_LIGHTING, false);
+	node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1);
+
+	smgr->addTextSceneNode(gui->getBuiltInFont(),
+			L"PS & VS & EMT_SOLID",
+			video::SColor(255,255,255,255),	node);
+
+	scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator(
+			core::vector3df(0,0.3f,0));
+	node->addAnimator(anim);
+	anim->drop();
+

Same for the second cube, but with the second material we created.

+ + + + +
	// create test scene node 2, with the new created material type 2
+
+	node = smgr->addCubeSceneNode(50);
+	node->setPosition(core::vector3df(0,-10,50));
+	node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
+	node->setMaterialFlag(video::EMF_LIGHTING, false);
+	node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2);
+
+	smgr->addTextSceneNode(gui->getBuiltInFont(),
+			L"PS & VS & EMT_TRANSPARENT",
+			video::SColor(255,255,255,255),	node);
+
+	anim = smgr->createRotationAnimator(core::vector3df(0,0.3f,0));
+	node->addAnimator(anim);
+	anim->drop();
+
+ Then we add a third cube without a shader on it, to be able to compare + the cubes.
+
+ + + + +
	// add a scene node with no shader 
+
+	node = smgr->addCubeSceneNode(50);
+	node->setPosition(core::vector3df(0,50,25));
+	node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
+	node->setMaterialFlag(video::EMF_LIGHTING, false);
+	smgr->addTextSceneNode(gui->getBuiltInFont(), L"NO SHADER",
+		video::SColor(255,255,255,255), node);
+            
+
+ And last, we add a skybox and a user controlled camera to the scene. For + the skybox textures, we disable mipmap generation, because we don't need + mipmaps on it.
+
+ + + + +
	// add a nice skybox

driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

smgr->addSkyBoxSceneNode(
driver->getTexture("../../media/irrlicht2_up.jpg"),
driver->getTexture("../../media/irrlicht2_dn.jpg"),
driver->getTexture("../../media/irrlicht2_lf.jpg"),
driver->getTexture("../../media/irrlicht2_rt.jpg"),
driver->getTexture("../../media/irrlicht2_ft.jpg"),
driver->getTexture("../../media/irrlicht2_bk.jpg"));

driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

// add a camera and disable the mouse cursor

scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
cam->setPosition(core::vector3df(-100,50,100));
cam->setTarget(core::vector3df(0,0,0));
device->getCursorControl()->setVisible(false);
+
+ Now draw everything. That's all.
+
+ + + + +
	int lastFPS = -1;

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

int fps = driver->getFPS();

if (lastFPS != fps)
{
core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}

device->drop();

return 0;
+
+ Compile and run this, and I hope you have fun with your new little shader + writing tool :).
+
+
+
+ + + + + + + +
Shader files
+
+

The files containing the shaders can be found in the media directory + of the SDK. However, they look like this:

+ + + + + + + +
D3D9.HLSL
+
+// part of the Irrlicht Engine Shader example.
+// These simple Direct3D9 pixel and vertex shaders will be loaded by the shaders
+// example. Please note that these example shaders don't do anything really useful. 
+// They only demonstrate that shaders can be used in Irrlicht.
+
+//-----------------------------------------------------------------------------
+// Global variables
+//-----------------------------------------------------------------------------
+float4x4 mWorldViewProj;  // World * View * Projection transformation
+float4x4 mInvWorld;       // Inverted world matrix
+float4x4 mTransWorld;     // Transposed world matrix
+float3 mLightPos;         // Light position
+float4 mLightColor;       // Light color
+
+
+// Vertex shader output structure
+struct VS_OUTPUT
+{
+	float4 Position   : POSITION;   // vertex position 
+	float4 Diffuse    : COLOR0;     // vertex diffuse color
+	float2 TexCoord   : TEXCOORD0;  // tex coords
+};
+
+
+VS_OUTPUT vertexMain( in float4 vPosition : POSITION,
+                      in float3 vNormal   : NORMAL,
+                      float2 texCoord     : TEXCOORD0 )
+{
+	VS_OUTPUT Output;
+
+	// transform position to clip space 
+	Output.Position = mul(vPosition, mWorldViewProj);
+	
+	// transform normal 
+	float3 normal = mul(vNormal, mInvWorld);
+	
+	// renormalize normal 
+	normal = normalize(normal);
+	
+	// position in world coodinates
+	float3 worldpos = mul(mTransWorld, vPosition);
+	
+	// calculate light vector, vtxpos - lightpos
+	float3 lightVector = worldpos - mLightPos;
+	
+	// normalize light vector 
+	lightVector = normalize(lightVector);
+	
+	// calculate light color 
+	float3 tmp = dot(-lightVector, normal);
+	tmp = lit(tmp.x, tmp.y, 1.0);
+	
+	tmp = mLightColor * tmp.y;
+	Output.Diffuse = float4(tmp.x, tmp.y, tmp.z, 0);
+	Output.TexCoord = texCoord;
+	
+	return Output;
+}
+
+
+
+// Pixel shader output structure
+struct PS_OUTPUT
+{
+    float4 RGBColor : COLOR0;  // Pixel color    
+};
+
+
+sampler2D tex0;
+	
+PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,
+                     float4 Position : POSITION,
+                     float4 Diffuse  : COLOR0 ) 
+{ 
+	PS_OUTPUT Output;
+
+	float4 col = tex2D( tex0, TexCoord );  // sample color map
+	
+	// multiply with diffuse and do other senseless operations
+	Output.RGBColor = Diffuse * col;
+	Output.RGBColor *= 4.0;
+
+	return Output;
+}
+
+ + + + + + + +
D3D9.VSH
+; part of the Irrlicht Engine Shader example.
+; This Direct3D9 vertex shader will be loaded by the engine.
+; Please note that these example shaders don't do anything really useful. 
+; They only demonstrate that shaders can be used in Irrlicht.
+vs.1.1 + +dcl_position v0; ; declare position +dcl_normal v1; ; declare normal +dcl_color v2; ; declare color +dcl_texcoord0 v3; ; declare texture coordinate
+; transpose and transform position to clip space +mul r0, v0.x, c4 +mad r0, v0.y, c5, r0 +mad r0, v0.z, c6, r0 +add oPos, c7, r0 + +; transform normal +dp3 r1.x, v1, c0 +dp3 r1.y, v1, c1 +dp3 r1.z, v1, c2 + +; renormalize normal +dp3 r1.w, r1, r1 +rsq r1.w, r1.w +mul r1, r1, r1.w + +; calculate light vector +m4x4 r6, v0, c10 ; vertex into world position +add r2, c8, -r6 ; vtxpos - lightpos + +; normalize light vector +dp3 r2.w, r2, r2 +rsq r2.w, r2.w +mul r2, r2, r2.w + +; calculate light color +dp3 r3, r1, r2 ; dp3 with negative light vector +lit r5, r3 ; clamp to zero if r3 < 0, r5 has diffuce component in r5.y +mul oD0, r5.y, c9 ; ouput diffuse color +mov oT0, v3 ; store texture coordinates
+
+ + + + + + + +
D3D9.PSH
+; part of the Irrlicht Engine Shader example.
+; This simple Direct3D9 pixel shader will be loaded by the engine.
+; Please note that these example shaders don't do anything really useful. 
+; They only demonstrate that shaders can be used in Irrlicht.
+ps.1.1 + +tex t0 ; sample color map +add r0, v0, v0 ; mulitply with color +mul t0, t0, r0 ; mulitply with color +add r0, t0, t0 ; make it brighter and store result +
+
+ + + + + + + +
D3D8.VSH
+; part of the Irrlicht Engine Shader example.
+; This Direct3D9 vertex shader will be loaded by the engine.
+; Please note that these example shaders don't do anything really useful. 
+; They only demonstrate that shaders can be used in Irrlicht.
+vs.1.1 + +; transpose and transform position to clip space +mul r0, v0.x, c4 +mad r0, v0.y, c5, r0 +mad r0, v0.z, c6, r0 +add oPos, c7, r0 + +; transform normal +dp3 r1.x, v1, c0 +dp3 r1.y, v1, c1 +dp3 r1.z, v1, c2 + +; renormalize normal +dp3 r1.w, r1, r1 +rsq r1.w, r1.w +mul r1, r1, r1.w + +; calculate light vector +m4x4 r6, v0, c10 ; vertex into world position +add r2, c8, -r6 ; vtxpos - lightpos + +; normalize light vector +dp3 r2.w, r2, r2 +rsq r2.w, r2.w +mul r2, r2, r2.w + +; calculate light color +dp3 r3, r1, r2 ; dp3 with negative light vector +lit r5, r3 ; clamp to zero if r3 < 0, r5 has diffuce component in r5.y +mul oD0, r5.y, c9 ; ouput diffuse color +mov oT0, v3 ; store texture coordinates
+
+ + + + + + + +
D3D8.PSH
+; part of the Irrlicht Engine Shader example.
+; This simple Direct3D9 pixel shader will be loaded by the engine.
+; Please note that these example shaders don't do anything really useful. 
+; They only demonstrate that shaders can be used in Irrlicht.
+ps.1.1 + +tex t0 ; sample color map +mul_x2 t0, t0, v0 ; mulitply with color +add r0, t0, t0 ; make it brighter and store result
+
+ + + + + + + +
OPENGL.VSH
+!!ARBvp1.0
+# part of the Irrlicht Engine Shader example.
+# Please note that these example shaders don't do anything really useful. 
+# They only demonstrate that shaders can be used in Irrlicht.
+#input +ATTRIB InPos = vertex.position; +ATTRIB InColor = vertex.color; +ATTRIB InNormal = vertex.normal; +ATTRIB InTexCoord = vertex.texcoord; + +#output +OUTPUT OutPos = result.position; +OUTPUT OutColor = result.color; +OUTPUT OutTexCoord = result.texcoord; + +PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix. +TEMP Temp; +TEMP TempColor; +TEMP TempNormal; +TEMP TempPos; + +#transform position to clip space +DP4 Temp.x, MVP[0], InPos; +DP4 Temp.y, MVP[1], InPos; +DP4 Temp.z, MVP[2], InPos; +DP4 Temp.w, MVP[3], InPos; + +#transform normal +DP3 TempNormal.x, InNormal.x, program.local[0]; +DP3 TempNormal.y, InNormal.y, program.local[1]; +DP3 TempNormal.z, InNormal.z, program.local[2]; + +#renormalize normal +DP3 TempNormal.w, TempNormal, TempNormal; +RSQ TempNormal.w, TempNormal.w; +MUL TempNormal, TempNormal, TempNormal.w; + +# calculate light vector +DP4 TempPos.x, InPos, program.local[10]; # vertex into world position +DP4 TempPos.y, InPos, program.local[11]; +DP4 TempPos.z, InPos, program.local[12]; +DP4 TempPos.w, InPos, program.local[13]; + +ADD TempPos, program.local[8], -TempPos; # vtxpos - lightpos + +# normalize light vector +DP3 TempPos.w, TempPos, TempPos; +RSQ TempPos.w, TempPos.w; +MUL TempPos, TempPos, TempPos.w; + +# calculate light color +DP3 TempColor, TempNormal, TempPos; # dp3 with negative light vector +LIT OutColor, TempColor; # clamp to zero if r3 < 0, r5 has diffuce component in r5.y +MUL OutColor, TempColor.y, program.local[9]; # ouput diffuse color +MOV OutColor.w, 1.0; # we want alpha to be always 1 +MOV OutTexCoord, InTexCoord; # store texture coordinate +MOV OutPos, Temp; + +END
+
+ + + + + + + +
OPENGL.PSH
+!!ARBfp1.0
+# part of the Irrlicht Engine Shader example.
+# Please note that these example shaders don't do anything really useful. 
+# They only demonstrate that shaders can be used in Irrlicht.
+#Input +ATTRIB inTexCoord = fragment.texcoord; # texture coordinates +ATTRIB inColor = fragment.color.primary; # interpolated diffuse color + +#Output +OUTPUT outColor = result.color; + +TEMP texelColor; +TEMP tmp; +TXP texelColor, inTexCoord, texture, 2D; + +ADD tmp, inColor, inColor; # mulitply with color +MUL texelColor, texelColor, tmp; # mulitply with color +ADD outColor, texelColor, texelColor; # make it brighter and store result + +END
+

 

+
+
+

 

+

 

+ + -- cgit v1.1