QodotPlugin / qodot-plugin

(LEGACY) Quake .map support for Godot 3.x
MIT License
960 stars 70 forks source link

Investigate a single-mesh solution w/texture atlasing #38

Closed Shfty closed 4 years ago

Shfty commented 4 years ago

Combine all meshes into one and use a texture atlas, presumably with a customized fragment shader to allow for wrapping textures that are looked up?

Shfty commented 4 years ago

Godot provides the AtlasTexture class that wraps a subsection of another texture, so you can get native wrapping etc.

However, I don't think this would work for the single-mesh idea, since AtlasTexture objects are CPU-side. You'd need a way to feed an array of textures into a shader, at which point you might as well just write a custom atlas lookup yourself.

This might be a bit less limited than I thought, at least as far as PBR goes. You could atlas all the PBR content's channels separately from regular textures, then feed them all into a shader that outputs the appropriate PBR information.

DeadlyLampshade commented 4 years ago

I think meshes / collisions should be generated on a "per brush" basis. Since you can benefit from Godot's basic frustum culling. That being said, I think it could potentially be good if you split them up in layers, and/or groups. Having recently used Trenchbroom, I've noticed it supports grouping of brushes. Just depends on how well that is stored in the map files.

Shfty commented 4 years ago

The basis on which meshes and collisions are generated is fully controllable through the build step system, so that can be arranged @DeadlyLampshade

As far as groups go, those become top-level func_group entities alongside the worldspawn in the resulting .map file. The QodotBuildMaterialMeshes step doesn't account for that as it's just splitting by texture, but such behaviour could be implemented by creating a new build step class in a similar vein, by inheriting from QodotBuildMeshes.

TL;DR Qodot is designed to be able to output optimal geo for a given use case, so compatibility with culling won't be a problem.

Shfty commented 4 years ago

Need to do some draw call profiling with AtlasTexture and figure out if Godot is smart enough to batch up instances of the same material that all draw from the same atlas.

Could make doing this trivial if so.

Shfty commented 4 years ago

AtlasTexture was a bust, but I managed to put together a ShaderMaterial-driven single-mesh atlas setup in the latest commit.

Still to do:

Shfty commented 4 years ago

Todo: Investigate 3D textures. These might be a perfect way to avoid mipmap / aniso issues.

Shfty commented 4 years ago

TextureArray was the key to getting properly-mipmappable textures, but unfortunately it and its TextureLayered superclass don't serialize properly if created in the editor, so they can't be used for offline baking like this.

I've opened an issue on the Godot GitHub: https://github.com/godotengine/godot/issues/34312

On way to work around this may be to build a TextureArray that's internal to QodotMap and not serialized, then rebuild it from a list of textures on startup both at runtime and in the editor. That would work around the issue, but requires build steps being able to store persistent post-build data in the map. Needs some thinking about.

Shfty commented 4 years ago

I built a wrapper class to work around the TextureLayered issue, and integrated it into the atlased mesh pipeline in the latest two commits.