美文网首页
Shadertoy--旋涡效果分析

Shadertoy--旋涡效果分析

作者: 奔向火星005 | 来源:发表于2019-12-26 17:16 被阅读0次

前言

Shadertoy是一个神奇的网站,有无数图形学大神分享的用shader写的各种让人匪夷所思的效果,而代码仅仅只有数十行至数百行。虽然很多实现无法直接应用到我们开发的实时渲染上,但分析它们的实现可以让我们理解shader以及带来很多灵感。

本文分析一下Shadertoy上一个比较通用的涡旋效果,也是个人非常喜欢的一个效果(主要是像写轮眼的神威),当然分析过程纯属个人猜测,不代表原作者思路,原文地址如下:
https://www.shadertoy.com/view/Ml2GDR
原效果如下:

正文

原文的实现除了扭曲外还加了光照和混合等,为了简化分析,我去掉了一些代码,如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
    vec2 uv = fragCoord.xy/iResolution.xy-vec2(.5);
    uv.y *= iResolution.y/iResolution.x;
    
    float dist = length(uv);
    float angle = atan(uv.y,uv.x);
    
    uv = vec2(cos(angle+dist*3.),dist+(iTime*0.2));

   fragColor = texture(iChannel0,uv);
}

另外为了看清特效如何实现,我换了纹理,得到的效果如下:


xuanwo.gif

第一步:纹理采样。

代码如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
    vec2 uv = fragCoord.xy/iResolution.xy;
    fragColor = texture(iChannel0,uv);
}

效果如下:


第一步先把纹理采样到屏幕上,可以看到一张没有任何扭曲效果的原图。这里需要注意是屏幕空间和纹理空间的概念。如下图,


代码中的iResolution代表屏幕分辨率(640, 360),fragCoord.xy/iResolution.xy得到的uv的范围就是(0, 1),也就是它在纹理空间中的坐标。

其实扭曲的原理就是,改变顶点坐标或者纹理坐标。因为Shadertoy中只有像素着色器,我们只能通过改变纹理坐标达到扭曲的效果

第二步,求出当前像素点距离原点(0, 0)的距离,以及它与x轴的角度。

代码如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
    vec2 uv = fragCoord.xy/iResolution.xy;

    float dist = length(uv);    //到原点(0,0)的距离
    float angle = atan(uv.y, uv.x);   //与x轴角度

   fragColor = texture(iChannel0,uv);
}

第三步,改变纹理坐标

3.1 现在我们稍稍改变一下纹理坐标,看看画面会变成什么样子。

现在我们把采样坐标uv改成了uv = vec2(cos(angle),0.0)。画面瞬间变得面目全非。我们来仔细分析一下向量vec2(cos(angle), 0.0),我把uv的y置为0.0,什么意思呢?其实就是,在纹理空间中,限定了只在v==0.0的那条线上面进行采样
那么uv的x,也就是cos(angle)意味着上面呢。意味着,所有在屏幕空间中,angle相同的坐标,它们的颜色是一样的!这就是为什么我们看到渲染的画面是一道道不同角度的直线组成的。如下图:

3.2 接下来我们再改变一下代码,把uv = vec2(cos(angle),0.0)换成uv = vec2(cos(angle + dist),0.0)。

画面会变成下面这样:


把原来的angle变成angle+dist,意味着,在所有angle+dist相同的点,它们的颜色是一样的,我们知道所有angle相同的点连起来是一条直线,那么所有angle+dist相同的点连起来是个什么形状呢?从渲染出来的画面我们看到是一条曲线,那为啥会是以这样的角度弯曲的曲线呢,看下图:


假设屏幕空间上有两点(图中的橙点和红点),红点的距离为dist1,角度为angle1,橙点的距离为dist2,角度为angle2。假设他们的dist1 + angle1 = dist2 + angle2,如果dist1>dist2,那么angle1就必然小于angle2,也就是距离越大,那么它的角度必然要越小,所以这些点组成的曲线必然是往右下方弯曲的!

3.3 我们把cos(angle+dist)改回cos(angle),同时把uv = vec2(cos(angle),0.0)的0.0改为uv.y

渲染出来的画面是这样的:


前面我们说过,uv = vec2(cos(angle), 0.0)表示在屏幕空间中所有angle相同的点的颜色都是相同的,该颜色就是在纹理空间中u==cos(angle),v==0.0的那一点的颜色。由此推出,uv = vec2(cos(angle), uv.y)意味着,在屏幕空间中所有angle相同的点的颜色,是对映射纹理空间中u==cos(angle),v==uv.v的颜色,如下图:


通过这个修改,屏幕空间中angle相同的直线上所有点的颜色不再是一个单一的颜色,而是采样了纹理贴图中的某一条u==cos(angle)的直线上的颜色,因此渲染出来的画面已经可以看出原图的内容了,只不过是被拉伸了。

3.4 把uv = vec2(cos(angle), uv.y)改成uv = vec2(cos(angle), dist)

渲染出来的画面是这样的:


那么,对于屏幕空间中angle的直线,仍然是采样纹理贴图中u==cos(angle)的直线上的颜色,只不过采样的步长变了,如下:


我们可以看到uv = vec2(cos(angle), dist)时渲染的画面没有uv = vec2(cos(angle), uv.y)拉伸的那么厉害,还需要注意的是,当uv == vec2(cos(angle), dist)的dist大于1.0时,采样坐标就超出了纹理贴图的范围,由于纹理是wrap设置的是repeat的,因此会重复采样。


3.5 把前面的效果都组合起来,将uv设为uv = vec2(cos(angle + dist * 3.), dist)

(dist *3中的3.是调整弯曲的程度)。得到下面的渲染效果:


第四步, “转”起来

对uv坐标加入时间变化因素,例如设为uv = vec2(cos(angle+dist3.), dist+(iTime0.2));那么对于每一个屏幕空间中的像素点,它们采样的纹理贴图的坐标不再是固定不变的,采样坐标的uv.v会随着iTime不断增大,超出1.0后会以wrap==repeat规则继续循环采样。可以看到下面的动效:

xuanwo3.gif
第五步,调整纹理坐标
5.1 渲染椭圆

现在我们有的是一个椭圆形的四分之一,如果我们想要渲染出完整的椭圆形该如何做呢?首先我们把扭曲效果先屏蔽,然后调整一下uv坐标,得到如下效果:


我们只在代码第一句,将uv坐标减去vec2(0.5, 0.5),它的效果是对采样坐标平移了(-0.5, -0.5),那么在纹理空间中采样的位置就会改变,如下:


蓝色虚线可以认为是我们的屏幕,我们看到屏幕的右上角四分之一采样的是纹理的左下角的四分之一,而其他四分之三并没有在纹理贴图(0,0)~(1,1)的范围,但是他们会以wrap==repeat的规则采样。

我们再把扭曲的效果加回来(把uv = vec2(cos(angle+dist3.),dist+(iTime0.2));前面的注释去掉),就可以得到如下动效:

5.2 渲染圆

现在的效果已经非常接近我们开头的效果了,只是开头呈现的旋涡是圆形的,而我们现在的是椭圆形的,这是由于屏幕的宽高比不等于1造成的。如果想要得到圆形的旋涡效果,只需要把uv的宽高逼调整一下即可,加入uv.y *= iResolution.y/iResolution.x;这句,得到


相关文章

  • Shadertoy--旋涡效果分析

    前言 Shadertoy是一个神奇的网站,有无数图形学大神分享的用shader写的各种让人匪夷所思的效果,而代码仅...

  • Shadertoy--闪电效果分析

    前言 Shadertoy是一个神奇的网站,有无数图形学大神分享的用shader写的各种让人匪夷所思的效果,而代码仅...

  • Shadertoy--波纹效果分析

    前言 Shadertoy是一个神奇的网站,有无数图形学大神分享的用shader写的各种让人匪夷所思的效果,而代码仅...

  • 艺术旋涡

    艺术旋涡 近期迷恋于旋涡,尤其是愚公移山做旋涡效果,表现出愚公与子女热火朝天的移山状态,就像以前电影《旋涡里的歌》...

  • OpenGL-滤镜效果(二)

    接上篇OpenGL-滤镜效果(一),接着探讨一些滤镜的算法实现。 原图放一张我家宠物怡宝: 旋涡滤镜 图像旋涡主要...

  • 旋涡

    人们会习惯性地不断获取新事物,而并不将其付诸于实践,从而导致信息超载。 现在的我就是这样的状态,不断得学习新东西而...

  • 旋涡

    中性笔

  • 旋涡

    June 18, MOMA,现代艺术博物馆。 第一到纽约是三年前的2014,横穿整个美洲大陆从加州到这里,从干净的...

  • 旋涡

    你的笑 你的芳香 你的旋涡磁场 蛛网 粘住了蜻蜓的翅膀 缩萎的宇宙 可怜的欲望 风吹影散 一切都被还原 我与你互为镜像

  • 旋涡

    风气云涌,风平浪静下,有很多旋涡.身处在水中,你根本不知道旋涡在哪。今天听闻以前公司部分人,已被离职。这个事,谁也...

网友评论

      本文标题:Shadertoy--旋涡效果分析

      本文链接:https://www.haomeiwen.com/subject/pcyinctx.html