Jump to content
  • Advertisement

Gnollrunner

Member
  • Content Count

    266
  • Joined

  • Last visited

  • Days Won

    2

Gnollrunner last won the day on October 15

Gnollrunner had the most liked content!

Community Reputation

136 Neutral

About Gnollrunner

  • Rank
    Member

Personal Information

  • Role
    Programmer
  • Interests
    Programming

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Riiiiiiight ........ OK I don't think I'm going to discuss this further here. I'll let blog stand on it's on in the upcoming months. Also it'll be interesting to see what you come up with.
  2. I don't know about that. I think I can implement complex tasks quite well. I wrote the final programming assignment for one of my friends university classes last year. So people couldn't copy each other's work he handed out different tasks to different students. I had to write his in x64 ASM which I didn't even know when I started. He got a 5+ which means he not only got a perfect score but he didn't have to take the final exam. He told me the professor had written the same program and said to him "How did you do it? You smoked my code!". So yes it's possible to do decent work without a degree. ...... My blog is pretty basic at the moment, but if you follow it maybe I can change your mind in the next few months.
  3. I'll throw another 2 cents in. I think the value of a degree varies greatly depending on where you live. I now live in Russia and my wife tells me that the paper is worth everything here, and for some jobs your actual skill means next to nothing. This kind of stretches over to trade skills too. What they call a "master" here may be OK, or may do complete crap work. I've learned to do a few things here like welding and some other construction type work, because hiring someone is a crap shoot. Even if I do hire them, I'll sometimes stand over their shoulder and make sure they are dong a decent job. On the other hand I was born and grew up in silicon valley. I had a high school diploma and went to community college but was kind of unmotivated until I fell into programming. I got hired by a major semiconductor company as a tech in 1983 with not even an AA degree. I guess I must have impressed them in the interview. I worked there for nearly 25+ years and for most of that I was working as an engineer. I was higher ranked than a lot of the PhDs for much of that time. We had no world wide web, when I started but what we did have was "computer literacy", a book store that stocked all the latest tech books. To this day I think books are better than the web. I went there nearly every week and I spent a good chunk of money on books over the years. I think my main strength is not knowing so much, but rather being willing to dig in and solve problems, by doing a lot of reading, and sometimes sitting for hours with paper and pencil and figuring out new ways to do stuff. At this point the only reason I feel I might want a degree is to show it to someone else in a job interview. That being said I think having the paper can help get you in the door in many places. When you apply for a job, most times people just expect you to have it. That's not to say they will never hire you without it, but it's just one conversation you don't have to have about why you never got your degree. Again to the OP, I would say if you have the time, money and inclination, it's worth it, but the bottom line is still motivation.
  4. Ok I'll throw my 2 cents in. I don't have a degree but I have a lot of experience. I have always been able to find a job but still sometimes I wish I had the degree. Not necessarily because I would learn anything new, I do that all the time on my own, but just because people look at my resume and kind of go WTF ?!?! I worked for a long time at a MAJOR semi-conductor company as an engineer and they are kind of not sure what to think about me. Some companies won't even consider you without a degree, or they think maybe you aren't really that good. I sometimes even now think about trying to get some sort of base level programming degree. To the OP I would say go for it! You don't have to have the uber-degree but I think just having something is a good idea. You will probably learn something too. I've actually helped a couple friends get degrees. In some cases I wrote whole final projects for them. It was actually quite educational for me. At one point I learned X64 ASM. Another time I learned some stuff about prime numbers and encoding. Some of the stuff I actually think I can use in my game work, so I don't look at it as wasted time.
  5. Ok where to begin.... First off I just noticed you were using Unity which means you are probably using C#. I haven't used C# in a long time an in general I don't like managed languages for algorithmic work, because I feel it handcuffs you somewhat in how you build your data structures. I guess you sill have some sort of weak pointers in C#, but I'm not exactly sure how they work. However maybe you can do something similar to what I did in C++. So just to reiterate. We have vertexes, edges, and faces (triangles) . You are starting with hexes so you could also do a top level hex class if you want with six sub faces which gets you to your tri-faces. Or you could just do all tri-faces and flag the internal edges as special. It really depends on the details of what you want to do. In any case once you get to the tri-faces, each tri-face references 3 edges and each edge references two vertexes. so there's the basic structure. Now you want to subdivide tri-faces to n levels. Each tri-face needs to be able to reference 4 child faces. Three will have the same orientation, and the center one (I call face 4) will be upside down. Likewise each edge needs to be able to reference 2 child edges. Edges are naturally directed meaning there is a vertex #1 and a vertex #2. What I do is I keep 3 bits in the tri-face that describe the orientation of each edge relative to it's face. This way it's easy to go clockwise or counterclockwise around your face. Remember an edges will have the opposite orientation for the face on the other side of it. You can also add a 2 slot array of weak pointers from edges back to faces and you can index that with your bit codes or rather the inverse ( ! ) of your bit code to get to the opposite tri-face. That will let you do your path-finding quickly. It's also useful for going around a vertex and calculating mesh normals (although there is a faster way to do this depending on your specific needs) Again when you need to subdivide a singe tri-face, just ask the edge to return it's two child edges. If it doesn't have any it creates them at that time. Now you have six edges (2 from each face) but you still need an additional 3 crossing edges for the center, which you can simply create from the appropriate end points of the 6 child edges you received. Once you have all 9 edges you can now build your 4 child faces and and add them as children to the parent. Each of those new faces can be subdivided in the same way and they will share edges and vertexes correctly. As for lists and stuff like that, I don't use any. You don't really need them except maybe for the very top level face geometry. In certain cases having a vertex list might be useful, but if you are using this for LOD you will be creating and destroying vertexes, edges and faces in semi-random order and a list will just get in your way. I just ended up doing a post processing step that walks the whole faces tree, visits nodes and assigns indexes to the nodes. It also simultaneously writes them to the graphics card. You just need a flag bit on the vertex to make sure you don't write a vertex more than once. If you aren't using this for LOD your requirements are a bit simpler and you might want to use a vertex list in that case. This is a place where the exact implementation will likely be different from C++ to C#. In C++ you will typically have a custom heap and might use reference counting. In C#.... well.... someone with more C# experience will be able to better help you. You also have the option of writing most of this code in C++, and then linking it into C#. Another issue you will have if you are building meshes this way is cracks. You can even see where you will have them in the picture in your first post. There are a couple ways to handle this. First I want to say I recommend not having more than one level of difference between neighboring triangles. There are two reasons for this. First to fix the cracks you might need to have some special triangles subdivisions . Here's a little drawing I made when I did mine: Notice you don't have more than 3 sub-faces so you can store those in your child-face fields without modifying your data structure. if you have one faces next to a highly sub-divided neighbor you will need a more complex crack healing strategy. Most likely you will put a point in the middle then put radials out to the edge vertexes. At big levels of difference this looks crappy, especially with noise based stuff. In order for this to be useful you have to sub-divide based on some error between the noise function and the new nodes you want to add. However I tried this, and I found the function would quite often fool the algorithm. The edge points would look like they were close to the function but the center could vary quite quite a bit. In short it just looked crappy in places. Having one level of of mesh difference ended up being way better and simpler to boot. You just base it on the square of the distance to the viewer. Again I'm assuming you're doing LOD here. A few more points .... I talked about edge direction above. If you terrain is flat you might be able to get a way with a standard edge direction. I'm doing a sphere so there is a minor difference in the way I handle it. In any case my standard is as such: Edge 1 goes clockwise, Edge 3 goes counter clockwise and Edge 2 can go either way. I label my tri-faces as as either Point Up or Point Down. If your terrain is flat then Edge 2 of all Point Up faces will be clockwise, and counter clockwise for all Point Down faces. This next picture is a flattened icosahedron. Just ignore the colors and numbers for a second. Those are for a special coordinates system for trees and rocks, etc. Look at the left where I drew in some stuff for you. The bottom red tri-faces is Point Down, The the upper teal tri-face is Point Up. Note the directions and the edge numbers. Even though this standard works, you still might want to keep the bit codes to handle the special crack healing faces. If you are doing this on a sphere like me, you need to support both directions of Edge 2 to handle the low and high latitudes of the world, but the rest is the same. Also this is just my standard. It's not some common thing. You can use whatever standard you like for this. So I guess that's about it for now. It might sound a bit complex but I implemented the system in about a day minus the crack healing code. This was the second time around. First time it took me quite a while to figure it all out but once you know the tricks it's not that bad.
  6. Gnollrunner

    3D artist looking for experience and motivation

    It's in C++. It's not really that far along yet. You can check my blog if you are interested. I don't want to hijack Mikhail's thread 🙂
  7. Gnollrunner

    3D artist looking for experience and motivation

    Let's put it this way......I've actually programmed on a computer with real magnetic-core memory, where you could look inside the box and see the individual bits. However it's not as bad as it sounds because that computer was at least somewhat old by the time I got to it.
  8. Gnollrunner

    3D artist looking for experience and motivation

    Nope, not a dumb question. I would just prefer to work with someone I can talk too directly. Call it a quark. I guess it's because I want anyone I'm working with to be heavily invested in what we are doing and it's easier to know that in person. I've actually never worked as a game programmer either. On the other hand I'm a very experienced programmer, 30+ years. I pretty much feel I can building anything with enough time. What I want to make is a Fantasy MMO or perhaps even a Sci-Fi MMO akin to the old Traveller table top game. However I know given the shear amount of code I would need to write, it's really not feasible for me to do that on my own, especially since I'm not using a game engine. I think a game engine would get in the way given the specific requirements of my game, so I'm writing the engine right now, but I only intend to include stuff I actually need. What I'm hoping to do however, is build a demo impressive enough to get some other people involved. I guess I haven't yet reached disillusionment, so you're father along than me 😀
  9. Gnollrunner

    3D artist looking for experience and motivation

    Ahh .... well not so close. I'm way south. I'm American but I'm in Krasnodar these days. So in any case what kind of game is your dream game?
  10. Gnollrunner

    3D artist looking for experience and motivation

    Where exactly are you. I mean what city (if I'm allowed to ask)? I'm asking because I might be kind of close to you, and at some point I'll need the help of an artist.
  11. I do almost exactly this and it's actually quite simple, but......I use a data structure with explicit edges, which are shared by neighboring triangles. trangles are stored in a quadtree. So each tri can have four children. The edges are in a binary tree, and so each edge has two children. Then the whole thing is simple. When you ask an edge for its midpoint and child edges, if it needs to, it subdivides, otherwise it just returns the data it already has, because its neighbor has asked already. BTW, this is the perfect place to implement some sort of reference counting, but there are a few details. The edge trees should have weak back pointers and the edge child pointers should also be weak. When an edge is deleted, it deletes it's reference in its parent. Strong pointers are from parent faces to child faces and also from faces to edges and from edges to vertexes. Now when a parent face deletes its children, everything else that needs to be deleted, is deleted automatically.
  12. Gnollrunner

    Destroying reference counted objects immediately

    I've never used Angelscript but I have encountered similar problems. The way I usually handle this is to create an interface object between the script and the actual C++ object. Then you have a destroy functions which deletes the C++ object and invalidates the interface object. The interface object is collected in it's own time by the GC.
  13. Gnollrunner

    Mountain Ranges

    So basically the terrain is described not by polygons, but by functions. They can be stacked on top of each other in various ways so you have regions of different types of terrain: mountains, hills deserts, caves, what have you. The voxels just make it into a mesh at whatever LOD is required. This way the world can be very large and all players can fit on the same world. It also means that you can have a game were you can really travel long distances, so I'm hoping that gives more of a sense of adventure. Finally I want to implement some function override ability that will let players do some limited modification of terrain. For instance you could flatten an area you want to build a house on. That's just for the terrain however. there has to be trees, cities, and stuff like that for a real MMO. I think the trees aren't too bad. I'm working on an algorithm to build trees using voxels. The nice thing about prisms is that you can build a trunk or branch easily with voxels because it's easy to build a round structure with a central line with prisms. I also came up with a particular way to put them together so you can branch off of a column of voxels but retain prism connectivity in a way the LOD will still work. So the whole tree with branches will be built as a single mesh as it should be, except for the foliage. Then it's a matter of just building the voxels in the right way to form a tree. For that I plan to use a series for 2D nose functions. one axis will run along the length of the branch and the second axis will the angles around the branch. With simplex and Perlin nose there is a trick you can use to copy the last row of vectors so basically as you go around the branch the function is continuous . At points where there is a noise value higher than some limit, you will start another branch at a some angel range defined by the tree building parameters. You should be able to apply other nose functions to twist branches around or change the diameters as they go along. Ideally you have a lot of parameters to adjust things for a given type of tree. For shading I want to use 4D simplex noise. Three dimensions will simply be the X,Y,Z coordinates of the mesh as usual, and the forth dimension will be generated along the length of the branches. The reason for the 4th dimension is so you can have some control of how bark is generated. I mean in general bark patterns follow branches so having a noise dimension along the branch will give you a lot of versatility. For buildings I want to finish implementing normal cubic voxels and I have an idea for doing sharp corners that you need for buddings. It's a modified version of marching cubes. My general goal is address all the stuff that's needed for a real game. I know it's a huge undertaking but I'm hoping I can make it impressive enough that I can get help with, the more standard parts of an MMO.
  14. Gnollrunner

    Working on Materials - Lava Based

    That's cool! The bottom one in particular kind of looks like a sun to me. I'll have to do something like this at some point. I want to have a sun so I can have real day/night cycles. I already have a kind of astral system to do the orbits rotations.
  15. Gnollrunner

    Mountain Ranges

    Sure, I'll try. It can be a bit hard to explain though........ We have an octree of voxels divided into chunks. A chunk is basically some point in the octree and everything below it. The depth of leaf nodes for a chunk is determined by the distance the chunk is from the player. However we don't build down to our leaf nodes unless there is a sign change, (i.e. mesh data) otherwise it would defeat the purpose of the octree. So most parts of a chunk's octree or even the whole octree will not go all the way down to it's leaf depth, and it's leaf depth could be several levels down from a bottom voxel.......The problem is as you approach an area of terrain, the leaf node level will increase to provide more detail, and we can not assume that just because a voxel has no data it's children will not have data also. A good example of this is if you have some floating terrain in the middle of a voxel. However this can also happen without floating terrain. For instance if some geometry pierces the side of a voxel but doesn't contact any of it's corners the voxel will appear empty, but after you subdivide it you might find data. So for build iterations we have to go all the way down to where leaf nodes should be, just to check if there is data. We need to do this because our terrain functions accept X,Y,Z coordinates and we don't have those until we have built the octree down. So it's kind of a chicken and egg problem. We need the octree to find the data, and we need the data to figure out where the octree should be. Instead of building the whole octree down however, we use a lightweight tree without all the faces edges and nodes, just to find coordinates to feed to our functions. Since our coordinates are on the surface of a sphere we need to subdivide an icosahedron and that's really what our unit sphere is. Then to calculate the position of a given voxel vertex we just multiply it's corresponding unit sphere vertex by it's altitude to get our final voxel vertex X,Y,Z coordinates. We are really dong this for virtual vertexes since they don't exist yet. The ghost-tree code handles this stuff. Also we don't un-subdivide the unit sphere on every iteration. We use it to cache the sphere related part of our coordinates between build iterations, in addition to height related components of any terrain functions we are using. We therefore don't need to recalculate all that stuff on each iteration. We just recalculate the height part when we do our ghost walking which is a simple calculation..... Our ghost walking is implemented by recursion and on the way back up we throw away any parts of the ghost tree with no data, so we are left with a map of how to build the actual tree. Note this whole processes is only done on cells that appear empty. Cells that already have a sign change will be at the current leaf level, and when we increase the level we can just subdivide them normally. This handles the vast majority of cases. However as I said you can't make the assumption because for anything but the simplest cases it won't hold true very long. Generally you won't have to ghost walk very deep but there are cases where it's possible. For instance say you have a long thin spike that avoids all nodes up until the last level of LOD. There is one more feature I didn't really talk about yet but I'll add it in here. if we have simple height-map data, we can store those terrain function values in the unit-sphere vertexes no problem. However when we start getting into caves and stuff like that, you really can't do that. So now there is another problem. As as you build your ghost tree down to find your data, you are running terrain functions on 3D coordinates and those can be expensive. Note that each voxel vertex is used by 12 voxels ( just like for cube voxels, each for vertex is used by 8 voxels). Since during the ghost walk process there are no voxel vertexes built yet, there is no place to store calculated terrain function values. Ostensibly you would have to calculate the same terrain function value 12 times, but that would be a disaster. Instead we have a 3D matrix cache that we use for temporarily storing terrain function values as we search for data, and there is a special "chunk address" that we index it with so we can quickly see if we have already calculated a needed value. Since our voxels are prisms it uses something akin to barycentric integer coordinates. In fact there is a partially implicit addressing system that assigns each voxel a unique ID. I call it GNOLLS coordinators If you you start at the top, the world is constructed from an icosahedron. That's twenty faces. we can combined those into pairs to a get a diamond shape which we call a "Group". The group has two axes one that points roughly "North" and the other is at an "Oblique" angle to it. That gets us to a pair of voxels which we call "Legs" (a term I stole form investment jargon, there is a one "up" Leg and one point "down" Leg). Then we have the altitude of the a voxel which we call a "Level" and finally we have the "Subdivision" as defined by our octree. So its: Group North Oblique Leg Level Subdivision GNOLLS! (Yes I had to think a while to make the acronym work )
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!