Transition-rendering Status Management

Source: Internet
Author: User

Rendering Status Management

(Rendering States Management)

 

 

Contents
1. Basic Ideas
2. Actual Problems
3 rendering script


--------------------------------------------------------------------------------
  
Improving the Performance of 3D graphics programs is a big topic. The optimization of graphics programs can be roughly divided into two major tasks. One is to have a good scenario management program to quickly remove invisible polygon, select the appropriate details based on the distance between the object and the camera. Second, you must have a good rendering program to quickly render the visible polygon sent to the rendering pipeline.
  
We know that when using OpenGL or Direct3D to render a graph, you must first set the rendering status, which is used to control the rendering behavior of the Renderer. Applications can control the rendering behavior of OpenGL or Direct3D by changing the rendering state. For example, set Vertex/Fragment Program, bind texture, enable deep test, and set fog effect.
  
Changing the rendering status is a time-consuming operation for the video card. If you can reasonably manage the rendering status and avoid unnecessary status switching, the graphics program performance will be significantly improved. This article will discuss how to manage rendering states.


1. Basic Ideas
  
We consider a typical game scenario, including people, animals, plants, buildings, transportation tools, and weapons. After a brief analysis, we will find that in fact, many objects are rendered in the same State. For example, the rendering States of all people and animals are the same, and the rendering States of all plants are the same, the same is true for buildings, transportation tools, and weapons. We can group the objects with the same rendering status and render them in groups. For each set of objects, we only need to set the rendering status once before rendering, you can also save the current rendering status. When setting the rendering status, you only need to change the status different from the current status. This greatly reduces unnecessary status switching. The following code snippet demonstrates this method:

// Render state group linked list, filled by the Scenario Management Program
RenderStateGroupList groupList;
// Current rendering status
RenderState curState;

......

// Each group in the recurring list
RenderStateGroup * group = groupList. GetFirst ();
While (group! = NULL)
{
// Set the rendering status of the Group
RenderState * state = group-> GetRenderState ();
State-> ApplyRenderState (curState );

// Object linked list of the rendering status Group
RenderableObjectList * objList = group-> GetRenderableObjectList ();
// Traverse each object in the object linked list
RenderableObject * obj = objList-> GetFirst ();
While (obj! = NULL)
{
// Render object
Obj-> Render ();
Obj = objList-> GetNext ();
}

Group = groupList. GetNext ();
}

The ApplyRenderState method of the RenderState class is shown as follows:

Void RenderState: ApplyRenderState (RenderState & curState)
{
// Deep Test
If (depthTest! = CurState. depthTest)
{
SetDepthTest (depthTest );
CurState. depthTest = depthTest;
}

// Alpha test
If (alphaTest! = CurState. alphaTest)
{
SetAlphaTest (alphaTest );
CurState. alphaTest = alphaTest;
}

// Other rendering statuses
......
}

  
The rendering status of these groups is generally referred to as Material or Shader. Material is different from Vertex/Fragment Program in OpenGL and Vertex/Pixel Shader in Direct3D. It refers to the State required to encapsulate the graphics card rendering graphics (including OpenGL and Direct3D original Material and Shader ).
  
Literally, Material (Material) focuses more on the description of the object's surface appearance attributes, while Shader (which is really difficult to represent in Chinese) controls the meaning of the object's surface appearance using a program. Due to the introduction of the graphics card programmable pipeline, the rendering State contains Vertex/Fragment Program, which can control the rendering of objects. Therefore, I think it is more appropriate to call the encapsulated rendering State Shader. This article is also called the Shader.
  
The above code snippet simply demonstrates the basic idea of rendering state management. In fact, there are many issues to consider when managing rendering state.

 

2. Actual Problems
  
2.1 time consumption problems

  
When the rendering state is changed, the time consumed by different States is not the same, or even the time consumed to change the rendering state under different conditions is different. For example, binding a texture is a very time-consuming operation, and when the texture is already in the texture cache of the video card, the speed will be very fast. With the development of hardware and software, the time consumed by some time-consuming rendering States may be reduced. Therefore, there is no accurate time-consuming data.
  
Although the time consumed cannot be quantified and the time consumed varies, the following State switches consume time:

Vertex/Fragment Program mode and Fixed Pipeline mode switching (FF, Fixed Function Pipeline)

Switch between Vertex/Fragment Program Programs.
Change the Vertex/Fragment Program constant.
Texture switching.
Vertex & Index Buffers switch.
  
Sometimes it is necessary to make a compromise based on the amount of time consumed. This situation will be encountered below.

  
2.2 rendering status classification
  
In actual scenarios, This is often the case where other rendering states of a class of objects are the same, except that the texture and vertex and index data are different. For example, in a scenario, people only have different figures, looks, clothes, and so on. That is to say, only textures, vertices, and index data are different, while other rendering statuses such as Vertex/Fragment Program and deep test are the same. On the contrary, there is generally no situation where the texture is the same as the vertex and index data, while other rendering states are different. We can exclude textures, vertices, and index data from the Shader, so that all people in the scenario can use a Shader for rendering and then group and sort the textures under this Shader, people with the same texture are put together for rendering.

  
Multipass Rendering)
  
