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
20191218 add support for blend modes #1578
20191218 add support for blend modes #1578
Conversation
to be made into geometry groups when ending the batch
@johnSjo Thanks very much for implementing this. I'm testing it just now. I noticed that the screen blending mode throws an error. To do screen blending, the following seems to work in ThreeJS: material.blending = THREE.CustomBlending In the function toThreeJsBlending, maybe that can return a custom value (or array/object) for screen blending and in findMaterialGroup, check if blending equals that value and if so, set meshMaterial_1.blendDst = THREE.OneFactor. |
@adevart Sure :) (Btw, are you sure it's suppose to be 'blendDst = OneFactor'? When looking at the WebGL runtime it looks like it's 'blendSrc' that should be set to OneFactor...) |
Screen is the only missing blend mode for Spine. It only supports normal, add, multiply, screen: http://esotericsoftware.com/spine-api-reference#BlendMode I don't think they'll add more so it would be ok to hard-code 'screen' to those values. One way I did it was to set a variable in ThreeJsTexture: static BLEND_SCREEN = "SCREEN"; Then cast the blending assignments: but it's ok if you return CustomBlending for screen to avoid the type workarounds. It's also possible to return an object for all the options in ThreeJsBlending like {mode:THREE.CustomBlending, blendDst:THREE.OneFactor} I'm not sure if it should be blendDst = OneFactor. That gives the correct visual output. This page shows the blend modes: https://threejs.org/examples/webgl_materials_blending_custom.html# According to the following page, screen mode should be That also gives the correct visual output for screen mode. It's probably best to go with that one if it matches the screen mode equation. |
Added support for screen blendMode |
Nice, thanks. I'll do some testing on this update. |
@johnSjo Hi, I tested it on a number of Spine animations and for the most part it works really well. No layering issues and mixed blending modes works fine for normal, screen and additive modes. The one issue I saw was with multiply mode. For some reason multiply mode renders some faces black. I attached an image showing the raptor Spine animation where its materials have been changed to multiply mode. Next to it shows the source spritesheet in multiply mode as a sprite. The Spine correctly renders some of the parts, where transparency is rendered as a black outline but some of the parts like the tail render completely black. From what I could tell, this seems to be an issue in ThreeJS rather than this update because this happens in other places with multiply mode. I tested it on the original Spine runtime implementation with a single material and switched the blending mode to multiply and the entire Spine object rendered black. I don't know if it's to do with the shader material that is used in the Spine runtime, maybe there's some custom code in the normal shaders for multiply mode. ThreeJS interprets transparency as black for multiply mode when it should interpret it as white. With a white background in the texture map, it renders much better. But doing this didn't fix every Spine animation for me, some layers still rendered as solid black. I couldn't see any obvious reason why it would do this because it seems to work ok for some layers. At random, an object or layer in multiply mode just renders solid black. |
Humm, odd |
Hello @adevart :) It's working as it should but maybe not as expected... The normal 'multiply' works on the color values of the pixels, regardless if they are transparent or not, i.e. a pixel with the value (123,43,23,0) would normally be invisible, but with blenMode 'multiply' turned on the color of (123,43,23) will be used. That's why you get those black boxes around items (if you set the alpha on every pixel to 1 you will see that black is used as the "background" color). A white background (like what you tried) will work, the reason that the "tail-shadow" still stayed black was because they animated the alpha (but were using black as the base color, "color": "0000004a" instead of "color": "ffffff4a") When I change that I get this: So the take away is that if you're going to use 'multiply' you need to prep your textures (and possibly your animation) in the right way. It's not the most intuitive way and I don't think it's explained enough in the three.js docs... Do you think we should do anything more with this or leave it as is? |
Aha, thanks for checking that out. Yes there needs to be special consideration for the assets when dealing with multiply mode in ThreeJS.
I think it's working great. I don't think there's much that can be done to improve on this solution for supporting multiple blend modes. |
@NathanSweet So was it decided not to add this, or? since it's closed without a merge. |
Ah, sorry! I didn't notice that GitHub closed this PR automatically when the 3.9-beta branch was deleted. Our next release will be quite large so we are skipping 3.9 and the next release will be 4.0. Can I bother you to create a new PR on the 4.0-beta branch? Sorry for the trouble. |
sure, I'll make a new one |
A suggestion for adding support for blendModes in the Three.js runtime
The idea (from andrew_spn) is basically to make several geometry groups and materials.
I'm not sure why gitHub thinks the entier files have been modified
Ok, turn on "Hide whitespace changes" to see only the proper changes :)