-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Proposal for shader functions #602
Comments
Agreed. Shader logic should be modular. Ideally it would be possible to make a "custom pbr shader" by just pulling in the relevant functions. |
To answer to the modularity purpose, at my studio we used to create our shader from a collection of chunks with nanogl-pbr. Each material is defined by a collection of inputs. An input is basically a number of arguments (1, 2, 3, 4...?), then anything can be linked to that input (an attribute, an uniform, a constant, an enum, a texture, etc...). An input can me mixed by multiple sources for example for an input of three arguments, one can be set by a texture red channel, the other by a constant, and the other by a uniform. |
One approach I see here is to provide some kind of framework shader(s) where the user code is "injected" (basically #included/copy-pasted) and accessed through a single function call. In my own PBR code I liked to use structs to express sets of parameters for different stages of the shading process. In combination it could look something like this: Framework code (not accessed by the user): struct Material { // user input parameters
vec3 albedo;
float opacity;
vec3 normal; // tangent space [-1, 1]
float roughness; // perceptual roughness [0, 1]
float metallic; // [0, 1]
vec3 emissive; // [0, ...]
float reflectance; // [0, 1]
float clearcoat; // clearcoat blend factor [0, 1]
float clearcoat_roughness; // [0, 1]
};
void main() {
// ...
Material mat = get_material(uv); // get_material is defined in the user's code
// ... shading based on the material properties goes here
} User defined material function: uniform vec3 tint;
uniform sampler2D sAlbedo;
Material get_material(vec2 uv) {
Material mat;
mat.albedo = texture(sAlbedo, uv).rgb * tint;
mat.normal = vec3(0.0, 0.0, 1.0);
// ...
return mat;
} Difficulties I see with this approach:
Another way is to turn the concept upside down and provide function libraries that the user can |
Related: #3615 |
This can be safely closed right? The PBR shader has been split in many functions. While it's not (yet) extensible, it allows picking and composing your own shader based on the smaller functions. |
Yup this can be closed! |
Take as a reference the you create a shader in Blender:
Essentially, instead of always having one shader you'd use for all materials, binding the different textures in a single UV (diffuse, specular, normals, etc), you should be able to make your own shaders calling shader functions.
In the Blender example, "Principled BSDF" is a function that would take in the diffuse, ambient occlusion, etc. values for a single pixel and use it to create a color.
You could conceive of many other functions, maybe dividing sub surface and other features that aren't used for everything into different shaders you can use depending on the mesh.
When writing your own shaders, you might use different samplers, or might use some other method to call the pre-made shader functions.
This relates to the following issues:
#185
#179
The text was updated successfully, but these errors were encountered: