Title: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 07, 2013, 04:21:48 PM I just joined these forums, and haven't yet had the time to apply any of the techniques to make things faster that are mentioned here.
The fragment shader is here: http://www.kinostudios.com/includes/shaders/bulb1/bulb.frag Any GLSL optimizations wanted! I just ported the code from the webgl-mandelbulb (https://code.google.com/p/webgl-mandelbulb/source/browse/3dmandelbrot.html) repo. Try it out here! (http://www.kinostudios.com/mandelbulb.html) Here's a screenshot: (https://s3.amazonaws.com/f.cl.ly/items/3R2z0I0542183t372y1Q/mandelbulb.jpg) Try it out here! (http://www.kinostudios.com/mandelbulb.html) Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: eiffie on August 07, 2013, 06:02:24 PM I doubt this code produces the exact bulb as yours and I don't know how much faster it is but it is certainly fewer instructions.
Code: float DE(vec3 z0){//MandelBulb by twinbee (sine version)Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 10, 2013, 04:05:46 AM eiffie,
I doubt this code produces the exact bulb as yours and I don't know how much faster it is but it is certainly fewer instructions. In honor of you, and as a personal project, I've updated the link with a full-blown editor that lets you live-update the shader: (http://cl.ly/image/063V2F2F002B/badassbulb.jpg) I tried for a while to get the code you sent to work, but couldn't. Something is different between the type of ray it expects. Your function is defined as DE_forum. There's also DE_blog and DE (which is what is being used by default). The pixels immediately surrounding the bulb provide some debug output: Code: // some debugging to show the difference That gives you an idea of the difference between the values the three DE's are giving. I also tried a very similar DE function from this blog post (http://blog.hvidtfeldts.net/index.php/2011/09/distance-estimated-3d-fractals-v-the-mandelbulb-different-de-approximations/). The two are almost identical, except the cosine and sine functions are somewhat interchanged. Otherwise they are identical. Results: - Your function produces no mandelbulb. - The blog post's function produces a very dark and weird looking mandelbulb. - Attempting to rotate around the mandelbulb (by using a combination of the D and Right-Arrow keys) results in extremely weird stuff. It shouldn't happen, whatever it's doing. So, any help, from you or anyone else, in getting this thing to function better would be greatly appreciated! ^_^ Launch it here: http://www.kinostudios.com/mandelbulb.html Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: Syntopia on August 10, 2013, 01:31:52 PM I also tried a very similar DE function from this blog post (http://blog.hvidtfeldts.net/index.php/2011/09/distance-estimated-3d-fractals-v-the-mandelbulb-different-de-approximations/). The two are almost identical, except the cosine and sine functions are somewhat interchanged. Otherwise they are identical. - The blog post's function produces a very dark and weird looking mandelbulb. In 'DE_blog' you start out by setting 'min_dist' to zero, which probably causes some wrong ambient occlusion. Notice, that as I mention in my blog post, there are (at least) two different versions around of the Mandelbulb. I couldn't update the code, got this error: Code: Error: Globals.shaders[file.substr(...)] is undefined DisplaySource@http://www.kinostudios.com/mandelbulb.html:97 updateMenu@http://www.kinostudios.com/mandelbulb.html:119 @http://www.kinostudios.com/mandelbulb.html:129 Scope.prototype.$eval@http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.js:8926 Scope.prototype.$apply@http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.js:9006 @http://www.kinostudios.com/mandelbulb.html:128 x.event.dispatch@http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js:5 x.event.add/y.handle@http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js:5 Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: knighty on August 10, 2013, 01:53:25 PM hi,
in the code posted by eiffie, IIRC we should have: r=length(z.xyz); instead of: r=length(z); Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 10, 2013, 02:54:22 PM In 'DE_blog' you start out by setting 'min_dist' to zero, which probably causes some wrong ambient occlusion. Notice, that as I mention in my blog post, there are (at least) two different versions around of the Mandelbulb. Good catch! That fixed the lighting. Quote I couldn't update the code, got this error: Code: Error: Globals.shaders[file.substr(...)] is undefined DisplaySource@http://www.kinostudios.com/mandelbulb.html:97 updateMenu@http://www.kinostudios.com/mandelbulb.html:119 @http://www.kinostudios.com/mandelbulb.html:129 Scope.prototype.$eval@http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.js:8926 Scope.prototype.$apply@http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.js:9006 @http://www.kinostudios.com/mandelbulb.html:128 x.event.dispatch@http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js:5 x.event.add/y.handle@http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js:5 I've updated the page with some debug output to the console. Go ahead and do Command+Shift+R (on a Mac), or Ctrl+Shift+R on Windows/Linux to get the latest version of the fragment shader. When you click "Update Shaders", copy/paste the output from the console, I'm looking for a line that says something like: "displaying file: bulb.frag ext: frag" Also, what browsers did you try? hi, in the code posted by eiffie, IIRC we should have: r=length(z.xyz); instead of: r=length(z); Thanks knighty! I think given enough time I could've even figured that out myself! :-D It runs fine now, there are just three problems left:
(http://cl.ly/image/15183x2m2o3H/sideview.jpg) I'm guessing some multiplication via the eye/ray and the modelViewMatrix isn't correct... Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: knighty on August 10, 2013, 03:40:37 PM It looks more like the FOV is too wide.
Try higher bailout (say 100) values for better distance estimate -> better results. The code provided by eiffie uses "scalar derivative" which is less accurate. Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 10, 2013, 03:46:21 PM It looks more like the FOV is too wide. Try higher bailout (say 100) values for better distance estimate -> better results. The code provided by eiffie uses "scalar derivative" which is less accurate. I don't see what FOV has to do with this. If it was a FOV problem, wouldn't that affect it similarly when you're looking at it straight on too? 100 for the bailout...? I don't see how putting such a high bailout is going to fix that problem either. Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: cKleinhuis on August 10, 2013, 03:50:33 PM bailout influences the noise, fov influences the stretch
Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 10, 2013, 04:09:15 PM bailout influences the noise, fov influences the stretch What should the FOV be? It's 45 right now. Why would the stretch get worse and worse the more you turn it? I've never seen FOV do that. You're of course welcome to edit the source, although the FOV is modified in the html file (you might be able to do it with Firebug for example). Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: eiffie on August 10, 2013, 04:24:34 PM Thanks for creating the editor! And thanks knighty for correcting the code. I believe I have yet to post working code on this site. Just keeping you all on your toes.
Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 10, 2013, 04:28:54 PM Np eiffie! :-)
BTW, as suspected, bailout has nothing to do with it. Here I've set it to 100: (http://cl.ly/image/2u3d0k390I2e/bailout-has-nothing-to-do-with-it.jpg) Of course, the reason I made this editor is so that anyone can edit the source themselves to try to improve it... Just replace DE with DE_forum, and DE_forum with DE to use the forum version. Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: knighty on August 10, 2013, 05:29:33 PM Sorry, I was not clear enought. Of course, bailout have nothing to do with the "effect" you are having.
Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: knighty on August 10, 2013, 06:47:22 PM How do you set up view position and direction?
Assuming you set up the camera in the host program: When rendering a mesh, you construct the modelViewProjection matrix (and usually the modelView matrix) then in the (basic) vertex shader is: Code: void main() For raytracing one have to reverse the process because the vertices of the quad that is drawn are in the view space and we need to compute the rays directions in the "world space". here is roughly how I do (BTW I'm not up to date with OpenGL): Vertex shader: Code: varying vec3 rayDir; Code: varying vec3 rayDir; Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 10, 2013, 10:39:33 PM How do you set up view position and direction? three.js does much of the work, but the part that's on me you can find by viewing the page source. The only geometry/vertices that are sent are 4 vertices representing a square. I believe they should be the same as these (found from another source, and checked via the implementation of THREE.PlaneGeometry): Code: var vertexPositions = [ Quote :Vertex shader: Code: varying vec3 rayDir; Code: varying vec3 rayDir; I had to create modelViewMatrixInverse on my own, but it's there now as a uniform. This is how it's created: Code: var modelViewProjectMatrixInverse = new THREE.Matrix4(); Just look at the source of the page to get an idea of what's going on. However, now I'm getting even worse results: (http://cl.ly/image/453z0U2g1W2z/bizarrobulb.jpg) You can try it out yourself now (make sure to do a Command/Ctrl+Shift+R refresh). Just uncomment this line near the top of bulb.frag: Code: // #define USE_KNIGHTY http://www.kinostudios.com/mandelbulb.html Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: Syntopia on August 11, 2013, 12:11:11 AM Code: modelViewProjectMatrixInverse.multiplyMatrices(camera.matrixWorldInverse, mesh.matrixWorld).multiply(camera.projectionMatrix) The order seems wrong: I think the matrix you need to invert is: camera.projectionMatrix * camera.matrixWorldInverse * mesh.matrixWorld Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 11, 2013, 12:14:21 AM The order seems wrong: I think the matrix you need to invert is: camera.projectionMatrix * camera.matrixWorldInverse * mesh.matrixWorld In what order should that be done? Also, one thing to keep in mind is that the controls do not update the camera's position, but the object's. The camera's position stays fixed, but because the model is being moved and rotated, it gives the illusion that the camera is flying around. Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 11, 2013, 12:20:56 AM In what order should that be done? Also, one thing to keep in mind is that the controls do not update the camera's position, but the object's. The camera's position stays fixed, but because the model is being moved and rotated, it gives the illusion that the camera is flying around. I just tried multiplying it like this: Code: modelViewProjectMatrixInverse.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse).multiply(mesh.matrixWorld); And that didn't fix it, it just made the controls super sensitive. I'll mention this again just in case you didn't see it, as I think it's what's causing the problem: "Also, one thing to keep in mind is that the controls do not update the camera's position, but the object's. The camera's position stays fixed, but because the model is being moved and rotated, it gives the illusion that the camera is flying around." Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 11, 2013, 01:09:50 AM I'm thinking that perhaps somewhere in the vertex shader something along these lines needs to be done:
Code: vec4 WPpos = modelViewProjectMatrixInverse * gl_Position; In otherwords, making use of "modelMatrix[3].xyz" instead of the camera position to figure out the ray direction, because the camera position is a constant. None of my foolings-around have made anything that looks correct, however. EDIT: of course, there's also this: Code: rayDir = (modelViewMatrix * gl_Position).xyz; But that just produces the same strange warped scaling effect when you rotate. Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: Syntopia on August 11, 2013, 09:03:07 AM In what order should that be done? In the order stated. Matrix multiplication is associative, so (AB)C=A(BC) Quote Also, one thing to keep in mind is that the controls do not update the camera's position, but the object's. The camera's position stays fixed, but because the model is being moved and rotated, it gives the illusion that the camera is flying around. I think you should use FlyControls on the camera instead of the object. Btw, looking at your code, I realized this is based on Tom Beddards PixelBender script. Be sure to include his copyright notice and license conditions in your shader code. Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 11, 2013, 04:13:11 PM In the order stated. Matrix multiplication is associative, so (AB)C=A(BC) K, I was wondering whether to read it from left-to-right or right-to-left. I assume you meant left-to-right. Quote I think you should use FlyControls on the camera instead of the object. Yes, I was doing that originally but because things weren't working very well I changed it (and it improved the situation, but did not fix other problems). Changing the controls to manipulate the camera has fixed the crazy stretching problem! :D (http://cl.ly/image/0T0t1P2k0D00/mandelbulb-almost.jpg) The problem now is that for some reason movement via the controls is very jittery. Try it out.. (http://www.kinostudios.com/mandelbulb.html) I'm not sure why this is happening. Any more help appreciated! It's almost perfect. :) I decided to remove the phasing for now (you can add it back by editing the fragment shader) because it's just too ugly with the DE function from your blog and the one here on the forums, but I'd rather use those because they're much faster. Quote Btw, looking at your code, I realized this is based on Tom Beddards PixelBender script. Be sure to include his copyright notice and license conditions in your shader code. Thanks for pointing that out! I had a link to the original file where you could find the copyright notice but at your suggestion I've copied that into the file itself. Note that the original file doesn't include the license conditions verbatim either, but rather a link to the MIT license. Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 11, 2013, 04:43:52 PM One observation: the epileptic jitteriness is only caused by the WASD keys that affect the position/translation of the object, while the arrow keys, which only affect the rotation, do not cause any jitteriness.
Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: knighty on August 11, 2013, 09:15:28 PM Yay! it works! :D
i've modified the intersect sphere: Code: bool intersectBoundingSphere(vec3 origin, one have to change the value of min_dist to 2. for example (in renderPixel function). It doesn't work when min_dist==4. Strange! Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 12, 2013, 02:02:36 AM Yay! it works! :D i've modified the intersect sphere: Code: bool intersectBoundingSphere(vec3 origin, one have to change the value of min_dist to 2. for example (in renderPixel function). It doesn't work when min_dist==4. Strange! Awesome! Thanks knighty! :-D I've updated the source and have added your changes. :) I've also fixed the jitteriness problem! The problem was that the camera's matrixWorldInverse and the mesh's matrixWorld were getting out of sync, thus creating an out of sync value for modelViewProjectMatrixInverse. When controls.update is called, it updates the "matrix" value of the camera (but NOT its matrixWorld or matrixWorldInverse values). Then modelViewProjectMatrixInverse was set using those values, and then the renderer.render function was called. In the render function, however, all of the matrixWorld's and matrixWorldInverse were set to the updated values, but our modelViewProjectMatrixInverse was set using the previous values, thus making it out of sync, yet it was multiplied by the updated vertex values. So to fix this we have to update the matrices ourselves before calling render: Code: function render() {Also, I've updated the source code comments to give thanks to all of you for helping me with this! Thanks a ton for your help! ;D There's only really one major problem now (and one "wish I could have"): - You can't fly into the Mandelbulb. If you get too close, the camera will fly off into space for some reason. - It would be nice if we could have the neat phasing effects that the original DE function supported while still having the same fast framerate. Link, as always: http://www.kinostudios.com/mandelbulb.html Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 12, 2013, 02:33:35 AM It's a lot of fun to color it too. If you enable the phase and use the original DE function, it can look really neat.
I found that right at the end of the color function, before the pixel_color.a = 1.0; line, you can insert random equations and get very neat (and surprising results). Like this one (not safe for epileptics!): Code: pixel_color.g /= cos(pow(sin(phase.x),phase.y)); And this one: Code: pixel_color.g /= cos(pow(sin(phase.x),phase.y)); Which produces a neat swirling rose-like effect: (http://cl.ly/image/0X2K1z0M2s3d/mandelred.jpg) If you find any particularly interesting combinations, let me know! :) If I had all the time in the world I'd implement adding color presets. :) Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: knighty on August 12, 2013, 09:56:31 PM I's almost perfect now :). Maybe it needs a log window to display shaders errors and warnings.
Here is a modification of eiffie's code to make it look like subblue's DE_original. pahse also looks the same: Code: // FROM: http://www.fractalforums.com/index.php?topic=16793.msg64299#msg64299 For the interior, infortunately the DE formula doesn't really work inside. It's an open problem. As noticed by visual.bermarte, you can still use the DE (especially those based on scalar derivative like the one above) to dive inside but: - The DE is negative inside so you need to modify the code in order to take this into account. - It's not perfect at all: epsilonScale have to be smaller than one. - It's still not perfect at all. :banginghead: Title: Re: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted) Post by: itistoday on August 12, 2013, 11:47:08 PM I's almost perfect now :). Maybe it needs a log window to display shaders errors and warnings. Here is a modification of eiffie's code to make it look like subblue's DE_original. pahse also looks the same: Code: // FROM: http://www.fractalforums.com/index.php?topic=16793.msg64299#msg64299 For the interior, infortunately the DE formula doesn't really work inside. It's an open problem. As noticed by visual.bermarte, you can still use the DE (especially those based on scalar derivative like the one above) to dive inside but: - The DE is negative inside so you need to modify the code in order to take this into account. - It's not perfect at all: epsilonScale have to be smaller than one. - It's still not perfect at all. :banginghead: AWESOME knighty! Thanks a bunch! :D Exactly what I was hoping for. I've updated the code with yours and have also done a lot of cleanup. :) (http://cl.ly/image/02412d2a1Z2g/mandelbulb-final.jpg) http://www.kinostudios.com/mandelbulb.html |