Logo by KRAFTWERK - Contribute your own Logo!

END OF AN ERA, FRACTALFORUMS.COM IS CONTINUED ON FRACTALFORUMS.ORG

it was a great time but no longer maintainable by c.Kleinhuis contact him for any data retrieval,
thanks and see you perhaps in 10 years again

this forum will stay online for reference
News: Follow us on Twitter
 
*
Welcome, Guest. Please login or register. May 23, 2022, 09:48:10 AM


Login with username, password and session length


The All New FractalForums is now in Public Beta Testing! Visit FractalForums.org and check it out!


Pages: 1 [2]   Go Down
  Print  
Share this topic on DiggShare this topic on FacebookShare this topic on GoogleShare this topic on RedditShare this topic on StumbleUponShare this topic on Twitter
Author Topic: WebGL Mandelbulb with THREE.js flythrough controls (optimizations wanted)  (Read 7714 times)
0 Members and 1 Guest are viewing this topic.
Syntopia
Fractal Molossus
**
Posts: 681



syntopiadk
WWW
« Reply #15 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
Logged
itistoday
Forums Freshman
**
Posts: 15


« Reply #16 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.
Logged
itistoday
Forums Freshman
**
Posts: 15


« Reply #17 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."
Logged
itistoday
Forums Freshman
**
Posts: 15


« Reply #18 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;
    WPpos /= WPpos.w;
    rayDir = WPpos.xyz - modelMatrix[3].xyz;

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.
« Last Edit: August 11, 2013, 01:29:10 AM by itistoday » Logged
Syntopia
Fractal Molossus
**
Posts: 681



syntopiadk
WWW
« Reply #19 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.
Logged
itistoday
Forums Freshman
**
Posts: 15


« Reply #20 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! cheesy



The problem now is that for some reason movement via the controls is very jittery. Try it out.. I'm not sure why this is happening. Any more help appreciated! It's almost perfect. smiley

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.
Logged
itistoday
Forums Freshman
**
Posts: 15


« Reply #21 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.
Logged
knighty
Fractal Iambus
***
Posts: 819


« Reply #22 on: August 11, 2013, 09:15:28 PM »

Yay! it works!  cheesy

i've modified the intersect sphere:
Code:
bool intersectBoundingSphere(vec3 origin,
    vec3 direction,
    out float tmin,
    out float tmax)
{
    bool hit = false;

    float b = dot(origin, direction);
    float c = dot(origin, origin) - bounding*bounding;
    float disc = b*b - c;         // discriminant
    tmin = tmax = 0.0;

    if (disc > 0.0) {
        // Real root of disc, so intersection
        float sdisc = sqrt(disc);
       
        tmin=max(0.,-b - sdisc);//DE(origin + max(0.,t0) * direction, min_dist);//
        tmax=max(0.,-b + sdisc);//max(0.,t0)+t1;
        hit = true;
    }

    return hit;
}
This way the value of ray_length is correct and the details change while zooming is even  and the fractal doesn't disapear when far away. But
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!

Logged
itistoday
Forums Freshman
**
Posts: 15


« Reply #23 on: August 12, 2013, 02:02:36 AM »

Yay! it works!  cheesy

i've modified the intersect sphere:
Code:
bool intersectBoundingSphere(vec3 origin,
    vec3 direction,
    out float tmin,
    out float tmax)
{
    bool hit = false;

    float b = dot(origin, direction);
    float c = dot(origin, origin) - bounding*bounding;
    float disc = b*b - c;         // discriminant
    tmin = tmax = 0.0;

    if (disc > 0.0) {
        // Real root of disc, so intersection
        float sdisc = sqrt(disc);
       
        tmin=max(0.,-b - sdisc);//DE(origin + max(0.,t0) * direction, min_dist);//
        tmax=max(0.,-b + sdisc);//max(0.,t0)+t1;
        hit = true;
    }

    return hit;
}
This way the value of ray_length is correct and the details change while zooming is even  and the fractal doesn't disapear when far away. But
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. smiley

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() {
            controls.update( clock.getDelta() );

            // BUG!! in three.js (at least r59). we need to calculate the
            // matrixWorldInverse here ourselves, otherwise we'll get a
            // jittery effect.
            camera.updateMatrixWorld();
            camera.matrixWorldInverse.getInverse( camera.matrixWorld );

            uniforms.time.value += 0.05;
            modelViewProjectMatrixInverse.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse).multiply(mesh.matrixWorld);
            modelViewProjectMatrixInverse.getInverse(modelViewProjectMatrixInverse);
            uniforms.modelViewProjectMatrixInverse.value = modelViewProjectMatrixInverse;
           
            renderer.render( scene, camera );
        }

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!  grin

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
Logged
itistoday
Forums Freshman
**
Posts: 15


