Chunky by FelipeFS
Chunky by FelipeFS
GPWiki.org
It is currently Thu Jul 31, 2014 5:34 pm

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Sat Feb 15, 2014 3:02 pm 
Grossly Helpful

Joined: Wed Apr 12, 2006 6:22 pm
Posts: 156
Hi,

its been a while since I have posted something, I have been working hard on my procedural planet which is going quite well, but I have been stuck well for almost 1 year on trying to get the ocean done I have been working on porting Eric Bruneton proland spherical ocean to slimdx. I have the shader working and on non spherical mode I can almost get away with the dodgy transformation, now I am no mathematician. I belive the issue that is causing my problem is in the spherical transform part.
I have 2 main problems.
Porting the local to ocean matrix from opengl RH to dx RH this is what I believe is the problem and also the fact that in calculating the origin of ocean frame in local space I believe due to the fact that he uses z as up axis and y as depth. I would very much appreciate it if anybody can see anything obviously wrong with my code.

original:
Code:
    // compute ltoo = localToOcean transform, where ocean frame = tangent space at
    // camera projection on sphere o->radius in local space
    mat4d ctol = n->getLocalToCamera().inverse();
    vec3d cl = ctol * vec3d::ZERO; // camera in local space

    if ((o->radius == 0.0 && cl.z > o->zmin) ||
        (o->radius > 0.0 && cl.length() > o->radius + o->zmin) ||
        (o->radius < 0.0 && vec2d(cl.y, cl.z).length() < -o->radius - o->zmin))
    {
        o->oldLtoo = mat4d::IDENTITY;
        o->offset = vec3d::ZERO;
        return true;
    }

    vec3d ux, uy, uz, oo;

    if (o->radius == 0.0) {
        // flat ocean
        ux = vec3d::UNIT_X;
        uy = vec3d::UNIT_Y;
        uz = vec3d::UNIT_Z;
        oo = vec3d(cl.x, cl.y, 0.0);
    } else if (o->radius > 0.0) {
        // spherical ocean
        uz = cl.normalize(); // unit z vector of ocean frame, in local space
        if (o->oldLtoo != mat4d::IDENTITY) {
            ux = vec3d(o->oldLtoo[1][0], o->oldLtoo[1][1], o->oldLtoo[1][2]).crossProduct(uz).normalize();
        } else {
            ux = vec3d::UNIT_Z.crossProduct(uz).normalize();
        }
        uy = uz.crossProduct(ux); // unit y vector
        oo = uz * o->radius; // origin of ocean frame, in local space
    } else {
        // cylindrical ocean
        uz = vec3d(0.0, -cl.y, -cl.z).normalize();
        ux = vec3d::UNIT_X;
        uy = uz.crossProduct(ux);
        oo = vec3d(cl.x, 0.0, 0.0) + uz * o->radius;
    }

    mat4d ltoo = mat4d(
        ux.x, ux.y, ux.z, -ux.dotproduct(oo),
        uy.x, uy.y, uy.z, -uy.dotproduct(oo),
        uz.x, uz.y, uz.z, -uz.dotproduct(oo),
        0.0,  0.0,  0.0,  1.0);
    // compute ctoo = cameraToOcean transform
    mat4d ctoo = ltoo * ctol;


my code:
Code:
                // compute ltoo = localToOcean transform, where ocean frame = tangent space at
                // camera projection on sphere o->radius in local space
                Matrix ctol = Matrix.Invert (cam.View);
                Vector3 cl = Vector3.TransformCoordinate(Vector3.Zero, ctol);

            /*
                if ((radius == 0.0 && cl.Y > zmin) ||
                (radius > 0.0 && cl.Length() > radius + zmin) ||
                (radius < 0.0 && new Vector2(cl.Z, cl.Y).Length() < -radius - zmin))
                {
                    oldLtoo = Matrix.Identity;
                    offset = Vector3.Zero;
                    return;
                }*/

              Vector3 ux, uy, uz, oo;


                if (radius == 0.0)
                {
                    // flat ocean
                    ux = Vector3.UnitX;
                    uy = Vector3.UnitY;
                    uz = Vector3.UnitZ;
                    oo = new Vector3(cl.X, 0.0f, cl.Z);
                }
                    else
                {
                    //################################
                    // The current problem I belive it here.
                    // spherical ocean
                    uz = Vector3.Normalize (cl); // unit z vector of ocean frame, in local space
                   
                    if (oldLtoo != Matrix.Identity) {
                       ux = Vector3.Normalize(Vector3.Cross(new Vector3(oldLtoo.M12, oldLtoo.M22, oldLtoo.M32), uz));
                    } else {
                        ux = Vector3.Normalize(Vector3.Cross(Vector3.UnitZ, uz));
                    }
                    uy = Vector3.Cross(uz, ux); // unit y vector
                    oo = uz * radius; // origin of ocean frame, in local space       
                }

                Matrix ltoo;
                ltoo.M11 = ux.X; ltoo.M12 = uy.X; ltoo.M13 = uz.X; ltoo.M14 = 0;
                ltoo.M21 = ux.Y; ltoo.M22 = uy.Y; ltoo.M23 = uz.Y; ltoo.M24 = 0;
                ltoo.M31 = ux.Z; ltoo.M32 = uy.Z; ltoo.M33 = uz.Z; ltoo.M34 = 0;
                ltoo.M41 = -Vector3.Dot(ux, oo); ltoo.M42 = -Vector3.Dot(uy, oo); ltoo.M43 = -Vector3.Dot(uz, oo); ltoo.M44 = 1.0f;



                // compute ctoo = cameraToOcean transform
                Matrix ctoo = ctol * ltoo;


Any help would be much appreciated, I can post some screenshots if needed.

edit 16/02/2014
Ok the ltoo matrix seems to work fine as it look's like I have the flat version working perfectly. So I guess I now need to fix the spherical part .


Top
 Profile  
 
PostPosted: Mon Feb 17, 2014 1:50 am 
Digerati

Joined: Thu Sep 09, 2004 1:17 pm
Posts: 1804
Location: burrowed
Nice to see you seem to start figuring it out yourself.
As much as i'd love to assist, i dont know a lot about hlsl. And i don't really understand the problem you described.

Care to elaborate on that?

_________________
Long pork is people!

wzl's burrow


Top
 Profile  
 
PostPosted: Mon Feb 17, 2014 8:32 am 
Grossly Helpful

Joined: Wed Apr 12, 2006 6:22 pm
Posts: 156
weezl wrote:
Nice to see you seem to start figuring it out yourself.
As much as i'd love to assist, i dont know a lot about hlsl. And i don't really understand the problem you described.

Care to elaborate on that?


Hi,

I have worked most of it out by myself. Like I said the flat version is working almost perfectly. Do bare in mind that I had to rework a lot of the init code, and hlsl. Like I said its from opengl to directx both RH so everything is quite simple to port. The only problem I have is he uses a mathematical coordinate system of xzy. as appose to the one im using xyz. SO my problem is that the sphere well the hemisphere should rotate to face the camera always. I cant seem to get it to work. the main problem I think im having is it doesn't seem to b centred around the 0,0,0 axis. Which leads me to believe it is that bit of code that is causing it. Im trying not to use his code and rework it but this part of the code is important so as the shader works properly. which also has a spherical part in it too, which I believe to be correct.

e.g
Code:

           float cy = -oceanCameraPos.y;
             float dy = oceanDir.y; 

      float b = dy * (cy + radius);
      float c = cy * (cy + 2.0 * radius);
      float tSphere = -b - sqrt(max(b * b - c, 0.0));
      float tApprox = -cy / dy * (1.0 + cy / (2.0 * radius) * (1.0 - dy * dy));
      t = abs((tApprox - tSphere) * dy) < 1.0 ? tApprox : tSphere;



Sorry not very good at explaining things. I hope I have made some sense.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron

Powered by phpBB® Forum Software © phpBB Group