|
As in reality, the penumbra width and shadow sharpness vary depending on the distance from the occluder and the shape of the light source. At the occluder, the shadow edge starts sharply, getting more and more soft with the distance. For example, a rectangular ceiling light casts corresponding full scene soft shadows in real-time. Objects truly stand on a floor without floating effect.
Such techniques are implemented in a highly optimized way, using tricks and aggressive approximations at the right places.
In contrast to simple shadowing techniques or techniques relying on precalculated data, Shark 3D lighting and shadowing looks consistent. For example, if a dynamic character is partly shadowed by some static pillar, the shadow of the character vanishes correctly within the shadow of the pillar. Also dynamic objects cast shadows onto other dynamic objects. Thereby, shadowing looks realistic and natural.
For example, all various variants of shadow mapping have the well-known in-principle aliasing limitations. Typical problematic situations are long distance views when looking into the direction where the light comes from. With Shark 3D you can get nice full scene soft shadows without artifacts also in such situations.
A different aspect of avoiding artifacts is for example render-to-texture in conjunction with antialiasing, which sometimes causes subtle issues and requires special care to avoid artifacts.
|
|
In practice, this means that not Shark 3D is the bottleneck. The limiting factors are only the hardware itself and highly optimized platform specific low-level code doing the hard work. As a side effect, on PCs Shark 3D can take advantage of better hardware and better drivers automatically.
This includes using multiple rendering passes, multi-texturing, parameter calculations, shader animations, and much more. Using all these features don't require scripts or C++-code.
Another feature of configuration is to define different rendering techniques depending on the available hardware. Depending on the presence of particular 3d-card features, one of several shader variants is selected.
Also new shader components can be included into a Shark 3D based application simply by configuration.
For example, a mirror is not simply implemented by a single shader. Instead, at least two shaders work together. These two shaders build a compound shader, which is assigned to the mirror object. The first shader component implements the mirroring functionality. This shader may for example generate a texture containing the mirror image. The second shader component is used to render this texture, and possibly to apply additional effects, for example distortion. Thereby, the mirroring feature can be combined with other features provided by different shaders.
|
These features are all accessible on a simple configuration level. For example, a sensor volume may start and stop a pixel program shader animation. The animation may be controlled by the server, but is executed completely on the client. Such features can be implemented fully on a configuration level needing only few configuration entries. There is no need for any C++ code or scripting code.
Each animation slot can be configured in different ways. First, it can be a simple animation, which is played automatically locally on the client, for example for decorative shader animations. But it is also possible to control an animation slot by the server, taking advantage of all advanced animation techniques of Shark 3D, including server-client optimizations and interpolations.
As a very simple example, you can write a shader blending two textures into each other controlled by a script on server-side. All this can be done by configuration without any line of C++ or script code.
As another example, you may write a customized shader for an energy-protected door in a game using animated pixel and vertex programs. This shader may use one automatic animation slot for a decorative energy fluctuation animation, and a second animation slot for fading between an open and closed state of the gate, which is controlled by the server. Also this sample can be implemented without any line of C++ or script code.
There are special shader components that define different shader sub-sections depending on the current hardware. This can be done completely on configuration level. In the extreme case you can define separate shaders depending on the current 3d hardware and current game configuration.
For that purpose, we designed a universal shader program mechanism that is smoothly integrated into the Shark 3D shader and animation system. The developer can combine the advantages of the configurable shader system, lighting and shadowing modules with vertex and pixel programs of 3d chips, opening for you the door to new rendering effects.
Advanced projects typically come to the point where the built-in rendering features are not sufficient, even if you can combine and configure them in a very flexible way.
Therefore it is very important that the renderer is not a closed system. Instead, the renderer must be very modular on C++ level, too. This makes it possible to add completely new rendering techniques in a modular way without having to modify or even rewrite the renderer.
Instead, all advanced local and global rendering effects described above and included in the Shark 3D SDK are implemented in separate, independent shader modules. And new advanced local or global rendering features can be implemented in a modular way without having to change the core rendering code of Shark 3D.
|
Another sample is that the core renderer does not know anything about mirroring. Especially, mirrors are not hard-coded in the renderer. Instead, a mirror is implemented by an independent shader module.
This means that for example that different scene traversals and different ways how render targets are used are active at one time.
Shark 3D naturally supports this. You can combine different advanced rendering techniques in an orthogonal, modular and clean way.
The Re-entrant Modular Shader System™ of Shark 3D brings the same power to real-time rendering. There is no renderer with fixed functionality anymore, which only can be enhanced or customized by modifying the core renderer. Instead, the renderer is completely modular. This opens new unique possibilities for high-end game projects.
|
For instance, the designer can change shader parameters and see the results in the running game level without having to restart Shark 3D. The designer does not only have a limited material preview, but can see all changes in the running game.
The developer can change pixel programs and can inspect the change immediately in the running game level.
For example, a developer may have created a new shadow-volume effect, based on existing or new C++ shader components, vertex or pixel programs, and having used the Shark 3D shader language. By writing a simple customized configuration entry, every designer can assign this new shader to objects, and manipulate proprietary shader parameters.
For this new proprietary shader, the designer can use all workflow features. This includes Live editing the running console and PC game, so that the designer can see shader parameter changes in the running game.
|
These are default mechanisms. Using the modular structure of the component editor and the component architecture, it is easy to integrate shader editing functionality into other tools, including proprietary tools.
Shark 3D provides a modern basis for these modern requirements. This includes among others that Shark 3D provides a clear separation of the Shark 3D visibility system from a generic object database. The object database provides generic object enumeration that may or may not be related to visibility aspects. More importantly, the database approach provided us with the foundation and freedom we needed to push the renderer without hitting limits all the time.
Multiple instances can have different textures, shaders, and animation states. These states can be also switched at runtime by scripting.
|
|
However rendering using precalculated PVS gives the following result:
|
Only potentially visible objects are rendered and only they cost any performance.
You can mix static and dynamic approaches in a flexible way and optimize the static parts by PVS. For example, you can dynamically create a building that itself is static and is optimized by PVS.
Although the PVS visibility data is precalculated, dynamic objects, of course, also can take advantage of PVS. For example, if a character currently is inside a particular room, and this room is stored as being not visible from the current camera position, both the room and the character are not rendered.
At the end, the question is: Do the complex work at runtime? Or do it off-line, and only use a simple look-up at runtime? The second approach does not waste performance at runtime and does not risk a negative return on investment of valuable processor time.
These relationships are managed automatically. For example, a graphical context may be re-created due to a fundamental configuration change. Or a new graphical context may be connected to an existing abstract game state. Then the corresponding context resources are created and uploaded automatically. If necessary, this automatically includes reloading such data from disk. For example such data may be texture data, vertex buffer data and index buffer data.
|