Some Complex graphic effects need to be rendered multiple times on low-end graphics cards. One effect is rendered each time, and then merged into the final effect using GL_BLEND. This method is called multi-channel Rendering Multipass Rendering. Rendering once is a pass. For example, to perform pixel-by-pixel concave and convex illumination, You need to calculate the environmental light, diffuse light concave and convex effects, and high-gloss concave and convex effects. Only one pass is required on the NV20 video card, the NV10 video card requires three passes. The Shader should support multi-channel rendering, that is, a Shader should contain the rendering status of each pass.
  
Different pass rendering statuses and textures are often different, while vertices and index data are the same. This brings about a problem: rendering in units of objects, rendering all the pass of an object at a time, and then rendering the next object; or rendering in units of pass, rendering the first pass of all objects for the first time, the second pass for rendering all objects for the second time. The following program section demonstrates the two methods:

  
2.3.1 rendering in objects

// Render state group linked list, filled by the Scenario Management Program
ShaderGroupList groupList;

......

// Each group in the recurring list
ShaderGroup * group = groupList. GetFirst ();
While (group! = NULL)
{
Shader * shader = group-> GetShader ();
RenderableObjectList * objList = group-> GetRenderableObjectList ();

// Traverse each object with the same Shader
RenderableObject * obj = objList-> GetFirst ();
While (obj! = NULL)
{
// Obtain the shader pass count
Int iNumPasses = shader-> GetPassNum ();
For (int I = 0; I <iNumPasses; I ++)
{
// Set the rendering status of shader's I pass
Shader-> ApplyPass (I );
// Render object
Obj-> Render ();
}
Obj = objList-> GetNext ();
}
Group = groupList-> GetNext ();
}

2.3.2 rendering in pass

// Render state group linked list, filled by the Scenario Management Program
ShaderGroupList groupList;

......

For (int I = 0; I <MAX_PASSES_NUM; I ++)
{
// Each group in the recurring list
ShaderGroup * group = groupList. GetFirst ();
While (group! = NULL)
{
Shader * shader = group-> GetShader ();
Int iNumPasses = shader-> GetPassNum ();

// If the number of shader passes is smaller than the number of cycles, Skip This shader
If (I> = iNumPasses)
{
Group = groupList-> GetNext ();
Continue;
}

// Set the rendering status of shader's I pass
Shader-> ApplyPass (I );
RenderableObjectList * objList = group-> GetRenderableObjectList ();

// Traverse each object with the same Shader
RenderableObject * obj = objList-> GetFirst ();
While (obj! = NULL)
{
Obj-> Render ();
Obj = objList-> GetNext ();
}
Group = groupList-> GetNext ();
}
}

  
What are their advantages and disadvantages? Rendering in units of objects. After rendering the first pass of an object, the second pass of the object is immediately rendered. the vertices of each pass are the same as the index data, therefore, after the first pass sends the vertex and index data to the video card, the video card Cache has the vertex and index data of this object, and the subsequent pass does not have to copy the vertex and index data to the video card again, therefore, the speed will be very fast. The problem is that the rendering status of each pass is different, which makes it necessary to set a new rendering status for each rendering, resulting in a large number of redundant rendering status switching.
  
Rendering in pass is exactly the opposite. objects with the same Shader are rendered together in the Shader group. You can set the rendering state only once at the beginning of this set, compared to objects, rendering status switching is greatly reduced. However, each rendered object is different, so it takes a lot of time to copy the vertex and index data of the object to the video card. We can see that if you want to reduce the rendering status switching, You need to copy the vertex index data frequently. If you want to reduce the number of copying the vertex index data, you have to increase the rendering status switching. You cannot have both the fish and the bear's paw. Because the hardware conditions and scenario data are complex, there is no definite formula for which method is more efficient, the method used must be tested in the actual environment before it can be known.

  
More than 2.3 light source Problems
To be continued ......

  
2.4 shadow Problems
To be continued ......

 


3. rendering script
  
Nowadays, many graphics programs define a script file to describe the Shader.
  
For example, the Material script of the earlier OGRE (Object-oriented Graphics Rendering Engine, object-oriented Graphics Rendering Engine), the Shader script of Quake3, and the Effect File of Direct3D, nVIDIA CgFX scripts (File format is compatible with Direct3D Effect File) and ATI RenderMonkey uses xml scripts. The OGRE Material and Quake3 Shader scripts are historical and do not support programmable rendering pipelines. The three new scripts later support the programmable rendering pipeline.

Script feature example
OGRE Material encapsulates various rendering statuses and does not support programmable rendering pipelines >>>
Quake3 Shader encapsulates the rendering status and supports some special effects. It does not support programmable rendering pipelines >>>
Direct3D Effect File encapsulates the rendering status, supports multipass, and supports programmable rendering pipelines >>>
NVIDIA CgFX script encapsulates rendering status, supports multipass, and supports programmable rendering pipelines >>>
The ATI RenderMonkey script encapsulates the rendering status, supports multipass, and supports programmable rendering pipelines >>>

  
Using scripts to control rendering has many advantages:

You can easily modify the appearance of an object without re-writing or compiling the program.
You can use peripheral tools to create and modify script files in WYSIWYG mode (similar to ATI RenderMonkey), so that the artist and level designer can set the object appearance, establish contact between peripheral tools and the graphics engine.
Objects with the same appearance attributes and rendering status (that is, objects with the same Shader) can be grouped for rendering, you only need to set a rendering state for each group of objects before rendering, greatly reducing unnecessary state switching.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.