Jump to content

  • Log In with Google      Sign In   
  • Create Account

BlueSpud

Member Since 17 Jul 2013
Offline Last Active Yesterday, 09:29 AM

Topics I've Started

Crop Matrix Changing Far Plane? [CSM]

11 January 2015 - 06:42 PM

I've been working on CSM, and I'm really close to getting the hard, math part done. I've been following this: https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch10.html and this: http://developer.download.nvidia.com/SDK/10.5/opengl/src/cascaded_shadow_maps/doc/cascaded_shadow_maps.pdf 

I'm only doing one cascade right now, so everything near my Camera should be shadowed and everything else should be funky because its not actually in the shadow map. My frustum slice is at 0.1 to 10.0, which should shadow the objects in my scene properly. Here is my code for the crop matrix: 

//we have the projected corners, which we no longer need, as well as a crop matrix now
glm::vec2 S = glm::vec2(2.0/(max.x-min.x),2.0/(max.y-min.y));
glm::vec2 O = glm::vec2(-0.5*(max.x + min.x)*S.x,-0.5*(max.y + min.y)*S.y);

float scaleZ = 1.0f / (max.z - min.z);

glm::mat4 cropMatrix = glm::mat4(S.x,0,0,0,
0,S.y,0,0,
0,0,scaleZ,0,
O.x,O.y,-min.z*scaleZ,1.0);

glm::mat4 newOrtho = glm::ortho(orthoConst, -orthoConst, orthoConst, -orthoConst, 0.1f, 1000.0f);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glLoadMatrixf(&(newOrtho*cropMatrix)[0][0]);
glMatrixMode(GL_MODELVIEW); 

The above code doesn't really produce the right results. After a debug draw, I saw that as objects got further away from the light camera, they clipped through the far plane, even though its set to 1,000. Shouldn't it be zooming in to the smaller area as the frustum moves farther away from the light? Thats why I think something is up with the near and far planes. I've tried using the min and max z of the bounding box, but that doesn't seem to help, because I think they are in light clip-space instead of "world space", which is what glOrtho, or in this case glm::ortho uses, I think. I've done debug draws of all the bounding boxes and stuff, and those are correct. When I make the frustum slice to 50, it seems to work fine. Whats wrong with my projection matrix or cropping matrix? Is the cropping matrix scaling the far plane wrong? 

Any advice or help would be appreciated. Thanks.


Multiple Textures Per Draw Call

03 January 2015 - 01:49 PM

Hey,

In the past I've used multiple draw calls to put multiple textures on an object. This is really simplistic, and not very optimal. Optimally, a texture atlas would be the best solution, but I might want to have shared textures between objects. For instance 2 objects that are made out of the same stone and there are 4 different colors. Thats not a great example because a texture atlas could be used for that, but I think you get the point.

 

My question is, is there any way to bind multiple textures to a single draw call? I know that it is possible by changing the active texture, but then I need to somehow determine which vertex uses which texture, blah blah blah. If it makes a difference, I'm using display lists just because they're simpler than VBO's and VBO's don't provide any benefit. (These are all static meshes).

 

Anyone have any ideas how this could be done?


Getting The Proper Matrices for Collada Bones

02 January 2015 - 09:00 AM

Hey,

I've been working on  a collide parser so that I can load animations into my 3D game engine. Loading the mesh was fine, but the matrices are proving more difficult. Heres an excerpt of the collide file where I'm getting the matrixes from:

<node id="Bone" name="Bone" sid="Bone" type="JOINT">
          <matrix sid="transform">1 0 0 0 0 0 -1 0 0 1 0 0 0 0 0 1</matrix>
          <node id="Bone_L_003" name="Bone_L.003" sid="Bone_L_003" type="JOINT">
            <matrix sid="transform">-0.09441032 0.9104859 -0.4026195 0 -0.003315724 0.4041361 0.9146928 1 0.9955279 0.08769138 -0.03513567 0 0 0 0 1</matrix>
            <node id="Bone_L_004" name="Bone_L.004" sid="Bone_L_004" type="JOINT">
              <matrix sid="transform">0.9903602 -0.1379391 -0.01263393 4.42378e-9 0.1280975 0.8773445 0.4624475 0.5919743 -0.05270529 -0.4596079 0.8865565 0 0 0 0 1</matrix>
              <node id="Bone_L_005" name="Bone_L.005" sid="Bone_L_005" type="JOINT">
                <matrix sid="transform">0.9998035 0.01974073 0.001811555 0 -0.01976132 0.9997309 0.01215545 1.170679 -0.001571106 -0.01218885 0.9999247 0 0 0 0 1</matrix>
              </node>
            </node>
          </node>

