Jump to content

Textures in Vulkan

Josh

549 views

I finally got a textured surface rendering in Vulkan so we now have officially surpassed StarFox (SNES) graphics:

Untitled.thumb.png.f83d2ea65e0813ef1a46bf0f81032968.png

Although StarFox did have distance fog. 😂

Star-Fox-Banner.jpg.45d228161bb92b6016a5557b43c7fc21.jpg

Vulkan uses a sort of "baked" graphics pipeline. Each surface you want to render uses an object you have to create in code that contains all material, texture, shader, and other settings. There is no concept of "just change this one setting" like in OpenGL. Consequently, the new renderer may be a bit more rigid than what Leadwerks 4 uses, in the interest of speed. For example, the idea of 2D drawing commands you call each frame is absolutely a no-go. (This was likely anyways, due to the multithreaded design.) A better approach for that would be to use persistent 2D primitive objects you create and destroy. I won't lose any sleep over this because our overarching design goal is performance.

Right now I have everything hard-coded and am using only one shader and one texture, in a single graphics pipeline object. Next I need to make this more dynamic so that a new graphics pipeline can be created whenever a new combination of settings is needed. A graphics pipeline object corresponds pretty closely to a material. I am leaning towards storing a lot of settings we presently store in texture files in material files instead. This does also resolve the problem of storing these extra settings in a DDS file. Textures become more of a dumb image format while material settings are used to control them. Vulkan is a "closer to the metal" API and that may pull the engine in that direction a bit. That's not bad.

I like using JSON data for file formats, so the new material files might look something like this:

{
    "material": {
        "color": "1.0, 1.0, 1.0, 1.0",
        "albedoMap": {
            "file": "brick01_albedo.dds",
            "addressModeU": "repeat",
            "addressModeV": "repeat",
            "addressModeW": "repeat",
            "filter": "linear"
        },
        "normalMap": {
            "file": "brick01_normal.dds",
            "addressModeU": "repeat",
            "addressModeV": "repeat",
            "addressModeW": "repeat",
            "filter": "linear"
        },
        "metalRoughnessMap": {
            "file": "brick01_metalRoughness.dds",
            "addressModeU": "repeat",
            "addressModeV": "repeat",
            "addressModeW": "repeat",
            "filter": "linear"
        },
        "emissiveMap": {
            "file": "brick01_emissive.dds",
            "addressModeU": "repeat",
            "addressModeV": "repeat",
            "addressModeW": "repeat",
            "filter": "linear"
        }
    }
}

Of course getting this to work in Vulkan required another mountain of code, but I am starting to get the hang of it.

  • Like 4


5 Comments


Recommended Comments

5 minutes ago, Thirsty Panther said:

Are you still going to add PBR files to the new Engine?

What exactly are "PBR files"? 

  • Confused 1

Share this comment


Link to comment

Yes. Once I get the basics done all the work I did in OpenGL will transfer over easily because the same shaders can be used.

  • Like 3

Share this comment


Link to comment

Not to be outdone by Nintendo, I have added the Vulkan Fog of Death (TM).

Untitled.thumb.png.e67ecdb71fc151a785f95605ddaf2717.png

  • Like 2

Share this comment


Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Blog Entries

    • By Josh in Josh's Dev Blog 0
      I've restructured the plugin SDK for our new engine and created a new repository on Github here:
      https://github.com/Leadwerks/PluginSDK
      The GMF2 format will only be used as an internal data transfer protocol for model loader plugins. Our main supported file format will be GLTF.
      As of now, the plugin system can be used to write texture loaders for different file formats, model loaders, or to modify behavior of particles in the new particle system. The FreeImage texture loader has been moved out of the core engine and into a plugin so you no longer have to include the FreeImage DLL unless you want to use it. The main supported texture format will be DDS, but the FreeImage plugin supports many common image file formats.
    • By Admin in Leadwerks Company Blog 2
      The GMF2 file format provides the fastest possible load times for 3D models. A preliminary specification and SDK for loading and saving files in the GMF2 file format is now available on GitHub here:
      A Quake 3 MD3 model loader is included as an example.
    • By Josh in Josh's Dev Blog 2
      The Leadwerks 5 beta will soon be updated with particle emitters and an example particle system plugin. Previously, I showed some impressive results with physically interactive particles that collide with and exert forces on the environment. I decided to use the plugin system for controlling particle behavior, as this offers the best performance and can be run on the physics thread. 
      A particle system plugin uses some predefined structures and functions to modify the behavior of particles when they are emitted or as they are updated. This allows for unlimited features to be added to the particle system, because anything you want can be added with a plugin. A system for sending settings to the plugin will be implemented in the future so you can adjust the plugin settings and see the results. The default particle settings and features will probably stay pretty barebones and I will just use the plugin system to add any advanced functionality since it is so flexible.
      void EmitParticle(ParticleModifier* mod, ParticleSystem* particlesystem, Particle* particle) { if (mod->emissionshape == EMISSION_SHAPE_BOX) { particle->position[0] = Random(-mod->area[0], mod->area[0]); particle->position[1] = Random(-mod->area[1], mod->area[1]); particle->position[2] = Random(-mod->area[2], mod->area[2]); } else if (mod->emissionshape == EMISSION_SHAPE_CYLINDER) { particle->position[0] = Random(-mod->area[0], mod->area[0]); particle->position[1] = Random(-mod->area[1], mod->area[1]); particle->position[2] = Random(-mod->area[2], mod->area[2]); auto l = sqrt(particle->position[0] * particle->position[0] + particle->position[1] * particle->position[1] + particle->position[2] * particle->position[2]); if (l > 0.0f) { particle->position[0] /= l; particle->position[1] /= l; particle->position[2] /= l; } } particle->position[0] += particlesystem->matrix[12]; particle->position[1] += particlesystem->matrix[13]; particle->position[2] += particlesystem->matrix[14]; } There are three other new Lua examples included. Coroutines.lua shows how a sequence of actions can be added to an entity before the game starts, and the actions will be executed in order:
      --Create model local model = CreateBox(world) --Add some behaviors to be executed in order model:AddCoroutine(MoveToPoint, Vec3(3,0,0), 2) model:AddCoroutine(MoveToPoint, Vec3(-3,0,0), 2) model:AddCoroutine(MoveToPoint, Vec3(0,0,0), 2) --Main loop while window:Closed() == false do world:Update() world:Render(framebuffer) end This is great for setting up cut scenes or other sequences of events.
      An example showing how to enable tessellation is also included. Tessellation is now a per-camera setting.
      camera:SetTessellation(10) The number you input is the size in pixels of the tessellated primitives. Use zero to disable tessellation. Tessellation is disabled by default on all cameras.
      Finally, an example showing how to use a texture loader plugin is included. All you have to do is load the plugin and after that textures can be loaded in VTF format:
      local vtfloader = LoadPlugin("Plugins/VTF.dll") local tex = LoadTexture("Materials/wall01.vtf")  
×
×
  • Create New...