Skip to content
Li, Xizhi edited this page Jul 18, 2018 · 11 revisions

3D Scene

There are a number of 3D objects which one can create via scripting API, such as mesh, physics mesh, skybox, camera, biped character, light, particles, containers, overlays, heightmap terrain, blocks, animations, shaders, 3D assets, etc.

Triangle Limitations

One can set the maximum number of total triangles of animated characters in the 3d scene per frame, like below

ParaScene.GetAttributeObject():SetField("MaxCharTriangles", 150000);

Faraway objects exceeding this value will be skipped during rendering. Another way of reducing triangle count is via level-of-detail (LOD) when loading mesh or characters. Currently, one must manually provide all LOD of mesh when loading a 3d file.

Rendering Pipeline

Currently, all fixed function, shaders, and deferred shading share the same predefined rendering pipelines. The render order can be partially affected by RenderImportance, RenderOrder, several Shader files property. But in general, it is a fixed general purpose rendering pipeline suitable in most situations.

The source code of the pipeline is hard-coded in SceneObject.cpp's AdvanceScene() function.

Here is what it does:

For each active viewport, we do the following:

  • traverse the scene and quad-tree tile manager and call PrepareRender() for each visible scene object, which will insert the object into a number of predefined global render queues.
  • PIPELINE_3D_SCENE
    • draw MiniSceneGraph with local cameras and render into textures
    • draw owner-draw objects like render targets.
    • draw all m_mirrorSurfaces into local textures
    • tesselate global terrain according to current camera
    • render shadow map for shadow casters queue, and other global object like blocks that cast shadows.
    • draw block engine multiframe world texture
    • render global terrain
    • draw opaque blocks in block engine
    • draw alpha-test enabled blocks in block engine
    • draw static meshes in big mesh queue from front to back
    • draw static meshes in small mesh queue from back to front
    • draw sprite objects queue
    • draw animated characters queue
    • render selection queue
    • render current sky object
    • draw block engine multiframe world texture on sky
    • draw missile object queue
    • draw block engine water reflection pass
    • block engine deferred shading post processing for opaque objects
    • draw batched transparent particles
    • block engine draw all alpha blended blocks
    • draw transparent animated characters in transparent biped queue
    • block engine deferred shading post processing for alpha blended object
    • draw block engine deferred lights
    • draw all head-on display
    • draw simulated global ocean surface
    • draw transparent static mesh objects in transparent mesh queue
    • draw transparent triangle face groups
    • draw objects in post render queue
    • draw particle systems
    • invoke custom post rendering shaders in NPL script for 3d scene
    • draw water waves
    • draw helpers for physics world debugging
    • draw helpers for bounding boxes of scene objects
    • draw portal system
    • draw overlays
  • PIPELINE_UI
    • render all visible GUI objects by traversing the GUIRoot object.
  • PIPELINE_POST_UI_3D_SCENE
    • only MiniSceneGraph whose GetRenderPipelineOrder() == PIPELINE_POST_UI_3D_SCENE will be rendered in this pipeline
  • PIPELINE_COLOR_PICKING

Pipeline customization

  • RenderImportance property of ParaObject only affects render order in a given queue.
  • RenderOrder property of ParaObject will affect which queue the object goes into, as well as the order inside the queue. However, only RenderOrder>100 is used to insert objects to post render queue.

For example, the following code will ensure the two objects are rendered last and ztest is disabled.

	local asset = ParaAsset.LoadStaticMesh("","model/common/editor/z.x")
	local obj = ParaScene.CreateMeshPhysicsObject("blueprint_center", asset, 1,1,1, false, "1,0,0,0,1,0,0,0,1,0,0,0");
	obj:SetPosition(ParaScene.GetPlayer():GetPosition());
	obj:SetField("progress",1);
	obj:GetEffectParamBlock():SetBoolean("ztest", false);
	obj:SetField("RenderOrder", 101)
	ParaScene.Attach(obj);

	local player = ParaScene.CreateCharacter ("MyPlayer1", ParaAsset.LoadParaX("","character/v3/Elf/Female/ElfFemale.x"), "", true, 0.35, 0, 1.0);
	local x,y,z = ParaScene.GetPlayer():GetPosition()
	player:SetPosition(x+1,y,z);
	player:SetField("RenderOrder", 100)
	player:GetEffectParamBlock():SetBoolean("ztest", false);
	ParaScene.Attach(player);

Mouse Ray Picking

Use ParaScene.MousePick.

/**
* Pick scene object at the current mouse cursor position. 
* pick the smallest intersected object which is un-occluded by any objects. Object A is considered occluded by object B only if 
* (1) both A and B intersect with the hit ray. 
* (2) both A and B do not intersect with each other. 
* (3) B is in front of A, with regard to the ray origin.
* 
* this function will ray-pick any loaded scene object(biped & mesh, but excluding the terrain) using their oriented bounding box. 
* a filter function may be provided to further filter selected object. 
* this function will transform all objects to the near-camera coordinate system. 
* This will remove some floating point inaccuracy near the camera position. Hence this function is most suitable for 
* testing object near the camera eye position. This function does not rely on the physics engine to perform ray-picking. 
* @param x: screen position relative to the render target. 
* @param y: screen position relative to the render target. 
* @params fMaxDistance: the longest distance from the ray origin to check for collision. If the value is 0 or negative, the view culling radius is used 
*	as the fMaxDistance.
* @param sFnctFilter: it can be any of the following string or a number string
* "mesh": mesh any mesh object in the scene. Usually for selection during scene editing.
* "cmesh": mesh object that is clickable (associated with scripts). Usually for game playing.
* "notplayer": any object in the scene except for the current player. Usually for selection during scene editing.
* "": any object in the scene except. Usually for selection during scene editing.
* "light": only pick light objects
* "biped": any character objects :local or global.
* "anyobject": any objects, including mesh and characters. but not including helper objects, such as light.
* "global": all global objects, such as global character and mesh. This is usually for game mode.
* "point": the returned object is invalid if there no collision with any physics faces. otherwise, one can use GetPosition function of the returned object to retrieve the intersection point.
* "terrain":  pick a point on the global terrain only.
* "walkpoint":  pick a point on the global terrain or any physical object with camera obstruction attribute set to true. 
* "actionmesh": mesh with action script. 
* number: if it is a number, it is treated as a 32 bitwise DWORD filter code. see SetPickingFilter() for more example. 
* @return :the scene object. if the object is invalid, it means that the ray has hit nothing.
*/
ParaObject MousePick(float x, float y, float fMaxDistance, const char* sFilterFunc);

3D Object

All 3D object interface is exposed via ParaObject interface in NPL. One can access almost all C++ properties via GetField() and SetField() method. They are just short-cuts to ParaObject:GetAttributeObject():GetField()

3D Object Rendering

In NPL, one can change the appearance of 3d object, using replaceable textures, attachment point, primary asset file and primary effect file.

To change a user defined shader parameter in NPL, use GetEffectParamBlock

local params = obj:GetEffectParamBlock();
params:SetFloat("g_opacity", 1);

To manually animate 3d object

obj:SetField("AnimFrame", 33);
obj:SetField("IsAnimPaused", true);
Clone this wiki locally