And heres the code that I use to load the matrix for each bone:

 //we get the matrix of this bone
            search = root->getChildrenWithName("matrix");
            
            //read the matrix
            float matrixArray[16];
            
            std::stringstream contentStream(search[0]->contents);
            std::string nextNum;
            
            //fill up the array with the matrix data. We use 16 because its a 4x4 matrix
            for (int i = 0; i < 16; i++)
            {
                getline(contentStream, nextNum, ' ');
                matrixArray[i] = atof(nextNum.c_str());
            }
        
            newBone->matrix = glm::make_mat4(matrixArray);

My understanding of the collada file comes from here: http://www.wazim.com/Collada_Tutorial_1.htm which says that the matrices are local and need to be multiplied with their parent in order to get the world matrix. I do that in this function (and I order the bones so that the parents are always multiplied before the children)

for (int i = 0; i < orderedBones.size(); i++)
            {
                //orderedBones[i]->matrix *= shapeMat;
                
                if (orderedBones[i]->parent != nullptr)
                    orderedBones[i]->matrix *= orderedBones[i]->parent->matrix;
            }

A quick debug render:

for (int i = 0; i < c->skeleton->orderedBones.size(); i++)
            {
               
                if (c->skeleton->orderedBones[i]->parent != nullptr)
                {
                    glBegin(GL_LINES);
                    glm::vec4 point = c->skeleton->orderedBones[i]->matrix*glm::vec4(0, 0, 0.7538023,1);
                    glm::vec4 pointP = c->skeleton->orderedBones[i]->parent->matrix*glm::vec4(0, 0, 0.7538023,1);
                    glVertex4fv(&pointP[0]);
                    glVertex4fv(&point[0]);
                    glEnd();
                }
                
            }

And I don't get the result that I can see in blender, which befuzzles me. Is there a matrix I've missed? I've tried multiplying the orderedBones[i]->matrix by the bind shape matrix, but that doesn't do anything but make the whole rig smaller. If anyone can clarify my understanding of how this is supposed to work, or tell me what code is wrong, I would be much appreciated. Thanks.


Quadratic Attenuation For Radius

29 December 2014 - 10:06 AM

Hey,

I have a light, with a radius, and I want to calculate the attenuation for it given a radius. I've looked at several equations and tried out a few myself, but I can't seem to find the one that looks just right. Anyone have any good equations for it?


Getting Bounding Box For Sphere on Screen

13 December 2014 - 05:35 PM

Hey,

So I want to do a bit of optimization on my deferred renderer, in that currently I render all the lights as full screen quads, which wastes a lot of time on unnecessary pixels. Right now, all I have is point lights, so basically lights are represented with a position and a radius. I want to compute the bounding box for the sphere so that I can either render quads where the fragment shader is going to be preformed or tile-based shading, all though I'm not sure if tile based shading needs this kind of computation. Right now I've used an approximation algorithm to get the radius and the center on screen and then I can construct the bounding box by that. It goes something like this:

float rad = glm::atan(lightRad, screenSpacePos.z);
            rad = rad*(glm::max(ENGINE_WIDTH, ENGINE_HEIGHT) / glm::radians(RENDERENGINE_FOV));

It kinda works, but, like I said, its only an approximation, and when the camera is rotated, things that it covers becomes uncovered, so I need a more accurate representation. My thought was to construct a bounding box of the sphere in world space and translate it to clip space, get the min and max of all the points and construct a bounding box that way. Is there any way to do this more optimally? Or is this going to be one of the best ways to make sure that this is fairly accurate, as well as include other shapes ultimately (because bounding boxes can be calculated for those too). 

 

Thanks.


PARTNERS