Random errors in Release builds

Started by
11 comments, last by rip-off 8 years, 5 months ago

Hey, I'm trying to deploy a game application based on my own game engine.

Inside Visual Studio, the Release build works perfectly every time.

HOWEVER, when I run the application outside (I have an installer), ZERO, ONE or TWO animated models are simply NOT RENDERED. This behavior seems to be completely random, sometimes everything renders properly, sometimes only one model missing, and sometimes both are missing.

What may be the cause of this problem?

Advertisement

You should check your variables if one is not initialized.

If the problem is random, it can be the cause.

I've often found uninitialized variables and/or memory to be the culprit behind these kinds of issues, where things mysteriously break in one build or once deployed, *especially* in release builds.

Start with remote debugging when the issue presents, and then lots and lots of logging!

Thank you, that was exactly the kind of hint I was looking for, I'll do my best.

Turn up warnings to level 4. It'll notify you about unused variable, uninitialized variables, etc. Fix all of that.

If you're using Visual Studio 2015 (and maybe 2013?) you can also run static code analysis. It might show extra issues (possible nullptr, etc.), but sometimes it also points out false positives.

Nailed down the exact piece of code. It turned out to be the skinning update inside vertex shader (using Direct3D 11).

Here it is, the HLSL code:


float4 newPos = { 0.0f, 0.0f, 0.0f, 1.0f };
float4 newNormal = { 0.0f, 0.0f, 0.0f, 1.0f };

// Perform the skinning update.
if (i1 > -1) {
	newPos = newPos + mul(input.position, boneTransforms[i1]) * w1;
	newNormal = newNormal + mul(boneTransforms[i1], input.normal) * w1;
}
if (i2 > -1) {
	newPos = newPos + mul(input.position, boneTransforms[i2]) * w2;
	newNormal = newNormal + mul(boneTransforms[i2], input.normal) * w2;
}
if (i3 > -1) {
	newPos = newPos + mul(input.position, boneTransforms[i3]) * w3;
	newNormal = newNormal + mul(boneTransforms[i3], input.normal) * w3;
}
if (i4 > -1) {
	newPos = newPos + mul(input.position, boneTransforms[i4]) * w4;
	newNormal = newNormal + mul(boneTransforms[i4], input.normal) * w4;
}

newPos.w = 1.0f;
newNormal.w = 1.0f;

Any leads?

Don't do any if/else, just do a for loop like that :


float4 SkinnedPos = float4( 0.0f, 0.0f, 0.0f, 0.0f );
float3 SkinnedNormal = float3( 0.0f, 0.0f, 0.0f );
for( int i = 0; i < 4; ++i )
{
  SkinnedPos += mul( Input.Position, BoneMatrices[ Input.Indices[ i ] ] ) * Input.Weights[ i ];
  SkinnedNormal += mul( Input.Normal, (float3x3)BoneMatrices[ Input.Indices[ i ] ] ) * Input.Weights[ i ];
}
Output.Position = mul( SkinnedPos, WorldViewProjection );
Output.Normal = mul( SkinnedNormal, (float3x3)WorldViewInverseTranspose );

Maybe check the value of i1, i2, i3, i4 and how you send to shader.

Alundra: He had the if clauses to guard against unused bone indices. However, profiling would indicate if it would be more performant to simply include an "identity" bone matrix at a specified index and use that instead of a sentinel value like -1.

Ryder052: What do you mean, "any leads"? That's a small piece of a shader program. We can see two variables initialized there, and can't see where the other 3-7 are or are not initialized. Not much we can do to help with that little information. Why do you think that piece of code is to blame? If you do know that's where things are going wrong, just walk through the possibilities and check them. Can input.weights be uninitialized? Can the indices be uninitialized?

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

Yeah, sorry for not giving more detailed info, I was leaving for a break and quick posting here in hope to make some progress not actually digging through the stuff, you know, laziness.

Fixed the issue, the cause was indeed the indices and weights not properly initialized. The model loading flow was the following:

LoadModel() {

LoadGeometry ( if(FLAG) then initialize bone w / ids to default values )

LoadTextures()

LoadAnimations( set FLAG )

}

As you can see, it was flawed. Thanks for all the input.

@Alundra: Using arrays in shader code is very suboptimal both computing- and memory-wise, as each array element eats at least 16 bytes no matter what type you actually put there and it screws your indexing HARD! It is much more economical to pack your data into float4's as I did with bone indices and weights (which I limit to 4/vertex tops).

It is much more economical to pack your data into float4's as I did with bone indices and weights (which I limit to 4/vertex tops).

This is what I also do in my answer, you can access the value using the operator [] from float4 and uint4.

This topic is closed to new replies.

Advertisement