Curvas de forma
Curve uma rampa de 0 a 1 com pow, exp e abs para controlar como um valor sobe e desce.
Como funciona
Muitos valores num shader são uma rampa de 0 a 1: uma coordenada UVUma posição 2D numa superfície ou na tela, em geral de 0 a 1 nos dois eixos. Shaders desenham formas e padrões como funções dela. Coordenadas UV Uma posição 2D numa superfície ou na tela, em geral de 0 a 1 nos dois eixos. Shaders desenham formas e padrões como funções dela. 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).uv = gl_FragCoord.xy / resolutiondot(a, b) = |a| |b| cos θ
Para ver uma curva, desenhe o gráfico: acenda os pixels cuja altura está perto do valor da função no x deles.
float y = pow(uv.x, 2.0); // a curva a inspecionar
float line = 1.0 - smoothstep(0.0, 0.01, abs(uv.y - y)); // 1 perto da curva
vec3 color = mix(vec3(y), vec3(0.1, 0.9, 0.3), line); // uma linha verde sobre a rampa
Potências
Efeito Fresnel Superfícies refletem mais luz vistas em ângulo rasante do que de frente. Shaders costumam imitar isso com o produto escalar entre a normal e a direção de visão.pow(x, k) entre 0 e 1 é o burro de carga. Com k acima de 1, a curva fica baixa e sobe tarde (um ease-in); com k
abaixo de 1, ela sobe cedo e achata (um ease-out). 1.0 - pow(1.0 - x, k) espelha a curva e dá o ease-out que
combina com o ease-in de pow(x, k). Um rim light de FresnelSuperfícies refletem mais luz vistas em ângulo rasante do que de frente. Shaders costumam imitar isso com o produto escalar entre a normal e a direção de visão.F = F0 + (1 − F0)(1 − cos θ)^51.0 - dot(n, v) a uma
potência exatamente por isso: uma potência maior empurra o brilho para uma faixa mais fina na silhueta.
O pow é indefinido para base negativa, e para base zero com expoente zero ou menor. Limite a base antes,
pow(max(x, 0.0), k), sempre que ela puder ficar abaixo de zero.
Exponenciais
exp(-k * x) começa em 1 e decai em direção a 0 sem nunca chegar lá: o formato da névoa que engrossa com a distância
e de um brilho que some ao se afastar de uma forma. Um k maior decai mais rápido. Multiplicar um termo que sobe por
um que desce dá um impulso que dispara e some devagar; x * exp(1.0 - x) chega ao pico exatamente em 1 quando x é 1.
Dobrando com abs
abs(x) dobra os valores negativos para cima e transforma uma rampa de -1 a 1 num V. 1.0 - abs(uv.x * 2.0 - 1.0) é
uma tenda: 0 nas duas bordas e 1 no meio. Para uma versão arredondada, 4.0 * x * (1.0 - x) é uma parábola que vale 0
nas duas pontas e 1 em x = 0.5, um jeito barato de fazer algo aparecer e sumir ao longo de um intervalo de 0 a 1.
smoothstep como curva
Smoothstep Um limiar suave. Vale 0 abaixo da primeira borda, 1 acima da segunda e segue uma curva em S com as pontas planas entre elas.smoothstep(0.0, 1.0, x) também é uma curva de forma: um S que suaviza a entrada e a saída (veja
smoothstepUm limiar suave. Vale 0 abaixo da primeira borda, 1 acima da segunda e segue uma curva em S com as pontas planas entre elas.t = clamp((x − e0) / (e1 − e0), 0, 1); s = t² (3 − 2t)
A graça está em combinar. Cada curva custa poucas instruções, e uma cadeia de duas ou três, como um remap, depois uma potência, depois um smoothstep, cobre a maior parte do que um shader precisa antes de recorrer a uma textura de consulta. Desenhe o gráfico de cada elo enquanto monta a cadeia.