Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Steve_Segreto

Member Since 26 Jun 2009
Offline Last Active Yesterday, 09:21 PM

#5203940 Skinning - normal calculations

Posted by Steve_Segreto on 13 January 2015 - 09:08 AM

Here's a quick thing to try ... since your input normal and temp normal are float4, don't multiply by float3x3 in the inner loop and simply convert from float4 to float3 right before outputting the normal.

 

Here's a working skin shader from my engine:

 

EDIT: Studying your code and my code a bit more, I realized you need to have the normal as a float4 with a w component equal to 0 in order for the math to work, and have the position as a float4 with a w component of 1.0f throughout.

CRenderableMesh 108047F8:
=================================================================================
Vertex Declaration: 0C00B7A0
=================================================================================
 8 Vertex Elements
{ Stream = 0, Offset = 0, Type = D3DDECLTYPE_FLOAT3, Method = D3DDECLMETHOD_DEFAULT, Usage = D3DDECLUSAGE_POSITION, UsageIndex = 0 },
{ Stream = 0, Offset = 12, Type = D3DDECLTYPE_FLOAT3, Method = D3DDECLMETHOD_DEFAULT, Usage = D3DDECLUSAGE_NORMAL, UsageIndex = 0 },
{ Stream = 0, Offset = 24, Type = D3DDECLTYPE_FLOAT3, Method = D3DDECLMETHOD_DEFAULT, Usage = D3DDECLUSAGE_BLENDWEIGHT, UsageIndex = 0 },
{ Stream = 0, Offset = 36, Type = D3DDECLTYPE_D3DCOLOR, Method = D3DDECLMETHOD_DEFAULT, Usage = D3DDECLUSAGE_BLENDINDICES, UsageIndex = 0 },
{ Stream = 0, Offset = 40, Type = D3DDECLTYPE_FLOAT4, Method = D3DDECLMETHOD_DEFAULT, Usage = D3DDECLUSAGE_TEXCOORD, UsageIndex = 0 },
{ Stream = 0, Offset = 56, Type = D3DDECLTYPE_FLOAT4, Method = D3DDECLMETHOD_DEFAULT, Usage = D3DDECLUSAGE_TEXCOORD, UsageIndex = 1 },
{ Stream = 0, Offset = 72, Type = D3DDECLTYPE_FLOAT4, Method = D3DDECLMETHOD_DEFAULT, Usage = D3DDECLUSAGE_TEXCOORD, UsageIndex = 2 },
{ Stream = 0, Offset = 88, Type = D3DDECLTYPE_FLOAT4, Method = D3DDECLMETHOD_DEFAULT, Usage = D3DDECLUSAGE_TEXCOORD, UsageIndex = 3 }
Vertex Shader 10B15880:
=================================================================================
//--------------------------------------------------------------------------------------
// Automatically generated Vertex Shader.
//
// Copyright (c) Steve Segreto. All rights reserved.
// Shader Flags = 887f9
// Shader Type = Linear-Based Quaternion Skinning
// Shader Quality = PHONG_LIGHTING
//--------------------------------------------------------------------------------------
struct DirLight
{
    float4 ambient;
    float4 diffuse;
    float4 spec;
    float3 dirW;
    float4 fogColor;
    float3 lightPosW;
};
struct Mtrl
{
    float4 ambient;
    float4 diffuse;
    float4 spec;
    float  specPower;
    float4 emissive;
};
//--------------------------------------------------------------------------------------
// Macro defines
//--------------------------------------------------------------------------------------
#define MATRIX_PALETTE_SIZE (15)
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
uniform extern DirLight gLight;
uniform extern Mtrl gMtrl;
uniform extern float4x4 gWorld;
uniform extern float4x4 gWVP;
uniform extern float4x4 gInvWorld;
uniform extern float4x4 gView;
uniform extern float3 gEyePosW;
uniform extern float gFarClipDist;
uniform extern float gAlphaRef = 0.29f;
uniform extern float gFogRange = 250.0f;
uniform extern float gFogStart = 1.0f;
uniform extern matrix amPalette[ MATRIX_PALETTE_SIZE ];
uniform extern float gNumBones;
//----------------------------------------------------------------------------
// Shader body - VS_Skin
//----------------------------------------------------------------------------
//
// Define the inputs -- caller must fill this, usually right from the VB.
//
struct VS_SKIN_INPUT
{
    float4 vPos;
    float3 vNor;
    float3 vBlendWeights;
    float4 vBlendIndices;
};
//
// Return skinned position and normal
//
struct VS_SKIN_OUTPUT
{
    float4 vPos;
    float3 vNor;
};
//
// Call this function to skin VB position and normal.
//
VS_SKIN_OUTPUT VS_Skin( const VS_SKIN_INPUT vInput, int iNumBones )
{
    VS_SKIN_OUTPUT vOutput = (VS_SKIN_OUTPUT) 0;
    float fLastWeight = 1.0;
    float afBlendWeights[ 3 ] = (float[ 3 ]) vInput.vBlendWeights;
    int aiIndices[ 4 ]        = (int[ 4 ])   D3DCOLORtoUBYTE4( vInput.vBlendIndices );
    for( int iBone = 0; (iBone < 3) && (iBone < iNumBones - 1); ++ iBone )
    {
        float fWeight = afBlendWeights[ iBone ];
        fLastWeight -= fWeight;
        vOutput.vPos.xyz += mul( vInput.vPos, amPalette[ aiIndices[ iBone  ] ] ) * fWeight;
        vOutput.vNor     += mul( float4(vInput.vNor, 0.0f), amPalette[ aiIndices[ iBone  ] ] ) * fWeight;
    }
    vOutput.vPos.xyz += mul( vInput.vPos, amPalette[ aiIndices[ iNumBones - 1 ] ] ) * fLastWeight;
    vOutput.vNor     += mul( float4(vInput.vNor, 0.0f), amPalette[ aiIndices[ iNumBones - 1 ] ] ) * fLastWeight;
    return vOutput;
}
struct VS_in
{
    float3 posL         : POSITION0;
    float3 normalL      : NORMAL0;
    float3 BlendWeights : BLENDWEIGHT;
    float4 BlendIndices : BLENDINDICES;
    float4 tex0_tex1    : TEXCOORD0;
    float4 tex2_tex3    : TEXCOORD1;
    float4 tex4_tex5    : TEXCOORD2;
    float4 tex6_tex7    : TEXCOORD3;
};
struct VS_out
{
    float4 posH         : POSITION0;
    float4 tex0_tex1    : TEXCOORD0;
    float4 tex2_tex3    : TEXCOORD1;
    float4 tex4_tex5    : TEXCOORD2;
    float4 tex6_tex7    : TEXCOORD3;
    float3 normalW      : TEXCOORD4;
    float4 posVS        : TEXCOORD5;
    float4 color        : COLOR0;
    float  fogLerpParam : COLOR1;
};
VS_out VS_Scene( VS_in i )
{
    //
    // Zero out our output.
    //
    VS_out o = (VS_out)0;
    //
    // Skin VB inputs
    //
    VS_SKIN_INPUT  vsi = { float4( i.posL, 1.0f ), i.normalL, i.BlendWeights, i.BlendIndices };
    VS_SKIN_OUTPUT vso = VS_Skin( vsi, gNumBones );
    i.posL = vso.vPos.xyz;
    i.normalL = vso.vNor;
    //
    // Transform normal to world space and pass along
    // to be interpolated by rasterizer.
    //
    o.normalW = mul( gInvWorld, float4(i.normalL, 0) ).xyz;
    //
    // Pass along material color to be interpolated by rasterizer.
    //
    o.color = gMtrl.diffuse;
    //
    // Transform position to homogeneous clip space.
    //
    float4 vPositionVS = mul(float4(i.posL, 1.0f), mul(gWorld, gView));
    o.posH = mul(float4(i.posL, 1.0f), gWVP);
    //
    // This position will be used to output view space depth.
    //
    o.posVS = vPositionVS;
    o.posVS.z = max(o.posVS.z, 0.0f);
    //
    // Pass on texture coordinates to be interpolated in rasterization.
    //
    o.tex0_tex1.xy = i.tex0_tex1.xy;
    o.tex0_tex1.zw = i.tex0_tex1.zw;
    o.tex2_tex3.xy = i.tex2_tex3.xy;
    o.tex2_tex3.zw = i.tex2_tex3.zw;
    o.tex4_tex5.xy = i.tex4_tex5.xy;
    o.tex4_tex5.zw = i.tex4_tex5.zw;
    o.tex6_tex7.xy = i.tex6_tex7.xy;
    o.tex6_tex7.zw = i.tex6_tex7.zw;
    //
    // Compute vertex distance from camera in world
    // space for fog calculation.
    //
    float dist = distance(mul(float4(i.posL, 1.0f), gWorld).xyz, gEyePosW);
    o.fogLerpParam = saturate((dist - gFogStart) / gFogRange);
    //
    // Done--return the output.
    //
    return o;
}
Pixel Shader 10B1DA90:
=================================================================================
//--------------------------------------------------------------------------------------
// Automatically generated Pixel Shader.
//
// Copyright (c) Steve Segreto. All rights reserved.
// Shader Flags = 807e8
// Shader Type = Linear-Based Quaternion Skinning
// Shader Quality = PHONG_LIGHTING
//--------------------------------------------------------------------------------------
struct DirLight
{
    float4 ambient;
    float4 diffuse;
    float4 spec;
    float3 dirW;
    float4 fogColor;
    float3 lightPosW;
};
struct Mtrl
{
    float4 ambient;
    float4 diffuse;
    float4 spec;
    float  specPower;
    float4 emissive;
};
//--------------------------------------------------------------------------------------
// Macro defines
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
uniform extern DirLight gLight;
uniform extern Mtrl gMtrl;
uniform extern float4x4 gInvWorld;
uniform extern float4x4 gView;
uniform extern float3 gEyePosW;
uniform extern float gFarClipDist;
uniform extern float gAlphaRef = 0.29f;
uniform extern float3 gFogColor;
uniform extern texture gTex0;
struct PS_in
{
    float4 tex0_tex1    : TEXCOORD0;
    float4 tex2_tex3    : TEXCOORD1;
    float4 tex4_tex5    : TEXCOORD2;
    float4 tex6_tex7    : TEXCOORD3;
    float3 normalW      : TEXCOORD4;
    float4 posVS        : TEXCOORD5;
    float4 color        : COLOR0;
    float  fogLerpParam : COLOR1;
};
struct PS_out
{
    float4 vMaterial    : COLOR0;
    float4 vWorldNrm    : COLOR1;
    float4 vEmittance   : COLOR2;
    float4 vDepth       : COLOR3;
};
sampler TexS0 = sampler_state
{
    Texture   = <gTex0>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Point;
    AddressU  = Wrap;
    AddressV  = Wrap;
};
PS_out PS_Scene( PS_in i )
{
    //
    // Zero out our output.
    //
    PS_out o = (PS_out)0;
    //
    // Interpolated normals can become unnormal.
    //
    i.normalW   = normalize(i.normalW);
    //
    // VERT_MODE_SRC_IGNORE
    //
    float3 matAmbient  = gMtrl.ambient.rgb;
    float4 matDiffuse  = gMtrl.diffuse;
    float3 matEmissive = gMtrl.emissive.rgb;
    //
    // Incoming colors.
    //
    float3 color_stage0 = saturate((matAmbient * gLight.ambient) + matDiffuse + matEmissive);
    o.vEmittance.y = gMtrl.spec.r;
    o.vEmittance.z = gMtrl.specPower;
    float  alpha_stage0 = matDiffuse.a;
    //
    // Sample textures.
    //
    float4 color0 = tex2D(TexS0, i.tex0_tex1.xy);
    //
    // Apply texturing stages
    //
    //
    // Diffuse map.
    //
    float3 color_stage1  = color_stage0 * color0.rgb;
    alpha_stage0 = alpha_stage0 * color0.a;
    //
    // Final (pre-fog) color.
    //
    float4 texColor = float4( color_stage1.rgb, alpha_stage0 );
    //
    // Add fog
    //
    o.vMaterial = texColor;
    o.vEmittance.w = i.fogLerpParam;
    // convert normal to texture space [-1;+1] -> [0;1]
    o.vWorldNrm.xyz = i.normalW * 0.5 + 0.5;
    // post-perspective z/w depth
    o.vDepth = i.posVS.z / gFarClipDist;
    //
    // Done--return the output.
    //
    return o;
}
 



#5203586 Updating subset of vertex buffer

Posted by Steve_Segreto on 11 January 2015 - 06:54 PM

I don't know a lot of specifics about the AngelCode library. In my experience you can get better performance by staying with Direct3D rather than going to Direct2D. YMMV. If you stick to D3D, one thing you could do in D3D9 is to fill your vertex buffer with all possible geometry one time at initialization and then use a much smaller constant buffer for per-frame values that need to change. With the appropriate shaders you can use your constant buffer to enable/disable quads, translate them around the screen, color them, u/v animate them, scale them, rotate them, etc. You could also relink textures to each quad per-frame using a different API. All of this is done to avoid locking, modifying and unlocking all or part of the original VB you spoke of (which would be the simpler (e.g. less code to write) way of doing this).




#5203360 D3d9 returning from FullScreen and Window Composition

Posted by Steve_Segreto on 10 January 2015 - 06:10 PM

If this is D3D9 you could study the DXUT parts of one of the smaller DX9 samples (like SimpleSample) and see how they transition from windowed to fullscreen and back again.




#5201475 How come there is 2 attribute groups when doing skinning?

Posted by Steve_Segreto on 02 January 2015 - 11:18 PM

This is what happened, When I use physique to rig the character, the frame (leg) of the mesh has only one attribute group.

When rigged with skin, that frame has 2. Originally,

this produces no problems at all, but ever since the attribute value is 1

(returned from attribute table) during a loop like this

for(int i=0;i < (int)boneMesh->NumAttributeGroups;i++)
{
	int mtrlIndex = boneMesh->attributeTable[i].AttribId;
	g_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));

I only got one material in my array, don't know why mtrlIndex returns 1 (2nd position of the array)

while my materials array has only 1 element in there.

 

Does that mean the frame is affected by 2 bones?

Any ideas why?

Thanks a lot

Jack

 

No this has nothing to do with blend weights/indices. The attribute groups are referring to subsets of the overall mesh that use different materials and/or textures. This may or may not correspond to a skin partition, but doesn't necessarily have to.

 

https://books.google.com/books?id=cbYLAAAAQBAJ&pg=PA51&lpg=PA51&dq=numattributegroups&source=bl&ots=5wtPQ0MZX_&sig=P1VXqGHChoQFz09RVs2jfhG1uMY&hl=en&sa=X&ei=k3mnVLbNDM66ogSbmYKoBQ&ved=0CCcQ6AEwAQ#v=onepage&q=numattributegroups&f=false

 

It sounds like the operation you are performing is adding a 2nd attribute group over the mesh without adding a corresponding entry in the material/texture arrays. How well do you understand the tool you are using and the skinned mesh format it produces? Can you explain them a little bit more here? Are they just X files?




#5201231 Free Sample Code for beginners

Posted by Steve_Segreto on 02 January 2015 - 12:55 AM

Hi,

 

Interesting stuff, i wonder if it's worth creating an article for it with analysis, and advice on how to bring it up to date with DX11 or such, as this would be the expected place to find it and i am sure it would be very useful to have.

Please feel free to do so if you wish.

 

From my perspective it doesn't make any sense, b/c there are only two novelties in the "BigWorld" sample code above:

 

1. Kasper Faurby's swept ellipsoid collision and response algorithm being used to roll our own character controller.

1. Using progressive meshes for terrain rendering to create drastically reduced triangle counts further from the camera while still retaining the shape of the heightmap.

 

Both are highly dependent on d3d9 and d3dx and would be overshadowed by the need to re-invent d3dx in d3d11. Essentially you would drown out those example parts with auxiliary code to replicate simple things like texture loading, skinned mesh animation, etc. You would need to integrate/write a huge amount of code to get a d3d11 version to have parity with d3d9 (plus d3d12 is right around the corner).

 

EDIT: Plus if you really dig into this sample code you will find it's idiotically written and the shader code is filled with math/lighting errors and inefficiencies. It's mostly just a vehicle to showcase the two things above.




#5200111 Beginning Bullet SDK Collision

Posted by Steve_Segreto on 26 December 2014 - 01:19 PM

http://www.gamedev.net/topic/641213-bullet-cameraobject-positions/




#5120219 Self-Taught Programmer Stuck in a Rut

Posted by Steve_Segreto on 30 December 2013 - 09:52 PM

Ok so it's been 10 days and not two weeks but I think it's ready to show smile.png

I wrote a crappy engine (doing that went waaaaaaay past my comfort zone - it was awesome) and in like no time at all I wrote this little Procedural City thing.

 

http://imgur.com/tvWyU1F,XDVZjZ5#1

 

There's a current screenshot of it, I have a lot of plans for it, and it's gonna be doing some cool things soon.

 

Anyway it had been about a year and a half since I programmed something like that, so I figure that's why I felt so stuck in a rut.

 

Thanks for the advice guys!

Great work! Have a look at this great blog. http://www.shamusyoung.com/twentysidedtale/?p=2940




#5116923 Self-Taught Programmer Stuck in a Rut

Posted by Steve_Segreto on 14 December 2013 - 01:55 PM

While programming can be enjoyable in its own right, its usually a means to an end. Focus on what kind of a project you want to create and let that project dictate the technical challenges that you will face. You should know that since you were able to disseminate and understand the concepts in Game Coding Complete, that is a very good indication that you will be able to overcome the new technical challenges you face while making a project that sparks your fancy.

 

For example, if you are interested in a 2-d platformer with good jump/attack physics like Mario, you may find yourself learning about sprite sheets and 2-d physics.

 

If you are more interested in a voxel world with an organic crafting system, you may start learning about procedural content generation with a focus on making voxel terrains.

 

Or you might get interested in old school roguelikes and just focus on cool and interesting game algorithms and AI/pathfinding code.

 

The point is you can be more directed and get out of your rut, if you focus on *MAKING* a complete finished game and not just learning one piece of tech after another in a vacuum.




#5116293 Manually creating textures in Direct3D11

Posted by Steve_Segreto on 11 December 2013 - 02:27 PM

So if I do that do I need to pass only the top level full resolution image data to the initData? Or do I use UpdateSubresource on the top mip level?

My experience is you just pass the top level full resolution image and then the routine internally computes and fills in the mip maps for you. Of course then you don't have control of the mip-map quality, but at least you get the work done for free :)




#5116071 Manually creating textures in Direct3D11

Posted by Steve_Segreto on 10 December 2013 - 07:33 PM

Wait ... am I missing something,  I thought the first API supports automatically generating mip maps for you?

 

To generate mipmap levels automatically, set the number of mipmap levels to 0.




#5094034 3rd person cam vs walls

Posted by Steve_Segreto on 14 September 2013 - 11:42 AM

Here's another simple idea to try ... move your 3rd person camera as normal, allowing user input to control yaw, pitch and zoom. At the end of the frame (before rendering) use your physics system to cast a ray from the camera's position to the camera's eye and if there is a collision, then adjust the camera's position to a little bit in front of the collision (use a point on plane to figure out which way to push the camera position to be in front of the collision hitpoint),




#5092885 Limiting Light

Posted by Steve_Segreto on 09 September 2013 - 10:15 PM

Two simple solutions: During art content creation, either make your light radius small enough that the light never goes out of the building or move the position of the light such that the light never goes out of the building.




#5082387 Using FX files without -shipping- my FX shader files

Posted by Steve_Segreto on 01 August 2013 - 09:02 PM

Well nothing stops you from including them in the PE image as a binary resource, and then use the rc apis to get the fx file (or better the compiled bytecode for the shader, but then u have to roll ur own parts for some of the fx framework).

 

http://blog.kowalczyk.info/article/zy/Embedding-binary-resources-on-Windows.html




#5079340 Shader Unlimited Lights

Posted by Steve_Segreto on 21 July 2013 - 10:41 AM

@Steve_Segreto: Even If there are many variables?

 

Example:

LightDirectional directionalLight[8];
PointLight pointLight[100];
SpotLight spotLight[100];

Basically, I'm trying to set the maximum number possible.

Hi Medo,

 

First convert the max number of floating point registers available for your shader model from a count of float4s to a count of bytes (16 per register). Then you need to take the sizeof( LightDirectional ) in bytes (multiplied by 100, since you want that many), plus the sizeof( PointLight ) in bytes (multiplied by 100) plus sizeof( SpotLight ) multiplied by 100. Now subtract that from the number of bytes available for variables/constants and that should tell you if you could compile that declaration within that shader model. Or you could just run fxc from the command line and try it out :)

 

Also if you were confused because I said 256 const float registers, I was just using some terminology I've seen in DX9 docs, I believe those same registers are used for uniform externs that you can set from a C++ program (i.e. variables)




#5075855 This Friend of mine

Posted by Steve_Segreto on 07 July 2013 - 12:49 AM

Well I can give an opinion ... I think its important for you and your friend to work together - it's great experience. I think DX9 FF is still broadly accepted and I don't think your OpenGL experience will be terribly valuable in transitioning to Direct3D. I think you should just start working with your buddy on the engine he already created and make a game. Have fun guys!!!






PARTNERS