In this tutorial we will be using the Maya camera from the Cameras tutorial. Note that this tutorial does not cover volumetric lighting using GB.Scene.VolumeLightSceneNode or creating shadows using GB.Scene.ShadowVolumeSceneNode. The following topics are covered:
The tutorial's code files and media files are installed along with Ginjo-Builder and can be accessed from the 'Project' window that is shown when the editor starts. This tutorial is called '05_Lights' in the 'Tutorials' tab.
First we create a project and compiler options XML file. (See Render loop for a more detailed description of creating a project.)
Open "Lights.xml" and just like in Render loop add the <exe> and <startup> elements. We will also import the GB namespace so we don't have to type it out every time. (For the full list of XML tags see Compiler options.)
<?xml version="1.0" encoding="utf-8"?> <root> <exe path=".\game.exe" /> <startup name="scenelighting.main" /> <ImportSymbols> <namespace name="GB" /> </ImportSymbols> </root>
In our XML file we specified the startup function as "scenelighting.main". Double-click on "scenelighting.gbc" in the project tree to open it, and add the "main" function from the Cameras tutorial and use the Maya camera so that the camera moves based on the mouse movement. As in the previous tutorial we initialize the Irrlicht engine, add the drone model and the render loop. However, this time around we comment out the line where we set the Lighting material flag of the model to false.
function main(var:string cmdArgs[]) returns Int32 { var:gb.IrrlichtCreationParameters options=new gb.IrrlichtCreationParameters() //Without anti-aliasing our model edges would be jagged options.AntiAliasing=255 //Tell Irrlicht to use OpenGL for graphics options.DriverType=gb.video.DriverType.OpenGL //Turn off logging, we won't be using it for now options.LoggingLevel=gb.LogLevel.None var:gb.IrrlichtDevice engine = gb.IrrlichtDevice.CreateDevice(options) //Also set our window's title engine.SetWindowCaption('Lighting the scene') var:video.VideoDriver driver=engine.VideoDriver var:Scene.SceneManager smgr=engine.SceneManager //add camera var:core.Vector3Df position=new gb.core.Vector3Df(0, 60, -180) var:core.Vector3Df lookat=new gb.core.Vector3Df(10, 10, 0) var:CameraSceneNode camera = smgr.AddCameraSceneNodeMaya() camera.Position=position camera.Target=lookat //load model from relative path ..\media\GlobalHawk.obj var:scene.Mesh drone = smgr.GetMesh('..\media\GlobalHawk.obj') //add model to scene var:Scene.MeshSceneNode droneNode = smgr.AddMeshSceneNode(drone) if(!isNull(droneNode)){ droneNode.Position=new gb.core.Vector3Df(0, 0, 0) droneNode.Rotation=new gb.core.Vector3Df(0, 45, 0) droneNode.Scale=new gb.core.Vector3Df(0.2, 0.2, 0.2) //THIS LINE COMMENTED OUT: //droneNode.SetMaterialFlag(gb.video.MaterialFlag.Lighting, false) } var:video.Color background=new video.Color(160, 160, 160) while (engine.Run()){ driver.BeginScene(video.ClearBufferFlag.All, background) smgr.DrawAll() driver.EndScene() } }
When you run the program you will now see a completely black model:
Global illumination in Irrlicht is accomplished with ambient lighting. An ambient light source models how light can be scattered or reflected many times producing a uniform lighting effect. It is a fixed-intensity and fixed-color light source that affects all objects in the scene equally. Upon rendering, all objects in the scene are brightened with the specified intensity and color. To add ambient light to the scenes specify the scene managers ambient light property using GB.Scene.SceneManager.AmbientLight:
smgr.AmbientLight=new gb.video.Colorf(0.96, 0.96, 0.96)
Note that you can use the IntelliDoc Symbol Info feature to look-up symbol types and definitions. The 'lightbulb' button on the toolbar looks-up the symbol type for the current cursor location and displays it in a tooltip. Pressing F1 also shows the tooltip.
Now when you run the program you will see a completely black model just like before. Materials in the real world do not reflect light uniformly, and the Irrlicht engine takes that into account. We need to specify how the model's materials reflect light. Modify to drones block of code as follows:
if(!isNull(droneNode)){ droneNode.Position=new gb.core.Vector3Df(0, 0, 0) droneNode.Rotation=new gb.core.Vector3Df(0, 45, 0) droneNode.Scale=new gb.core.Vector3Df(0.2, 0.2, 0.2) for(var:Int32 i=0; i<droneNode.MaterialCount; i+=1){ droneNode.GetMaterial(i).AmbientColor=new gb.video.Color(255,255,255) } }
Now when you run the program you should see the model.
The GB.Scene.LightSceneNode supports three types of lights: point, directional and spot lights. We will discuss each in turn, but first we need to modify how much of the ambient light is reflected by the model's materials. In the previous section we set it to reflect completely. However, we need to lower the reflective color, otherwise the model is fully illuminated and we won't see the effects of the light source we are going to add. Change the line that sets the ambient color of the model's materials to the following:
droneNode.GetMaterial(i).AmbientColor=new gb.video.Color(220,220,220)
The default light type for the GB.Scene.LightSceneNode is Video.LightType.Point. A LightSceneNode can be configured using it's LightData property. However, in this tutorial we will be using the default settings for the most part.
A point light produces light in all directions, thus the Rotation and Direction values of the LightData property are meaningless. Add the following lines of code after the drone's code, but before the render loop:
var:scene.LightSceneNode light=smgr.AddLightSceneNode(droneNode, new core.Vector3Df(100)) light.LightType=gb.video.LightType.Point light.LightData.DiffuseColor=new video.Colorf(0.96, 0.96, 0.96, 0.6) light.Radius=70
When you run the program you should see that the light, which is at position core.Vector3Df(100) relative to the drone illuminates the model. Rotate the model by holding down the left mouse button and moving the mouse. Try changing the Radius of the light to 1 and run the program again.
A directional light illuminates all objects equally from a given direction, like an area light of infinite size and infinite distance from the scene. The direction of the light can be changed using the Rotation property. Replace the point light code with the following:
var:scene.LightSceneNode light=smgr.AddLightSceneNode(droneNode, new core.Vector3Df(100)) light.LightType=gb.video.LightType.Directional light.LightData.DiffuseColor=new video.Colorf(0.96, 0.96, 0.96, 0.6) light.Rotation=new core.Vector3Df(100)
Light from a spotlight originates from a single point and spreads outward in a cone shape in a given direction. The direction of a spotlight is calculated from its rotation. Spot lights have a bright inner cone and a larger outer cone (both defined by an angle), with the brightness of the light decreasing gradually from the inner cone to the outer cone. Replace the previously added lighting code with the following:
var:scene.LightSceneNode light=smgr.AddLightSceneNode(droneNode, new core.Vector3Df(200,200,100)) light.LightType=gb.video.LightType.Spot light.LightData.DiffuseColor=new video.Colorf(0.4, 0, 0, 0.1) light.Rotation=new core.Vector3Df(0,-140,-300) light.LightData.OuterCone=30 light.LightData.InnerCone=5
When you run the program you should see that the red light, which is at position core.Vector3Df(100) relative to the drone illuminates the model.