Intel sponsors gamedev.net search:   
mittentacularBy mittens      

Thursday, December 20, 2007
Last week, with the fixing of Boney and the id Tech 4 MD5 format that powers his reanimated flesh under my belt, I turned my error-prone fingertips to writing a high-dynamic range rendering option to Rawr. I realize that bloom filters are, without question, the most overused graphical feature this side of lens flares and ragdoll physics, but I do have a special attachment to the effect. In case there was any doubt after my last entry I have a bit of a hard-on for scene composition and, more specifically, color. I realize that this sounds like kind of an ignorant thing to say, "I LIKE COLORS THEY ARE PRETTY," but there's definitely a case to be made in regards to intelligent uses of color to set or enhance the "feel" of a game. The overall color palette, along with a unique style, worked very well for Darwinia and Geometry Wars to help set them apart visually as well as thematically. So, to get back to the topic at hand, I thought writing a method of HDR rendering would help to enhance the visual style of whatever projects I choose to develop using Rawr and, specifically, the game that is brewing in my head right now.

I've always enjoyed playing with methods of HDR rendering in the past; my first experiment involved adding HDR rendering using 64-bit floating-point surfaces to the Torque Shader Engine -- now called the Torque Game Engine Advanced. That seemed to work well at the time but when I looked back to the methods I used during that project I found that they were lacking, so I went with a different series of techniques when I added HDR rendering to my XNA project (more screenshots can be found in my XNA dev gallery). I don't actually remember a great deal about my implementation there or else I'd relate what I learned from that but all I really know is that when I looked at the code a few weeks ago my eyes bled a little bit.

This implementation, for the most part, went very smoothly. I chose to use 128-bit floating-point surfaces and, as of now, they remain that way. I'm not sure how well various types of cards support floating-point surfaces as render targets, since I felt no need to limit myself with last week's implementation with Direct3D 10 but, as I'm now realizing, I'm going to have to think of some decent ways to scale the system when I write the Direct3D 9 portion of Rawr's rendering routines (which I'm in the process of doing now). There are a bunch of test shots of my first few iterations of testing the code over at their usual home in my Direct3D 10 dev gallery but most of them don't have any real remarkable story behind them. I found the best methods for blurring the results of the brightness-filtered scene came from a separable Gaussian filter (with values computed by the CPU; hard-coding them into the shader proved to be annoying and inflexible). One of the best changes I found to alter the final pass of the process (the composition stage) involved darkening the portions of the tone-mapped, blurred surface where the bloom intensity was particularly high. Once I added that single line to the shader code the results were noticeably nicer as can be seen from the before (left) and after (right) below:



The next troublesome portion of the process was changing the HDR render target to be multi-sampled. Direct3D 10 does support this but not only is it poorly documented -- the DirectX SDK docs don't even list the correct texture object Load declaration -- but, despite numerous attempts and example comparisons, I simply could not get texture sampling through the Load functionality to work. Eventually I fell back to making the HDR render target multi-sampled then used ID3D10Device::ResolveSubresource to resolve the render target to a non-multi-sampled surface and sent that to the shader. This came with a drop from 200 frames-per-second (from the non-antialiased code) to 100 frames-per-second and the video memory allocation of another full screen-sized 128-bit surface. The results were still acceptable but hopefully some later tweaking proves to be more practical.



This time I held off on mentioning the show-of-the-week until the end of the article so as to avoid any unintentional tangents. The show worth mentioning now is Showtime's Californication which showcases all-around excellent acting (especially on the part of David Duchovny) and some of the best writing I've ever seen in a comedy/drama. I may make a short entry tomorrow about the rendering structure of Rawr but, if not, Merry Christmas and such.

Comments: 0 - Leave a Comment

Link



Monday, December 17, 2007
Over the last week I've been carefully balancing working on adding HDR rendering to Rawr along with watching the first and only two seasons of Twin Peaks. It's hard to judge a show like that, on the whole, because while the first, say, sixteen-seventeen episodes are absolutely remarkable in just about every sense, the episodes leading up to the series finale ping pong back-and-forth between awful and passable. What is even more interesting, as an enormous fan of David Lynch, is the pure, focused power that he can have on any episode which he takes a part in. His abilities as a writer are second only to his numerous abilities as a director. There are instances where Lynch clearly conveys an emotion in the scenes he directs to remarkable effect. The viewer reaction to his work are generally polarized in the sense that people either thoroughly dislike or completely love it, but it's hard to deny the man's auteur-like status as a filmmaker.

I believe that it's pretty clear that I take an interest in storytelling in both games, literature, and film, but something that I generally don't discuss all that much is my interest in the power that a visually well-constructed scene can have on a viewer or gamer. One of the reasons that I enjoy the things that directors like Steven Spielberg and David Lynch is that they both possess a very clear and thorough knowledge of what "looks good" for a given scene. For Spielberg, I think this concept is best presented recently in Minority Report and Saving Private Ryan. The use of color is so ingrained into David Lynch's work that it's difficult not to spot it in any given title; he frames a scene using a very specific and carefully-chosen color palette generally set against a very contrasting backdrop to provoke a subtle emotion in the viewers without any action taken on the part of the actors. Just take a look at the image below for an idea:



There is a very definite, consistent color palette that the entire scene draws from all set against a crimson red background atop a very jarring floor pattern. The entirety of the composition, especially in context, has absolutely no soothing qualities about it. Even without the presence of the midget who, for those that haven't seen the show, consistently dances and talks in a spoken-backwards-but-processed-so-it-comes-out-forward-spoken kind of way.

I actually meant to discuss the HDR rendering, but I'll save those details for another post. In the meantime here's a screenshot:



Comments: 1 - Leave a Comment

Link



Sunday, December 9, 2007
He lives again. As it turns out, the big, complicated function isn't necessarily the source of the bug.



Original Code:
void CMD5MeshNode::InterpolateSkeletons( int iCurrentFrame, int iNextFrame, float fDelta )
{
	if( !m_pAnimations || !m_pAnimations[m_ulActiveAnimationID].ppSkeletonFrames || !m_pJoints )	return;
 
	for( int iJointIdx = 0; iJointIdx < m_iNumJoints; iJointIdx++ )
	{
		const MD5File_Joint* pJoint_SkelA = &m_pAnimations[m_ulActiveAnimationID].ppSkeletonFrames[iCurrentFrame][iJointIdx];
		const MD5File_Joint* pJoint_SkelB = &m_pAnimations[m_ulActiveAnimationID].ppSkeletonFrames[iNextFrame][iJointIdx];
 
//		m_pJoints[iJointIdx].strName = pJoint_SkelA[iJointIdx].strName.c_str( );
		m_pJoints[iJointIdx].iParent = pJoint_SkelA[iJointIdx].iParent;
 
		m_pJoints[iJointIdx].v3Position = pJoint_SkelA[iJointIdx].v3Position + ( fDelta*( pJoint_SkelB[iJointIdx].v3Position - pJoint_SkelA[iJointIdx].v3Position ) );
		m_pJoints[iJointIdx].quatOrientation = pJoint_SkelA[iJointIdx].quatOrientation;
		D3DXQuaternionSlerp( &m_pJoints[iJointIdx].quatOrientation, &pJoint_SkelA[iJointIdx].quatOrientation, &pJoint_SkelB[iJointIdx].quatOrientation, fDelta );
	}
}


