1. 通过修改距离场可以变化形状。
#ifdef GL_ES
precision mediump float; // 如果是在OpenGL ES环境下,设置中等精度的浮点数
#endif
uniform vec2 u_resolution; // uniform变量,用于传入画布分辨率
uniform vec2 u_mouse; // uniform变量,用于传入鼠标位置
uniform float u_time; // uniform变量,用于传入当前时间
void main(){ // 着色器的主函数
vec2 st = gl_FragCoord.xy/u_resolution.xy; // 将片元的坐标规范化到[0,1]的范围内
st.x *= u_resolution.x/u_resolution.y; // 根据屏幕宽高比调整x坐标,保证图形不会被拉伸
vec3 color = vec3(0.0); // 初始化颜色为黑色
float d = 0.0; // 初始化距离值为0
// Remap the space to -1. to 1.
st = st *2.-1.; // 将坐标范围重新映射到[-1,1]
// Make the distance field
d = length( abs(st)-.3 ); // 计算当前点到半径为0.3的圆的距离
// d = length( min(abs(st)-.3,0.) ); // 注释的代码,生成实心圆形的距离场
// d = length( max(abs(st)-.3,0.) ); // 注释的代码,生成空心圆形的距离场
// Visualize the distance field
gl_FragColor = vec4(vec3(fract(d*10.0)),1.0); // 根据距离值生成颜色,用于可视化距离场
// Drawing with the distance field
// gl_FragColor = vec4(vec3( step(.3,d) ),1.0); // 注释的代码,使用step函数生成硬边界的圆
// gl_FragColor = vec4(vec3( step(.3,d) * step(d,.4)),1.0); // 注释的代码,生成环形区域
// gl_FragColor = vec4(vec3( smoothstep(.3,.4,d)* smoothstep(.6,.5,d)) ,1.0); // 注释的代码,生成带有平滑过渡的环形区域
}
效果如图
2. 选择实心圆和环形过度可以生成类似星星的样式。
#ifdef GL_ES
precision mediump float; // 如果是在OpenGL ES环境下,设置中等精度的浮点数
#endif
uniform vec2 u_resolution; // uniform变量,用于传入画布分辨率
uniform vec2 u_mouse; // uniform变量,用于传入鼠标位置
uniform float u_time; // uniform变量,用于传入当前时间
void main(){ // 着色器的主函数
vec2 st = gl_FragCoord.xy/u_resolution.xy; // 将片元的坐标规范化到[0,1]的范围内
st.x *= u_resolution.x/u_resolution.y; // 根据屏幕宽高比调整x坐标,保证图形不会被拉伸
vec3 color = vec3(0.0); // 初始化颜色为黑色
float d = 0.0; // 初始化距离值为0
// Remap the space to -1. to 1.
st = st *2.-1.; // 将坐标范围重新映射到[-1,1]
// Make the distance field
//d = length( abs(st)-.3 ); // 计算当前点到半径为0.3的圆的距离
d = length( min(abs(st)-.3,0.) ); // 注释的代码,生成实心圆形的距离场
// d = length( max(abs(st)-.3,0.) ); // 注释的代码,生成空心圆形的距离场
// Visualize the distance field
gl_FragColor = vec4(vec3(fract(d*10.0)),1.0); // 根据距离值生成颜色,用于可视化距离场
// Drawing with the distance field
// gl_FragColor = vec4(vec3( step(.3,d) ),1.0); // 注释的代码,使用step函数生成硬边界的圆
// gl_FragColor = vec4(vec3( step(.3,d) * step(d,.4)),1.0); // 注释的代码,生成环形区域
gl_FragColor = vec4(vec3( smoothstep(.3,.4,d)* smoothstep(.6,.5,d)) ,1.0); // 注释的代码,生成带有平滑过渡的环形区域
}
3. 极坐标的变换
极坐标下的半径函数(r-θ)图案。它是通过改变角度θ和对应的半径r值,然后使用这个函数生成一系列形状和纹理。
#ifdef GL_ES
precision mediump float; // 如果是在OpenGL ES环境下,设置中等精度的浮点数
#endif
uniform vec2 u_resolution; // uniform变量,用于传入画布分辨率
uniform vec2 u_mouse; // uniform变量,用于传入鼠标位置
uniform float u_time; // uniform变量,用于传入当前时间
void main(){
vec2 st = gl_FragCoord.xy/u_resolution.xy; // 将片元的坐标规范化到[0,1]的范围内
vec3 color = vec3(0.0); // 初始化颜色为黑色
vec2 pos = vec2(0.5)-st; // 计算当前坐标点到中心点(0.5, 0.5)的向量
float r = length(pos)*2.0; // 计算当前坐标点到中心点的距离,然后乘以2
float a = atan(pos.y,pos.x); // 计算当前坐标点相对于中心点的角度
float f = cos(a*3.); // 通过角度计算一个cos值,用于后面的颜色生成
// f = abs(cos(a*3.)); // 注释的代码,取cos值的绝对值
// f = abs(cos(a*2.5))*.5+.3; // 注释的代码,通过调整cos值的频率和振幅,改变形状
// f = abs(cos(a*12.)*sin(a*3.))*.8+.1; // 注释的代码,通过复合函数生成更复杂的形状
// f = smoothstep(-.5,1., cos(a*10.))*0.2+0.5; // 注释的代码,使用平滑函数改变形状的边缘
color = vec3( 1.-smoothstep(f,f+0.02,r) ); // 根据距离r和f值生成颜色,使用了平滑函数smoothstep
gl_FragColor = vec4(color, 1.0); // 将计算得到的颜色赋给片元
}
效果如下。
4. 使用sin cos组合可以生成雪花。
#ifdef GL_ES
precision mediump float; // 如果是在OpenGL ES环境下,设置中等精度的浮点数
#endif
uniform vec2 u_resolution; // uniform变量,用于传入画布分辨率
uniform vec2 u_mouse; // uniform变量,用于传入鼠标位置
uniform float u_time; // uniform变量,用于传入当前时间
void main(){
vec2 st = gl_FragCoord.xy/u_resolution.xy; // 将片元的坐标规范化到[0,1]的范围内
vec3 color = vec3(0.0); // 初始化颜色为黑色
vec2 pos = vec2(0.5)-st; // 计算当前坐标点到中心点(0.5, 0.5)的向量
float r = length(pos)*2.0; // 计算当前坐标点到中心点的距离,然后乘以2
float a = atan(pos.y,pos.x); // 计算当前坐标点相对于中心点的角度
float f = cos(a*3.); // 通过角度计算一个cos值,用于后面的颜色生成
// f = abs(cos(a*3.)); // 注释的代码,取cos值的绝对值
// f = abs(cos(a*2.5))*.5+.3; // 注释的代码,通过调整cos值的频率和振幅,改变形状
f = abs(cos(a*12.)*sin(a*3.))*.8+.1; // 注释的代码,通过复合函数生成更复杂的形状
//f = smoothstep(-.5,1., cos(a*10.))*0.2+0.5; // 注释的代码,使用平滑函数改变形状的边缘
color = vec3( 1.-smoothstep(f,f+0.02,r) ); // 根据距离r和f值生成颜色,使用了平滑函数smoothstep
gl_FragColor = vec4(color, 1.0); // 将计算得到的颜色赋给片元
}
效果如下。