OpenGL Shader实现阴影遮罩效果

作者:JulyYu 时间:2022-04-23 19:38:02 

smoothstep另一种用法

在之前OpenGL Shader-抗锯齿实现文章中所介绍的那样:为了抗锯齿效果可以用smoothstep函数对绘制形状进行平滑过渡来实现。其中也提到了当smoothstep函数中入参ab范围过大时就会出现渐变效果。如OpenGL Shader-抗锯齿实现中所展示的效果:

OpenGL Shader实现阴影遮罩效果

遮罩效果实现

看到这个效果后似乎可以利用smoothstep函数中ab入参取大范围来实现不一样的特效能力。例如可以使用该特点来实现类似于老电影中遮罩效果,在视图边缘出现一层朦胧遮罩中间最亮四周有一层淡淡的阴影效果。

OpenGL Shader实现阴影遮罩效果

实现原理其实就是利用smoothstep函数入参使用大范围值,在绘制圆基础上改造处理。底色使用白色vec3(1.),阴影遮盖使用黑色vec3(1.)就能达到阴影遮罩效果了。

void main() {
   vec2 uv = gl_FragCoord.xy / iResolution.xy;

vec4 texture = texture(iChannel2,uv);
   uv -= 0.5;
   uv.x *= iResolution.x/iResolution.y;
   float m = 0.4;
   m = smoothstep(m-0.2,m+0.2,length(uv) - 0.2);
   vec3 pixel = mix(vec3(1.),vec3(0.),m);
   gl_FragColor = vec4(pixel,1.0);

}

OpenGL Shader实现阴影遮罩效果

除了采用smoothstep函数实现外,下面还有一种方法也能实现阴影遮罩效果。如下glsl所示 对颜色向量vec4 texturevignette相乘,相当于改变色值通道亮度达到明暗对比;同时对于取值uv.y-0.5可以理解越接近中心取值越接近为0,那么计算得出的vignette就越大约接近为1。

void main() {
   vec2 uv = gl_FragCoord.xy / iResolution.xy;
   vec4 texture = vec4(1.);
   float vigAmt = 4.0;
   float vignette = (1.0-vigAmt*(uv.y-0.5)*(uv.y-0.5))*(1.0-vigAmt*(uv.x-0.5)*(uv.x-0.5));
   texture *= vignette;
   gl_FragColor = texture;
}

OpenGL Shader实现阴影遮罩效果

通过对照也能发现采用圆形公式实现遮罩是有一定圆弧趋势,而另一种遮罩是偏向矩形,在特效效果上略有差异。以此类推肯定还可以根据这种方式来实现星型,爱心等形状遮罩。

smoothstep

OpenGL Shader实现阴影遮罩效果

OpenGL Shader实现阴影遮罩效果

vignette

OpenGL Shader实现阴影遮罩效果

OpenGL Shader实现阴影遮罩效果

效果扩展

最后可以增加一个time时间入参,通过vigAmt值不断变化vignette强弱来实现忽明忽暗的效果,会有一种在看老电影的感受。

#define time iTime
void main() {
   vec2 uv = gl_FragCoord.xy / iResolution.xy;
   vec4 texture = texture(iChannel2,uv);
   float vigAmt = 4.0 + 0.3 * sin(time + 5.0 * cos(time*5.0));
   float vignette = (1.0-vigAmt*(uv.y-0.5)*(uv.y-0.5))*(1.0-vigAmt*(uv.x-0.5)*(uv.x-0.5));
   texture *= vignette;
   gl_FragColor = texture;
}

OpenGL Shader实现阴影遮罩效果

来源:https://juejin.cn/post/7060143723211915301

标签:OpenGL,Shader,阴影遮罩
0
投稿

猜你喜欢

  • Java中的阻塞队列详细介绍

    2023-12-14 15:00:49
  • SpringBoot返回Json对象报错(返回对象为空{})

    2022-06-30 03:31:19
  • 关于SpringMVC在Controller层方法的参数解析详解

    2022-10-29 01:06:10
  • Spring学习笔记1之IOC详解尽量使用注解以及java代码

    2021-10-07 16:17:02
  • 解析C#中@符号的几种使用方法详解

    2022-11-09 03:26:03
  • C#实现在购物车系统中生成不重复订单号的方法

    2022-06-21 04:03:09
  • c#委托把方法当成参数(实例讲解)

    2021-07-29 04:38:14
  • Android中检查、设置默认程序详解

    2021-08-25 14:14:21
  • Java实现微信公众号发送模版消息

    2021-07-16 17:03:35
  • java实现鲜花销售系统

    2023-08-29 20:23:42
  • Spring Boot thymeleaf模板引擎的使用详解

    2022-07-27 07:42:54
  • C语言形参和实参的区别详解

    2023-08-27 19:41:53
  • C#如何自定义multipart/form-data的解析器

    2023-12-04 18:59:03
  • 解决idea每次新建项目都需要重新指定maven目录

    2022-12-25 17:39:52
  • Android实现微信登录的示例代码

    2022-04-04 15:55:56
  • 使用chatgpt实现微信聊天小程序的代码示例

    2022-04-26 17:18:24
  • Android Handler runWithScissors 梳理流程解析

    2023-01-29 11:51:27
  • Android Dialog对话框实例代码讲解

    2021-12-18 06:34:50
  • Java动态规划方式解决不同的二叉搜索树

    2023-03-02 01:56:52
  • Java的RxJava库操作符的用法及实例讲解

    2021-12-14 22:31:41
  • asp之家 软件编程 m.aspxhome.com