Skip to content

Skyboxes and new materials workflow!

Compare
Choose a tag to compare
@avilapa avilapa released this 14 Dec 21:15
· 26 commits to master since this release
affc196

screenshot_139

Materials

Quite an important change I've been wanting to do for a while was to separate the actual GPU material from its settings completely (color, textures, and other uniforms). I am quite happy with how it turned out, but it will surely undergo some more changes in the future as I really get used to it, but at the moment this is how it stands:

Creating materials and their instances goes as follows:

class Unlit : public Material
  {
    VXR_OBJECT(Unlit, Material);
  public:
    Unlit();

    class Instance : public MaterialInstance
    {
      VXR_OBJECT(Instance, MaterialInstance);
    public:
      Instance();

      virtual void onGUI() override;

      void set_color(Color color);
      Color color() const;
    };
  };

The Unlit() constructor contains the actual gpu shader data, while the Instance() constructor just needs to initialize itself with the name of the material (textures could be initialized here if wanted, as its a per-instance operation (a single MaterialInstance can be used in multiple objects!)):

Unlit::Unlit()
{
    set_name("Unlit");
    set_shaders("unlit.vert", "unlit.frag");

    set_num_textures(0);
    set_uniforms_enabled(true);
    set_uniforms_name("Unlit");
}

Unlit::Instance::Instance()
{
    init("Unlit");
}

The AssetManager comes to play in the Instance() constructor, as the actual material reference will be retrieved via the manager. In order for a new user-created Material to be considered by the manager, you just need to make the following call:

Engine::ref().assetManager()->addMaterial<MyNewMaterialClass>();

In the future, materials will be loaded from files in the assets folder, and the process will be even more automatic!

Some useful material instances have been added as engine provided materials, and more will shortly join the crew! At the moment Screen, Unlit, Wireframe, Skybox and Standard (lit) are available.

What is cool about the System, is that more complex instances can be created by initializing more than one material in them. This comes in handy for example when using materials that can be rendered using a flat color, a 2D texture, a CubeMap texture, or any other type. This is the case of the Standard material, which is actually 3 different materials (Standard, Standard::Textured and Standard::TexturedCubemap) but a single instance class. Depending on which texture you set it to render (or if you set a texture at all) a material will be selected internally.

You can see this example here:

And for an example of use, check: https://github.com/avilapa/vxr/blob/master/examples/dev/dev.cpp#L59

Changelog

  • New Material / MaterialInstance workflow.
  • Materials that don't use shader blocks can now be flagged with set_uniforms_enabled(false).
  • Added functionality to AssetManager.
  • Reorganized folders inside graphics.
  • Added Skybox rendering!
  • Started to work towards const-correctness.
  • Fixed texture world position in PlanetEditor.