Fixed:
void CMD5MeshNode::InterpolateSkeletons( int iCurrentFrame, int iNextFrame, float fDelta )
{
	if( !m_pAnimations || !m_pAnimations[m_ulActiveAnimationID].ppSkeletonFrames || !m_pJoints )	return;

	const MD5File_Joint* pJoint_SkelA = m_pAnimations[m_ulActiveAnimationID].ppSkeletonFrames[iCurrentFrame];
	const MD5File_Joint* pJoint_SkelB = m_pAnimations[m_ulActiveAnimationID].ppSkeletonFrames[iNextFrame];

	for( int iJointIdx = 0; iJointIdx < m_iNumJoints; iJointIdx++ )
	{
		m_pJoints[iJointIdx].iParent = pJoint_SkelA[iJointIdx].iParent;

		m_pJoints[iJointIdx].v3Position = pJoint_SkelA[iJointIdx].v3Position + ( fDelta*( pJoint_SkelB[iJointIdx].v3Position - pJoint_SkelA[iJointIdx].v3Position ) );
		m_pJoints[iJointIdx].quatOrientation = pJoint_SkelA[iJointIdx].quatOrientation;
		D3DXQuaternionSlerp( &m_pJoints[iJointIdx].quatOrientation, &pJoint_SkelA[iJointIdx].quatOrientation, &pJoint_SkelB[iJointIdx].quatOrientation, fDelta );
	}
}


Comments: 2 - Leave a Comment

Link



Saturday, December 8, 2007
I'm certain that I've written about this back in the days of yore but, slowly, as time went on, I actually began to trust and even like using the Direct D3DX utilities in my own codebase. I have generally only relied on the matrix, vector, and quaternion functionality early on in developing a codebase simply to the reliability of knowing that the D3DX math routines are fool-proof as opposed to the routines I could write on my own that may do something stupid like CVector::CVector( float x, float y, float z ) { x = x; y = y; z = z; } or something along those lines. Early on in the development of any engine or framework the kind of functionality that D3DX grants to programmers is incredibly useful as a launching point.

In the past my complaints about D3DX were that it was an unnecessarily bloated aspect of the DirectX SDK that contained some features which, really, should have been part of the core SDK from the beginning. For the most part, this complaint has been rendered completely invalid as of DirectX 10. The most notable inclusion in the core SDK from D3DX is that the shader compiler has been moved to the core runtime from its previous position in D3DX. In fact, as of now, it seems that the D3DX functionality in DirectX 10 has been vastly trimmed down from DirectX 9. The most-frequently used functionality is still present such as file importers (mesh and image) and math routines but, other than that (unless the documentation is just lacking), the D3DX library seems to be far more skeletal than it was under DX9.

The functionality migration from D3DX9 to D3DX10 is a cause for great happiness for me. Some of the routines that were present in D3DX9 do still exist in some capacity, as it has now been moved over to the DirectX Utility Toolkit (DXUT), but, most importantly, they're not in D3DX or the core API. This move seems to indicate that D3DX has become more of a staple of the SDK than it was originally intended to be. When I started doing research on the file specifications for the X format the frequent reliance on D3DX became more apparent then I'd ever realized. Most of the code snippet or article that I found focused solely on using the format alongside the D3DX9 functionality that existed. The resources that didn't use D3DX, instead, used IDirectXFile to parse the data as-necessary (this interface has now been deprecated). What's more unfortunate is that some of these resources were actual published books and the contents of these articles are, as of DX10, fairly useless.

My disdain for prolific use of D3DX in any setting outside test cases for new codebases is most likely a result of my preference as a programmer to always use code that I don't have to treat as a mystical black box. I like knowing not only what is going on underneath the hood of functions or classes but, also, to be have the option to optimize the code or erase extraneous functionality which is of no use to me. I have always been of this mindset as a programmer and, despite my recent tendency to actually rely on the D3DX math utilities, I don't see that changing of my own volition.

TL;DR - I don't like the frequent use of D3DX and I like the changes DirectX 10 introduces in relation to it.

Comments: 2 - Leave a Comment

Link


I think something is broken.



This kind of supreme screw-up only occurs in Release mode, though, so I guess that's something to go on.

Comments: 0 - Leave a Comment

Link



Friday, December 7, 2007
This isn't really much of a dev journal entry -- admittedly, I'm actually playing Disgaea: Afternoon of Darkness on my beloved PSP while I write this. I do have plans for a real entry sometime this weekend on the topic of D3DX so, yeah, that's my preview. And, unlike the previews for television shows, I won't ruin the best part to titillate your senses.

