Shader特效——“翻页”的实现 【GLSL】

2024-08-20 15:58
文章标签 实现 特效 shader 翻页 glsl

本文主要是介绍Shader特效——“翻页”的实现 【GLSL】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考自:http://webvfx.rectalogic.com/examples_2transition-shader-pagecurl_8html-example.html

效果图





[cpp] view plain  copy
  1. precision mediump float;  
  2.   
  3. varying vec2 texCoord;  
  4. uniform sampler2D sourceTex;  
  5. uniform sampler2D targetTex;  
  6. uniform float time; // Ranges from 0.0 to 1.0  
  7.   
  8. const float MIN_AMOUNT = -0.16;  
  9. const float MAX_AMOUNT = 1.3;  
  10. float amount = time * (MAX_AMOUNT - MIN_AMOUNT) + MIN_AMOUNT;  
  11.   
  12. const float PI = 3.141592653589793;  
  13.   
  14. const float scale = 512.0;  
  15. const float sharpness = 3.0;  
  16.   
  17. float cylinderCenter = amount;  
  18. // 360 degrees * amount  
  19. float cylinderAngle = 2.0 * PI * amount;  
  20.   
  21. const float cylinderRadius = 1.0 / PI / 2.0;  
  22.   
  23. vec3 hitPoint(float hitAngle, float yc, vec3 point, mat3 rrotation) {  
  24.     float hitPoint = hitAngle / (2.0 * PI);  
  25.     point.y = hitPoint;  
  26.     return rrotation * point;  
  27. }  
  28.   
  29.   
  30. vec4 antiAlias(vec4 color1, vec4 color2, float distance) {  
  31.     distance *= scale;  
  32.     if (distance < 0.0) return color2;  
  33.     if (distance > 2.0) return color1;  
  34.     float dd = pow(1.0 - distance / 2.0, sharpness);  
  35.     return ((color2 - color1) * dd) + color1;  
  36. }  
  37.   
  38. float distanceToEdge(vec3 point) {  
  39.     float dx = abs(point.x > 0.5 ? 1.0 - point.x : point.x);  
  40.     float dy = abs(point.y > 0.5 ? 1.0 - point.y : point.y);  
  41.     if (point.x < 0.0) dx = -point.x;  
  42.     if (point.x > 1.0) dx = point.x - 1.0;  
  43.     if (point.y < 0.0) dy = -point.y;  
  44.     if (point.y > 1.0) dy = point.y - 1.0;  
  45.     if ((point.x < 0.0 || point.x > 1.0) && (point.y < 0.0 || point.y > 1.0)) return sqrt(dx * dx + dy * dy);  
  46.     return min(dx, dy);  
  47. }  
  48.   
  49. vec4 seeThrough(float yc, vec2 p, mat3 rotation, mat3 rrotation) {  
  50.     float hitAngle = PI - (acos(yc / cylinderRadius) - cylinderAngle);  
  51.     vec3 point = hitPoint(hitAngle, yc, rotation * vec3(p, 1.0), rrotation);  
  52.   
  53.     if (yc <= 0.0 && (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0)) {  
  54.         return texture2D(targetTex, texCoord);  
  55.     }  
  56.   
  57.     if (yc > 0.0) return texture2D(sourceTex, p);  
  58.   
  59.     vec4 color = texture2D(sourceTex, point.xy);  
  60.     vec4 tcolor = vec4(0.0);  
  61.   
  62.     return antiAlias(color, tcolor, distanceToEdge(point));  
  63. }  
  64.   
  65. vec4 seeThroughWithShadow(float yc, vec2 p, vec3 point, mat3 rotation, mat3 rrotation) {  
  66.     float shadow = distanceToEdge(point) * 30.0;  
  67.     shadow = (1.0 - shadow) / 3.0;  
  68.     if (shadow < 0.0) shadow = 0.0;  
  69.     else shadow *= amount;  
  70.   
  71.     vec4 shadowColor = seeThrough(yc, p, rotation, rrotation);  
  72.     shadowColor.r -= shadow;  
  73.     shadowColor.g -= shadow;  
  74.     shadowColor.b -= shadow;  
  75.     return shadowColor;  
  76. }  
  77.   
  78. vec4 backside(float yc, vec3 point) {  
  79.     vec4 color = texture2D(sourceTex, point.xy);  
  80.     float gray = (color.r + color.b + color.g) / 15.0;  
  81.     gray += (8.0 / 10.0) * (pow(1.0 - abs(yc / cylinderRadius), 2.0 / 10.0) / 2.0 + (5.0 / 10.0));  
  82.     color.rgb = vec3(gray);  
  83.     return color;  
  84. }  
  85.   
  86. vec4 behindSurface(float yc, vec3 point, mat3 rrotation) {  
  87.     float shado = (1.0 - ((-cylinderRadius - yc) / amount * 7.0)) / 6.0;  
  88.     shado *= 1.0 - abs(point.x - 0.5);  
  89.   
  90.     yc = (-cylinderRadius - cylinderRadius - yc);  
  91.   
  92.     float hitAngle = (acos(yc / cylinderRadius) + cylinderAngle) - PI;  
  93.     point = hitPoint(hitAngle, yc, point, rrotation);  
  94.   
  95.     if (yc < 0.0 && point.x >= 0.0 && point.y >= 0.0 && point.x <= 1.0 && point.y <= 1.0 && (hitAngle < PI || amount > 0.5)){  
  96.         shado = 1.0 - (sqrt(pow(point.x - 0.5, 2.0) + pow(point.y - 0.5, 2.0)) / (71.0 / 100.0));  
  97.         shado *= pow(-yc / cylinderRadius, 3.0);  
  98.         shado *= 0.5;  
  99.     } else  
  100.         shado = 0.0;  
  101.   
  102.     return vec4(texture2D(targetTex, texCoord).rgb - shado, 1.0);  
  103. }  
  104.   
  105. void main(void) {  
  106.     const float angle = 30.0 * PI / 180.0;  
  107.     float c = cos(-angle);  
  108.     float s = sin(-angle);  
  109.   
  110.     mat3 rotation = mat3(  
  111.         c, s, 0,  
  112.         -s, c, 0,  
  113.         0.12, 0.258, 1  
  114.     );  
  115.   
  116.     c = cos(angle);  
  117.     s = sin(angle);  
  118.   
  119.     mat3 rrotation = mat3(  
  120.         c, s, 0,  
  121.         -s, c, 0,  
  122.         0.15, -0.5, 1  
  123.     );  
  124.   
  125.     vec3 point = rotation * vec3(texCoord, 1.0);  
  126.   
  127.     float yc = point.y - cylinderCenter;  
  128.   
  129.     if (yc < -cylinderRadius) {  
  130.         // Behind surface  
  131.         gl_FragColor = behindSurface(yc, point, rrotation);  
  132.         return;  
  133.     }  
  134.   
  135.     if (yc > cylinderRadius) {  
  136.         // Flat surface  
  137.         gl_FragColor = texture2D(sourceTex, texCoord);  
  138.         return;  
  139.     }  
  140.   
  141.     float hitAngle = (acos(yc / cylinderRadius) + cylinderAngle) - PI;  
  142.   
  143.     float hitAngleMod = mod(hitAngle, 2.0 * PI);  
  144.     if ((hitAngleMod > PI && amount < 0.5) || (hitAngleMod > PI/2.0 && amount < 0.0)) {  
  145.         gl_FragColor = seeThrough(yc, texCoord, rotation, rrotation);  
  146.         return;  
  147.     }  
  148.   
  149.     point = hitPoint(hitAngle, yc, point, rrotation);  
  150.   
  151.     if (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0) {  
  152.         gl_FragColor = seeThroughWithShadow(yc, texCoord, point, rotation, rrotation);  
  153.         return;  
  154.     }  
  155.   
  156.     vec4 color = backside(yc, point);  
  157.   
  158.     vec4 otherColor;  
  159.     if (yc < 0.0) {  
  160.         float shado = 1.0 - (sqrt(pow(point.x - 0.5, 2.0) + pow(point.y - 0.5, 2.0)) / 0.71);  
  161.         shado *= pow(-yc / cylinderRadius, 3.0);  
  162.         shado *= 0.5;  
  163.         otherColor = vec4(0.0, 0.0, 0.0, shado);  
  164.     } else {  
  165.         otherColor = texture2D(sourceTex, texCoord);  
  166.     }  
  167.   
  168.     color = antiAlias(color, otherColor, cylinderRadius - abs(yc));  
  169.   
  170.     vec4 cl = seeThroughWithShadow(yc, texCoord, point, rotation, rrotation);  
  171.     float dist = distanceToEdge(point);  
  172.   
  173.     gl_FragColor = antiAlias(color, cl, dist);  
  174. }  


翻页的“分块”结构:









版权声明:涉猎过的知识都像是不断汇入大海的涓涓细流,你怎么知道是哪条汇入的溪流让海洋成为海洋呢【转载请注明出处】 https://blog.csdn.net/panda1234lee/article/details/52282741

这篇关于Shader特效——“翻页”的实现 【GLSL】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1090521

相关文章

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

java父子线程之间实现共享传递数据

《java父子线程之间实现共享传递数据》本文介绍了Java中父子线程间共享传递数据的几种方法,包括ThreadLocal变量、并发集合和内存队列或消息队列,并提醒注意并发安全问题... 目录通过 ThreadLocal 变量共享数据通过并发集合共享数据通过内存队列或消息队列共享数据注意并发安全问题总结在 J