WebGL State Sorting
31 Mar 2013今天又思考了一下 OpenGL alpha 问题。很早之前就研究过,因为一会儿 Ruby on Rails 一会儿 Node.js,翻来覆去就忘了。
Reducing OpenGL state changes is one of the several ways to optmize the performance. Sorting the objects into categories directly reduced state changes.
Alpha transparency is definitely required in game. This also requires objects sorting. Opaque object must be drawn first, before translucent object.
What order?
- From my understanding first of all, the objects must be transformed using
model view matrix
, into eye coordinates. - Second, because opaque must be drawn before translucent object. Objects must be sorted into 2 categories: opaque and translucent.
- Sort by other states, into categories, e.g., texture id.
- Opaque objects must be sorted into
near to far
order. - Translucent objects must be sorted into
far to near
order.
Of course, z-order is related to the eye position, near means closer to eye.
How to sort?
Here is a simple JavaScript code. Basically, it is a very simple insertion sort.
JavaScript can use Array.sort
.
1 var list = [];
2 var len = 100;
3 for(var i=0; i<len; ++i){
4 var obj = {
5 texture: Math.ceil(Math.random()*4),
6 translucent: Math.random() < 0.5 ? true : false,
7 z: Math.ceil(Math.random() * len)
8 };
9 list[i] = obj;
10 }
11
12 list.sort(sortFunc);
13
14 function sortFunc(a, b){
15 if(a.translucent != b.translucent){
16 if(b.translucent)
17 return 1;
18 else
19 return -1;
20 }
21
22 if(a.texture != b.texture){
23 if(a.texture < b.texture)
24 return 1;
25 else
26 return -1;
27 }
28
29 if(a.z != b.z){
30 if(a.z < b.z)
31 return (a.translucent) ? -1 : 1;
32 else if(a.z == b.z)
33 return 0;
34 else
35 return (!a.translucent) ? -1 : 1;
36 }
37
38 return 0;
39 }
40
41 for(var i=0; i<list.length; ++i){
42 console.dir("translucent: " + list[i].translucent + " texture: " +list[i].texture + " z: " + list[i].z);
43 }
You can view the log result in the developer tool’s console.
This is a very naive code, hopefully it will work in the future proper implementation.
References: