Paletas e rampas
Transforme um valor de 0 a 1 numa cor com rampas de várias paradas, paletas de cosseno ou uma textura de faixa de gradiente.
Como funciona
A maioria dos shaders calcula primeiro um único número, uma distância, um valor de ruído, uma altura, um
produto escalarMultiplica dois vetores componente a componente e soma os resultados. Para vetores unitários é o cosseno do ângulo entre eles, de 1 (mesma direção) a -1 (opostos). Produto escalar Multiplica dois vetores componente a componente e soma os resultados. Para vetores unitários é o cosseno do ângulo entre eles, de 1 (mesma direção) a -1 (opostos).dot(a, b) = |a| |b| cos θt entre 0 e 1 para uma cor. Mantê-la separada permite recolorir um mesmo padrão de uma dúzia de
jeitos, e as escolhas de cor ficam num lugar só.
Duas paradas e mais
A menor paleta é um mixMistura de a até b por um fator t, em linha reta. O GLSL chama de mix; o HLSL e a maioria dos editores de nós chamam de lerp. Interpolação linear (mix) Mistura de a até b por um fator t, em linha reta. O GLSL chama de mix; o HLSL e a maioria dos editores de nós chamam de lerp.mix(a, b, t) = a (1 − t) + b t
vec3 ramp3(vec3 a, vec3 b, vec3 c, float t) {
return t < 0.5 ? mix(a, b, t * 2.0) : mix(b, c, t * 2.0 - 1.0);
}
Qualquer número de paradas igualmente espaçadas cabe num array. Escale t pelo número de trechos, use a parte inteira
como o trecho e a parte fracionária como a posição dentro dele:
const vec3 STOPS[4] = vec3[4](
vec3(0.02, 0.01, 0.05), // noite
vec3(0.45, 0.05, 0.20), // ameixa
vec3(0.95, 0.40, 0.10), // brasa
vec3(1.00, 0.90, 0.60)); // chama
vec3 ramp(float t) {
float x = clamp(t, 0.0, 1.0) * 3.0; // 3 trechos entre 4 paradas
int i = int(min(floor(x), 2.0)); // o último trecho inclui t = 1
return mix(STOPS[i], STOPS[i + 1], x - float(i));
}
Troque o mix por um smoothstep da posição para suavizar as quinas onde os trechos se encontram, ou por um step
para ter faixas chapadas, um visual posterizado barato.
Paletas de cosseno
Uma paleta de cosseno, forma popularizada por Inigo Quilez, descreve um esquema de cores inteiro com quatro parâmetros
vec3 e nenhuma parada. Cada canal segue a própria onda de cosseno ao longo de t:
vec3 cosinePalette(float t, vec3 offset, vec3 amp, vec3 freq, vec3 phase) {
return offset + amp * cos(6.2831853 * (freq * t + phase));
}
Leia os parâmetros por canal, como uma onda da página de funções periódicas: offset é o centro em volta do qual o
canal oscila, amp o quanto ele oscila, freq quantos ciclos ele faz enquanto t vai de 0 a 1, e phase em que ponto
do ciclo ele começa. Dar valores diferentes aos três canais é o que produz os matizes; com os mesmos quatro valores em
todos os canais eles andam juntos e o resultado continua cinza.
// uma rampa de pôr do sol: do vermelho escuro ao laranja e ao amarelo claro
vec3 sunset = cosinePalette(t, vec3(0.70, 0.485, 0.325), vec3(0.30, 0.465, 0.275),
vec3(0.5), vec3(0.50, 0.45, 0.40));
Mantenha offset ± amp dentro de 0–1 em todos os canais e a paleta nunca corta. Como as ondas se repetem, t pode
passar de 1: passe uma distância ou um t + time * 0.1 rolando e as cores circulam suavemente para sempre. Uma paleta
com freq igual a 1 em todos os canais fecha o ciclo sem emenda a cada unidade de t.
Faixas de gradiente
Quando um artista já pintou o gradiente, guarde-o numa textura de um texel de altura e leia com t como coordenada
horizontal:
// no escopo do arquivo:
uniform sampler2D uRamp; // N×1 texels, clamp to edge
// dentro de main():
vec3 color = texture(uRamp, vec2(t, 0.5)).rgb;
A filtragem linear mistura os texels, e a filtragem nearest dá faixas duras, o que combina com paletas de pixel art.
O clamp to edge impede que as duas pontas se misturem uma com a outra. Com filtragem linear, o primeiro e o último
meio texel ficam chapados; para espalhar as paradas por igual de uma ponta à outra, leia em (t * (N - 1.0) + 0.5) / N.
Uma faixa custa uma leitura de textura, mas guarda qualquer curva, e uma textura mais alta pode guardar várias paletas,
uma por linha, escolhida por uma segunda coordenada.
Quais valores escolher
As cores de uma paleta costumam ser escolhidas no olho, como num programa de pintura, então são valores sRGBA codificação padrão das cores de tela. Os valores guardados seguem uma curva próxima de uma potência 1/2.2 da luz, então precisam ser decodificados antes de iluminar ou mesclar. sRGB A codificação padrão das cores de tela. Os valores guardados seguem uma curva próxima de uma potência 1/2.2 da luz, então precisam ser decodificados antes de iluminar ou mesclar.linear = ((c + 0.055) / 1.055)^2.4 for c > 0.04045