怎么用OpenGL编写心形图案,如图!!!

版权声明:本文为博主原创文章,遵循 版权协议,转载请附上原文出处链接和本声明。

有时候我们需要绘画一些复杂的路径,就需要用到贝塞尔曲线

同时,我们希望展示绘画过程,就需要用到PathMeasure

下面就是一个简单的例子。

//这个方法的意思是取路径片段,0是指从头截取,mLength是指截取的长度

简单明了,就不多做解释咯。

---仅作备份,方便以后查阅--

身份认证 购VIP最低享 7 折!

计算机图形学 OPENGL 中点画椭圆法 计算机图形学 OPENGL 中点画椭圆法 计算机图形学 OPENGL 中点画椭圆法

该原创文章首发于微信公众号:字节流动

浏览博客时,偶然间发现这个"跳动的心"特效,瞬间被感动了,当得知这个特效是用纯代码实现( GLSL 实现)的,确实又被惊到了。

追溯该特效最初的来源,最终在 SahderToy 网站看到它的原始实现,另外在 SahderToy 上还发现了无数类似惊人的特效,并且这些特效的实现代码完全公开。

ShaderToy 是一个跨浏览器的在线社区,并且是用于通过 WebGL 创建和共享着色器的工具,用于在 Web 浏览器中学习和教授 3D 计算机图形学。

在 SahderToy 网站上浏览了一番,感觉仿佛发现了新大陆,该网站支持在线编写并运行 GLSL 脚本,堪称 GL 界的 Github 。

我们把网站上"跳动的心"特效的脚本转换为 OpenGLES 对应的 GLSL 脚本在手机上运行,并对整个脚本进行一一解析,完整的代码如下:

关于内建变量 gl_FragCoord ,从中我们知道:与屏幕空间坐标相关的视区是由视口设置函数 glViewport 函数给定,并且可以通过片段着色器中内置的 gl_FragCoord 变量访问,gl_FragCoord 的 x 和 y 表示该片段的屏幕空间坐标 ((0,0) 在左下角),其取值范围由 glViewport 函数决定,屏幕空间坐标原点位于左下角。

下面一段代码主要作用是调整坐标系,将原点从左下角移至屏幕坐标系中央,这样所有片元的向量 gl_FragCoord.xy 均以屏幕中心为起点,则向量 p 就是屏幕中心与屏幕像素点坐标之间的方向向量。

接下来计算背景颜色,length(p) 表示计算当前片元(像素)与屏幕中心点的距离,背景颜色以 vec3(1.0,0.8,0.8) 该颜色为基础,距离屏幕越远颜色越暗。

这时,我们把背景颜色渲染出来看看:

接着绘制心形,主要利用反正切函数值和当前片元(像素)与屏幕中心点的距离相比较,来确定心形状的边界。GLES 中的反正切函数 atan(p.x,p.y) 取值范围是[-π, π],然后除以 PI 后,取值范围变成了 [-1, 1] 。

我们通过上图来理解心形的绘制过程,每条直线上像素点得到的 a 值都是相同的,我们用黄点表示距离屏幕中心的远近,然后通过 d-r 的值来确定心形的边界。

以上是绘制心形的关键函数,hcol 是心的颜色,bcol 是背景色。

smoothstep 是一个很常用的平滑过渡函数,当第三个参数比 -0.06 小时,返回 0,比0.06 大时返回 1 ,如果在 -0.06 和 0.06 之间,则返回 0 到 1 之间的值,其作用是用于平缓 d-r 的值在正负交界处的突变。

mix函数用于加权混合心的颜色和背景色,根据 smoothstep 函数特性,在心形内用心的颜色,在心形外用背景色,而边界则是两种颜色之间的模糊过渡。

再说说心形扁平化函数的作用,当我们不使用扁平化函数,而是直接用 h-r 来控制心的形状,得到的图像是一个又胖又肥的心形,这样你大概可以得知这个函数的作用。

然后看看心的颜色生成,由表达式 vec3(1.0,0.5*r,0.3) 可以看出心的颜色是红色,且由屏幕中心向四周红色逐渐减弱,然后产生一系列渐变,最后分出心形内外的区域颜色。

我们直接输出心的颜色 hcol ,看看是什么效果:

最后是跳动效果的实现,其原理就是对屏幕像素在 x、y 方向进行周期性偏移,偏移幅度由特殊的函数来控制。

我们通过下面的代码控制输入时间周期为 2000ms 。

振幅控制函数的模拟曲线如下图所示,大致可以看出心跳动时幅度变化情况。

最后还有一点需要注意的是 GLSL 脚本中精度的声明,文中代码我们使用的是 highp 精度,但是当使用 mediump 精度时,会出现由于精度不够导致的毛刺现象,如下图所示:

我要回帖

更多关于 c语言输出心形图案表白 的文章

 

随机推荐