ReMix Posted September 5, 2015 Share Posted September 5, 2015 Hi everybody ! I'm trying to do a ShaderMaterial that renders fur.Here is how it looks right now. It's starting to look good, but I still have some issues with it :Each layer of fur is rendered using an instance of the object. I have some background of making shaders in Unity3D and I like the way we can do multi-pass shaders, is there a way to do the same with babylon or my instance system the only one ?To render smoothly the material needs to be alpha blended, but then it doesn't write the depth. But in this case, I have issue when multiples "fur faces" overlay (try rotating the view in the link to overlap the fur at different distances on the object). I think the solution would be to have alpha blending and alpha cutout enabled at the same time (cutout to write in depth buffer and blending for nice effect) but it seems that if I enable both the alpha cutout is ignored (no "define ALPHATEST" in generated shader) I still have some work to do on supporting dynamic lights and stuff, but the two issues here are really blocking me. Also, I've had to add some exceptions in the ShaderMaterial attributes I pass to render the instances like listed here. Let me explain : The effect needs to work on smartphones, and I've discoverd that on my smartphone (Galaxy Note 2, Android 5.1.1, Firefox) doesn't support GPU instancing. I had to check this using engine.getCaps().instancedArrays != null, and if false pass the uniform "world" instead of the 4 "world[n]" attributes. It was quite a funny thing to find why the shader wasn't working ... That's the reason why a multi-pass shader would be useful. If somebody has some answers to my issues, any help would be greatly appreciated! Thanks! iiceman 1 Quote Link to comment Share on other sites More sharing options...
Convergence Posted September 6, 2015 Share Posted September 6, 2015 Can't answer your questions, but very cool My FPS is a tad low though for that single mesh. Quote Link to comment Share on other sites More sharing options...
ReMix Posted September 8, 2015 Author Share Posted September 8, 2015 Also, is there a way to add custom #define directive to a ShaderMaterial ? It would allow me to disable shader features depending on the platform capabilities. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 8, 2015 Share Posted September 8, 2015 Hello #define are not supported by ShaderMaterial. You have two options here:- Use differents shaders and then select the right one at runtime- Create a custom Material (by inheriting from Material). This is more advanced but you will have complete control. You can almost copy/paste code from ShaderMaterial: https://github.com/BabylonJS/Babylon.js/blob/master/src/Materials/babylon.shaderMaterial.ts Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 8, 2015 Share Posted September 8, 2015 Ok option 3 is coming You will be able to do this in the next commit: var outMaterial = new BABYLON.ShaderMaterial( name , scene, shaderPath, { attributes: matAttributes, uniforms: matUniforms, needAlphaTesting : true, needAlphaBlending: true, defines: ["#define option1", "#define option2"] }); adam 1 Quote Link to comment Share on other sites More sharing options...
Vousk-prod. Posted September 8, 2015 Share Posted September 8, 2015 Nice this Fur shader !! You definitly rocks DK, prompt and helpful, as always, and with user satisfaction in mind, BJS god is once again among us! GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
jahow Posted September 8, 2015 Share Posted September 8, 2015 Hi ReMix, Your shader is awesome. Fur always looks nice! Have you tried using only alpha cutout meshes for this effect? from a distance, it may look sufficiently nice and not require any headache with alpha blend rendering order. Also, you can try keeping your meshes alpha blended and using the alphaIndex property, see: http://doc.babylonjs.com/tutorials/Transparency_and_How_Meshes_Are_Rendered#alpha-index There is no such thing as multipass shaders in WebGL (yet). Rendering several meshes requires making several rendering calls, unless you merge all your identical meshes in one big buffer and then, through clever use of attributes and uniforms, define which part of the buffer belongs to which pass, etc. Hope that helps in any way. Quote Link to comment Share on other sites More sharing options...
MidnightCow Posted September 16, 2015 Share Posted September 16, 2015 Damn this is really nice so far! Quote Link to comment Share on other sites More sharing options...
ReMix Posted September 16, 2015 Author Share Posted September 16, 2015 Thanks for the hints and answers ! I've tried to optimize a bit the effect by moving some of the vertex deformation to javascript by generating a new mesh with the desired amount of fur layers (instead of instances) and offsetting the vertex positions. The layer "index" is stored in the vertex colors. But now I'm trying to make this work on mobile, and for some reason the demo that you can see here is extremely slow.I've disabled a bunch of features in the fragment shader (normal map, specular, rim lighting) and moved some calculations from fragment to vertex. Also, no more alpha blending but alpha test instead. Still, I think I have less then 5 fps (the debug layer on my phone says 0, but I can see it's a bit more though). I really don't know why it's so slow, any help ? EDIT : Well, even when displaying the "fur object" with the standard shader it's slow, what could be the cause ? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 16, 2015 Share Posted September 16, 2015 Hello on low end devices this may come from a crappy GPU. is a scene with just a box still slow? Quote Link to comment Share on other sites More sharing options...
ReMix Posted September 16, 2015 Author Share Posted September 16, 2015 My device is a Samsung Galaxy Note 2, a bit old but I think it still has a pretty decent GPU. The same scene with only the "skin" plane (so, a simple texture plane with standard material) runs smoothly. But as soon as I duplicate the mesh to have the fur layers, the fps drops (but still under 100 vertices and only 2 draw calls).Here is this test scene, it's the fur scene but with a standard material applied on the layers. It runs at about 5fps on my phone. Quote Link to comment Share on other sites More sharing options...
chg Posted September 16, 2015 Share Posted September 16, 2015 Dumb question: does inverting the order of the fur layers have any effect? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 16, 2015 Share Posted September 16, 2015 What kind of perf do you get by turning alpha testing off? Quote Link to comment Share on other sites More sharing options...
ReMix Posted September 17, 2015 Author Share Posted September 17, 2015 Dumb question: does inverting the order of the fur layers have any effect? No changes. What kind of perf do you get by turning alpha testing off? Apparently, no perf change. Quote Link to comment Share on other sites More sharing options...
MidnightCow Posted September 17, 2015 Share Posted September 17, 2015 Is it worth trying, rather than looping through the verts for each layer etc, taking the original plane mesh, then using SubMesh functionality, and SubMesh.clone() to build up the layers.. I think submesh is optimised for fast access ( for octree use etc ) so it may be that some small performance gain could be leveraged out of it.. Quote Link to comment Share on other sites More sharing options...
chg Posted September 17, 2015 Share Posted September 17, 2015 MidnightCow, spatial partitioning schemes like octrees shouldn't help here, the meshes are basically all in the same location (ie. they are pretty much all visible or none are) or and there is no collision detection. Quote Link to comment Share on other sites More sharing options...
ReMix Posted September 17, 2015 Author Share Posted September 17, 2015 I don't really understand, how can I clone the SubMesh inside the original mesh, without creating a new mesh ? In the doc the function is like this : clone(newMesh)So if I clone it, it must generate a new mesh object, right ? Quote Link to comment Share on other sites More sharing options...
MidnightCow Posted September 17, 2015 Share Posted September 17, 2015 CHG no I didn't mean use octree just pointing out that submesh might be better optimised than a standard mesh with duplicated internals all in serial..I would have thought .clone would create a new submesh.. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 17, 2015 Share Posted September 17, 2015 Do you use instances? Quote Link to comment Share on other sites More sharing options...
ReMix Posted September 17, 2015 Author Share Posted September 17, 2015 Do you use instances?I tried using instances at first, but on my mobile device GPU instances are not supported, so I tried this "duplicate mesh in script" trick. I got a small performance boost, probably due to having less objects to handle. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 17, 2015 Share Posted September 17, 2015 arg Quote Link to comment Share on other sites More sharing options...
ReMix Posted September 17, 2015 Author Share Posted September 17, 2015 To be sure I tried generating fake fur layers by instancing my object (a base plane) multiple times (16). And even with the standard material, this simple scene is still extremely slow.I now have absolutely no idea why it's so slow on mobile, is this normal ? EDIT : Here is the mentioned scene : 17 planes (original + 1 clone + 15 clone instances ) rendered with default material, and still slow on mobile. I found the more I have objects in the scene, more the fps drops. Same when duplicating polygons in the fur mesh.I really don't understand why this is happening, the scene with the red spaceship featured on the babylonjs homepage runs at arount 15fps on my phone, and has more vertices and more objects. Please great god Deltakosh, help me . Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 18, 2015 Share Posted September 18, 2015 It seems that your mobile is fillrate limited which means that the pixel shader seems to be the limitating factor. The spaceship works at 15fps because the number of pixel drawn is limited. In your case every layer is almost fullscreen which means that the GPU needs to render 16x480x840 pixels (I have no idea about your true resolution of your phone but you get the point ) Quote Link to comment Share on other sites More sharing options...
ReMix Posted September 18, 2015 Author Share Posted September 18, 2015 You seem to be right, I tried placing the camera further, and it runs better. (btw, the resolution is 1280x720) So I have no other choices than avoiding to see this from too close ? Or draw less layers (but that makes an ugly effect) ? That's sad . An other option I would have is to draw the fur with only one mesh like on this demo. I've never done a raymarching shader, but it's not impossible. The only thing I'm afraid of is the even this would not help me with perfs, this demo also runs at about 4 fps in fullscreen on my phone . Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 18, 2015 Share Posted September 18, 2015 On mobile we all need to reduce our quality Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.