kinect沙池游戏
1,先獲得kinect的深度數(shù)據(jù),原始數(shù)據(jù)并不是一張圖,而是一個(gè)數(shù)組,我們需要將此數(shù)組轉(zhuǎn)成二維數(shù)組,方便使用著色器計(jì)算,專業(yè)術(shù)語應(yīng)該是gpgpu:
?
此段代碼意思為,先創(chuàng)建一個(gè)ComputeBuffer,用來存儲(chǔ)kinect獲取的深度數(shù)據(jù),然后傳入一個(gè)材質(zhì)球的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);//這個(gè)材質(zhì)球在下面會(huì)做說明
? ? }
這個(gè)材質(zhì)球的shader等下再講,先定義了六個(gè)深度值分別對應(yīng)六張圖,也就是說kinect獲取了深度值,當(dāng)該深度值等于對應(yīng)的值得時(shí)候就顯示對應(yīng)圖片上的像素,當(dāng)該深度值處于兩張圖的中間,就取兩張圖根據(jù)深度差距做紋理的混合。
3,重點(diǎn)來了,上面的工作完成后,意味著,我們已經(jīng)將kinect獲取的深度數(shù)據(jù)完美地傳入了shader,并且6張紋理也已經(jīng)傳進(jìn)去,一切準(zhǔn)備就緒,我們來看看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 小于雪山的深度值,則設(shè)置為雪山的紋理
?? ??? ??? ??? ?if (depthValue < _DepthValue0)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?blendCol = blendCol0;
?? ??? ??? ??? ?}
//_DepthValue1為樹林紋理的深度值,如果depthValue 大于雪山,小于樹林,則取雪山和樹林的紋理間插值計(jì)算出混合的紋理,以下以此類推,不一一說明
?? ??? ??? ??? ?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;
?? ??? ??? ??? ?}
? ? ? ? ? ? ? ? //將深度值大于海洋或者小于天空的當(dāng)前像素顏色設(shè)置為黑色
?? ??? ??? ??? ?if(depthValue > _CloudDepthFlag_min && depthValue < _CloudDepthFlag_max)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?blendCol = fixed4(0.0f, 0.0f, 0.0f, 1.0f);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?return blendCol;
?? ??? ??? ?}
?? ??? ??? ?ENDCG
?? ??? ?}
?? ?}
?? ?FallBack "Diffuse"
}
2,我們需要定義深度值所對應(yīng)的紋理,我們這個(gè)項(xiàng)目準(zhǔn)備了6張圖
在片元著色器中獲取了6張上面說過的紋理像素顏色,float depthValue = _DepthBuffer[_DepthMapWidth* y + x];這一句就是kinect獲取在此uv坐標(biāo)下的深度值了,然后就是根據(jù)這個(gè)深度值處于哪兩張紋理之間取得插值。
?
原文地址:https://blog.csdn.net/lj820348789/article/details/83410618
總結(jié)
以上是生活随笔為你收集整理的kinect沙池游戏的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么改造http服务器响应soap,使用
- 下一篇: Stellarium PC完全移植安卓版