kinect沙池游戏

22 篇文章 3 订阅

1,先获得kinect的深度数据,原始数据并不是一张图,而是一个数组,我们需要将此数组转成二维数组,方便使用着色器计算,专业术语应该是gpgpu:

 

此段代码意思为,先创建一个ComputeBuffer,用来存储kinect获取的深度数据,然后传入一个材质球的shader中。

 

m_ComputeBuffer = new ComputeBuffer(m_DepthMapLimitWidth * m_DepthMapLimitHeight, sizeof(float));

void UpdateDepthMap()
    {

       
        ushort[] ushortRes = m_KinectManager.GetRawDepthMap();
        int arrLength = ushortRes.Length;
        int curIndex = 0;
        for (int i = 0; i < arrLength; ++i)
        {
            int depthCoordX = i % m_KinectManager.GetDepthImageWidth();
            int depthCoordY = i / m_KinectManager.GetDepthImageWidth();
            if (depthCoordX >= m_DepthMapOffsetX && depthCoordX < m_DepthMapLimitWidth + m_DepthMapOffsetX &&
                depthCoordY >= m_DepthMapOffsetY && depthCoordY < m_DepthMapLimitHeight + m_DepthMapOffsetY)
            {
                if (ushortRes[i] == 0)
                {
                    ushortRes[i] = 4500;
                }
                m_DepthMapBuffer[curIndex] = m_DepthMapBuffer[curIndex]*0.8f + ushortRes[i]*0.2f;
                ++curIndex;
            }
        }
        MapManager.Single.UpdateDepthData(m_DepthMapBuffer);
        m_ComputeBuffer.SetData(m_DepthMapBuffer);
        m_DepthBlendTextureMat.SetBuffer("_DepthBuffer", m_ComputeBuffer);//这个材质球在下面会做说明
    }

这个材质球的shader等下再讲,先定义了六个深度值分别对应六张图,也就是说kinect获取了深度值,当该深度值等于对应的值得时候就显示对应图片上的像素,当该深度值处于两张图的中间,就取两张图根据深度差距做纹理的混合。

3,重点来了,上面的工作完成后,意味着,我们已经将kinect获取的深度数据完美地传入了shader,并且6张纹理也已经传进去,一切准备就绪,我们来看看shader是怎么工作的:

