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

Allow ShaderChunk overrides in materials (feature request/idea) #13364

Closed
nhalloran opened this issue Feb 19, 2018 · 3 comments
Closed

Allow ShaderChunk overrides in materials (feature request/idea) #13364

nhalloran opened this issue Feb 19, 2018 · 3 comments

Comments

@nhalloran
Copy link
Contributor

I know that the challenge of customizable materials has been discussed quite a bit, but here is a feature I would love to see to that end. I've included proposed (incomplete) code changes, and I could try doing the PR, but I am not sure if the idea is well conceived.

Problem:

I often run into situations where I want to use an existing material, e.g. THREE.MeshPhongMaterial and modify the shaders. Rebuilding such materials from scratch as a THREE.ShaderMaterial is cumbersome, but my current solution.

This tool I found allows you to insert code into existing shaders, which is nice, though a bit hacky.
https://www.npmjs.com/package/three-material-modifier
But in some cases I would like to modify a line or more.

Proposed Solution:

Materials allow a shaderChunks argument to be passed, which is an object containing glsl strings that override ShaderChunks used by ShaderLib. For example:

var shaderChunks = {
//monochrome just from R channel of texture
map_fragment:  "diffuseColor *= vec4(vec3(texture2D( map, vUv ).x),1.0);"
};
var material = new THREE.MeshBasicMaterial({shaderChunks:shaderChunks});

Implementation

I started making some changes to see how hard it would be:
nhalloran@7795a9a
nhalloran@44d35a5

But a tricky part would be the handling the #includes in the ShaderLib directory
https://github.com/mrdoob/three.js/tree/dev/src/renderers/shaders/ShaderLib

I'm not exactly sure how those are built....

Would love feedback before going any further towards a PR.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 26, 2018

Have you checked out Material.onBeforeCompile() (see #11475)? It allows you to modify built-in materials via a callback function.

There is also an example that illustrates the approach: https://threejs.org/examples/webgl_materials_modified.html

@pailhead
Copy link
Contributor

pailhead commented Mar 2, 2018

@nhalloran
Maybe also check out this PR and pitch in with some thoughts. So far i've not seen anyone use onBeforeCompile but i've seen a lot of:

THREE.ShaderChunk.some_chunk = myChunk

It seems intuitive and natural that you would pass bits, or chunks of data into the material. Even the name ShaderChunk sounds appropriate for this.

#13198

myMaterial.shader.chunks.fog_fragment = myFogFragment
myMaterial.shader.uniforms.vertex.myVertFloat = { type: 'f', value: 1 }
myMaterial.shader.attributes.index = { type: 'f' }
//etc..

It's very unlikely that onBeforeCompile will ever change. I'd love to compare notes if you find a good way of using it.

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 15, 2019

Please use Material.onBeforeCompile() for such use cases for now. Alternatively, have a look at the experimental NodeMaterial.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants