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

Per material GLSL ShaderChunk includes #10789

Closed
3 of 12 tasks
pailhead opened this issue Feb 10, 2017 · 3 comments
Closed
3 of 12 tasks

Per material GLSL ShaderChunk includes #10789

pailhead opened this issue Feb 10, 2017 · 3 comments

Comments

@pailhead
Copy link
Contributor

pailhead commented Feb 10, 2017

Description of the problem

I was able to do magical things with a few undocumented features Material.defines , Material.customDepthMaterial and Material.customDistanceMaterial.

#10764

I'm wondering now if this whole system could be extended by having the renderer use a chunk provided by the material instead of THREE.ShaderChunks.

It's possible to modify the shader chunks so that they don't break by using the preprocessor.

This can then easily be monkey patched into three. Before the first render call is made, THREE.ShaderChunk[ chunk ] is modified. Then, that branch can be controlled by assigning a define to a material instance's defines.

The shader chunk mechanism is already so neatly broken up, that it could probably cover most cases.

For example, something that modifies the geometry can use uv_pars_vertex to safely be included in all the needed shaders. Depth shader doesnt need to render maps, but it needs to fetch a texture if it uses displacement, so it includes the uvs. Something that modifies lighting, can make a branch in one of the lighting includes.

I'm thinking, monkey patching and branching can be avoided if the renderer would look up a chunk provided by something like Material.shader.entryPoint['uv_pars_vertex'].

In addition to this, i'd add more entry points, at least a global_vertex and global_fragment, or a define #IS_FRAGMENT so then any global stuff could be appended to common.

Confused though why are parameters being passed here:
https://github.com/mrdoob/three.js/blob/master/src/renderers/webgl/WebGLProgram.js#L496

tl:dr;

would this be a good idea?

	vertexShader = parseIncludes( vertexShader, material.shader.entryPoints );

https://github.com/mrdoob/three.js/blob/master/src/renderers/webgl/WebGLProgram.js#L153

function parseIncludes( string , materialIncludes ) {

	var pattern = /#include +<([\w\d.]+)>/g;

	function replace( match, include ) {
                
		var replace = materialIncludes[ include ] ?  materialIncludes[ include ] : ShaderChunk[ include ];

		if ( replace === undefined ) {

			throw new Error( 'Can not resolve #include <' + include + '>' );

		}

		return parseIncludes( replace );

	}

	return string.replace( pattern, replace );

}

@WestLangley @mrdoob

Three.js version
  • Dev
  • r84
  • ...
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • Linux
  • Android
  • IOS
Hardware Requirements (graphics card, VR Device, ...)
@WestLangley
Copy link
Collaborator

I assume you want to inject code into a built-in material's shader on a per-instance basis.

One hack was posted here.

I assume you are looking for an nicer API for doing so.

Is that correct?

@pailhead
Copy link
Contributor Author

pailhead commented Feb 11, 2017

Yes, to not override the global chunks. See the pull request. The hack takes care of the defines, but then the defines are further hacked by adding conditional branching in the preprocessor. You have to take care it's coordinated with the defines correctly, and that it doesn't break other stuff. With this there would be no need for branching.

#10791

@pailhead
Copy link
Contributor Author

In the future, i'd consider an api where you can inject glsl in more abstract entry points. lighting, transform_vertices etc.

As much as i hated working with scenekit, i really liked this api

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

No branches or pull requests

2 participants