Shader "lj/DepthBlendTexture"
{
    Properties
    {
        _BlendTex0("Texture", 2D) = "white" {}
        _BlendTex1("Texture", 2D) = "white" {}
        _BlendTex2("Texture", 2D) = "white" {}
        _BlendTex3("Texture", 2D) = "white" {}
        _BlendTex4("Texture", 2D) = "white" {}
        _BlendTex5("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags
        {
            "Queue" = "Transparent-100"
            "RenderType" = "Transparent"
        }
        Pass
        {
        Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma exclude_renderers d3d9
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }
            
            sampler2D _BlendTex0;
            sampler2D _BlendTex1;
            sampler2D _BlendTex2;
            sampler2D _BlendTex3;
            sampler2D _BlendTex4;
            sampler2D _BlendTex5;
            fixed4 _Color;

            uniform float _DepthValue0;
            uniform float _DepthValue1;
            uniform float _DepthValue2;
            uniform float _DepthValue3;
            uniform float _DepthValue4;
            uniform float _DepthValue5;

            uniform float _UvAnimationOffsetX;
            uniform int _DepthMapWidth;
            uniform int _DepthMapHeight;

            uniform float _CloudDepthFlag_min;
            uniform float _CloudDepthFlag_max;


            StructuredBuffer<float> _DepthBuffer;

            fixed4 frag (v2f i) : SV_Target
            {
                int x = floor(i.uv.x * _DepthMapWidth);
                int y = floor(i.uv.y * _DepthMapHeight);

                float depthValue = _DepthBuffer[_DepthMapWidth* y + x];

                fixed4 blendCol0 = tex2D(_BlendTex0, i.uv);
                fixed4 blendCol1 = tex2D(_BlendTex1, i.uv);
                fixed4 blendCol2 = tex2D(_BlendTex2, i.uv);
                fixed4 blendCol3 = tex2D(_BlendTex3, i.uv);
                fixed4 blendCol4 = tex2D(_BlendTex4, i.uv);
                fixed4 blendCol5 = tex2D(_BlendTex5, float2(i.uv.x + _UvAnimationOffsetX, i.uv.y));
                blendCol5.a = 0.4f;

                float4 blendCol;
                float alpha = 0.05f;
//_DepthValue0是雪山,距离kinect最近,所以深度值最小,如果depthValue 小于雪山的深度值,则设置为雪山的纹理
                if (depthValue < _DepthValue0)
                {
                    blendCol = blendCol0;
                }
//_DepthValue1为树林纹理的深度值,如果depthValue 大于雪山,小于树林,则取雪山和树林的纹理间插值计算出混合的纹理,以下以此类推,不一一说明
                else if (depthValue < _DepthValue1)
                {
                    float offset01 = _DepthValue1 - _DepthValue0;
                    float alpha1 = (depthValue - _DepthValue0) / offset01;
                    blendCol = blendCol0*(1.0f - alpha1) + blendCol1*alpha1;
                    alpha = alpha1;
                }
                else if (depthValue < _DepthValue2)
                {
                    float offset12 = _DepthValue2 - _DepthValue1;
                    float alpha2 = (depthValue - _DepthValue1) / offset12;
                    blendCol = blendCol1*(1.0f - alpha2) + blendCol2*alpha2;
                    alpha = alpha2;
                }
                else if (depthValue < _DepthValue3)
                {
                    float offset23 = _DepthValue3 - _DepthValue2;
                    float alpha3 = (depthValue - _DepthValue2) / offset23;
                    blendCol = blendCol2*(1.0f - alpha3) + blendCol3*alpha3;
                    alpha = alpha3;
                }
                else if (depthValue < _DepthValue4)
                {
                    float offset34 = _DepthValue4 - _DepthValue3;
                    float alpha4 = (depthValue - _DepthValue3) / offset34;
                    blendCol = blendCol3*(1.0f - alpha4) + blendCol4*alpha4;
                    alpha = alpha4;
                }
                else if (depthValue < _DepthValue5)
                {
                    float offset45 = _DepthValue5 - _DepthValue4;
                    float alpha5 = (depthValue - _DepthValue4) / offset45;
                    blendCol = blendCol4*(1.0f - alpha5) + blendCol5*alpha5;
                    alpha = alpha5;
                }
                else
                {
                    blendCol = blendCol5;
                }
                //将深度值大于海洋或者小于天空的当前像素颜色设置为黑色
                if(depthValue > _CloudDepthFlag_min && depthValue < _CloudDepthFlag_max)
                {
                    blendCol = fixed4(0.0f, 0.0f, 0.0f, 1.0f);
                }

                return blendCol;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

2,我们需要定义深度值所对应的纹理,我们这个项目准备了6张图

在片元着色器中获取了6张上面说过的纹理像素颜色,float depthValue = _DepthBuffer[_DepthMapWidth* y + x];这一句就是kinect获取在此uv坐标下的深度值了,然后就是根据这个深度值处于哪两张纹理之间取得插值。

 

原文地址:https://blog.csdn.net/lj820348789/article/details/83410618

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要下载 Kinect Unity 游戏,首先需要确保你的计算机系统满足运行游戏的最低要求。你需要具备一台安装了 Kinect 传感器的计算机,并且系统要求支持 Unity 引擎和 Kinect 插件。 首先,你需要前往 Unity 官方网站(https://unity.com/)下载并安装 Unity 引擎。在安装完成后,打开 Unity 编辑器。 接下来,你需要下载 Kinect 官方提供的 Unity 插件。你可以在微软官方网站(https://developer.microsoft.com/zh-CN/windows/kinect)上找到 Kinect 开发人员资源,包括 Unity 插件。 在下载完成后,将插件导入到 Unity 编辑器中。打开 Unity,并在 "Assets"(资源)选项卡中选择 "Import Package"(导入选项),然后选择你下载的 Kinect Unity 插件文件。 安装好 Kinect 插件后,你可以开始寻找和下载你感兴趣的 Kinect Unity 游戏。你可以在 Unity Asset Store(https://assetstore.unity.com/)和其他游戏开发者社区中找到众多 Kinect 游戏资源,一些资源可能是免费提供的,而另一些可能需要付费购买。 一旦你找到心仪的 Kinect Unity 游戏资源,点击下载按钮,并根据提示安装游戏资源到你的 Unity 编辑器。 在安装完成后,你可以使用 Unity 编辑器中的预览功能调试和测试游戏。确保你的 Kinect 传感器已正确连接到计算机,并且你已经设置好合适的摄像头和声音设置。 最后,当你满意游戏的表现并准备发布时,你可以在 Unity 编辑器中选择 "Build"(生成)选项,将游戏项目导出为可执行文件或其他适当的格式。 请注意,这仅仅是一个基本的步骤指南,具体的细节和流程可能因 Kinect Unity 游戏的需求、版本和开发者所使用的技术而有所不同。参考相关的文档和教程可以更好地指导你完成下载和使用 Kinect Unity 游戏的过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值