GLSL and Irrlicht Ambient color lighting.

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

that was it, my bad.

a typo!
No problem, It did confuse me too at first.
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

looks like you've figured out lighting in glsl.

what's next? my guess is probably setting up a texture then move on to multi-texture.

anyway, here's the whole she-bang...

Code: Select all

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

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif


int main() 
{ 

	video::E_DRIVER_TYPE driverType;

	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) Burning's Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i = 'c';
	//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;
	}	

	// create device and exit if creation failed
	core::dimension2di videoDim ( 800,600 );

	IrrlichtDevice *device = createDevice(driverType, videoDim, 32, false );

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


   //IrrlichtDevice* device = createDevice( 
   //   video::EDT_OPENGL, 
   //   core::dimension2d<s32>(640, 480), 32, false, false, false, 0); 
    
   video::IVideoDriver* driver = device->getVideoDriver(); 
   scene::ISceneManager* smgr = device->getSceneManager(); 
    
   video::IGPUProgrammingServices *services = driver->getGPUProgrammingServices(); 
    
   s32 customMaterial = services->addHighLevelShaderMaterialFromFiles( 
      "shaders/shader_v.glsl", "main", video::EVST_VS_1_1, 
      "shaders/shader_f.glsl", "main", video::EPST_PS_1_1, 
      0, 
      video::EMT_SOLID); 
    
   scene::ISceneNode *sphere = smgr->addSphereSceneNode(7); 
   sphere->setPosition(core::vector3df(0,0,0)); 
   sphere->setMaterialType((video::E_MATERIAL_TYPE)customMaterial); 
   sphere->getMaterial(0).AmbientColor = video::SColor(0, 0, 255, 255); 
   sphere->getMaterial(0).Shininess = 200;
    
   sphere = smgr->addSphereSceneNode(5); 
   sphere->setPosition(core::vector3df(12,0,0)); 
   sphere->getMaterial(0).AmbientColor = video::SColor(255, 255, 0, 0); 
   sphere->getMaterial(0).Shininess = 128;
    
    
   scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 50, 10); 
   camera->setPosition(core::vector3df(0,10,-10)); 
   camera->setTarget(core::vector3df(6,0,0)); 
    
   scene::ILightSceneNode *light = smgr->addLightSceneNode(0, core::vector3df(50,50,-50), 
      video::SColorf(1.0f, 1.0f, 1.0f), 10.0f, -1); 
   video::SLight *ldata = &light->getLightData(); 
   ldata->AmbientColor = video::SColorf(0.5f, 0.5f, 0.5f, 1.0f); 

   smgr->setAmbientLight( video::SColorf(0.0f, 0.0f, 1.0f) ); // not influencing shader material sphere!!! 
    
   scene::ISceneNodeAnimator *anim2 = smgr->createFlyCircleAnimator(core::vector3df(0,0,0), 50.0f, 0.001f); 
   light->addAnimator(anim2); 
    
   while(device->run()) 
   { 
      driver->beginScene(true, true, video::SColor(255,100,101,140)); 
      
      smgr->drawAll(); 

      driver->endScene(); 
   } 
   device->drop(); 

   return 0; 
}
Vertex:

Code: Select all

varying vec3 N;
varying vec3 v;

void main(void)
{
   v = vec3(gl_ModelViewMatrix * gl_Vertex);

   N = normalize(gl_NormalMatrix * gl_Normal);   
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Fragment:

Code: Select all

varying vec3 N;
varying vec3 v;

void main (void)
{
vec3 L = normalize(gl_LightSource[0].position.xyz - v); 
vec3 E = normalize(-v); 
// we are in Eye Coordinates, so EyePos is (0,0,0)
vec3 R = normalize(-reflect(L,N)); 
//calculate Ambient Term:
vec4 Iamb = gl_FrontLightProduct[0].ambient;

//calculate Diffuse Term:
vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0);

// calculate Specular Term:
vec4 Ispec = gl_FrontLightProduct[0].specular * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess);

// write Total Color:
gl_FragColor = gl_FrontLightModelProduct.sceneColor + Iamb + Idiff + Ispec; 
//gl_FragColor = Iamb + Idiff + Ispec; 

}
Image
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

looks like you've figured out lighting in glsl.
Not yet!
Until now we have just one point light in the scene. Shader should be able to handle any number of lights (maximum 8 ) of any type.

So first I would code shader for directional light, which will be probably easy then spot light, which will be more difficult. Then add things like radius and attenuation in to the mix. And last made it in to one shader capable of handling several lights.

I would say, number of lights and their type have to be passed in to shader from Irrlicht. I see no other way of how to determine number of lights in scene nor their type.
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

ok, i've looked in several places, including gpugems 2 & 3 books and it turns out this one is new to me. i have no experience setting up multiple lights.

maybe we could set up test cases, very specific moment-in-time render could work, though.

for example, we could try to render a hallway lighted from flickering candles. well, we could try even easier than that, maybe an alley lighted by a neon sign that turns on and off, cars passing by, headlights dimly lighting up the alley.

anyway, those are just examples, i'll leave it up to you how would you like them tested.
Image
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Well setting up multiple lights will not be such a problem. Its just matter of doing for loop and calculate each light. There is even code floating somewhere on net. Number of lights must be probably handed in to shader manually. But thats not problem.

Problem is spot light. If you can find some code somewhere, let me know. So we don't have to reinvent the wheel again :wink:

Here is shader code for directional light (again, per vertex lighting without specular):
vertex shader:

Code: Select all

varying vec4 color;

void main()
{
	vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
	vec3 lightVector = normalize(gl_LightSource[0].position.xyz);
	vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dot(normal,lightVector));
	color = gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + diffuse;

	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Fragment shader is the same as for point light.
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

And here is spot light (again only ambient and diffuse, per vertex):

vertex shader:

Code: Select all

varying vec4 color;

void main()
{
	vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
	vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
	vec3 lightVector = normalize(gl_LightSource[0].position.xyz - position);

	color = gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient;

	float NdotL = max(dot(normal, lightVector), 0.0);

	if (NdotL > 0.0)
	{
		float spotEffect = dot( normalize(gl_LightSource[0].spotDirection), -lightVector );
		if (spotEffect > gl_LightSource[0].spotCosCutoff)
		{
			vec4 diffuse = gl_FrontLightProduct[0].diffuse * NdotL;
			spotEffect = pow(spotEffect, gl_LightSource[0].spotExponent);

			color += diffuse * spotEffect;
		}
	}

	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Fragment shader is same as before.

Now some code to test it:

Code: Select all

#include <irrlicht.h>
using namespace irr;

int main()
{
   IrrlichtDevice* device = createDevice(
      video::EDT_OPENGL,
      core::dimension2d<s32>(640, 480), 32, false, false, false, 0);
    
   video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();
	
	video::IGPUProgrammingServices *services = driver->getGPUProgrammingServices();
   
   s32 customMaterial = services->addHighLevelShaderMaterialFromFiles(
		"shaders/shader_spot_v.glsl", "main", video::EVST_VS_1_1,
      "shaders/shader_spot_f.glsl", "main", video::EPST_PS_1_1,
      0,
      video::EMT_SOLID);
   
   scene::ISceneNode *sphere = smgr->addSphereSceneNode(5,256);
   sphere->setPosition(core::vector3df(0,0,0));
   sphere->setMaterialType((video::E_MATERIAL_TYPE)customMaterial);
   sphere->getMaterial(0).AmbientColor = video::SColor(255, 255, 255, 255);
   
   sphere = smgr->addSphereSceneNode(5,256);
   sphere->setPosition(core::vector3df(12,0,0));
   sphere->getMaterial(0).AmbientColor = video::SColor(255, 255, 255, 255);
   
   scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 50, 10);
   camera->setPosition(core::vector3df(0,10,-10));
   camera->setTarget(core::vector3df(6,0,0));
   
   scene::ILightSceneNode *light = smgr->addLightSceneNode(0, core::vector3df(0,0,-20), 
      video::SColorf(1.0f, 1.0f, 1.0f), 10.0f, -1);
   video::SLight *ldata = &light->getLightData();
   ldata->Type = video::ELT_SPOT;
   ldata->InnerCone = 5.0f;
   ldata->OuterCone = 10.0f;
   ldata->Falloff = 100.0f;

   smgr->setAmbientLight( video::SColorf(0.0f, 0.0f, 0.3f) );
   
   scene::ISceneNodeAnimator *anim2 = smgr->createFlyCircleAnimator(core::vector3df(0,0,0), 50.0f, 0.001f);
   
   f32 x = 0.06f;
   
	while(device->run())
   {
      driver->beginScene(true, true, video::SColor(255,100,101,140));
      
      light->setPosition(core::vector3df(x,0,0)+light->getPosition());
      if(light->getPosition().X > 17.0f) x = -0.06f;
      if(light->getPosition().X < -5.0f) x = 0.06f;
      
		smgr->drawAll();

		driver->endScene();
   }
   device->drop();

   return 0;
}
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

ok, got it.

i need time to figure this out.

let me get back to you sometime later, ok?
Image
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Hmm, it turns out this guy (living in dubai uae) who volunteered to write the parser/interpreter written in lex/yacc for the procedural building submitted his first code submission. I need to review this code and write a reply to him and that will take days. after that, i'll be writing more specs for him to code for.

please pardon the delay, i don't want to lose this great guy, he's pretty good in c/c++ writing yacc parsers.

i'll catch up with you later.
Image
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Ok, I'm back.

I'll be working on this sometime late night later, I have to meet a study-buddy and continue on the OpenGL project we're working on, he's setting-up the transform matrix without the matrix lib, which is really bordering on insanity. I've pulled a lot of hair on this already.

Anyway, I'm hoping this book ( http://www.amazon.com/Physics-Developme ... 012369471X ) will be a lot of help.
Image
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Hey thats a great discovery, nice work arras :D
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

just got home, at 3:00AM. six hours of matrix math coding. that was a huge debate about 4x4 matrices and vectors that have four elements. anyway, we settled on using 4 instead of 3. 32 bit floats for textures.

i did some test on the code you posted above, i'll add more code it and see if you have any comments.

see ya later.
Image
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Thanks Blindside :)

dlangdev >> I did some research meanwhile about attenuation and fog. I also did some optimizations to my code. Here are results so far:

Code: Select all

// fragment shader common for all vertex shaders belove

void main()
{
	gl_FragColor = gl_Color;
}
Per vertex point light model with ambient, diffuse, specular and attenuation:

Code: Select all

// point light vertex shader

void main()
{
	
	vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
	vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
   vec3 lightVector = gl_LightSource[0].position.xyz - position;
   float distance = length(lightVector);
   lightVector = normalize(lightVector);
	
	// ambient color
	gl_FrontColor = gl_FrontLightProduct[0].ambient;
   
	float difusePower = max(0.0, dot(normal, lightVector));
	
	if(difusePower != 0)
	{
      // diffuse color
      gl_FrontColor += gl_FrontLightProduct[0].diffuse * difusePower;
      
      // specular color
      vec3 cameraVector = normalize(-position);
      vec3 halfVector = normalize(lightVector + cameraVector);
      float specularPower = max( 0.0, dot(normal, halfVector) );
      if(specularPower != 0)
      {
         specularPower = pow( specularPower, gl_FrontMaterial.shininess );
         gl_FrontColor += gl_FrontLightProduct[0].specular * specularPower;
      }
   }
	
   // attentuation
   float attentuation = 1.0 / (gl_LightSource[0].constantAttenuation +
                               gl_LightSource[0].linearAttenuation * distance +
                               gl_LightSource[0].quadraticAttenuation * distance * distance);
   
   // final color
   gl_FrontColor = gl_FrontColor * attentuation + gl_FrontLightModelProduct.sceneColor;

	gl_Position = ftransform();
}
Per vertex directional light complete with ambient, diffuse, specular and attenuation:

Code: Select all

// directional light vertex shader

void main()
{
	vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
   vec3 lightVector = gl_LightSource[0].position.xyz;
   float distance = length(lightVector);
   lightVector = normalize(lightVector);
	
	// ambient color
	gl_FrontColor = gl_FrontLightProduct[0].ambient;
   
   // diffuse color
	float difusePower = max(0.0, dot(normal, lightVector));
	
	if(difusePower != 0)
	{
      gl_FrontColor += gl_FrontLightProduct[0].diffuse * difusePower;
      
      // specular color
      vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
      vec3 cameraVector = normalize(-position);
      vec3 halfVector = normalize(lightVector + cameraVector);
      float specularPower = max( 0.0, dot(normal, halfVector) );
      
      if(specularPower != 0)
      {
         specularPower = pow( specularPower, gl_FrontMaterial.shininess );
         gl_FrontColor += gl_FrontLightProduct[0].specular * specularPower;
      }
   }
   
   // attentuation
   float attentuation = 1.0 / (gl_LightSource[0].constantAttenuation +
                               gl_LightSource[0].linearAttenuation * distance +
                               gl_LightSource[0].quadraticAttenuation * distance * distance);
   
   // final color
   gl_FrontColor = gl_FrontColor * attentuation + gl_FrontLightModelProduct.sceneColor;

	gl_Position = ftransform();
}
Per vertex spot light with ambient, diffuse, specular and attenuation:

Code: Select all

// spot light vertex shader

void main()
{
	
	vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
	vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
   vec3 lightVector = gl_LightSource[0].position.xyz - position;
   float distance = length(lightVector);
   lightVector = normalize(lightVector);
	
	// ambient color
	gl_FrontColor = gl_FrontLightProduct[0].ambient;
   
   // diffuse color
	float difusePower = max(0.0, dot(normal, lightVector));
	
	if(difusePower != 0.0)
	{
      float spotEffect = dot( normalize(gl_LightSource[0].spotDirection), -lightVector );
      if (spotEffect > gl_LightSource[0].spotCosCutoff)
		{
         spotEffect = pow(spotEffect, gl_LightSource[0].spotExponent);
         gl_FrontColor += gl_FrontLightProduct[0].diffuse * difusePower * spotEffect;

         // specular color
         vec3 cameraVector = normalize(-position);
         vec3 halfVector = normalize(lightVector + cameraVector);
         float specularPower = max( 0.0, dot(normal, halfVector) );
         if(specularPower != 0)
         {
            specularPower = pow( specularPower, gl_FrontMaterial.shininess );
            gl_FrontColor += gl_FrontLightProduct[0].specular * specularPower * spotEffect;
         }
      }
   }
   
   // attentuation
   float attentuation = 1.0 / (gl_LightSource[0].constantAttenuation +
                               gl_LightSource[0].linearAttenuation * distance +
                               gl_LightSource[0].quadraticAttenuation * distance * distance);
   
   // final color
   gl_FrontColor = gl_FrontColor * attentuation + gl_FrontLightModelProduct.sceneColor;

	gl_Position = ftransform();
}
Linear fog:

Code: Select all

// linear fog vertex shader

void main()
{
   gl_Position = ftransform();
   
   vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
   //float distance = length(position); // distance based
   float distance = position.z; // standard Irrlicht
   
   float fogFactor = (gl_Fog.end - distance) / (gl_Fog.end - gl_Fog.start);
   fogFactor = clamp(fogFactor, 0.0, 1.0);
   
   gl_FrontColor = gl_Color;
   gl_FrontColor = mix(gl_Fog.color, gl_FrontColor, fogFactor );
}
Exponential fog (this one is not working exactly the same as Irrlicht fog ...if somebody can find the better formula, please let me know):

Code: Select all

// exponential fog vertex shader

