Jump to content

  • Log In with Google      Sign In   
  • Create Account


Michael Smith_49683

Member Since 07 Jan 2012
Offline Last Active Jan 27 2012 04:10 AM

Topics I've Started

Spotlight Shadow Mapping Issue, please help =)

24 January 2012 - 08:36 PM

Hello everyone,

I am having an issue with shadow mapping with a spot light in XNA. The issue is, my shadow map area does not seem to coincide with the spot light area. I'm done a lot of internet searching. Found some tutorials and many forum topics, but am still unable to solve my issue. Perhaps an illustration will better show my problem =)

Attached File  SM_Error_0.jpg   45.88KB   23 downloads

The light (white blob in center) is positioned in the world and it's direction is (0, 0, -1). The error region (green square) seems incorrect, I would like the shadow map region to coincide with the (white square) region, "wrapping around" the spot-light.

Here is the 1024x1024 floating point 32-bit shadow-depth map in PNG format. White is furthest possible distance, blue is occluding objects.

Attached File  SM_Error_DepthMap_0.jpg   15.61KB   29 downloads

I will post some test CODE SNIPPETS to show my methods, keep in mind these are not finished or optimized yet :

--------------

HLSL Effect file - Shadow Map Creation :


// Vertex Shader
VSOut TransformVS( VSIn _vsin )
{
// Zero out our output structure
VSOut _output = (VSOut)0;

_output.pos = float4(_vsin.pos, 1.0f);

#if defined(SKINNED)
int IndexArray[4] = (int[4])_vsin.BoneIndices;
_output.pos = SkinningTransformPosition(gBones, _vsin.BoneWeights, IndexArray, _vsin.pos);
#endif

float4 vPosLightCast = GetPositionFromLightCast(_output.pos, gWorld, gViewLight, gProjLight);

.....

#elif defined(SPOT)

float4 vLightViewSpace = mul( mul( _output.pos, gWorld ), gViewLight );
_output.depth = vLightViewSpace.z;

#endif

_output.pos = vPosLightCast;

// Return output
return _output;
}


// Pixel Shader
PSOut TransformPS( PSIn _psin ) : COLOR
{
PSOut _output = (PSOut)0;

.....

#elif defined(SPOT)

float fDepthVal = -(_psin.depth / gFarClipPlaneLight); // Negate because we are in Right-Handed Coordinate System.
_output.color = float4(fDepthVal, 0, 0, 1);

#endif

return _output;
}

--------------

HLSL Effect file - Spot Light Lighting - Depth Map already computed and being used here.
....


float4 GetPositionFromLight(float4 pos, float4x4 viewLight, float4x4 projLight)
{
float4x4 ViewProjection = mul( viewLight, projLight );
return mul(pos, ViewProjection);
}



float GetShadowMapDepthValue(float4 lightingPosition)
{
// Get the shadow map depth value for this pixel
float2 ShadowTexC = 0.5 * (lightingPosition.xy / lightingPosition.w) + float2( 0.5, 0.5 );
ShadowTexC.y = 1.0f - ShadowTexC.y;

return tex2D(TextureShadowMapSampler, ShadowTexC).r;
}



PSOut TransformPS( PSIn _psin ) : COLOR
{

.......

// _psin.pos3D is in world space
// gLightPos is light position in world space


float3 vLightToVertex = _psin.pos3D.xyz - gLightPos; // Compute the vector from the light position to the vertex.
float3 vLightToVertexNormalized = normalize( vLightToVertex );
float fLightToVertexLength = distance( _psin.pos3D.xyz, gLightPos );

......

#elif defined(SPOT)

float4 lightingPosition = GetPositionFromLight(_psin.pos3D, gViewLight, gProjLight); // Get our position on the shadow map
float4 lightPositionViewSpace = mul( _psin.pos3D, gViewLight );
float shadowdepth = GetShadowMapDepthValue(lightingPosition);
float shadowsample = -(lightPositionViewSpace.z / gFarClipPlaneLight) - 0.03f;

float fInShadow = (shadowsample < shadowdepth) ? 1.0f : 0.0f;

float fInnerConeTest = 1.0f - saturate( dot(vLightToVertexNormalized, normalize(gLightDirection)) );
float fStepResult = 1.0f - smoothstep(gLightInnerConeAngle, gLightOuterConeAngle, fInnerConeTest);

diffuseLightingFactor = saturate( dot(-vLightToVertexNormalized, _psin.normal)) * fStepResult * fInShadow;

#endif

....


// diffuseLightingFactor is then used in a lighting equation...

}

Next is some C# XNA code showing how the view and projection matrices are calculated for the depth map calculation phase, the depth map itself seems to be okay...I hope =)


// Angle between light direction and cone edge.
// Normalized between 0 and 1 for half-cone angle, where 0.0f is no angle and 1.0f is 90 degrees (both sides 90 degrees = full 180 spot-light).
private float m_fInnerConeAngle = 0.0f;
private float m_fOuterConeAngle = 0.0f;


public override Matrix GetLightProjectionMatrix()
{
float fFOV = Math.Min(m_fOuterConeAngle * (float)Math.PI, (float)Math.PI);

return Matrix.CreatePerspectiveFieldOfView(
fFOV, // Between 0 and PI (180 degrees).
1,
m_fNearClipPlane,
m_fFarClipPlane);
}



public override Matrix GetLightViewMatrix()
{
Vector3 m_vLookAtPoint = m_vPosition + m_vDirection;
Vector3 vUp = new Vector3(0.0f, 1.0f, 0.0f);

// Special case : Change the up-vector if looking straight UP or DOWN.
// Direction should always be normalized for testing.

float fUpDownTest = Math.Abs(m_vDirection.Y);
float fEpsilon = 1e-10f;

if (fUpDownTest < (1.0f + fEpsilon) &&
fUpDownTest > (1.0f - fEpsilon))
{
if (m_vDirection.Y > 0.0f)
{
vUp = new Vector3(0.0f, 0.0f, -1.0f);
}
else
{
vUp = new Vector3(0.0f, 0.0f, 1.0f);
}
}

return Matrix.CreateLookAt(m_vPosition, m_vLookAtPoint, vUp);
}

----------------

Any help would be so so so much appreciated, I've been spinning my wheels, perhaps looking at this too long. I just can't seem to figure it out. I'm also finding it hard to find tutorials on the subject, without holes in them, in general. =)

- Michael

Ragdoll Physics and Skinning

07 January 2012 - 01:05 AM

Hello All!

I have having a problem with skinned meshes and ragdoll physics using BEPUPhysics in XNA 3.1. I am not a math expert, and the issue lies mostly in not understanding how to skin my meshes when physics is activated on a mesh (ie. ragdoll)

I already have skinned meshes rendering and animating. The problem lies when physics takes over in my game.

When I activate physics, whether in the T-Pose or in the middle of an animation on a mesh, I create a bunch of physics boxes using BEPU and add them to the physics space. They are positioned in world space given the animations current bone transformations and world transform. Using constraints, they seem to render fine using debug boxes I created, and fall/contort realistically.

First picture is T-Pose with user defined collision boxes. Second picture is when physics takes over and the physics objects laying on some steps below.

Attached File  physics0.jpg   60.07KB   33 downloads

Attached File  physics1.jpg   89.8KB   41 downloads

So, again I am not sure how to transform my vertices to match the ragdoll. I have a skinned shader which takes a world matrix and skeleton transforms, and then performs pretty standard hardware skinning. The skeleton transforms are calculated below for animations, which I believe is pretty standard.


for (int i = 0; i < bones.Count; i++)
{
Bone bone = bones[i];
bone.ComputeAbsoluteTransform();

m_boneTransforms[i] = bone.AbsoluteTransform;
}

//
// Determine the skin transforms from the skeleton
//

for (int s = 0; s < m_modelExtra.Skeleton.Count; s++)
{
Bone bone = bones[m_modelExtra.Skeleton[s]];
skeleton[s] = bone.SkinTransform * bone.AbsoluteTransform;
}


public void ComputeAbsoluteTransform()
{
Matrix transform =
Matrix.CreateScale(Scale * bindScale) *
Matrix.CreateFromQuaternion(Rotation) *
Matrix.CreateTranslation(Translation) *
BindTransform;

if (Parent != null)
{
// This bone has a parent bone
AbsoluteTransform = transform * Parent.AbsoluteTransform;
}
else
{ // The root bone
AbsoluteTransform = transform;
}
}

I would appreciate some direction in how I need to calculate the skeleton matrices given box physics objects in world space. =) I am having lots of trouble understanding the concept and step-by-step instructions on how to proceed, especially after just wrapping my head around animation skinning. Thank you so much, I'm sure I'll need to elaborate more on certain things.

- Mike

PARTNERS