I spent part of the morning trying to find some good free model to render, but nothing really satisfied me, so I just gave up.
In the evening I started to experiment a few things just for fun, and in the end I came up with a "wave" effect to deform the sponza model. Just a simple vertex shader manipulation, but very satisfying.
sabato 21 maggio 2016
venerdì 20 maggio 2016
Day 129 & 130: Completed model loader!
I spent two days to finish the model loader, because of a series of really complex bugs to track and fix.
I won't go into much details because I did so many things in these two days that I don't even remember all of it. The important thing is that now the loader can load complex models, with multiple meshes and materials, and with full support of normal maps, specular/diffuse/ambient lights and so on.
To test the whole system I wrote a simple script to attach and detach a point light to the camera. This allows to place the light very fast, and see immediately the results.
Since this post covers two days I'll post two screens:
The first one is a the fixed version of the cathedral of the last post. I took the screen yesterday, and there were still a lot of problems, a few of them visible, like the directional shadows.
The second is the classic sponza model used in computer graphic. The loader is completely working in this screenshot.
I won't go into much details because I did so many things in these two days that I don't even remember all of it. The important thing is that now the loader can load complex models, with multiple meshes and materials, and with full support of normal maps, specular/diffuse/ambient lights and so on.
To test the whole system I wrote a simple script to attach and detach a point light to the camera. This allows to place the light very fast, and see immediately the results.
Since this post covers two days I'll post two screens:
The first one is a the fixed version of the cathedral of the last post. I took the screen yesterday, and there were still a lot of problems, a few of them visible, like the directional shadows.
The second is the classic sponza model used in computer graphic. The loader is completely working in this screenshot.
mercoledì 18 maggio 2016
Day 128: Model Loading WIP
Today I started to adapt the Assimp loader to the engine.
It required quite a lot of tweaks because the data are imported in a very general way.
The good news is that the mesh is splitted as I wanted (for instance, the cathedral in the screenshot is splitted in 1280 meshes and 16 materials, exactly as defined in the obj file).
The bad news, is that right now for some reason only one material of the ones loaded is actually used in rendering. As you can see in the screenshot, multiple areas are black, instead of a different material.
I also updated the texture manager to support caching. That's because with ~1300 meshes and only 16 materials, each texture is loaded on average ~100 times. Now it just checks if the texture is already loaded, and returns it. It could certainly be improved, and I didn't do any error checking or tested possible duplications, but for now it does its job.
Finally a note on the lights: point lights cast nice shadows, while directional lights are not really convincing....I'm not even sure if they are just wrong, or simply ugly looking because of peterpanning / complex geometry / moire patterns and all these other annoying problems.
It required quite a lot of tweaks because the data are imported in a very general way.
The good news is that the mesh is splitted as I wanted (for instance, the cathedral in the screenshot is splitted in 1280 meshes and 16 materials, exactly as defined in the obj file).
The bad news, is that right now for some reason only one material of the ones loaded is actually used in rendering. As you can see in the screenshot, multiple areas are black, instead of a different material.
I also updated the texture manager to support caching. That's because with ~1300 meshes and only 16 materials, each texture is loaded on average ~100 times. Now it just checks if the texture is already loaded, and returns it. It could certainly be improved, and I didn't do any error checking or tested possible duplications, but for now it does its job.
Finally a note on the lights: point lights cast nice shadows, while directional lights are not really convincing....I'm not even sure if they are just wrong, or simply ugly looking because of peterpanning / complex geometry / moire patterns and all these other annoying problems.
martedì 17 maggio 2016
Day 127: Probelm with single mesh and multiple materials
Today I finished to implement the loader, by writing the shader and completing the load_model function.
However the loader I'm using doesnt support mesh splitting (create multiple meshes when a single one is using multiple materials). For this reason I need to change the model loader. Tomorrow I'll try Assimp, which seems to do just that.
However the loader I'm using doesnt support mesh splitting (create multiple meshes when a single one is using multiple materials). For this reason I need to change the model loader. Tomorrow I'll try Assimp, which seems to do just that.
lunedì 16 maggio 2016
Day 126: Submodels and specular buffer
Today I did a lot of step towards the final manager of models.
First thing, I modified the engine to handle multiple models for each gameobject. Now a model is basically a list of submodels. This was not difficult in theory, but in practice it required me to modify tons of classes.
Then I started working on the new shader, but I noticed that there was a much bigger problem, that I failed to see until now: the renderer requires extra buffers to store info about the colors of the model!
Right now I was just using a single color buffer, and today I modified the renderer class to have an additional buffer, for the specular color. I will not support ambient color, because it is seldom used, but If required It should be simple to add in the future.
In the picture you can see a light with a white specular component reflecting on a material with a blue specular component. The result is blue.
The diffuse component of the light is purple, but the result is red because the material reflect only diffuse red lighting. The resulting color is still purple because it is on top of the blue specular color.
First thing, I modified the engine to handle multiple models for each gameobject. Now a model is basically a list of submodels. This was not difficult in theory, but in practice it required me to modify tons of classes.
Then I started working on the new shader, but I noticed that there was a much bigger problem, that I failed to see until now: the renderer requires extra buffers to store info about the colors of the model!
Right now I was just using a single color buffer, and today I modified the renderer class to have an additional buffer, for the specular color. I will not support ambient color, because it is seldom used, but If required It should be simple to add in the future.
In the picture you can see a light with a white specular component reflecting on a material with a blue specular component. The result is blue.
The diffuse component of the light is purple, but the result is red because the material reflect only diffuse red lighting. The resulting color is still purple because it is on top of the blue specular color.
giovedì 12 maggio 2016
Day 125: Replaced model loader
Today I replaced my model loader with the new one. I've not taken advantage yet of the new features, I just used it to achieve the same results as before.
To achieve that I substantially modified the new loader myself. It now uses directly the Vertex3D class (to avoid unnecessary copying at the end of the loading), and also supports normals generation and tangent generation.
Tomorrow I'll try to integrate the material loading as well. The main problem is that now I'll need a model loader, instead of a mesh loader, and I need to rethink a few things, like: who owns resources? where to check if they are already loaded? Where to destroy them?
Shouldn't be that hard, but it requires attention.
To achieve that I substantially modified the new loader myself. It now uses directly the Vertex3D class (to avoid unnecessary copying at the end of the loading), and also supports normals generation and tangent generation.
Tomorrow I'll try to integrate the material loading as well. The main problem is that now I'll need a model loader, instead of a mesh loader, and I need to rethink a few things, like: who owns resources? where to check if they are already loaded? Where to destroy them?
Shouldn't be that hard, but it requires attention.
mercoledì 11 maggio 2016
Day 124: A better model loader
The major flaw of the engine is the inability to automatically load complex model.
No material loading is supported, nor the abilty to load a model composed by multiple meshes.
No material loading is supported, nor the abilty to load a model composed by multiple meshes.
This morning I decided to implement a better obj loader, so I studied the specifications of the obj and mtl formats, and then I decided to avoid doing it myself, because it's quite a huge amount of work, and not a rewarding one.
So I'll use a single-header opensource class, tiny_obj_loader, which does exactly that and supports groups and materials. My job will be to pass these raw data to the correct structures, to add the support for multiple meshes, and to improve my other managers, like the texture loader, to avoid reloading textures with the same name. Quite a long (and boring) job on its own. I'll start implementing it tomorrow.
lunedì 9 maggio 2016
Day 123: Few improvements
Today I just fixed a few thing here and there, like a few flawed commands of the shell that stopped working at some point.
sabato 7 maggio 2016
Day 122: Hierarchical directional shadows
Today I finished the third and last kind of lights, and it was easier than the other ones, because the model matrix of the bounding box was not an issue (always a fullscreen quad), and the rest was similar to directional lights.
I also fixed a few things and improved little things in the engine that were bothering me.
In the end I refactored the whole scene and moved all the code to scripts. Now the main scene only adds a script to the central light, and a script to the floor. Everything else is created in their start methods, and the input and update handled by those scripts as well.
In the screenshot there are two different shadows, barely visible, and the rotates following their gameobjects.
I also fixed a few things and improved little things in the engine that were bothering me.
In the end I refactored the whole scene and moved all the code to scripts. Now the main scene only adds a script to the central light, and a script to the floor. Everything else is created in their start methods, and the input and update handled by those scripts as well.
In the screenshot there are two different shadows, barely visible, and the rotates following their gameobjects.
venerdì 6 maggio 2016
Day 121: Spotlights working with hierarchy
Today I noticed that what I did in the last couple of days was completely wrong! The shadows are all wrong, and I didn't notice it, even in the screens I took it is clear that something is wrong, but I somehow missed it.
The problem was pretty deep, and I had to convert the light positions with a custom matrix I made that ignores scaling (because the bounding box must be rotated and transleted, but not scaled).
I managed to fix the point light, and then I proceeded with the spot lights which required an even more complex matrix, thankfully I'm starting to getting used to these space conversions.
In the end I managed to fix those as well, and I added a switch to have two different behaviours:
1) Rotate ligths alongside object: The matrix is built so that the light is rotated by the whole hierarchy of objects, on top of its own rotation. This is nice if the light is attached, for instance, to a lamp mesh
2) Rotate lights alongisde the whole hierarchy except the object: On the other end, by setting a simple bool, it is possible to avoid the light to rotate with the object.
Tomorrow I'll fix the directional lights as well, and then I'll be done for good.
The screen captures a scene with lots of spotlights working and with a position dependent on the hierarchy.
The problem was pretty deep, and I had to convert the light positions with a custom matrix I made that ignores scaling (because the bounding box must be rotated and transleted, but not scaled).
I managed to fix the point light, and then I proceeded with the spot lights which required an even more complex matrix, thankfully I'm starting to getting used to these space conversions.
In the end I managed to fix those as well, and I added a switch to have two different behaviours:
1) Rotate ligths alongside object: The matrix is built so that the light is rotated by the whole hierarchy of objects, on top of its own rotation. This is nice if the light is attached, for instance, to a lamp mesh
2) Rotate lights alongisde the whole hierarchy except the object: On the other end, by setting a simple bool, it is possible to avoid the light to rotate with the object.
Tomorrow I'll fix the directional lights as well, and then I'll be done for good.
The screen captures a scene with lots of spotlights working and with a position dependent on the hierarchy.
giovedì 5 maggio 2016
Day 120: Scripting system
Today I implemented the scripting system. Each GameObject can have a list of scripts attached to it.
Each script ha a Start-Update-Input method, and these will be called automatically by the engine, only if the script are attached to a gameobject.
I played around with them in the scene I made a couple of days ago: a script handles the movement of the lights, another one their color, and finally the scene script calls methods on them to set the speed of the lights. Nothing of this could be deduced by the image, but still that's the result!
Finally I added a reset scene method in the shell, which can be called with \r.
Each script ha a Start-Update-Input method, and these will be called automatically by the engine, only if the script are attached to a gameobject.
I played around with them in the scene I made a couple of days ago: a script handles the movement of the lights, another one their color, and finally the scene script calls methods on them to set the speed of the lights. Nothing of this could be deduced by the image, but still that's the result!
Finally I added a reset scene method in the shell, which can be called with \r.
mercoledì 4 maggio 2016
Day 119: Local positions
Today I tried to mix local and global coordinates, but I'm handling the generation of model matrices in a way that makes it hard to convert from and to local coordinates.
Since I'm not really concerned about this, I'll leave it like that.
While I was trying things I also improved and optimized the transform class, and it now has more useful methods and better getter and setters
Since I'm not really concerned about this, I'll leave it like that.
While I was trying things I also improved and optimized the transform class, and it now has more useful methods and better getter and setters
martedì 3 maggio 2016
Day 118: Parent and children
Today I decided to implement a hierarchy system.
Each trasform can have a parent and a list of children. This means that moving a parent will move the children with it as well. To do so, the model matrix of each object is calculated by combining those of all the parents above it in the hierarchy
The system works, and I also had to change how the light position is passed to the shader to account for the new changes. There are a few big problems though, which i'll probably not fix because are pretty boring things, and I won't use them much, but they should definitely be supported in a decent engine:
1) local and global coordinates: the system now only uses the former. Implementing the latter is not so straightforward, and I'm also thinking of two possible ways to achieve that:
- Only store local coords, and set / retrieve the global ones by calculating them at runtime using the model matrices of the whole hierarcy
- Store them both, and if the last set was a local one, then proceed normaly. Otherwise avoid the whole matrix multiplication and directly send global coord to the shader. Problem is how to separate rotation scale and translation.
2) The second major problem are the rotation of the lights. I actually haven't even checked it, but surely the rotation will remain global. And being it a direction, I cannot use the usual hierarchy matrix, I would need to generate an inverse transpose and so on, maybe I'll fix it one day
For now I'll leave it like that, and I already tested it with a new scene. As you can see in the screenshot, there are 6 point lights (with a gameobject and model of course). They are all children of an invisible gameobject at the center of them. I tried to move it and rotate it, and all the lights follow it nicely.
Each trasform can have a parent and a list of children. This means that moving a parent will move the children with it as well. To do so, the model matrix of each object is calculated by combining those of all the parents above it in the hierarchy
The system works, and I also had to change how the light position is passed to the shader to account for the new changes. There are a few big problems though, which i'll probably not fix because are pretty boring things, and I won't use them much, but they should definitely be supported in a decent engine:
1) local and global coordinates: the system now only uses the former. Implementing the latter is not so straightforward, and I'm also thinking of two possible ways to achieve that:
- Store them both, and if the last set was a local one, then proceed normaly. Otherwise avoid the whole matrix multiplication and directly send global coord to the shader. Problem is how to separate rotation scale and translation.
2) The second major problem are the rotation of the lights. I actually haven't even checked it, but surely the rotation will remain global. And being it a direction, I cannot use the usual hierarchy matrix, I would need to generate an inverse transpose and so on, maybe I'll fix it one day
For now I'll leave it like that, and I already tested it with a new scene. As you can see in the screenshot, there are 6 point lights (with a gameobject and model of course). They are all children of an invisible gameobject at the center of them. I tried to move it and rotate it, and all the lights follow it nicely.
lunedì 2 maggio 2016
Day 117: Fixed old bug
Today I wanted to create a couple of test scenes, just for fun, and I noticed an old bug that has been following me for months... Basically the diffuse light of an object was changing with the view direction, but just under certain conditions, so I was never able to fix it, and sometimes I actually thought i had.
Today I finally tracked it down, and it was a problem in the coordinate space in which the normals are saved inside the geometry pass. Now it should definitely be fine, and tomorrow I'll make the scenes I was supposed to do today. After that I plan to add a few simple but important things to the engine, like a scripting system and the parent-child hineritance.
Today I finally tracked it down, and it was a problem in the coordinate space in which the normals are saved inside the geometry pass. Now it should definitely be fine, and tomorrow I'll make the scenes I was supposed to do today. After that I plan to add a few simple but important things to the engine, like a scripting system and the parent-child hineritance.
Iscriviti a:
Post (Atom)








