Saturday, January 29, 2011

Are you a tiger parent? Results

Well, the voting on the "are you a tiger parent?" poll seems to have petered out. A couple added other ideas to the mix. Here are the results. It is pretty clear that there aren't many tiger parents reading this blog. Indeed, most of you go for mild reasoning rather than any form of coercion, incentives or punishment. That said, just giving up isn't an option that was favoured either. So most are in the middle rather than the extremes which is, of course, true by definition.

Tuesday, January 25, 2011

Physics and Heightmaps

When I thought that all problems with heightmaps was over, I stumbled upon something sort of tricky recently. The only thing I had left for heightmaps was to add physics to them. This seemed easy to do as it was basically just a matter of sending the raw heightmap data to the physics engine (newton game dynamics) However just as I had done this I realized that this was not enough: the terrain could have many different physical properties at different places (a spot with dirt, one with rock, etc).

The thing is that in physics simulations you give a material per shape, each material having certain properties (friction, etc) and special effects (sounds, etc). The heightmap is counted as a single shape, and thus it only has a single physics material. This was something I had totally forgotten. Luckily, the physics engine supports the assigning of special properties to each point in the heightmap. Once I found the proper info, it was pretty simple to add this (see here).

Now it was just a matter of adding extra material values to the heightmap (basically just an array of single integers, the id of the physics material at each point). My initial idea was that this could be "painted" on as an extra step, and to be sure I asked Jens what he thought about it. His reaction was that this would be way too much work and wondered if it could not be auto-generated instead. We already had a physics material assigned to each render material, so the basic info was easily accessible.

However, when I started to thinking about this, I found the actual auto-generation increasingly tricky. How should we determine which of the many blended materials to set the physics properties (blending was not possible)? Also, how do I get this information, considering that the blend textures can saved as compressed textures, into a CPU buffer?

The way we chose to solve the material picking was that the top visible (meaning over a certain limit opacity) blend material always sets the physics material. This allows map creators to set priority on materials in terms of physics, by simply placing them at different places among all blend materials. For example, if a material like gravel should also have its effects shown no matter what it is blended with, then it should be placed high up in the list. While currently untested this seem pretty nice and can also be tweaked a bit (like having something else determining priority).

The generation of this data was made by rendering the blend textures to an off-screen target and then grabbing the data into normal memory. What this meant is that the GPU would decompress any packed textures for us. This also solved some other problems, like the need to resize the texture according to heightmap resolution. Once the data is grabbed from the GPU it is just a matter to loop through it, check values and write to the final buffer.

Problem was finally solved and physics properties auto-generated!


With this little post I hope to show that there often is more to a problem than what is visible at first. Also, this shows another advantage of using normal texture splatting (more info here), instead of megatextures or similar. With the auto-generation of physics, it is much easier to create and update the terrain, something extremely important when you are a small team like us.

Would be very interesting what other techniques people use (or known of) for setting up physics properties on terrain!

Saturday, January 22, 2011

Random fun activities

Living in a colder climate means real winter and that means Snow Days -- days where there is too much snow for people to have school so they don't. That means children at home. 

The consequence of this has been some exploration as to useful activities other than watching TV. Playing the snow could be one of them but it is a tad cold. 

First of all is Starfall. This is a site I have mentioned before. They now have a new website and this includes maths as well as reading. They also have a few iPhone apps but my kids are now too old for them.

For older kids, the go to site for us is BrainPop. We subscribed to the main edition but there is also a junior one too. Strictly speaking it is closer to TV than one would like but the material is terrific and covers so many areas.

Moving on, we also have been making use of the iPad. This week, the app of choice was Toontastic. For $3 you get an app that allows children to make animations. As my son remarked, "it's just like playing with puppets and videoing the show." That sounds right. Anyhow, you can see what my two youngest came up with here (as you can share the results). Warning: I suspect your kids will find the video more entertaining than you will.

