You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The first thing that you will notice is that we have increased the version to `460`. We also have removed the constants associated with animations (`MAX_WEIGHTS` and `MAX_BONES`), the attributes for bones indices and the uniform for bone matrices. You will see in next chapter that we will no need this information here for animations. We have created two new constants to define the size oif the `drawElements` and `modelMatrices` uniforms. The `drawElements` uniform will hold `DrawElement` instances. It will have one item per mesh and associated entity. If you remember, we will record a single instruction to draw all the items associated to a mesh, setting the number of instances to be drawn. We will need however, specific per entity data, such as the model matrix. This will be hold in the `drawElements` array, which will also point to the material index to be used. The `modelMatrices` array will just hold the model matrices for each of the entities. Material information will be used in the fragment shader you we pass it using the `outMaterialIdx` output variable.
578
+
579
+
The `main` function, since we do not have to deal with animations, has been simplified a lot:
The key here is to get the proper index to access the `drawElements` size. We use the `gl_BaseInstance` and `gl_InstanceID` built-in in variables. When recording the instructions for indirect drawing we will use the `baseInstance` attribute. The value for that attribute will be the one associated to `gl_BaseInstance` built-in in variable. The `gl_InstanceID` will start at `0` whenever we change form a mesh to another, and will be increased for of of the instances of the entities associated to the models. Therefore, by combining this two variables we will be able to access the per-entity specific information in the `drawElements` array. Once we have the proper index, we just transform positions and normal information as in previous versions of the shader.
606
+
607
+
The scene fragment shader (`scene.frag`) is defined like this:
The main changes are related to the way we access material information and textures. We will now have an array of materials information, which will be accessed by the index we calculated in the vertex shader which is now in the `outMaterialIdx` input variable (which has the `flat` modifier which states that this value should not be interpolated from vertex to fragment stage). We will be using an array of textures to access either regular textures or normal maps. The index to those textures are stored now in the `Material` struct.
668
+
669
+
670
+
Now it is the turn to examine the changes in the `SceneRender` class. We will start by defining a set of constants that will be used in the code and by modifying the `createUniforms` according to the changes in the shaders shown before:
You can see that we now have to bind the array of texture samplers and activate all the texture units. In addition to that, we iterate over the entities and set up the uniform values for the model matrices. After that, we call the `renderStaticMeshes` method which will be the one that populates the indirect drawing buffer. In the next chapter we will see that we need to separate how we do this for static vs animated meshes. The `renderStaticMeshes` method is defined like this:
In this case, we will populate the buffer that will hold the draw indirect instructions (by calling the `buildStaticCommandBuffer`). Each set of draw instructions si composed by five attributes, ech of the with a length of 4 bytes (total length of each set of parameters is what defines the `COMMAND_SIZE` constant). In this case, we are creating a new buffer in each draw call. This is not the most efficient way of doing it at all, but it keeps the things simple enough. In your game engine you will need to reuse a buffer. Also, there is no need to populate the indirect drawing buffer. We will keep this approach as an example, it gives you some flexibility so you can add new entities, but should think in caching for your engine.
0 commit comments