This page has been translated automatically.
UnigineEditor
Interface Overview
Assets Workflow
Settings and Preferences
Working With Projects
Adjusting Node Parameters
Setting Up Materials
Setting Up Properties
Landscape Tool
Using Editor Tools for Specific Tasks
Extending Editor Functionality
Programming
Fundamentals
Setting Up Development Environment
Usage Examples
UnigineScript
C++
C#
UUSL (Unified UNIGINE Shader Language)
File Formats
Rebuilding the Engine Tools
GUI
Double Precision Coordinates
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
Warning! This version of documentation is OUTDATED, as it describes an older SDK version! Please switch to the documentation for the latest SDK version.
Warning! This version of documentation describes an old SDK version which is no longer supported! Please upgrade to the latest SDK version.

4. Creating and Setting up Light Sources

Warning
The scope of applications for UnigineScript is limited to implementing materials-related logic (material expressions, scriptable materials, brush materials). Do not use UnigineScript as a language for application logic, please consider C#/C++ instead, as these APIs are the preferred ones. Availability of new Engine features in UnigineScipt (beyond its scope of applications) is not guaranteed, as the current level of support assumes only fixing critical issues.

<< RETURN TO THE PREVIOUS SECTION

Lighting is the basis of every scene defining colors and final look of your objects. Lights in UNIGINE are created the same way as all nodes.

Let us consider creation of a world light source as an example:

Source code (UnigineScript)
#include <core/unigine.h>

int init() {
	// creating a world light source an setting its color to white
	LightWorld thesun = new LightWorld(vec4(1.0f, 1.0f, 1.0f, 1.0f));
	
	// setting light source's parameters (intensity, disable angle, scattering type, name and rotation)
	thesun.setName("Sun");
	thesun.setDisableAngle(90.0f);
	thesun.setIntensity(1.0f);
	thesun.setScattering(LIGHT_WORLD_SCATTERING_SUN);
	thesun.setWorldRotation(quat(86.0f, 30.0f, 300.0f));

	return 1;
}

Additional information:

Project Progress#

In our project we are going to use three different light sources: LightWorld, LightOmni and LightProj. To create them let us write a method called initLights.

In the AppWorldLogic.h file, we include the UnigineLights.h library, define smart pointers for the light sources and declare our initLights method.

Source code (C++)
// AppWorldLogic.h
/* ... */
#include <UnigineLights.h>

/* ... */

class AppWorldLogic : public Unigine::WorldLogic {
	
public:

/* .. */

private:

/* .. */

	int initLights();
	
/* .. */

	// light sources
	Unigine::LightWorldPtr thesun;
	Unigine::LightOmniPtr light_omni;
	Unigine::LightProjPtr projector;
	
/* .. */
};

In the AppWorldLogic.cpp file let us implement our initLights method and insert it into the AppWorldLogic::init() method.

Source code (C++)
// AppWorldLogic.cpp

/* .. */
	
/// method performing initialization of lights
int AppWorldLogic::initLights()
{
	// creating an omni light and setting up its parameters
	light_omni = LightOmni::create(Math::vec4(1.0f, 1.0f, 1.0f, 1.0f), 10.0f, "");
	light_omni->setWorldPosition(Math::Vec3(0.0f, 0.0f, 5.0f));
	light_omni->setIntensity(0.1f);

	// reporting progress to the console
	Log::message("-> Created a %s light source.\n", light_omni->getName());

	// creating a world light and setting up its parameters
	thesun = LightWorld::create(Math::vec4(1.0f, 1.0f, 1.0f, 1.0f));
	thesun->setName("Sun");
	thesun->setDisableAngle(90.0f);
	thesun->setIntensity(1.0f);
	thesun->setScattering(LightWorld::SCATTERING_SUN);
	thesun->setWorldRotation(Math::quat(86.0f, 30.0f, 300.0f));

	// reporting progress to the console
	Log::message("-> Created a %s light source.\n", thesun->getName());

	// creating a proj light and setting up its parameters
	projector = LightProj::create(Math::vec4(1.0f, 1.0f, 0.5f, 1.0f), 10.0f, 60.0f, "");
	projector->setWorldPosition(Math::Vec3(2.5f, 2.5f, 3.0f));
	projector->setName("projector");
	projector->setRotation(Math::quat(-45.0f, 45.0f, 0.0f));
	projector->setPenumbra(0.425f);
	projector->setIntensity(1.0f);

	// reporting progress to the console
	Log::message("-> Created a %s light source.\n", projector->getName());
	Log::warning("Light initialization OK!\n");

	return 1;
}