Finally, if you want some higher level mathematics, then consider the YouTube channel of Vi Hart. She is a mathematician who has found a way to make advanced mathematical concepts accessible. Truth be told you may well enjoy this more than the kids but I'll give you the "education" excuse to drag everyone over to the computer. Below is my current favourite. You'll need paper, tape and scissors at the end to finish the story.



Relatedly, I tried to convince my kids that one of the brothers in Einstein bagels was THE EINSTEIN and that his brother was the one who took the food outlet route as Einstein kept on suggesting alternative shapes for bagels such as a Mobius Strip. Without skipping a beat, my son remarked, "Yeah, Einstein wouldn't have been so good at this. You can't hold a Mobius Strip with cream cheese on it without getting it all over your fingers."

Friday, January 21, 2011

Tiger Mother Management

I have written a post for HBR Blogs on management styles as informed by parenting.

Are you a tiger parent?

I'm interested in how parents might react to the piano practice issue. Click here to participate in a vote and feel free to pass it on to others. I'll come back in a few days to see how it goes.

Thursday, January 20, 2011

Tech Feature: Undergrowth

Introduction
After a little break with updates on the rendering system, holidays and super secret stuff, I could finally get back to terrain rendering this week. This meant work on the final big part of the terrain system: Undergrowth. This is basically grass and any kind of small vegetation close to the ground.

As always, I started out doing a ton of research on the subject to at least have a chance of making proper decisions at the start. The problem with undergrowth/grass is that while I could find a lot of resources, most were quite specific, describing techniques that only worked in special cases. This is quite common when doing technical stuff for games; while there are a lot of nice information, only a very small part is usable in an actual game. This is especially true when dealing with any larger system (like terrain) and not just some localized special effect. In these cases reports from other developers are by far best, and writing these blog posts is partly a way to pay back what I have learned from other people's work.

Now on with the tech stuff!


Plant Placement Data
The first problem I was faced with was how to define where the undergrowth should be. In all of the resources I found, there was some kind of density texture used (meaning a 2D image where each pixel defines the amount of plants at that point). I did not like this idea very much though, mainly because I would be forced to have lots of textures, one for each undergrowth type, or to not allow overlapping plants (meaning the same area on the map would not be able to contain two different types of undergrowth). There are ways past this (e.g. the FrostBite engine uses sort of texture atlases), but then making it work inside the editor would be a pain, most likely demanding pre-processing and a special editor renderer. I had to do something else.

What I settled on was to use area primitives, simple geometrical shapes that defined where the undergrowth would be. The way this works is that each primitive define a 2D area were plants should be placed. It then also contains variables such as density, allowing one to place thick grass at one place, and a sparser area elsewhere.

I ended up implemented circle and convex polygons primitives for this, which during tests seem to work just fine.


Generating the Plants
The next problem was how generate the actual geometry. My first idea was to simply draw the grass for each area, but there were some problems with this. One major was that it would not look good with overlapping areas. If areas of the same density overlapped, the cross section would have twice the density of the combined area. This did not seem right to me. Also, it was problematic to get a nice distribution only using areas and I was unsure how to save the data.

Once again, the report on the FrostBite engine gave me an idea on how to approach this. They way they did this was to fill a grid a with probability values. For each grid point a random number between 0 and 1 is generated and then compared to to the one saved in the grid. If the generated number is lower than the saved, a plant is generated at that point, else not. Each plant is then offset by random amount, creating a nice uniform but random distribution of the plants!

This system fit perfect with the undergrowth areas and simplified it too. Using this approach, an undergrowth area does not need to worry about generating the actual plants, but only to generate numbers on the grid.

The final version works like this:

There is an undergrowth material for each type of plant that is used on a level. This material specifies the max density of each plant and thus determines how the grid should look. A material with a high density will have a grid with many points and one with a low density will have few grid points. Each point (not all of course, some culling is used) on the grid is checked against a area primitive and a value is calculated. This is then repeated for each area, adding contributions from all areas that cover the same grid point.

