2017-03-21 18 views
0

저는 텍스처 메모리를 최적화하려고 노력 중이며 GL_RGBA32F LUT를 GL_RGBA16F로 변환하지 못하게하는 모든 것이 한계를 초과 할 수도있는 하나의 인덱스입니다. 어쨌든 내가 C에서 float을 받아서 2 개의 값으로 나눈 다음 GLSL에서 LUT에 저장된 2 개의 값으로부터 float을 재구성 할 수 있습니까?GLES 인코더/디코드 32 비트 float에서 2x16bits로

는 내 말은이 같은 것입니다 :

[C]

float v0,v1, *pixel_array; 

magic_function_in_c(my_big_value, &v0, &v1); 

pixel_array[ index++ ] = pos.x; // R 
pixel_array[ index++ ] = pos.y; // G 
pixel_array[ index++ ] = v0; // B 
pixel_array[ index++ ] = v1; // A 

[GLSL]

vec4 lookup = texture2D(sampler0, texcoord); 

float v = magic_function_in_glsl(lookup.b, lookup.a); 

가 PS : 임 GLES 2.0을 사용하여 (WebGL이와도 호환 될)

답변

1

float16이 제공하는 것보다 더 많은 범위가 필요하고 한 방향 (크거나 작은)으로 만 필요한 경우, 고정 된 배율 인수로 곱할 수 있습니다.

예를 들어, N이 65503 이상인 경우 N을 2로 나눈 값을 '인코딩'하고 2를 곱하면 '디코드'할 수 있습니다. 이렇게하면 유효 범위가 위로 이동하여 1/N, 그러나 +/- N에 대한 최대 범위를 확장합니다. +/- N보다 1/N의 범위가 더 필요하면 곱셈과 나눗셈을 바꿀 수 있습니다. 데이터를 기반으로 변경해야하는 경우 두 번째 값을 사용하여 크기 조정 요소가 저장되는 위치를 저장할 수 있습니다.

또한 EXP2 및 LOG2, 같은 실험을 할 수 있습니다 : 당신이 highp이 GLSL 쉐이더에서 수레가없는 경우이 중 어느 것도 작동하지 않습니다 것을

void 
magic_function_in_c(float fVal, uint16_t* hExponent, uint16_t* hMult) 
{ 
    float fExponent = log2f(f); 
    *hExponent = f32_to_f16(fExponent); 

    // Compensate for f32->f16 precision loss 
    float fActualExponent = f16_to_f32(*hExponent); 
    float fValFromExponent = exp2f(fActualExponent); 

    float fMult; 
    if (fValFromExponent != 0.0f) { 
     fMult = fVal/fValFromExponent; 
    } else if (fVal < 0.0f) { 
     fMult = -1.0f; 
    } else { 
     fMult = 1.0f 
    } 
    *hMult = f32_to_f16(fMult); 
} 

highp float 
magic_function_in_glsl(highp float hExponent, highp float hMult) 
{ 
    return exp2(hExponent) * hMult; 
} 

참고.