基础光照
Classic Phone
vec3 dif = clamp(dot(l,n),0.,1.)*diffusecol;
Half Lambert
vec3 dif = (dot(l,n)*.5+.5)*diffusecol;
"Leaky" Phong
上面二者中间插值。
float shade = dot(l,n);
vec3 dif = mix(max(shade,0.),shade*.5+.5,.25)*diffusecol;
Image Based Lighting
vec3 dif = diffusecol*(pow(textureLod(iChannel0, n, 7.).xyz, vec3(2)));
这里通过用normal对cubemap采样获得了一个fake的着色结果,目的是获得一个富有变化的光照环境,并非真正的环境光照明。
Fake Image Based Lighting ("studio lighting")
dif = pow(length(sin(n*2.)*.5+.5)/sqrt(3.), 2.)*diffusecol;
Fake Image Based Lighting ("outdoor lighting")
dif = length(sin(n*2.)*.5+.5)/sqrt(3.)*smoothstep(-1.,1.,n.y)*diffusecol;
Use Channels
2DTextures&Buffers&Vedios
texture()函数可以实现对2D、3D材质的采样:
vec2 uv1 = fragCoord/iResolution.y;
vec3 col = texture(iChannel0,uv1).xyz;
这里在iChannel0置入了一张类型为sampler2D的纹理图像,所以用vec2 采样。 也可以采样视频,会自动播放。(顺便一提中文版popup面板里的视频tag和纹理tag反了...) 右下角的小齿轮可以设置图像采样方式。 BufferABCD可以运行多Pass的Shader,每一个Buffer具有独立的RGBA通道,可以由image的tag页访问,访问方法和texture相似。
Cubemap
cubemap的采样也可以使用texture()函数,第一个参数的类型是samplerCube第二个参数的类型是vec3。 textureLod()可以降低材质采样的信息量,第三个参数为0.即为原图。前文的image based的环境光算法就是通过高LOD的采样来伪造环境光。
Reflection&Refraction
前面的环境光是fake的,现在整点真的环境反射:
vec3 render(vec2 uv){
...
vec3 color = texture(iChannel0,rd).rgb;//background
if(t > TMAX) return color;
...
vec3 cm = 1.5*vec3(.5)*texture(iChannel0,reflect(rd,n)).rgb;//cubemap reflect
vec3 diffusecol = vec3(1.);//diffuse color
vec3 specol = vec3(1.);//specular color
float dif = clamp(dot(l,n),0.,1.);//diffuse
float spe = pow(clamp(dot(h,n),0.,1.),50.);//specular
color = cm + .2*dif*diffusecol + spe*specol;
...
}
这样就得到了一个还不错的金属材质!不过毕竟是cubemap采样,是没有自体反射的。 把之前的阴影加上,再加一点点fake的fresnel边缘光。 float fresnel = pow(clamp(1. - dot(n,-rd),0.,1.),5.); 同理可得玻璃材质,但没有raytracing的玻璃着实有点Fake...... vec3 cmrfr = texture(iChannel0,refract(rd,n,.8)).rgb;//cubemap refraction color = cmrfr + .1difdiffusecol + smoothstep(.7,1.,spe)*specol;//glass 套了一下之前metaball的scene,很酷!
ExpFog
之前有一个忘记写的小技巧,关于指数雾: // fog color = exp( -0.0001ttt ); 对于有无限底平面的场景效果比较明显: 总之今天的结果就是这样啦!
Reference
- Quick Lighting in Shadertoy
- Shadertoy Tutorial Part 16 - Cubemaps and Reflections 这套教程感觉写的尤其好!要是早点看到的话应该可以少走很多弯路呜呜