ODOShader

ODOS丨上帝说要有光!

by ERIN.Z, 2022-02-26


Snipaste_2022-02-26_18-03-56.png

基础光照

Classic Phone

    vec3 dif = clamp(dot(l,n),0.,1.)*diffusecol;

Phone

Half Lambert

    vec3 dif = (dot(l,n)*.5+.5)*diffusecol;

half lambert

"Leaky" Phong

上面二者中间插值。

    float shade = dot(l,n);
    vec3 dif = mix(max(shade,0.),shade*.5+.5,.25)*diffusecol;

mix

Image Based Lighting

    vec3 dif = diffusecol*(pow(textureLod(iChannel0, n, 7.).xyz, vec3(2)));

cubemap 这里通过用normal对cubemap采样获得了一个fake的着色结果,目的是获得一个富有变化的光照环境,并非真正的环境光照明。

Fake Image Based Lighting ("studio lighting")

    dif = pow(length(sin(n*2.)*.5+.5)/sqrt(3.), 2.)*diffusecol;

studio

Fake Image Based Lighting ("outdoor lighting")

dif = length(sin(n*2.)*.5+.5)/sqrt(3.)*smoothstep(-1.,1.,n.y)*diffusecol;

outdoor

Use Channels

2DTextures&Buffers&Vedios

texture()函数可以实现对2D、3D材质的采样:

    vec2 uv1 = fragCoord/iResolution.y;
    vec3 col = texture(iChannel0,uv1).xyz;

这里在iChannel0置入了一张类型为sampler2D的纹理图像,所以用vec2 采样。 texture 也可以采样视频,会自动播放。(顺便一提中文版popup面板里的视频tag和纹理tag反了...) vedio 右下角的小齿轮可以设置图像采样方式。 filter BufferABCD可以运行多Pass的Shader,每一个Buffer具有独立的RGBA通道,可以由image的tag页访问,访问方法和texture相似。

Cubemap

cubemap cubemap的采样也可以使用texture()函数,第一个参数的类型是samplerCube第二个参数的类型是vec3。 cubemap textureLod()可以降低材质采样的信息量,第三个参数为0.即为原图。前文的image based的环境光算法就是通过高LOD的采样来伪造环境光。 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;
    ...
}

reflection 这样就得到了一个还不错的金属材质!不过毕竟是cubemap采样,是没有自体反射的。 把之前的阴影加上,再加一点点fake的fresnel边缘光。 float fresnel = pow(clamp(1. - dot(n,-rd),0.,1.),5.); reflection 同理可得玻璃材质,但没有raytracing的玻璃着实有点Fake...... vec3 cmrfr = texture(iChannel0,refract(rd,n,.8)).rgb;//cubemap refraction color = cmrfr + .1difdiffusecol + smoothstep(.7,1.,spe)*specol;//glass Glass 套了一下之前metaball的scene,很酷! metaball metaball

ExpFog

之前有一个忘记写的小技巧,关于指数雾: // fog color = exp( -0.0001ttt ); 对于有无限底平面的场景效果比较明显: Before After 总之今天的结果就是这样啦!

Reference

by ERIN.Z

2024 © typecho & elise