As we are not familiar with many details at the beginning, the following descriptions for the products may be inaccurate.
Both GSPs and ue3 support multi-threaded rendering, that is, there is a separate rendering thread. Of course, they can all be switched through a simple method. GSPs are controlled by the r_multithreaded value, ue3 passes the command line-onethread to disable multi-threaded rendering. In some cases, for example, perfhud must be used for debugging.ProgramYou need to disable multi-threaded rendering. In addition, multi-threaded rendering is enabled by default in the editor and game, while ce prohibits multi-threaded rendering in the editor.
The two methods to implement multi-threaded rendering are command buffering. I think this is the best way to achieve it now, right? In terms of structure, I prefer the ue3 method. ue3 implements rendering commands by encapsulating the derived class of rendercommand, and then uses some column macros, you can easily append new rendering commands without modifying any other places. In contrast, SSPS adopt a relatively old implementation method: command ID, which is somewhat similar to the ID of the message packet sent in online games. Therefore, we can see many switch cases, of course, this is an old design. In addition, another potential benefit of ue3's use of macros to generate a rendering command is that the newly generated rendering command must be at the same position when the main thread sends this command, in this way, we can easily find the initiator of the rendering instruction through ide during debugging. I once had a lot of questions about the existence of this macro, because it will make ourCodeIt is difficult to understand and debug, because the macro-generated code is not well analyzed by every IDE, but now it seems that this method is too wise. In the engine I wrote myself, I used a hand-writing method, so that I often cannot tell who sent this command.
In terms of the overall architecture, ue3 is dominant in this regard. ue3 well handles the relationship between the main thread resources and the rendering resources. For example, the basic rendering unit in ue3 is primitivecomponent, it has a lightweight general scenario in the rendering thread: primitivesceneinfo, and the proxy for rendering different primitivecomponent: primitivesceneproxy; primitivesceneproxy is controlled by primitivesceneinfo. The advantage is that the main thread does not need to care about how the resources of the rendering thread are processed, at least for the upper-layer encoding. For a rendering thread, it does not need to explain anything to the main thread. For example, if the main thread needs to dynamically create a model, the main thread does not need to care about how the rendering thread handles it, the staticmeshactor of the main thread is not required to manage vertexbuffer, indexbuffer, and inputlayout owned by the rendering thread.
In this respect, S3. it is much thinner than ue3. If the main thread in CE needs to create a resource such as texture and VB, you need to first serialize the command to the command buffer, and then wait for the rendering thread to complete the operation in synchronization. Undoubtedly, this is not as reasonable as the ue3 architecture. However, using some "Large commands" such as the init command to make the rendering thread execute many operations at a time, such as classification of VB, IB, and creation of texture, in this way, a large number of operations are completed in the rendering thread, which can significantly reduce the number of times to be synchronized.
In addition, in the debug mode of CE, it is obvious that the frame rate is improved after multi-threaded rendering is enabled. However, the debug mode of CE is indeed quite a card, and we haven't checked why it actually gets stuck yet, maybe it's the same as ogre's debug, haha. The CE efficiency under release is really high. If UE can have such efficiency, it is not ue, It is Uce...