Site Defunct

注意!截止到 16/9/2019 ,这个博客已经被搬迁到了 这里 。以后我的东西都会发在那里。拜拜啦!

GLSL 的各种着色器效果

GLSL 很牛逼

首先,我要说的是,GLSL 很牛逼。我知道大家都知道,但是今天我就来给大家展示一哈我为了我那个作业做的着色器(们),其中有很大一部分都是从 ShaderToy 上参考的!

Vignette

Vignette 我不知道咋翻译,他的中文是小插图?这也太奇怪了吧…… 但是总而言之,我们是可以知道 Vignette 的作用是可以让远离中心的地方(屏幕边缘)变黑,然后整个看起来就有点像 70 年代的电影一样的东西:

这个着色器一般在静物,或者是复古的六七十年代的东西的时候渲染起来效果很好。他的原理很简单,就是远离中心的就变黑:

vec2 uv = 1.0 - uv.yx;
float vig = uv.x * uv.y * 15.0; // 15.0 是 intensity
vig = pow(vig, 0.2); gl_FragColor = vec4(pixel * vig, 1.0);

其中,intensity 的作用就是让结果曝光,如果太大会过度曝光,而太小又会太暗。在 intensity 的下一行的 0.2 可以说是扩大范围,如果这个数字越大,暗的范围就越大。最后,用输出的像素和 vignette 值相乘就可以了。

ScanLine

ScanLine 就是扫描线。在老机器里面,扫描线经常是清晰可见的。现在由于科技呀,他进步了,扫描线就没了。但是假如还是为了这个美感的话,我们很容易用现代的,数学的方法把以前的 缺陷 给渲染出来。

实现 ScanLine 的方法有很多种。我这里用我自个儿的,其实不大高效,因为用了 if 。

vec2 realUV = vec2(uv.x * resolution.x, uv.y * resolution.y); // gl_FragCoord
pixel.rgb -= (
mod(realUV.y, 2.0) <= 1.0 ?
0.1 :
0.0
); gl_FragColor = vec4(pixel, 1.0);

这个贼明显,就是看看 realUV (gl_FragCoord) 的 y 值对 2 取余。如果是 1.0 的话,就直接把对应的像素哪一行 变暗

假如你喜欢的话,可以把 time 加上去,这样扫描线就会一直往下(上)移动:

vec2 realUV = vec2(uv.x * resolution.x, uv.y * resolution.y); // gl_FragCoord
pixel.rgb -= (
mod(realUV.y + ceil(time * <移速>), 2.0大专栏  GLSL 的各种着色器效果 class="p">) <= 1.0 ?
0.1 :
0.0
); gl_FragColor = vec4(pixel, 1.0);

你想扫描线移多快,就自个儿调移速吧。我觉得 20.0 还不错的。

实现扫描线的方法还有很多种。我找到的有 这种这种 ,还有 这种是我参考的做法

Pixelate

Pixelate 是像素化的意思。我 ShaderToy 上没找到,自个儿想的。如果有的话可以告诉我一哈,三克油!

我的做法其实很简单。我把屏幕分成比分辨率更小的小块,然后判断要渲染的点在哪个小块里头,对应采样那个小块的左上角的那个像素。(也就是强行下降分辨率):

vec2 realUV = vec2(uv.x * resolution.x, uv.y * resolution.y); // gl_FragCoord
vec2 fakeUV = floor(realUV / 8.0) * 8.0;
vec2 uv = fakeUV / resolution.xy;
vec4 pixel = texture2D(texture, uv);

可以看到,我们就是把真实坐标除了 8.0 以后,舍掉了一切的小数点,然后把他恢复成了原来的坐标。帅不?

Frosted Glass

还记得 Windows7 Aero 的酷炫毛玻璃效果吗?现在咱们也能大概实现它的效果啦!看回来我们的头图:

看到了吗?下面的对话框那里就是毛玻璃的效果。

其实毛玻璃的效果不难,就是瞎取样。这个来自 这里 。我们来看看:

float rand(vec2 uv) {
float a = dot(uv, vec2(92.0, 80.0));
float b = dot(uv, vec2(41.0, 62.0));
float x = (sin(a) + cos(b)) * 51.0;
return fract(x);
} void main() {
// ... 拿到 uv
vec2 rnd = vec2(rand(uv), rand(uv));
uv += rnd * 0.05;
gl_FragColor = texture2D(texture, uv);
}

rand() 可以说是一个伪随机函数吧?输入 uv ,然后通过 uv 和两个奇怪的向量点乘,并且把他们的正弦值和余弦值相加,然后放大 51 倍(这个可以改),最后舍弃掉整数部分,返回小数点后就可以了。回到 main 可以发现,结果被进一步减小了 - 为了不过分采样(就是离得太远)。这样就能让采样稍稍偏离原来的位置了!

当然,除此之外,其实你可以发现,假如不乘那个 51 ,然后点乘的那两个向量比较小的话 —— 就可以呈现出晶体的效果了:

帅不帅?快点儿去自己试试吧!

没了

上头就是我用的所有的着色器了。其实要模仿旧的 CRT 显示屏的话,这里还有:

玩得开心!

GLSL 的各种着色器效果的更多相关文章

  1. 编写Unity3D着色器的三种方式

    不管你会不会写Unity3D的shader,估计你会知道,Unity3D编写shader有三种方式,这篇东西主要就是说一下这三种东西有什么区别,和大概是怎样用的. 先来列一下这三种方式: fixed ...

  2. 【Unity Shaders】Lighting Models —— 衣服着色器

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  3. 翻译:探索GLSL-用几何着色器(着色器库)实现法线可视化

    翻译:探索GLSL-用几何着色器(着色器库)实现法线可视化 翻译自: Exploring GLSL – Normal Visualizer with Geometry Shaders (Shader ...

  4. 在pixi中使用你的自定义着色器

    通过几天的学习,对openGL.shader有了一个大致的了解. 回到学习的初衷吧,在基于pixi.js重构D3项目的时候,因为精灵层级的问题,我得按照一定的先后顺序将不同类别的精灵添加到场景中去. ...

  5. three中的着色器示例

    其实在3D引擎/库的帮助下,我们做webgl开发的难度已经很大大地降低了,熟悉相关API的话,开发一个简单的3D程序可以说是很轻松的事情. 在我看来,webgl的核心就是着色器(顶点着色器.片元着色器 ...

  6. WebGL 着色器语言(GLSL ES)

    1.类型转换内置函数 转换/函数/描述 转换为整形数/int(float)/将浮点数的小数部分删去,转换为整形数(比如,将3.14转换为3) 转换为整形数/intl(bool)/true被转换为1,f ...

  7. [GLSL]着色器周记02——火焰特效 【转】

    http://www.cnblogs.com/tkgamegroup/p/4214081.html 这周学了好多.包括伪随机数.柏林噪声.先说伪随机数.伪随机数我们用的是周期函数而不是那种由前一项乘一 ...

  8. OpenGLES2.0着色器语言glsl

    OpenGLES2.0中是强制使用可编程的渲染管线的,使用的是glsl着色器语言,因为着色器语言是使用的GPU,即图形处理单元,而不是CPU,这样可以使CPU从繁重的几何计算和像素的处理中解脱出来了. ...

  9. OpenGL入门1.3:着色器 GLSL

    前言 经过之前一段时间的学习(渲染管线简介)我们已经知道了着色器(Shader)是运行在GPU上的程序,这些小程序为图形渲染管线的某个特定部分而运行,着色器只是一种把输入转化为输出的程序,着色器也是一 ...

随机推荐

  1. LeetCode No.160,161,162

    No.160 GetIntersectionNode 相交链表 题目 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 输入:intersectVal ...

  2. JVM内存结构图表展示

    1.理解的JVM内存结构  2.对于垃圾回收问题 垃圾的回收只在堆和永久区(方法区)中,因为对于线程而言,私有存储空间如栈.本地方法区.程序计数器等,会随着方法的加载完成而直接释放空间,因此不需要进行 ...

  3. Linux(CENTOS7) Mysql不能远程连接解决办法

    今天,在腾讯云的服务器上面装了一个Mysql,装完发现我在linux下面可以连接,但是在我的window下面是用mysql可视化工具(SQLyog)连接不了,错误如下: Host ‘’ is not ...

  4. [Algo] 649. String Replace (basic)

    Given an original string input, and two strings S and T, replace all occurrences of S in input with ...

  5. jQuery篇

    jQuery 1.为什么使用jQuery? js中window onload事件只能出现一次,如果出现多次,后面的事件会覆盖掉前面的事件 js代码容错差 简单的动画效果实现很繁琐,例如简单的动画渐变效 ...

  6. ubuntu linux下解决“no java virtual machine was found after searching the following locations:”的方法

    现象:删除旧的jdk,安装新的jdk之后,打开eclipse报错: A Java Runtime Environment (JRE) or Java Development Kit (JDK)must ...

  7. 吴裕雄--天生自然python机器学习:使用决策树预测隐形眼镜类型

    解决策树如何预测患者需要佩戴的隐形眼镜类型.使用小数据 集,我们就可以利用决策树学到很多知识:眼科医生是如何判断患者需要佩戴的镜片类型:一旦 理解了决策树的工作原理,我们甚至也可以帮助人们判断需要佩戴 ...

  8. CF-595

    题目传送门 A .Yet Another Dividing into Teams sol:原先是用比较复杂的方法来解的,后来学弟看了一眼,发现不是1就是2,当出现两个人水平相差为1就分成两组,1组全是 ...

  9. shiro遇到的坑-重写sessionManager遇到的坑

    最近公司开发一个微信小程序项目加shiro的项目.因为微信小程序是不使用cookie,使用的是 storage .那么我们就不能使用传统的方式来保持登录状态了. 1.首先和网上的一样,先重写一个Ses ...

  10. Struts2加载自定义库注意事项

    新建Struts2项目,添加Struts2的jar包时,往往通过导入自定义库的方式,导入自定义库时,有个地方必须要设置,否则项目无法正常执行,如图所示: 必须要按照上述方式对自定义库进行加载!