This solves the problem of overlapping areas, as the density can never become larger than max defined by the grid. It allows makes it possible to have negative areas, that reduce the amount of undergrowth in a certain place. This way, the two simple area primitives I have implemented can be used for just about any kind of undergrowth layout.


Cache system
Now it is time to discuss how to generate the actual plants. A way to do this is to just generate the geometry for the entire map, but that would take up way too much memory and be quite slow. Instead, I use a cache system that only generate grass close to the camera (this is also how FrostBite does it).

The engine divides the entire terrain into a grid of quads, and then generates cache data for each quad that is close enough to the camera. For each quad, it is checked what areas intersect with it, and layers are made for each undergrowth material that it contain. Then for each layer, plants are generated based on the method described above. The undergrowth material also contains texture and model data as well as a bunch of other properties. For example, the size can be randomized and different parts of the texture used, all to add some variety to the patch of undergrowth. Finally plant is also offset in height according to the heightmap.

This cache generation took quite some work to get good enough. I had problems with the game stuttering as you traveled through a level, and had to do various tricks to make it faster. I also made sure that no more than one patch is generated at each frame (unless the camera is teleported or similar).


Rendering
Once the cache system was in place, rendering the plants were not that much of a problem. Each generated patch comes with the grass in world coordinates, so it is as simple as it can get. The only fancy stuff happening is that grass in the distance is dissolved. This means that the grass does not end with a sharp border, but smoothly fades out.


In the above image you can see how the grass dissolves at distance. Here it looks pretty crappy, but with proper art, it is meant that grass and ground texture should match, thus making the transition pretty much unnoticeable.

Another thing worth mentioning, is that the normal for each grass model is the same as the ground. This gives a nice look to many plants, but an individual plant gets quite crappy shading. Undergrowth is meant to be small and not seen close-up though, so I think this should work out fine. Also, when making grass earlier (during development Amnesia), normal normals (ha...) were used and the result was quite bad (sharp shading, etc).


Animation
Static grass is boring, so of course some kind of animation is needed. What I wanted was two different kinds of animation: A global wind animation (unique for each material) and also local animation due to events in a limited area (someone walking through grass, wind from a helicopter, etc).

My first idea was to do all of these on the cpu, meaning that I would need to resend all the geometry to the graphics card each frame. This would allow me to use all kinds of fanciness for animation (like my dear noise and fractals) and would easily allow for lots of local disturbances.

However, I did some thinking and decided that this would be a bad idea. Not only does the sending of data to the graphics card take up time, but there might be some pretty heavy calculations needed (like rotating normals) for a lot plants, so the cpu burden would be very heavy. Instead I chose to do everything on the GPU.

Implementing the global wind animation was quite simple; i was just a matter of sending a few new variables to the grass shader. But it was a bit harder to come up with the actual algorithm. Perhaps I did not look hard enough, but I could find very little help on this area, so I had to do a lot of experimenting instead. The idea was to get something that was fast (i.e. no stuff like Perlin noise allowed) and yet have a natural random feel to it. What I ended up with was this:

add_x = vec3(7.0, 3.0, 1.0) * VertexPos.z * wind_freq + vec3(13.0, 17.0, 103.0);
offset.x = dot( vec3(sin(fT*1.13 + add_x.x), sin(fT*1.17 + add_x.y), sin(fT + add_x.y)), vec3(0.125, 0.25, 1.0) );

add_y = vec3(7.0, 3.0, 1.0) * (VertexPos..x + vOffset.x) * wind_freq + vec3(103.0, 13.0, 113.0);;
offset.y = dot( vec3(sin(fT*1.13 + add_y.x), sin(fT*1.17 + add_y.y), sin(fT + add_y.z)), vec3(0.125, 0.25, 1.0) );


This is basically a couple of fractually nested sin curves (fbm basically) that take the current vertex position as input. The important thing to note is the prime numbers such as vec3(7.0, 3.0, 1.0) without these the cycles of the sin curves overlap and the end result is a very cyclic, boring and unnatural look.