« Reply #24 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));
            pixel_color.r *= -ray_length -dist * tan(pow(phase.x, pixel_color.g));
            pixel_color.b /= DE(ray, dist)* sin(phase.y) ;
            pixel_color.a = 1.0;

And this one:

Code:
           pixel_color.g /= cos(pow(sin(phase.x),phase.y));
            pixel_color.r /= tan(pow(float(i), cos(float(i))));
            pixel_color.b /= sin(pow(phase.y, sin(phase.y)));
            pixel_color.a = 1.0;

Which produces a neat swirling rose-like effect:



If you find any particularly interesting combinations, let me know! smiley

If I had all the time in the world I'd implement adding color presets. smiley
« Last Edit: August 12, 2013, 02:40:27 AM by itistoday » Logged
knighty
Fractal Iambus
***
Posts: 819


« Reply #25 on: August 12, 2013, 09:56:31 PM »

I's almost perfect now smiley. 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
float DE(vec3 z0, inout float min_dist){//MandelBulb by twinbee
    vec4 z = vec4(z0,1.0), c = z;
    float r = length(z.xyz),zr,theta,phi,p=power;//p is the power
    phi = atan(z.y, z.x) * p;// th = atan(z.y, z.x) + phase.x; ...and here
    theta = asin(z.z / r) * p;// ph = acos(z.z / r) + phase.y; add phase shifts here
    min_dist = min(min_dist, r);
    for (int n = 0; n < MAX_ITERATIONS; n++) {
        zr = pow(r, p-1.0);
        z=zr*vec4(r*vec3(sin(theta)*vec2(cos(phi),sin(phi)),cos(theta)),z.w*p)+c; // this version was from the forums
        r = length(z.xyz);
        min_dist = min(min_dist, r);
        if (r > bailout) break;
        phi = (atan(z.y, z.x) + phase.x) * p;// th = atan(z.y, z.x) + phase.x; ...and here
        theta = (acos(z.z / r) + phase.y) * p;// ph = acos(z.z / r) + phase.y; add phase shifts here 
    }
    return 0.5 * log(r) * r / z.w;
}
(I think it will look better with lower pixel_scale values.)

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.  head banging wall
Logged
itistoday
Forums Freshman
**
Posts: 15


« Reply #26 on: August 12, 2013, 11:47:08 PM »

I's almost perfect now smiley. 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
float DE(vec3 z0, inout float min_dist){//MandelBulb by twinbee
    vec4 z = vec4(z0,1.0), c = z;
    float r = length(z.xyz),zr,theta,phi,p=power;//p is the power
    phi = atan(z.y, z.x) * p;// th = atan(z.y, z.x) + phase.x; ...and here
    theta = asin(z.z / r) * p;// ph = acos(z.z / r) + phase.y; add phase shifts here
    min_dist = min(min_dist, r);
    for (int n = 0; n < MAX_ITERATIONS; n++) {
        zr = pow(r, p-1.0);
        z=zr*vec4(r*vec3(sin(theta)*vec2(cos(phi),sin(phi)),cos(theta)),z.w*p)+c; // this version was from the forums
        r = length(z.xyz);
        min_dist = min(min_dist, r);
        if (r > bailout) break;
        phi = (atan(z.y, z.x) + phase.x) * p;// th = atan(z.y, z.x) + phase.x; ...and here
        theta = (acos(z.z / r) + phase.y) * p;// ph = acos(z.z / r) + phase.y; add phase shifts here 
    }
    return 0.5 * log(r) * r / z.w;
}
(I think it will look better with lower pixel_scale values.)

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.  head banging wall


AWESOME knighty! Thanks a bunch! cheesy

Exactly what I was hoping for. I've updated the code with yours and have also done a lot of cleanup. smiley



http://www.kinostudios.com/mandelbulb.html
Logged
Pages: 1 [2]   Go Down
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
DOF controls Mandelbulb 3d Madman 4 1780 Last post November 29, 2010, 07:48:29 PM
by Madman
Firestorm Flythrough Movies Showcase (Rate My Movie) kon16ov 2 735 Last post February 04, 2011, 10:28:52 PM
by kon16ov
webgl mandelbulb Let's collaborate on something! MrMike 2 1765 Last post December 14, 2011, 08:37:17 PM
by marius
Mandelbulb in WebGl Gestaltlupe Gallery trafassel 0 521 Last post January 17, 2016, 01:15:26 PM
by trafassel
Mandelbulb in WebGl Gestaltlupe Gallery trafassel 0 690 Last post January 17, 2016, 01:18:54 PM
by trafassel

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM
Page created in 0.196 seconds with 26 queries. (Pretty URLs adds 0.013s, 2q)