depth map with more than 255 values

Started by
7 comments, last by TyrianFin 13 years, 6 months ago
I need to create a depth map with more than one channel of values but I'm unsure how to mix the colors to go through up to the full color range.
Advertisement
Why not just use a single-channel image with more than 8 bits per channel? Most image software can handle 16 bits/pixel images, and support for HDR (i.e. 32 bit floating point) is becoming pretty common.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Do pixel shaders support 16 bit images?

Anyways, while it's not exactly what I was planning, I'm just using 1020 depth values now with a combination of rgba.
Hardware depth buffers are usually 24bit
[size="1"]
You could use a 16 or 32 bit render target. See "Render Target" or FBO(OpenGL) tutorials. When you create a texture, you can usually tell which format it is (rgba 8 bit, RGBA16, RGBA32, etcetera). RGBA16 means that each color channel has 16 bits of data (thus in total 4 x 16 = 64 bit).

If you don't have that option due limited hardware, you can also encode the depth value over the multiple color channels. Most shader languages have pack/unpack functions to get the individual bytes out of a value:
byte b[3] = unpack_4byte( depthFloatValue ); // split a 32 bit float up in 4 bytesout.color.r = b[0];out.color.g = b[1];out.color.b = b[2];out.color.a = b[3];//......./// When reading the depth texture again in another shader:byte4 depthPixel = tex2D( depthMap, texcoords );float depthValue = pack_4byte( depthPixel.xyzw );

Packing and unpacking is slower of course, so first check if you can simply use a texture with more bits per channel.

A third option is not to render to a texture, but to a depth buffer (24 or 32 bit) directly. When rendering to a texture, you usually bind a depthMap and a texture. But it is also possible to render to a depthMap only.

Rick
You can get yee some examples here
http://www.opengl.org/wiki/GL_EXT_framebuffer_object

You can look at # 4 Quick example, render_to_texture (2D Depth texture ONLY)
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
A bit off topic, but another good way to "increase precision" is to use standard 24-bit Zbuffer and write logarithmic values to Zbuffer... here goes the link, where is also further description:

http://www.gamasutra.com/blogs/BranoKemen/20090812/2725/Logarithmic_ZBuffer.php

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Or you could stick to 8 bit colour channels and pack the float into, say, two channels. These functions work for me (I think I got them from a post on GameDev so thanks to the author whoever it was!)

///////////////////////////////////////////////////////////// Pack / unpack a float into two 8 bit channels float2 F32_Compress(float f){	float u,v;	float res_u;	u = floor(f*256.0);	res_u = f*256.0 - u;	v = floor(res_u * 256.0);	return (1/256.0*float2(u,v));}float F32_Decompress(float2 vec){	return (vec.x+vec.y*1.0/256.0);}
hmm.. if you wish to use 8bit hegthmap, then there is option of using detail height maps. Basicaly you offset heght maps value by another texture, but offsets scale is much smaller.

example:
heightmap 256 == 2560m (height resolution 10m)
detailmap 256 == 10m (height resolution 0.04m)

If tilling is problem, use multible octaves of detail texture.

/Tyrian

This topic is closed to new replies.

Advertisement