The offset generated is then applied differently depending on the height of the plant. There will be a lot of swaying at the top and none at the bottom. To do this the base y-coordinate of the plant is saved in a secondary texture coordinate and then looked up in the shader.

Now finally, the local animation. To do this entities called ForceFields are used. (Thanks Luis for the name suggestion! It made doing the boring parts so much more fun to make.) These are entities that come with a radius and a force value, and is meant to create effects on the graphics that they touch. Right now only grass is affected, but later on effects on ropes, cloth, larger plants , etc are meant to be added.

These effect of these are applied in the shader and currently I support a maximum of four ForceFields per cache patch. In the shader I either do none, a single entity or four at once. This means that if three entities affect a patch, I still render the outcome of four, but fill the last one's data with dummy (null) values. Using four is actually almost as fast as using a single. Because of how GPUs work, I can do a lot of work for all four entities in the same amount of instructions as for a single. This greatly cut down the amount of work that is needed.

Again, just like with the global wind, it was hard work to come up with a good algorithm for this. My first idea was to simply push each plant away from the center of the force field, but this looked really crappy. I then tried to add some randomness and animation to this in order to make it nicer. As inspiration, I looked at Titan Quest, which has a very nice effect when you walk through grass. After almost a days work the final algorithm look something like this:

fForce = 1 - distance(vtx_pos, force_field_pos)/force_field_radius

fAngle = T + rand_seed*6.28;
fForce *= sin(force_field_t + fAngle);

vDir = vec2(sin(fAngle), cos(fAngle));
vOffset.xz += vDir * fForce;


Rand seed is variable that is saved in the secondary texture coordinate and is generated for each plant. This helps gives more random and natural feel to it.

Here is how it all looks in action:


Note: Make sure to check in HD!

And in case you are wonder all of this is ugly, made in 10 seconds, graphics.


End notes
Now that undergrowth is finally done, it means that all basic terrain features are implemented! In case you have missed out on earlier post here is a summary:

Terrain Geometry
Fractals and Noise
Terrain Texturing

I hope this has been of use and/or interest to somebody! :)

Next up for me is some final terrain stuff (basically just some clean-up) and then I will move on to more gameplay related stuff. More on that later though...

Sunday, January 16, 2011

That Tiger Mother

Wow, it isn't hard to get attention as a parent. Engage in an extreme parenting style and hold it up as an underlying reason why the US will lose ground to China into the future.

I'm talking of course about Amy Chua -- a Yale law professor -- whose book, Battle Hymn of the Tiger Mother was ranked No.4 on the Amazon bestseller list. I bought the book for two reasons. First, if such a book is on the bestseller list then I want Parentonomics to be able to leverage off the "Customers who bought this item also bought ..." Amazon list. Second, I was pretty sure that the characterisations of Chua going around were distorted. I just didn't believe that the WSJ piece reflected what was in the book and, having now read it, I was right.

Let's begin with that shorter piece. It basically had a bold claim that Chinese mothers (very broadly construed -- and not confined even to Asia) were superior to Western mothers. There is no evidence for this presented and, instead, there is an allusion to stereotypes of superior performance of children at school and in some artistic endeavours. But while that might be a hook that gets the press interested, it isn't really what is interesting about the piece or the book. This is instead a case in point about extreme or perhaps obsessive parenting. We have seen all colours of that recently in terms of books. Most of the ones that seemed to have had a recent attention have been against strong parental involvement. There is, of course, Free-Range Kids that argues that we should have less fear and give our kids more independence. Free-Range Kids wasn't an extreme view but a reaction to extremes. But others have been different. There was one book -- whose name I have forgotten -- that basically said parents shouldn't put any effort into parenting at all!

The article plays Chua at the other extreme from these recent trends. It tries to soften the 'extreme' by alluding to a cultural parenting style. But in neither the article nor the book does that ring true. However, in contrast to the article, Chua's book is a different take on this parenting style. The article makes it seem that she did it her way, it was successful and all other parents who don't follow don't really love their children. That would make her an excellent candidate for Wife Swap.

