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 deletions(-) delete mode 100644 libraries/irrlicht-1.8.1/examples/10.Shaders/tutorial.html (limited to 'libraries/irrlicht-1.8.1/examples/10.Shaders/tutorial.html') diff --git a/libraries/irrlicht-1.8.1/examples/10.Shaders/tutorial.html b/libraries/irrlicht-1.8.1/examples/10.Shaders/tutorial.html deleted file mode 100644 index 05c4f08..0000000 --- a/libraries/irrlicht-1.8.1/examples/10.Shaders/tutorial.html +++ /dev/null @@ -1,566 +0,0 @@ - - -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