2015-07-05 3 views
0

Я создаю 2D-игру с использованием OpenGL ES 2 в Android и включаю в нее панель здоровья. Бар здоровья меняется на 5 цветов по мере уменьшения здоровья (зеленый, желто-зеленый, желтый, оранжевый, красный). Текстура для панели здоровья исходит из атласа текстуры, и я предпочел бы не загромождать атлас текстуры полосой для каждого цвета (в будущем было бы легче изменить эти цвета).Изменение цвета текстуры бара здоровья в GLSL ES

Это оригинальный зеленый цвет, который я хотел бы воспроизвести с использованием GLSL. Основной цвет для этого - # 77ee9a.

То, что я пытался это создать черно-белую версию текстуры. Базовый зеленый цвет здесь #aeaeae.

Затем я умножать цвет я хочу с этим черно-белым изображением. Я понял, что это не сработает правильно, поэтому я взял зеленый, который я хотел (# 77ee9a), и разделил его на черно-белый эквивалент (#aeaeae) до умножения. Это привело к:

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

Я не уверен, есть ли лучший способ достичь этого эффекта окраски, но я надеюсь, что есть решение, которое позволит мне это сделать.

Если нет, я бы мог создать две текстуры: 1 чистый белый в форме бара, а другой с прозрачными эффектами. Я мог бы затем наложить их, но для игры потребуется еще одна текстура и другой спрайт.

Спасибо!

ответ

0

На самом деле вы можете написать шейдер, так что вам нужна только 1 текстура, которая будет изменена таким образом, как: чем больше пустошь потеряна, тем больше она станет Чтобы получить значение цвета «серого текста», которое должно использоваться является:

Grayvalue = 0299 ​​× красный + 0587 × зеленый + 0114 × Синий

Таким образом, формула в затенении будет, как:

Healthpercantage * 0,711 + 0,299, Healthpercantage * 413 + 0587, Healthpercantage * 0,886 + 0,114

1

Вы можете вычислить 2 отдельных градиента, используя функцию смешивания GLSL: одну, которая идет от черного до выбранного цвета, что соответствует серым значениям от 0 до 0,68 (#aeaeae), а другое - от выбранного цвета до белого для значений серого от 0,68 до 1,0.

Пропускают оттенок цвета (например, зеленый) в качестве однородной:

uniform vec4 uTintColor; 

прочитать значение серого и принимать любой компонент (так как все они одинаковы). Затем вычислите, где серое значение лежит в каждом из градиентов и применяет их. Когда он находится в нижнем градиенте, upperGradientCol будет равен uTintColor, потому что upperGradientPos будет равен нулю, поэтому upperGradientCol можно использовать как верхнюю границу нижнего градиента.

// read grey scale value 
vec4 texel = texture2D(uTexture, vTexCoord); 
float greyValue = texel.r; 

// compute position in gradients: 
float upperGradientPos = clamp((greyValue - 0.68)/0.32, 0.0, 1.0); 
float lowerGradientPos = clamp(greyValue/0.68, 0.0, 1.0); 

// apply upper gradient from uTintColor up to white: 
vec4 upperGradientCol = mix(uTintColor, vec4(1.0, 1.0, 1.0, 1.0), upperGradientPos); 
// apply lower gradient from black up to uTintColor: 
vec4 lowerGradientCol = mix(vec4(0.0, 0.0, 0.0, 1.0), upperGradientCol, lowerGradientPos); 
gl_FragColor = vec4(lowerGradientCol.rgb, texel.a); 

Чтобы сделать это более универсальным вы могли бы пройти в разных цветах, а не черно-белый, как форма, а так же для серого значения, соответствующего цвету отлива (в настоящее время HARDCODED на 0,68).

Смежные вопросы