2015-09-29 3 views
2

В настоящее время у меня есть рабочая реализация, которая позволяет мне кодировать значение глубины в текстуру с плавающей точкой.Кодировка с половинным положением для глубины в шейдере фрагмента (WebGL 1.0)

Вот кодирование/декодирование функции:

"vec4 EncodeFloatRGBA(float v) {", 
 
       "float remainder = v;", 
 
       "vec4 res, r;", 
 

 
       "res[0] = floor(remainder * 255.0)/255.0;", 
 
       "remainder -= res[0];", 
 
       "res[1] = floor(remainder * 65535.0)/65535.0;", 
 
       "remainder -= res[1];", 
 
       "res[2] = floor(remainder * 16777215.0)/16777215.0;", 
 
       "remainder -= res[2];", 
 
       "res[3] = floor(remainder * 4294967295.0)/4294967295.0;", 
 

 
       "r[0] = clamp(floor((v) * 255.0),0.,255.);", 
 
       "r[1] = clamp(floor((v - res[0]) * 65535.0),0.,255.);", 
 
       "r[2] = clamp(floor((v - res[0] - res[1]) * 16777215.0),0.,255.);", 
 
       "r[3] = clamp(floor((v - res[0] - res[1] - res[2]) * 4294967295.0),0.,255.);", 
 

 
       "r[0] = r[0]/255.0;", 
 
       "r[1] = r[1]/255.0;", 
 
       "r[2] = r[2]/255.0;", 
 
       "r[3] = r[3]/255.0;", 
 
       "return r;", 
 
    "}", 
 
    
 
"float DecodeFloatRGBA(vec4 rgba) {", 
 
       "return dot(rgba, vec4(1.0, 0.003921568627450980392156862745098, 1.5259021896696421759365224689097e-5, 5.9604648328104515558750364705942e-8));", 
 
"}",

Вот как я их использовать:

//Encoding in depth pass 
 
"vec4 depth = EncodeFloatRGBA(1.0 - gl_FragCoord.z);", 
 
"depth = floor(depth * 255.) * 0.003921568627450980392156862745098;",//simulate 32-bit encoding 
 
"gl_FragColor = depth;", 
 
    
 
    
 
//Decoding in color pass 
 
"loc = vec2(gl_FragCoord.x/canvas_size.x, gl_FragCoord.y/canvas_size.y);", 
 
"float z = DecodeFloatRGBA(EncodeFloatRGBA(1.0 - gl_FragCoord.z));",//current fragment depth 
 
"float z_tex = DecodeFloatRGBA(texture2D(DX2RT, loc));",//depth in texture 
 
//...do some stuff using z and z_tex

Но когда дело доходит до половины текстур с плавающей запятой (ipad, ipod), этот метод больше не работает, и я лучше вообще не использую кодировку. Но в последнем случае у меня все еще есть некоторая потеря точности.

У кого-нибудь есть подобная техника, настроенная для половины текстур с плавающей запятой?

Заранее спасибо.

+0

испытывает те же проблемы, вы решили эту проблему? – deblocker

ответ

0

Для некоторых устройств, я отключил кодирование глубины, для других я использовал следующие биты кода:

"vec4 EncodeFloatRGBA(float v) {", 
    "float remainder = v;", 
    "vec4 res, r;", 

    "res[0] = floor(remainder * 127.0)/127.0;", 
    "remainder -= res[0];", 
    "res[1] = floor(remainder * 16383.0)/16383.0;", 
    "remainder -= res[1];", 
    "res[2] = floor(remainder * 2097151.0)/2097151.0;", 

    "r[0] = clamp(floor((v) * 127.0),0.,127.);", 
    "r[1] = clamp(floor((v - res[0]) * 16383.0),0.,127.);", 
    "r[2] = clamp(floor((v - res[0] - res[1]) * 2097151.0),0.,127.);", 

    "r.r = r[0]/127.0;", 
    "r.g = r[1]/127.0;", 
    "r.b = r[2]/127.0;", 
    "r.a = 1.;", 
    "return r;", 
"}", 


"float DecodeFloatRGBA(vec4 rgba) {", 
    "return rgba.r + rgba.g/127. + rgba.b/16383.;", 
"}"