Jump to content

  • Log In with Google      Sign In   
  • Create Account

BlueSpud

Member Since 17 Jul 2013
Offline Last Active Mar 24 2016 03:23 PM

Topics I've Started

Placing Things in a (Kinda) Voxel World

19 July 2015 - 12:59 PM

Hey,

I'm developing a game that is a sandbox game and I want everything to be snapped into a grid, but other than that I'm using full 3D model, not cubes or anything. All the models are different, but I've built them in mind that I'm going to be using a grid snapping system to keep building nice and neat. My dilemma is placing the objects. Because I'm not really building a full voxel world like Minecraft or similar games, I haven't figured out a solution to allowing the player to accurately place things. I tried constructing a plane at the player's feet, projecting a ray from the camera and seeing where they intersect, then placing the object there. This was really bad and made some really odd results, but it did kinda work. I was wondering if anyone else has any ideas as to how I could accomplish this. As a note, there is going to be mostly blank space in the world, so I need to allow the player to place things on nothing, which is why I can't just cast a ray and test for the nearest intersection with another object. Its also a first person game that is going to have verticality, so I need to handle that as well.

 

Thanks.


Cascaded Shadow Maps Look Bad

02 February 2015 - 11:16 AM

Hey,

After a long break, I finally got cascaded shadow mapping working in my game. I use 3 cascades, each with a 1024 texture in a texture atlas. The only problem is that the shadow maps seem to be very low resolution, so low that a regular 1024 shadow map would look better. Heres a few screenshots of what the different cascades look like.

 

This is the second cascade (the third looks fine)

pHG33sv.pngAnd the first cascade looks a bit better:

htZvXF8.png

 

But should the shadows really look this bad? I tried bumping the resolution up to 2048*2048 for each cascade, but that didn't do anything for the quality for the most part. If you look at the top picture, you can see that the farthest image on the left, in the top corner, is rendering the whole house, even though thats the first cascade. My input distances are {0.001,10},{0.001,50} and {0.001,100}. I have a feeling that this is a problem in my construction of my orthographic projection, because I've pretty much copy and pasted the crop matrix from the GPU gems on this.

 

Heres some code

float orthoConst = 1;
        glm::mat4 projL = glm::ortho(orthoConst, -orthoConst, orthoConst, -orthoConst, 0.0f, 1000.0f);

//then we project the frustum corners from clip space to world space to light space
// I've omitted this because its fairly straight forward, and I've done visual debugging, and this part is fine

//now we get the min and max bounding box on the screen
glm::vec3 min,max;
        for (int i = 0; i < 8; i++)
        {
            //we use the negative because the position on the in camera is negative
            corners[i] = projL*viewL*(corners[i]);
            projectedCorners[i] = glm::vec3(corners[i]);
            
            if (i == 0)
            {
                max = min = projectedCorners[i];
                
            } else
            
            {
                if (projectedCorners[i].x > max.x)
                    max.x = projectedCorners[i].x;
                if (projectedCorners[i].y > max.y)
                    max.y = projectedCorners[i].y;
                if (projectedCorners[i].z > max.z)
                    max.z = projectedCorners[i].z;
                
                if (projectedCorners[i].x < min.x)
                    min.x = projectedCorners[i].x;
                if (projectedCorners[i].y < min.y)
                    min.y = projectedCorners[i].y;
                if (projectedCorners[i].z < min.z)
                    min.z = projectedCorners[i].z;
                
            }
            
        }

//compute the crop matrix and multiply it with the orthographic one
        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);
        
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glLoadMatrixf(&(cropMatrix*projL)[0][0]);
        glMatrixMode(GL_MODELVIEW);

I'm pretty sure that the problem lies with the near and far planes of the orthographic projection, but I don't really understand the glOrtho call, so my values are probably wrong.

 

Thanks.


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.


PARTNERS