But the book is different. Here are the first sentences:
This is a story about a mother, two daughters, and two dogs. It's also about Mozart and Mendelssohn, the piano and the violin, and how we made it to Carnegie Hall.
This was supposed to be a story of how Chinese parents are better at raising kids than Western ones.
But instead, it's about a bitter clash of cultures, a fleeting taste of glory, and how I was humbled by a thirteen-year old.
So this is not a book about success. Instead it is a book about a strategy towards parenting and, in many respect, its failure. I felt a kinship to Chua in that. This blog and Parentonomics are often characterised as advocating some form of extreme economic rationalism applied to parenting where, more often than not, it is a story about the failure of such notions. That said, Chua is not quite as clear about those failures nor does she diagnose them with the starkness that I try to do here. But if you look you can see them and learn from them.

Chua isn't a parent who shys away from effort. Frankly, you can't help but be amazed (even if you are appauled) by the sheer volume of energy she is putting into her children. It seemed unbelievable but I've learned that people outside, doing things differently, are a poor judge of what others are capable of. Chua is not taking some easy way out but she is also not regarding this as something that is purely her own deal. A judgment against parents doing things differently runs through the book even if it is tortured by mixed success.

To deal with this, let's separate out two issues as only an economist might do: (1) appropriate goals for your children and what they mean and (2) how far you are willing to go to attain those goals.

Chua is clear about the goals for her children. They are to get straight A's, become virtuoso in an appropriate area (in this case piano and violin) and they are to put in high effort into everything they do. The latter part is exemplified by Chua's rejection of birthday cards made by her kids for her. (And in reading that part, while she was harsh, it was also pretty clear that the effort put in had been weak and her kids had known that they could do and should do better). 

Those goals, on the face of them, are pretty uncontroversial. Substitute virtuoso in music for excellence in sports or mathematics and you pretty much have covered some universal parental aspirations. They are not unique to Chinese parents nor unique to Chua. Of course, there are other character goals we have. As I wrote about some time ago, we value 'independence' as core to our parenting goals. But the point is that having clear goals actually can make the job of parenting easier.

What is true, however, is that having goals also means you have faced and decided on what you are trading off. For Chua, it is pretty clear that she was trading off against play, sleep-overs and other 'leisure' activities children might engage in. Her attitude is that those things are unimportant relative to preparing for the future but there is no evidence to support that. Instead, the book is about the goals she set and how they were achieved. In that respect, if you read it as a story rather than as advocacy, it is an interesting journey.

In many respects, of course, the real issue is how far you are willing to go to achieve goals you might set. Chua is willing to go to the hilt on these goals. She is committed to them; even as the costs of achieving them grow higher and higher. Moreover, given the fact that these choices -- particularly with regard to music -- were made and committed to when Chua's children were so young, it becomes clear to the reader that this entire strategy was high risk. Indeed, in pursuing those goals, she may have had sacrificed them -- although it would generate too many spoilers to go into detail on that here.

How far is Chua willing to go? Well, she wanted her kids to be child prodigies. That means you don't have much time and must start early. It also means that you have to devote enormous effort and time in an unrelenting fashion. Chua did that and, in part because she had good material to work with, she kept going. Up to 6 hours a day of practice. Constant pressure. And only hints that her children were become self-motivated.

I can tell you right now that when faced with similar choices, this is not one that we made. When Child No.1 was three, she sat at a piano and some moron told us, "she is quite interested. You should get her lessons." So, of course, we did. Her teacher was reluctant for someone so young but our daughter paid attention and made progress so she took her on. Did I mention she was three?

Well, that lasted about two months before she lost interest. Getting her to practice was difficult. So we decided to drop it. Of course that was not before we had, in our enthusiasm, procured a piano. Our goal was to start again later. Chua would not have given up so easily.

