OpenGL: GLSL имеет низкую точность

У меня есть плавающая альфа текстура, которая содержит значения амплитуды. Он преобразуется в децибелы и отображается в оттенках серого.

Вот код разговора (C ++):

const float db_min = -100, db_max = 0;
float image[height][width];
for (int y = 0; y<height; ++y) {
for (int x = 0; x<width; ++x) {
image[y][x]= 20.f * log(a[i])/log(10.f);
image[y][x] = (image[y][x]-db_min)/(db_max-db_min);
}
}

Вот фрагментный шейдер (GLSL):

#version 120
precision highp float;
varying vec2 texcoord;
uniform sampler2D texture;
void main() {
float value = texture2D(texture, texcoord).a;
gl_FragColor = vec4(value, value, value, 0);
}

Вот скриншот:
введите описание изображения здесь

Выглядит идеально! Теперь я хочу написать разговор в самом Fragment Shader вместо C ++:

#version 120
precision highp float;
varying vec2 texcoord;
uniform sampler2D texture;
const float db_min = -100., db_max = 0.;
void main() {
float value = texture2D(texture, texcoord).a;
value = 20. * log(value)/log(10.);
value = (value-db_min)/(db_max-db_min);
gl_FragColor = vec4(value, value, value, 0);
}

Вот скриншот:
введите описание изображения здесь

Почему результаты разные? Что я делаю неправильно?

4

Решение

Ограниченная точность текселя — это может быть проблемой. Я могу догадаться, что вы держите свой (очень высокий диапазон, как я понимаю, глядя на log) значения в 8-битной текстуре на канал (например, RGBA8). Затем вы можете использовать формат с плавающей запятой или упаковать ваши значения высокой точности / диапазона в 4-байтовый формат (например, с фиксированной точкой).

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]