Categories
Common talks Unity3D

Small but useful Unity3D shader for Augmented Reality

Sometimes when you do Augmented reality apps, you need hide parts of 3D which pass behind user body or head. Easiest way to make this – use hidden 3d mannequin or 3d head with special shader which cull all pixel data behind it.

358b2eefaa239355f0d5718942baf63c

I just wrote small one for Unity3D.

Shader "Custom/CullMaterial" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}
	 SubShader {
	 Tags { "Queue" = "Background-1" }
        Pass {
            Material {
                Diffuse (1,1,1,1)
            }
            Lighting On
            ColorMask 0
        }
    }
	FallBack "Diffuse"
}

Categories
AIR Flash Unity3D

Send texture from unity to flash via sockets.

For last project i was need show part of main display to distant big screen, connected to another PC. So i need somehow send video feed via Ethernet. Firstly i tried find any encoder lib for sending h264 video, but this was so complicated. So i did small Socket server in adobe air for this distant big screen PC and wrote some code in c# for unity client.

There is 2 ways for sending images to flash via sockets.

1. Send uncompressed bitmap data (ARGB = 4 bytes) from Unity and then use bitmapData.setPixels(rect, byteArray) for recteate bitmap
2. Convert bitmap data into PNG in Unity via Texture2D.EncodeToPNG and them use Loader.loadBytes() in flash.

some code below

Categories
Programming Unity3D

Unity3d mesh subdivision by threshold mask.

While doing one Unity3d project, i was need to make part of mesh subdivided. Not whole mesh, what is easy, but only few regions, defined by grayscale bitmap and threshold. After some googling, i found some nice publishings about this

Iterative Process to Improve Simple Adaptive Subdivision Surfaces Method with Butterfly Scheme
Adaptive Subdivision Schemes for Triangular Meshes
Incremental Subdivision for Triangle Meshes

and code below


Categories
Programming Unity3D

DirectX texture to HBitmap

Hi friends!
I was very busy last months, so didn’t update blog. Now i slowly learn Unity3D (such a great tool) for using it in my future projects. Slowly abandoning Flash and Processing. Love how Unity3D handle DirectX11 stuff. All those compute shaders etc.. ) During learning and doing some of my test projects, i was needed convert GPU texture to BITMAP for sending it to printer, so i wrote this small piece of code and want to share it )
I’m not C++ programmer, but this code is working )
If you know how to optimize it, just send me a comment )

Well, there is 2 parts:

1. For DirectX9 conversion

HGDIOBJ extractBitmap(void* texture){

	HBITMAP hBitmapTexture = NULL;
	HGDIOBJ hBitmap;

	IDirect3DTexture9* d3dtex = (IDirect3DTexture9*)texture;
	D3DSURFACE_DESC desc;
	d3dtex->GetLevelDesc (0, &desc);
	D3DLOCKED_RECT lr;
	d3dtex->LockRect (0, &lr, NULL, 0);

	hBitmapTexture = CreateCompatibleBitmap(GetDC(NULL), desc.Width, desc.Height);
	SetBitmapBits(hBitmapTexture,lr.Pitch*desc.Height,lr.pBits);
	hBitmap = CopyImage(hBitmapTexture,IMAGE_BITMAP,desc.Width,desc.Height,LR_CREATEDIBSECTION);
	d3dtex->UnlockRect (0);
	return hBitmap;
}

2. and for DIrectX11 conversion

HGDIOBJ extractBitmap(void* texture){

	HBITMAP	hBitmapTexture = NULL;
	HGDIOBJ hBitmap;

	ID3D11Texture2D* d3dtex = (ID3D11Texture2D*)texture;
	D3D11_TEXTURE2D_DESC desc;
	d3dtex->GetDesc (&desc);

	ID3D11Texture2D* pNewTexture = NULL;
	D3D11_TEXTURE2D_DESC description;
	d3dtex->GetDesc( &description );

	description.BindFlags = 0;

	description.CPUAccessFlags = D3D11_CPU_ACCESS_READ| D3D11_CPU_ACCESS_WRITE;
	description.Usage =	D3D11_USAGE_STAGING;
	HRESULT hr = g_D3D11Device->CreateTexture2D( &description, NULL, &pNewTexture );

	ID3D11DeviceContext* ctx = NULL;
	g_D3D11Device->GetImmediateContext (&ctx);

	ctx->CopyResource( pNewTexture, d3dtex );

	D3D11_MAPPED_SUBRESOURCE resource;
	UINT subresource = D3D11CalcSubresource( 0, 0, 0 );
	ctx->Map( pNewTexture, subresource, D3D11_MAP_READ_WRITE, 0, &resource );

	// COPY from texture to bitmap buffer
	uint8_t* sptr = reinterpret_cast<uint8_t*>( resource.pData );
        uint8_t* dptr = new uint8_t[desc.Width*desc.Height*4]; 

        for( size_t h = 0; h < desc.Height; ++h )
        {
            size_t msize = std::min<size_t>( desc.Width* 4, resource.RowPitch );
			memcpy_s( dptr, desc.Width*4, sptr, msize );
           sptr += resource.RowPitch;
           dptr += desc.Width * 4;
        }

		dptr -= desc.Width*desc.Height*4;

		// SWAP BGR to RGB bitmap
		 uint32_t *dPtr = reinterpret_cast<uint32_t*>(dptr);
            for( size_t count = 0; count < desc.Width*desc.Height*4; count += 4 )             {                 uint32_t t = *(dPtr);                 uint32_t t1 = (t & 0x00ff0000) >> 16;
                uint32_t t2 = (t & 0x000000ff) << 16;
                uint32_t t3 = (t & 0x0000ff00);
                uint32_t ta = (t & 0xFF000000);

                *(dPtr++) = t1 | t2 | t3 | ta;
            }

		hBitmapTexture = CreateCompatibleBitmap(GetDC(NULL), desc.Width, desc.Height);   
		SetBitmapBits(hBitmapTexture,desc.Width*desc.Height*4,dptr);

		hBitmap = CopyImage(hBitmapTexture,IMAGE_BITMAP,desc.Width,desc.Height,LR_CREATEDIBSECTION);	
}