/* .. */
	
int AppWorldLogic::init() 
{

/* .. */

	// creating lights
	initLights();

/* .. */
	
	return 1;
}
/* .. */

Source Files

You can copy the code below and paste it to the corresponding source files of your project:

AppWorldLogic.h

Source code (C++)
#ifndef __APP_WORLD_LOGIC_H__
#define __APP_WORLD_LOGIC_H__

#include <UnigineLogic.h>
#include <UnigineStreams.h>
#include <UnigineObjects.h>
#include <UnigineGame.h>
#include <UnigineLights.h>

using namespace Unigine;

class AppWorldLogic : public WorldLogic {

public:
	AppWorldLogic();
	virtual ~AppWorldLogic();

	virtual int init();

	virtual int update();
	virtual int postUpdate();
	virtual int updatePhysics();

	virtual int shutdown();

	virtual int save(const StreamPtr &stream);
	virtual int restore(const StreamPtr &stream);
private:
	PlayerSpectatorPtr player;

	// pointers to light sources
	LightWorldPtr thesun;
	LightOmniPtr light_omni;
	LightProjPtr projector;
	
	// auxiliary functions
	int addMeshToScene(const char *file_name, const char *mesh_name, const char *material_name, Math::Vec3 position);

	// initialization functions
	int initObjects();
	int initPlayer();
	int initLights();

	// scene objects vector
	Vector <ObjectMeshDynamicPtr> Objects;
};

#endif // __APP_WORLD_LOGIC_H__

AppWorldLogic.cpp

Source code (C++)
#include "AppWorldLogic.h"
// World logic, it takes effect only when the world is loaded.
// These methods are called right after corresponding world script's (UnigineScript) methods.
//-----------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------- AUXILIARY FUNCTIONS AND METHODS ----------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------

/// method adding a Dynamic Mesh Object to the scene. If an empty filename is passed the method creates a default box; otherwise, loads a mesh-file with a given name.
int AppWorldLogic::addMeshToScene(const char *file_name, const char *mesh_name, const char *material_name, Math::Vec3 position)
{
	MeshPtr mesh = Mesh::create();
	ObjectMeshDynamicPtr omd;
	if (file_name) {				// loading a mesh from a specified file
		if (!mesh->load(file_name))
		{
			Log::error("\nError opening .mesh file!\n");
			mesh.clear();

			return 0;
		}
		else omd = ObjectMeshDynamic::create(mesh);
	}
	else																// creating a default box
	{
		mesh->addBoxSurface("box_surface", Math::vec3(0.5f));

		omd = ObjectMeshDynamic::create(mesh);
	}

	// setting node material, name and position
	omd->setMaterial(material_name, "*");
	omd->setName(mesh_name);
	omd->setWorldPosition(position);

	// updating the list of scene objects
	Objects.append(omd);

	// reporting progress to the console
	Log::message("-> Object %s added to the scene.\n", mesh_name);

	// clearing the mesh
	mesh.clear();

	return 1;

}
//-----------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------- INITIALIZATION METHODS -------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------
/// method performing initialization of the set of 4 boxes
int AppWorldLogic::initObjects()
{
	int index = 0;

	for (int x = 0; x < 2; x++)
	{
		for (int y = 0; y < 2; y++)
		{
			addMeshToScene(NULL, String::format("my_meshdynamic_%d", index), "mesh_base", Math::Vec3(x, y, 1.0f));
			index++;
		}
	}

	// reporting progress to the console
	Log::warning("Objects generation OK!\n\n");

	return 1;
}
//-----------------------------------------------------------------------------------------------------------------------------
/// method performing initialization of the player
int AppWorldLogic::initPlayer()
{
	// creating a new PlayerSpectator instance
	player = PlayerSpectator::create();

	// setting player's FOV, ZNear, ZFar
	player->setFov(90.0f);
	player->setZNear(0.1f);
	player->setZFar(10000.0f);

	// setting player's view direction vector and position
	player->setPosition(Math::Vec3(3.0f));
	player->setDirection(Math::vec3(-1.0f), Math::vec3(0.0f, 0.0f, -1.0f));

	// setting the player as a default one via the Game singleton instance
	Game::setPlayer(player);

	// reporting progress to the console
	Log::warning("\nPlayer initialization OK!\n\n");

	return 1;
}
//-----------------------------------------------------------------------------------------------------------------------------
/// method performing initialization of lights
int AppWorldLogic::initLights()
{
	// creating an omni light and setting up its parameters
	light_omni = LightOmni::create(Math::vec4(1.0f, 1.0f, 1.0f, 1.0f), 10.0f, "");
	light_omni->setWorldPosition(Math::Vec3(0.0f, 0.0f, 5.0f));
	light_omni->setIntensity(0.1f);

	// reporting progress to the console
	Log::message("-> Created a %s light source.\n", light_omni->getName());

	// creating a world light and setting up its parameters
	thesun = LightWorld::create(Math::vec4(1.0f));
	thesun->setName("Sun");
	thesun->setDisableAngle(90.0f);
	thesun->setIntensity(1.0f);
	thesun->setScattering(LightWorld::SCATTERING_SUN);
	thesun->setWorldRotation(Math::quat(0.0f, 1.0f, 0.0f, 0.0f));

	// reporting progress to the console
	Log::message("-> Created a %s light source.\n", thesun->getName());

	// creating a proj light and setting up its parameters
	projector = LightProj::create(Math::vec4(1.0f, 1.0f, 0.5f, 1.0f), 10.0f, 60.0f, "");
	projector->setWorldPosition(Math::Vec3(2.5f, 2.5f, 3.0f));
	projector->setName("projector");
	projector->setRotation(Math::quat(-45.0f, 45.0f, 0.0f));
	projector->setPenumbra(0.425f);
	projector->setIntensity(1.0f);

	// reporting progress to the console
	Log::message("-> Created a %s light source.\n", projector->getName());
	Log::warning("Lights initialization OK!\n");

	return 1;
}
//-----------------------------------------------------------------------------------------------------------------------------
AppWorldLogic::AppWorldLogic() {

}

AppWorldLogic::~AppWorldLogic() {

}

int AppWorldLogic::init() {
	// Write here code to be called on world initialization: initialize resources for your world scene during the world start.

	// creating objects
	initObjects();

	// creating a player
	initPlayer();

	// creating lights
	initLights();

	return 1;
}

// start of the main loop
int AppWorldLogic::update() {
	// Write here code to be called before updating each render frame: specify all graphics-related functions you want to be called every frame while your application executes.

	return 1;
}

int AppWorldLogic::postUpdate() {
	// The engine calls this function before rendering each render frame: correct behavior after the state of the node has been updated.

	return 1;
}

int AppWorldLogic::updatePhysics() {
	// Write here code to be called before updating each physics frame: control physics in your application and put non-rendering calculations.
	// The engine calls updatePhysics() with the fixed rate (60 times per second by default) regardless of the FPS value.
	// WARNING: do not create, delete or change transformations of nodes here, because rendering is already in progress.

	return 1;
}
// end of the main loop

int AppWorldLogic::shutdown() {
	// Write here code to be called on world shutdown: delete resources that were created during world script execution to avoid memory leaks.

	// deleting all created nodes
	for (int i = 0; i < Objects.size(); i++)
	{
		// removing current node from the scene
		Objects[i]->deleteLater();
	}

	// updating the list of scene objects
	Objects.clear();

	// clearing the player pointer
	player->deleteLater();

	// clearing light sources
	thesun->deleteLater();
	light_omni->deleteLater();
	projector->deleteLater();


	return 1;
}

int AppWorldLogic::save(const StreamPtr &stream) {
	// Write here code to be called when the world is saving its state (i.e. state_save is called): save custom user data to a file.

	UNIGINE_UNUSED(stream);
	return 1;
}

int AppWorldLogic::restore(const StreamPtr &stream) {
	// Write here code to be called when the world is restoring its state (i.e. state_restore is called): restore custom user data to a file here.

	UNIGINE_UNUSED(stream);
	return 1;
}


PROCEED TO THE NEXT SECTION >>

Last update: 2020-07-31
Build: ()