void main()
{
   gl_Position = ftransform();
   
   vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
   float distance = length(position);
   
   const float LOG2 = 1.442695;
   float fogFactor = exp2(-gl_Fog.density * gl_Fog.density * distance * distance * LOG2);
   fogFactor = clamp(fogFactor, 0.0, 1.0);
   
   gl_FrontColor = gl_Color;
   gl_FrontColor = mix(gl_Fog.color, gl_FrontColor, fogFactor );
}
Does somebody know what gl_fog.scale is?
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Currently I am working on multi lighting. I am trying to pass lights number and type in to shader.
BlindSide, you did mention some problems ATI cards have with arrays. I have ATI card myself and was unable to pass array in to shader, which complicate things a bit. Do you know more about that problem?

Here is code:

vertex shader:

Code: Select all

uniform int LightsCount;
uniform int LightType0, LightType1, LightType2, LightType3, LightType4,
   LightType5, LightType6, LightType7;

void main()
{
   int LightType[8] = int[](LightType0, LightType1, LightType2, LightType3,
      LightType4, LightType5, LightType6, LightType7);

   gl_FrontColor = gl_Color;
	gl_Position = ftransform();
}
pixel shader:

Code: Select all

void main()
{
	gl_FragColor = gl_Color;
}
ShaderCallBack code:

Code: Select all

class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:

   virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
   {
      video::IVideoDriver* driver = Device->getVideoDriver();

      u32 LightsCount = (u32)driver->getDynamicLightCount();
      services->setVertexShaderConstant("LightsCount", (f32*)&LightsCount, 1);

      u32 LightType;
      for(u32 i=0; i<LightsCount; i++)
      {
      	LightType = (u32)Device->getVideoDriver()->getDynamicLight(i).Type;
      	core::stringc str("LightType");
      	str += i;
      	services->setVertexShaderConstant(str.c_str(), (f32*)&LightType, 1);
      }
   }
};
It does slow things down a little bit. I have found different approach somewhere on net. One which determined light type on its attributes (cone angle, possition ect...). I must test it if it would not be more efficient.

Any ideas are welcome.
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Just have found that gl_Fog.scale = 1.0 / (gl_Fog.end - gl_Fog.start) and is precomputed.

So here is code for both linear and exponential fog in per vertex and per pixel versions:

Code: Select all

// linear fog vertex shader

// per vertex linear fog
void main()
{
   gl_Position = ftransform();

   vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
   float fogPower = max(0.0, (gl_Fog.end - position.z) * gl_Fog.scale);

   gl_FrontColor = mix(gl_Fog.color,gl_Color, fogPower);
}

// per pixel linear fog
void main()
{
   gl_Position = ftransform();

   vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
   gl_FogFragCoord = position.z;

   gl_FrontColor = gl_Color;
}

Code: Select all

// linear fog fragment shader

// per vertex linear fog
void main()
{
   gl_FragColor = gl_Color;
}

// per pixel linear fog
void main()
{
   float fogPower = max(0.0, (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale);
   gl_FragColor = mix(gl_Fog.color,gl_Color, fogPower);
}

Code: Select all

// exponential fog vertex shader

// per vertex exponential fog
void main()
{
   gl_Position = ftransform();

   vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
   const float LOG2E = 1.442695;
   float fogPower = exp2(-gl_Fog.density * position.z * LOG2E);

   gl_FrontColor = mix(gl_Fog.color,gl_Color, fogPower);
}

// per pixel exponential fog
varying float FDxLOG2E;

void main()
{
   gl_Position = ftransform();

   const float LOG2E = 1.442695;
   FDxLOG2E = -gl_Fog.density * LOG2E; // precompuing it for fragment shader
   vec3 position = vec3(gl_ModelViewMatrix * gl_Vertex);
   gl_FogFragCoord = position.z;

   gl_FrontColor = gl_Color;
}

Code: Select all

// exponential fog fragment shader

// per vertex exponential fog
void main()
{
   gl_FragColor = gl_Color;
}

// per pixel exponential fog
varying float FDxLOG2E;

void main()
{
   float fogPower = exp2(FDxLOG2E * gl_FogFragCoord);

   gl_FragColor = mix(gl_Fog.color,gl_Color, fogPower);
}
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Is it defined what this variable returns if fog is disabled?
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Post Reply