初次接触glsl,写了一个简易版的旋转指南针demo,先上代码:
/**
*@param uv uv
*@param col color
*@param probe_l 探针长度
*@param probe_w 探针宽度
*@param center center
*/
vec4 campass(vec2 uv,vec4 col,float probe_l,float probe_w,vec2 center){
float half_l=probe_l/float(2);
float half_w=probe_w/float(2);
float si=sin(iTime*.7);
float cs=cos(iTime*.7);
// 变换矩阵
mat2 trans=mat2(cs,si,-si,cs);
// 探针4顶点
vec2 dot1=vec2(center.x-half_l,0.);
vec2 dot2=vec2(0,center.y+half_w);
vec2 dot3=vec2(center.x+half_l,0.);
vec2 dot4=vec2(0.,center.y-half_w);
// 对4顶点做矩阵变换
dot1=dot1*trans;
dot2=dot2*trans;
dot3=dot3*trans;
dot4=dot4*trans;
// 向量叉乘,uv同各顶点连线对应向量,叉乘多边形各边,叉乘结果 z 值同正\同负,可判断 uv 坐标在对应多边形内
vec3 inner12=cross(vec3(uv-dot1,.0),vec3(dot2-dot1,0.));
vec3 inner23=cross(vec3(uv-dot2,0.),vec3(dot3-dot2,0.));
vec3 inner34=cross(vec3(uv-dot3,0.),vec3(dot4-dot3,0.));
vec3 inner41=cross(vec3(uv-dot4,0.),vec3(dot1-dot4,0.));
vec3 inner24=cross(vec3(uv-dot4,0.),vec3(dot4-dot2,0.));
//判断探针两头,填充不同颜色
if((inner12.z>0.&&inner24.z>0.&&inner41.z>0.)||((inner12.z<0.&&inner24.z<0.&&inner41.z<0.))){
return col;
}
if((inner23.z>0.&&inner34.z>0.&&inner24.z<0.)||((inner23.z<0.&&inner34.z<0.&&inner24.z>0.))){
vec4 newcol=col*2.;
return newcol;
}
// 画圈
float panel_r=length(uv-center);
if(panel_r<half_l+.001&&panel_r>half_l-.001){
return vec4(vec3(0.),1.);
}
return vec4(vec3(1.),1.);
}
void mainImage(out vec4 fragColor,in vec2 fragCoord)
{
// uv范围(-0.5~0.5)
vec2 uv=fragCoord/iResolution.xy-.5;
uv.y=uv.y*(iResolution.y/iResolution.x);
float cs=cos(iTime*.047),si=sin(iTime*.79);
vec4 col=vec4(cs,si,.0,.5);
col=campass(uv,col,.4,.05,vec2(.0,.0));
fragColor=col;
}
似乎没有什么好说的,直接看效果图吧: