Lección 4 de 10 · Ray marching en GLSL
Normales
Hacia dónde apunta la superficie. El mapa de orientación.
Para iluminar algo primero hay que saber hacia dónde mira cada punto de su superficie. Eso es la normal: una flecha perpendicular a la cáscara.
No la tenemos guardada, pero la SDF nos la regala: mides la distancia en seis puntitos alrededor del hit (un poco a la izquierda, a la derecha, arriba, abajo, adelante, atrás) y la diferencia te apunta hacia afuera. Eso es el gradiente. Pintamos n*0.5+0.5 para verlo: cada eje un color.
El gradienteLa normal es la dirección en la que la SDF crece más rápido. Restar
map(p+e)-map(p-e) en cada eje mide esa pendiente. normalize la deja de largo 1. Una esfera muestra todo el arcoíris RGB porque mira en todas direcciones.Mueve el
0.0 de hueShift(col, 0.0) y giras toda la paleta de la normal. Cambia el radio 1.0 también.El código
precision highp float;
float map(vec3 p){
return length(p)-1.0;
}
vec3 nrm(vec3 p){
vec2 e=vec2(0.001,0.0);
return normalize(vec3(
map(p+e.xyy)-map(p-e.xyy),
map(p+e.yxy)-map(p-e.yxy),
map(p+e.yyx)-map(p-e.yyx)));
}
void main(){
vec2 uv=(gl_FragCoord.xy*2.0-R)/R.y;
vec3 ro=vec3(0.0,0.0,3.0);
vec3 rd=normalize(vec3(uv,-1.5));
float t=0.0;
float hit=0.0;
for(int i=0;i<64;i++){
vec3 pos=ro+rd*t;
float d=map(pos);
if(d<0.001){ hit=1.0; break; }
t+=d;
if(t>12.0) break;
}
vec3 pos=ro+rd*t;
vec3 n=nrm(pos);
vec3 col=mix(vec3(0.04,0.05,0.09), n*0.5+0.5, hit);
col=hueShift(col, 0.0);
gl_FragColor=vec4(col,1.0);
}