把float编码到RGBA8

From KlayGE游戏引擎, post http://www.klayge.org/?p=2635转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2635 前一阵子在把KlayGE的OpenGLES插件升级到OpenGL ES 3的过程中,原先还满怀希望地觉得GLES3总该全面支持浮点纹理的读写了,结果发现GLES3的标准支持float16和float32的读取,但不支持渲染到float16/float32的纹理上。只有支持GL_EXT_color_buffer_float或GL_EXT_color_buffer_half_float扩展的硬件,比如Tegra 4和Adreno 3xx才能很好地支持。所以,在其他设备上如果要渲染到浮点纹理,就得另想办法了。 编码和解码 单通道的float是32-bit,RGBA8也是,所以按说把float编码到RGBA8的纹理中应该没啥问题。很可惜的是,不支持浮点纹理的硬件往往也不支持整数指令和位运算操作。所以在这里需要有些限制。在网上搜了一下,最靠谱的应该是大牛Aras Pranckevičius(aras-p)多年前的帖子。他的做法可以把[0, 1)范围内的浮点数,仅仅用shader model 2的指令,就编码到RGBA8。其实[0, 1)基本就够用了,其他的只要除个常数,读取后乘回去就可以了。编码和解码的函数很简单: float4 EncodeFloatRGBA(float v) { float4 enc = float4(1.0f, 255.0f, 65025.0f, 16581375.0f) * v; enc = frac(enc); enc -= enc.yzww * float4(1 / 255.0f, 1 / 255.0f, 1 / 255.0f, 0); return enc; } float DecodeFloatRGBA(float4 rgba) { return dot(rgba, … Continue reading 把float编码到RGBA8