0
\$\begingroup\$

I currently working on Depth Data on Kinect SDK v1.8 on XNA and I wanna show an Image Inside the Depth view of Human body. the image below is just an example of what I wanna do :

http://static.gamespot.com/uploads/original/1535/15354745/2429785-screen4.jpg

for Depth View, this is what I've done :

void kinectSensor_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
    using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())
    {
        if (depthImageFrame != null)
        {
            short[] pixelsFromFrame = new short[depthImageFrame.PixelDataLength];

            depthImageFrame.CopyPixelDataTo(pixelsFromFrame);
            byte[] convertedPixels = ConvertDepthFrame(pixelsFromFrame, ((KinectSensor)sender).DepthStream, 640 * 480 * 4);

            Color[] color = new Color[depthImageFrame.Height * depthImageFrame.Width];
            kinectRGBVideo = new Texture2D(graphics.GraphicsDevice, depthImageFrame.Width, depthImageFrame.Height);

            // Set convertedPixels from the DepthImageFrame to a the datasource for our Texture2D
            kinectRGBVideo.SetData<byte>(convertedPixels);
        }
    }
}


// Converts a 16-bit grayscale depth frame which includes player indexes into a 32-bit frame
// that displays different players in different colors
private byte[] ConvertDepthFrame(short[] depthFrame, DepthImageStream depthStream, int depthFrame32Length)
{
    int tooNearDepth = depthStream.TooNearDepth;
    int tooFarDepth = depthStream.TooFarDepth;
    int unknownDepth = depthStream.UnknownDepth;
    byte[] depthFrame32 = new byte[depthFrame32Length];

    for (int i16 = 0, i32 = 0; i16 < depthFrame.Length && i32 < depthFrame32.Length; i16++, i32 += 4)
    {
        int player = depthFrame[i16] & DepthImageFrame.PlayerIndexBitmask;
        int realDepth = depthFrame[i16] >> DepthImageFrame.PlayerIndexBitmaskWidth;

        // transform 13-bit depth information into an 8-bit intensity appropriate
        // for display (we disregard information in most significant bit)
        byte intensity = (byte)(~(realDepth >> 4));

        if (player == 0 && realDepth == 0)
        {
            // white 
            depthFrame32[i32 + RedIndex] = 255;
            depthFrame32[i32 + GreenIndex] = 255;
            depthFrame32[i32 + BlueIndex] = 255;
        }
        else if (player == 0 && realDepth == tooFarDepth)
        {
            // dark purple
            depthFrame32[i32 + RedIndex] = 66;
            depthFrame32[i32 + GreenIndex] = 0;
            depthFrame32[i32 + BlueIndex] = 66;
        }
        else if (player == 0 && realDepth == unknownDepth)
        {
            // dark brown
            depthFrame32[i32 + RedIndex] = 66;
            depthFrame32[i32 + GreenIndex] = 66;
            depthFrame32[i32 + BlueIndex] = 33;
        }
        else
        {
            // tint the intensity by dividing by per-player values
            depthFrame32[i32 + RedIndex] = (byte)(intensity >> IntensityShiftByPlayerR[player]);
            depthFrame32[i32 + GreenIndex] = (byte)(intensity >> IntensityShiftByPlayerG[player]);
            depthFrame32[i32 + BlueIndex] = (byte)(intensity >> IntensityShiftByPlayerB[player]);
        }
    }

    return depthFrame32;
}

I'm not sure how I can get the Object inside the Depth View of the body. Update : I found out I can use HLSL to achieve this for a 3D model :

float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 WorldInverseTranspose;

float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.1;

float3 DiffuseLightDirection = float3(1, 0, 0);
float4 DiffuseColor = float4(1, 1, 1, 1);
float DiffuseIntensity = 1.0;

float Shininess = 200;
float4 SpecularColor = float4(1, 1, 1, 1);
float SpecularIntensity = 1;
float3 ViewVector = float3(1, 0, 0);

float Transparency = 0.5;

