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

Shader Preprocessor to simplify writing shaders. [For Discussion, Do Not Merge] #6273

Closed
wants to merge 4 commits into from

Conversation

bhouston
Copy link
Contributor

One of the issues that we have right now with our shader system is ShaderLib. It has inline shader code and manual includes of other shaders via directly referencing Shader Chunks. This is awkward.

I propose that we replace the code chunks in ShaderLib with just more ShaderChunks. And then we add a shader preprocessor that understands the standard C-Style include statements. And those allow for the recursive inclusion of other shader chunks.

I've made a quick prototype of this (untested) to show the idea.

  • I created material_basic_fragment.glsl that replaces the ShaderLib specification.
  • I created a simple THREE.ShaderPreprocessor for handling recursive #include statements in GLSL shaders. It can optionally take a directly specified shader or if one isn't provided it looks for a properly named "ShaderChunk." It also contains a caching system for speed purposes. If we want to seriously use this, one should add a check to prevent infinite recursion.

We can also incrementally move towards this new system as it can be made backwards compatible with older shaders.

(PS. I also discussed that I would like a GLSL preprocess to handle "#includes" back in January 2014 here: #4271 (comment) Also UE4 has one for their *.usf files.)

@crobi
Copy link
Contributor

crobi commented Mar 23, 2015

I like this idea. I have written such a GLSL preprocessor for a project in C++ once, for the same reason (to support #include). Apart from basic #include support, it had the the following additional functionality:

  • Automatically include each file only once, as if each file had a #pragma once. I have used low level .glsl files with struct/type definitions, intermediate .glsl files with individual function definitions, and high level .glsl files with whole shaders. This lead to dependencies like this: A includes B and C; B and C both include D.
    • I have implemented this by adding an additional parameter to ShaderPreprocessor.preprocess, which stored the names of files/chunks already included.
  • Support for dynamic defines. When asking for a preprocessed shader source, you could pass a list of key/value pairs that would be translated to #define {key} {value} lines, which would then be prepended to the final shader source.This was useful when testing shaders or creating shaders with configuration-dependent constants.
    • When caching compiled shaders (not just the shader source), the cache needs to be aware of this functionality.

@mrdoob
Copy link
Owner

mrdoob commented Mar 24, 2015

I like the idea 👍

@benaadams
Copy link
Contributor

glslify might be something to look at? https://github.com/stackgl/glslify also has interesting includes like https://github.com/aras-p/glsl-optimizer

@threejsworker
Copy link

The examples of this pullrequest are now built and visible in threejsworker. To view them, go to the following link:

http://threejsworker.com/viewpullrequest.html#6273

@mrdoob mrdoob closed this Oct 16, 2015
@bhouston bhouston deleted the glslPreprocessor branch April 19, 2017 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants