Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modularize Shaders #123

Open
cochrane opened this issue Apr 14, 2021 · 3 comments
Open

Modularize Shaders #123

cochrane opened this issue Apr 14, 2021 · 3 comments
Labels
enhancement refactoring Stuff that makes the coder nicer and easier to understand

Comments

@cochrane
Copy link
Owner

A while back, all the shaders (for XNALara models anyway) were unified already behind the scenes. They used the same GLSL files, just with different defines activating different code paths. All the code that decides which shader to use, though, remained the same.

This should be changed to a more modular approach, where the shader features can be combined dynamically by the user, or by the app during loading. For example, right now a user can't combine metallic with emission; this should be possible.

For app-selected shaders, the key example is for OBJ files, where an object might have a diffuse, a specular and a normal texture, but all of them are optional and textureless object files are supported. Right now every combination is its own slightly different shader as far as the loading code is concerned. Instead, the code should simply be able to say that these are the parameters that are set on the file, and the app should generate the appropriate shader explicitly.

The exact design needs to be worked out, but the general idea is that in the model parameters, there are base shaders (possibly just one), which specifies the files to use; and then shader modules, which can be turned on and off, and have their own parameters and textures (perhaps also required vertex attributes - in this case the UI should disallow shaders that require nonexistent vertex attributes). The mesh then uses a combination of one base shader and an arbitrary number of associated shader modules. Shader modules may also be hierarchical (need normal map shader if you want detail bump maps).

Backwards compatibility is going to be an issue - all XNALara models must still load correctly, and old scene files must as well. Also, how will this be saved in scene files anyway?

Pre-requisite for #122 - not strictly necessarily, but it's probably a good idea.

@cochrane cochrane added enhancement refactoring Stuff that makes the coder nicer and easier to understand labels Apr 14, 2021
@cochrane
Copy link
Owner Author

Very rough concept for the runtime classes (names TBD):

  • Class ShaderModule: Contains defines, uniforms that are colors, that are floats, and textures, all identified by string ids. Several modules can share their uniforms. E.g. if two modules used at the same time both use baseTexture or shininess, then both get the same value set by the user.
    • Can have children, which are just ShaderModules themselves. Nested arbitrarily deep. Activating a child means necessarily activating the parent.
    • Can have requirements for specific vertex attributes. Such modules will be activated by loading code directly.
    • Can be marked as non-UI; used by the engine depending on scene settings (this might be used for light settings or cube maps or what have you)
  • Class ShaderBase inherits from ShaderModule
    • Adds the actual shader files to use.
  • Class ShaderInstance consists of a ShaderBase and set of ShaderModules (that must all be descendants of that ShaderBase). Calculates effective used set of uniforms, vertex attributes, and preprocessor defines.
  • XNALara Shader specifically for loading XNALara files:
    • Contains a ShaderInstance to use
    • Contains mesh groups to which this ShaderInstance applies
    • Contains mapping from generic_mesh parameter values to shader parameters
    • Used only during loading, ignored by rest of system.

Possible expansion if necessary:

  • ShaderModuleGroup: Can be a child of a ShaderModule. Has a name and a set of ShaderModules. The shader modules are considered mutually exclusive by default.

@cochrane
Copy link
Owner Author

Loading from existing scene files:

  • Use the XNALara Shader data to map the existing shader string

Saving scene files:

  • Add array of selected shader modules to GLLItemMesh; use existing shader name as shader base (or new field for this?)

Actually not that difficult.

UI needs to be adapted for this, but having nicer UI is part of the point of all of this.

@cochrane
Copy link
Owner Author

Should probably also add a way for models to specify which texture coordinate goes with which texture while we're at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement refactoring Stuff that makes the coder nicer and easier to understand
Projects
None yet
Development

No branches or pull requests

1 participant