texture ModelTexture;
sampler2D textureSampler = sampler_state {
    Texture = (ModelTexture);
    MinFilter = Linear;
    MagFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float4 Normal : NORMAL0;
    float2 TextureCoordinate : TEXCOORD0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float4 Color : COLOR0;
    float3 Normal : TEXCOORD0;
    float2 TextureCoordinate : TEXCOORD1;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
        float4 viewPosition = mul(worldPosition, View);
        output.Position = mul(viewPosition, Projection);

    float4 normal = normalize(mul(input.Normal, WorldInverseTranspose));
        float lightIntensity = dot(normal, DiffuseLightDirection);
    output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);

    output.Normal = normal;

    output.TextureCoordinate = input.TextureCoordinate;
    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    float3 light = normalize(DiffuseLightDirection);
    float3 normal = normalize(input.Normal);
    float3 r = normalize(2 * dot(light, normal) * normal - light);
    float3 v = normalize(mul(normalize(ViewVector), World));
    float dotProduct = dot(r, v);

    float4 specular = SpecularIntensity * SpecularColor * max(pow(dotProduct, Shininess), 0) * length(input.Color);

        float4 textureColor = tex2D(textureSampler, input.TextureCoordinate);
        textureColor.a = 1;

    float4 color = saturate(textureColor * (input.Color) + AmbientColor * AmbientIntensity + specular);
        color.a = Transparency;
    return color;
}

technique Textured
{
    pass Pass1
    {
        AlphaBlendEnable = TRUE;
        DestBlend = INVSRCALPHA;
        SrcBlend = SRCALPHA;
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

and this is my Draw Code in Game1 Class:

protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Black);

        DrawModelWithEffect(model, world, view, projection);

        base.Draw(gameTime);
    }

    private void DrawModelWithEffect(Model model, Matrix world, Matrix view, Matrix projection)
    {
        foreach (ModelMesh mesh in model.Meshes)
        {
            foreach (ModelMeshPart part in mesh.MeshParts)
            {
                part.Effect = effect;
                effect.Parameters["World"].SetValue(world * mesh.ParentBone.Transform);
                effect.Parameters["View"].SetValue(view);
                effect.Parameters["Projection"].SetValue(projection);
            }
            mesh.Draw();
        }
    }

My problem is that I want to use this same idea to create a transparency between two 2D Images.

Is there something like this out there for 2D? If so where can I find it.

\$\endgroup\$
0
\$\begingroup\$

Keep in mind that in XNA (and all other 3D libraries), 2D is 3D! In XNA, sprites are just 3D planes drawn to the screen. Any shader you use in 3D will work just as well with the spritebatch. Spritebatch.Begin() has a parameter for the shader to pass in.

If I'm following you, you want to use the depth image to blend between two images. Here's what I would do:

  • Render the entire scene to a RenderTarget2D
  • Draw a quad to the screen using the RenderTarget2D as a texture.
  • In a custom HLSL shader, sample the depth image from the Kinect to determine whether to blend between the previous texture or some other texture.
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for your guides, but would you please help me in the code ? I totally confused :-( \$\endgroup\$ – Nathan Drake Nov 26 '14 at 16:34
0
\$\begingroup\$

I wrote HLSL code for transparency and then I will transparent one image inside the body and another image used for my foreground :

sampler stream : register(s0);
sampler back : register(s1);
sampler character : register(s2);



float4 DepthToRGB(float2 texCoord : TEXCOORD0) : COLOR0
{
// We can't easily sample non-normalized data,
// Texture is a short packed stuffed into a BGRA4444 (4 bit per component normalized)
// It's not really BGRA4444 which is why we have to reverse the normalization here
float4 color = tex2D(stream, texCoord);
float4 backColor =  tex2D(back, texCoord);
float4 characterColor = tex2D(character, texCoord);

// convert from [0,1] to [0,15]
color *= 15.01f;

// unpack the individual components into a single int
int4 iColor = (int4)color;
int depthV = iColor.w * 4096 + iColor.x * 256 + iColor.y * 16 + iColor.z;

// player mask is in the lower 8 bits
int playerId = depthV % 8;

if(playerId == 0)
{
    //Not yet recognized
    return backColor * float4(1.0,  1.0,  1.0,  1.0);
}
else
{
    return backColor * characterColor;
}
}

technique KinectDepth
{
pass KinectDepth
{
    PixelShader = compile ps_2_0 DepthToRGB();
}
}
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.