Thanks in a large part to Armadon, I found out that Visual Studio 2008 had a fancy-pants feature which automagickally generated a class diagram for all of the various structures and classes within a solution. I used this feature to generate the ever-so-elegant (and empty) framework for Rawr:



In a far more frustrating matter, I'm still having difficulties sorting out the bugs that are facing the skinning portion of my DOOM 3 MD5 mesh code. I've been searching through the loaded-in data -- joint parents, frame values, etc. -- and while I have narrowed down some real wonkiness with regard to the joint structure at a certain frame in the animation I still have no idea what is causing it. In the process of debugging the issue I added the ability to render bones and joints (as the last entry discussed). This has helped me to realize that yes, in fact, the skinning code is screwed up. As a slight consolation, Boney's AF pose has the skeleton looking just as it should. I think I'll be able to make some progress on the code this weekend when I look at it with a fresh set of eyes rather than the eyes of someone who has worked a full programming day on top of three hours of school work. Here are the shots from this evening:



Back to Disgaea for me. Also, 30 Rock is amazing.

Comments: 1 - Leave a Comment

Link



Wednesday, December 5, 2007
It's no coincidence that I haven't made a real dev journal entry since September 7 since that is about when class (my last class evar, even) started up. Since then my weekdays have been pretty filled with a combination of class, work, and homework so I haven't been able to make much progress on my hobby project (Rawr). With the class winding down now, though, I'm starting to make progress on the framework again and, along with that, I'm getting back into the habit of updating this little fella more often.

My first task upon opening up the Rawr solution in Visual Studio 2008 (yay upgrade) was to try and fix the issues that were plaguing poor Boney. My main problem with fixing the skeletal animation code is that, for one thing, my understanding of skeletal animation is pretty barren. The other thing is that, to the best of my understanding, I adhered to the MD5 format specs that I was going off of through the code-writing process very closely. I couldn't figure out what would be causing the animation to look so wonky. So I did what I always do when I need to fix something that I'm clueless about: I play with things until I hit a segment of code that seems to directly impact what I'm trying to change. This process led to Boney as envisioned by Picasso:



For a bit of a break from those precious thirty minutes of work I spent on Boney spread across five days I figured I'd write up an X format file importer since that seems like a neat thing to do at the time. This format is a complete and utter pain in the ass to load in outside of D3DX and IDirectXFile. If I'm feeling particularly verbose and bored at some point the future I'll probably write up an article about my experiences with it, but I'm not really expecting such a time to ever exist. Here some screenshots from the rendering experiences with tiny.x after I had the file reading in correctly:



As far as I can tell, I have a serious case of long-term ADD. After a couple of days of working with the X format and getting the basic mesh rendering correctly I jumped back to getting Boney's skeletal animation to a workable state. Following a suggestion from jpetrie I added some code to render mesh bones/joints along with the mesh itself and it seems fairly obvious now what I'll have to fix when I get home later tonight:



Comments: 0 - Leave a Comment

Link


All times are ET (US)

The entries in this journal have all been posted, along with many more, at mittens' personal site at www.polycat.net.
 
S
M
T
W
T
F
S
1
2
3
4
7
10
11
12
13
14
15
16
18
20
21
22
23
24
25
26
27
28
29
30
31

OPTIONS
Track this Journal

 RSS 

ARCHIVES
August, 2009
July, 2009
June, 2009
May, 2009
April, 2009
March, 2009
February, 2009
January, 2009
December, 2008
November, 2008
October, 2008
September, 2008
August, 2008
July, 2008
June, 2008
May, 2008
April, 2008
March, 2008
February, 2008
January, 2008
December, 2007
November, 2007
September, 2007
August, 2007
July, 2007
December, 2006
July, 2006
June, 2006
May, 2006
April, 2006
March, 2006
February, 2006
January, 2006
November, 2005
September, 2005
August, 2005
July, 2005