By the way, we did start again when our daughter was six and our son started when he was five. We found a wonderful teacher, Paula Mantay, who had the goal that success was to enjoy playing. She was very hard and demanding. We liked it and the kids started to do well. After a couple of years, it just became harder and harder to get Child No.1 to practice. Then, we were at a friend's house. Their daughter, who was the same age as ours, played for us. She was much much better. Something flipped for Child No.1. She didn't want to play anymore. It turned out that her goal was to become a virtuoso and that seeing another peer playing was clear evidence. We stuck out a little longer but relented. Ms Mantay was devastated but what can you do? It is with a hint of irony that I do have to mention that the other child was Chinese-American. Our son continues playing today but we have no aspirations for him beyond enjoyment. For Child No.3, she displayed enthusiasm for lessons but when she resisted practice, we stopped them. These things are going to have to be self-motivated or bust for us.

I think that this is the reason Chua's story resonates. It is a path not travelled and we are not 100% sure that is the right choice. Every parent faces these choices. Most would dearly like for their children to excel. But in the end, most parents don't push the issue. Indeed, think of the equilibrium if we all did! Could Chua have continued to push if everyone else was doing the same? There can only be so many children who are the best. It is like musical chairs. In the end, someone misses out no matter how much you all try.

So what lessons can we take from all this. First of all, parents have to face up to the fact that if they want their children to excel that is going to take a lot. You are going to have to identify an activity. Hope your kid has the requisite skills to develop excellence there. And then put in the practice. It is interesting that only a short while ago Malcolm Gladwell's Outliers adorned the bestseller list. There is one thing I remember from that. To be the best you need to put in 10,000 hours of practice. It is not entirely clear that if kids don't start early enough they will get there. Chua embraces that as do I am sure many others. For us, it is something we will support if a child wants to go there but we are not going to insist on it.

Second, half measures are probably a waste of time. One thing that many parents can identify with is Chua's belief that something worth doing is worth doing well. We have engaged in various activities and pushed them but not in a fully committed manner. We are much more likely to encourage activities that develop creativity than hone skills. But, with the caveat about whether your child is enjoying the activity or not, I'm not sure it is worth darting around continually exposing them to new things. But I guess it is hard to conceive of how an interest can start without exposure so this area is a parenting mess.

Third, children of Yale faculty do well. Chua's kids are a case in point. Barry Nalebuff's daughter, Rachel wrote My Little Red Book before graduating high school. Ian Ayres kids co-authored a statistical paper with him. And Ray Fair and Sharon Oster's daughter, Emily, was subject of a ground-breaking psychological study as a toddler and went on to be an economic star. There is something in the air in New Haven.

Fourth, I realised that there is a difference between far-sightedness and patience. In economics, we conflate these. A person who has a high discount factor (weighs the future heavily) is also someone who will be happy to incur costs now and wait for the benefits (a definition of patience). But Chua is, at once, both far-sighted (she only cares about her children's future) and impatient (she wants that future to arrive too quickly). Much to my surprise, it turns out you can be that way.

Finally, parenting books are at their most useful when they present stories. Parents find stories an effective way of learning about choices and Chua's is a good one for that. That said, it is not a well-written book. It rambles, digresses, spends too little time pondering her husband, Jed's role in all this. It is inconsistent. Chua rails at American parents' use of 'bribery' and then does so herself without really acknowledging it. As I read the book, I had to construct my own narrative of what it means. Chua wasn't going to help. It was at once too descriptive and too ranty for that. That is a shame. I suspect it could have been more.

In the end, I was left wondering about Chua's children's happiness and will be interested should, in twenty years time, either of them turn to pen their own reflections on their childhood. But I was also wondering what happened to Chua with the normal stuff of parenting. Did she have trouble getting her kids to put on shoes quickly or to brush their teeth? Did the fact that so much was expected of them in the abnormal stuff make it plain sailing for the day-to-day stuff? Or did that same fact mean that they had a free-ride then and everything was done for them? Either way, what will this mean for their ability to act as independent adults in the future. From the book, it seems that that looks good. I wonder if other kids with this form of parenting come out so secure.

[Update: Amy Chua's colleague and economist, Ian Ayres, comments on the economics of tiger parenting - as a commitment device to learn to weigh the future.]