前言
项目上有个需求,需要弄一个毛玻璃效果,效果大概如下。图有点糊,见谅…思考了下怎么做,首先做到完全一模一样肯定是不太简单,毕竟咱也是新手村的菜鸟,只能按照场景的思路,一步步想了下,最后看了下shadertoy上的一些图,看有没有大致符合的,然后慢慢动手试一试。
成品图
思路
-
毋庸置疑,我们得先画一个面,然后在面的片源着色器做点事,cesium提供的Material类,我们可以很方便的修改里面的相关参数,并自定义修改。
-
玻璃效果最开始想到用噪声,主要会显得真实一点,但后来试来试去,还是用了一张纹理贴图。
-
四周的边缘泛光的流动效果,显然也是用的噪声模拟出来的,只是最后怎么把位置弄到四周,最简单的当然是根据UV坐标手动划分,但最简单的显然不行,如图…一言难尽。
-
既然如此那么,再稍微加个距离变量呢。看似乎还是买家秀和卖家秀,但以后再优化吧。
float dis = 0.1;
float distance = distance(st, vec2(0.5,0.5));
floata = pow(distance, 4.3);
color2 = mix(color2, color1 , a);
代码
- 首先是流动光效,基本参考shadertoy,具体在哪忘记了…
// Simplex 3D Noise
// by Ian McEwan, Ashima Arts
//
vec4 permute(vec4 x){return mod(((x*34.)+1.)*x,289.);}
vec4 taylorInvSqrt(vec4 r){return 1.79284291400159-.85373472095314*r;}
float snoise(vec3 v){
const vec2 C=vec2(1./6.,1./3.);
const vec4 D=vec4(0.,.5,1.,2.);
// First corner
vec3 i=floor(v+dot(v,C.yyy));
vec3 x0=v-i+dot(i,C.xxx);
// Other corners
vec3 g=step(x0.yzx,x0.xyz);
vec3 l=1.-g;
vec3 i1=min(g.xyz,l.zxy);
vec3 i2=max(g.xyz,l.zxy);
// x0 = x0 - 0. + 0.0 * C
vec3 x1=x0-i1+1.*C.xxx;
vec3 x2=x0-i2+2.*C.xxx;
vec3 x3=x0-1.+3.*C.xxx;
// Permutations
i=mod(i,289.);
vec4 p=permute(permute(permute(
i.z+vec4(0.,i1.z,i2.z,1.))
+i.y+vec4(0.,i1.y,i2.y,1.))
+i.x+vec4(0.,i1.x,i2.x,1.));
// Gradients
// ( N*N points uniformly over a square, mapped onto an octahedron.)
float n_=1./7.;// N=7
vec3 ns=n_*D.wyz-D.xzx;
vec4 j=p-49.*floor(p*ns.z*ns.z);// mod(p,N*N)
vec4 x_=floor(j*ns.z);
vec4 y_=floor(j-7.*x_);// mod(j,N)
vec4 x=x_*ns.x+ns.yyyy;
vec4 y=y_*ns.x+ns.yyyy;
vec4 h=1.-abs(x)-abs(y);
vec4 b0=vec4(x.xy,y.xy);
vec4 b1=vec4(x.zw,y.zw);
vec4 s0=floor(b0)*2.+1.;
vec4 s1=floor(b1)*2.+1.;
vec4 sh=-step(h,vec4(0.));
vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy;
vec4 a1=b1.xzyw+s1.xzyw*sh.zzww;
vec3 p0=vec3(a0.xy,h.x);
vec3 p1=vec3(a0.zw,h.y);
vec3 p2=vec3(a1.xy,h.z);
vec3 p3=vec3(a1.zw,h.w);
//Normalise gradients
vec4 norm=taylorInvSqrt(vec4(dot(p0,p0),dot(p1,p1),dot(p2,p2),dot(p3,p3)));
p0*=norm.x;
p1*=norm.y;
p2*=norm.z;
p3*=norm.w;
// Mix final noise value
vec4 m=max(.6-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.);
m=m*m;
return 42.*dot(m*m,vec4(dot(p0,x0),dot(p1,x1),
dot(p2,x2),dot(p3,x3)));
}
void mainImage(out vec4 fragColor,in vec2 fragCoord)
{
vec2 uv=fragCoord.xy/iResolution.xy;
float scale=.2;
float rate=5.;
float t=iTime/rate;
float result=0.;
//octaves
for(float i=0.;i<5.;i++){
result+=snoise(vec3((uv.x*2.)/scale,(uv.y)/scale,t*2.))/pow(2.,i);
scale/=2.;
}
result=(result+1.)/4.;
result+=.5;
result=pow(result,1.5);
//powers for steeper curves
//float p1 = pow(fragCoord.y/iResolution.y, 1.7);
//float p2 = 8.0*(1.0 - p1);
//result = pow(result, 8.0 - p2);
//power for coloring
float g=pow(result,4.);
fragColor=vec4(.35,g+.3,result+.5,1.);
}
- 最后只在边缘处显示,上面思路最后那块就是。
总结
前路漫漫,其修远兮,世界好大,但一定得走下去。