这些屏幕特效是咋实现的
这些屏幕特效是咋实现的
随着图形卡以及图像 API 的升级换代,越来越多的特效使用可编程渲染实现,也是就是所谓的着色器。不同实时渲染接口的着色器语法不尽相同,在英伟达的统一下,CG 语言成为行业标准(下列片元着色器代码片段中均使用 CG 语法),着色器代码在实时渲染的地位越来越高,许多经典的屏幕特效也源于着色器
那些常用特效实现方法
1. 数字图像处理来实现简单特效
负片效果
这个效果是我接触数字图像处理的第一个例子,那时候很流行冈萨雷斯的那本书,基本方法就是把图像的 rgb 通道反色,在口碑不好的拳皇 2001 中几乎所有 MAX 超必杀都有背景负片效果
color.rgb = 1 - col.rgb;
拳皇 2001 拉尔夫超级机炮拳
模糊与锐化效果
模糊效果是美术最常用的的效果,在游戏开发中,根据像素深度来重建场景深度,远景使用模糊效果,近景清晰来模拟人眼专注效果;也可以模拟失去或恢复意识的相机效果。在使命召唤 8 现代战争 3 游戏中,有类似的模糊效果
// 高斯模糊 /*1 2 12 4 21 2 1 */ fixed3 col = tex2D(_MainTex,i.uv + _MainTex_TexelSize.xy*r*fixed2(-1,-1)).rgb * 1; col += tex2D(_MainTex,i.uv + _MainTex_TexelSize.xy*r*fixed2(0,-1)).rgb * 2; col += tex2D(_MainTex,i.uv + _MainTex_TexelSize.xy*r*fixed2(1,-1)).rgb * 1; col += tex2D(_MainTex,i.uv + _MainTex_TexelSize.xy*r*fixed2(-1,0)).rgb * 2; col += tex2D(_MainTex,i.uv + _MainTex_TexelSize.xy*r*fixed2(0,0)).rgb * 4; col += tex2D(_MainTex,i.uv + _MainTex_TexelSize.xy*r*fixed2(1,0)).rgb * 2; col += tex2D(_MainTex,i.uv + _MainTex_TexelSize.xy*r*fixed2(-1,1)).rgb * 1; col += tex2D(_MainTex,i.uv + _MainTex_TexelSize.xy*r*fixed2(0,1)).rgb * 2; col += tex2D(_MainTex,i.uv + _MainTex_TexelSize.xy*r*fixed2(1,1)).rgb * 1; col = col / 16;
使命召唤 8 现代战争 3 单人剧情开始
Bloom 效果
Bloom 效果是一种高亮度侵入,来实现昏暗光照切换到明亮光照的人眼不适应的效果。具体实现是先判断亮度较高的区域生产像素贴图,然后对该贴图经行高斯模糊,将亮度扩散到四周,最后和原图混合。下图为《杀手6》的光线效果,非常震撼杀手 6 迈阿密赛车关卡
其他形态学检测
边缘检测在图像处理中比较重要,但是在游戏开发中,边缘检测一般不在屏幕特效中完成,往往在单个模型的着色器中完成描边效果,所以这里不介绍
2. 噪声算法辅助完成复杂特效
柏林噪声的发明者 Ken Perlin 因此算法获得奥斯卡科技成果奖,该噪声符合自然规律,可以模拟很多自然现象,比如云雾、消融、火焰等效果。基本思想是在两两随机数之间进行平滑差值,让随机数生成具有过渡性,而不是断落变化
平滑插值
插值是图形学的基础运算 lerp(a,b,c) = a * c + (1 - c)*b
说到平滑插值,最有必要聊聊贝塞尔曲线,做过动画的小伙伴就知道,动画进度如果与时间成正比,动画会很单调,我们常常看到的 UI 弹窗动画都会“俏皮”回弹一下,这样的动画玩家更会买账,根据贝塞尔曲线模拟出响应的动画速度,比如先慢后快,比如回弹,比如越来越快等等
先慢后快的贝塞尔曲线 | 回弹的贝塞尔曲线 |
float rand(float2 p)
{return frac(sin(dot(p ,float2(12.9898,78.23673))) * 43758.5453);
}// 二维柏林噪声
float noise(float2 x)
{float2 i = floor(x);float2 f = frac(x);float a = rand(i);float b = rand(i + float2(1.0, 0.0));float c = rand(i + float2(0.0, 1.0));float d = rand(i + float2(1.0, 1.0));float2 u = f * f * f * (f * (f * 6 - 15) + 10);float x1 = lerp(a,b,u.x);float x2 = lerp(c,d,u.x);return lerp(x1,x2,u.y);
}
// 多噪声叠加,代码可以优化成不用循环的
float fbm(float2 x)
{float scale = 0.2;float res = 0;float w = 5;for(int i=0;i<4;++i){res += noise(x * w);w *= 1.5;}return res*scale;
}
3. 修改 uv 的小技巧
顶点着色器传递给片元着色器的纹理坐标 uv, 是片元着色器的最基础参数,我们适当加以扰动可以做出很多绚丽的效果。比如水波纹效果,用的是正/余函数的扰动来模拟水波效果
sampler2D _MainTex;
float _Amount;
float _W;
float _Speed;fixed4 frag (v2f i) : SV_Target
{float2 center_uv = {0.8,0.08};float2 uv = i.uv;float2 dt = center_uv - uv;float len = sqrt(dot(dt, dt));float amount = min(_Amount,_Amount / (0.0001 + len*len*_Speed));if(amount < 0.005) // 使用 step 优化{amount = 0;}uv.y += amount * cos(len * _W *UNITY_PI + UNITY_PI/2);fixed4 col = tex2D(_MainTex, uv);return col;
}
这些屏幕特效是咋实现的相关推荐
- 《Unity着色器和屏幕特效》——2.2 进阶的透明效果
本节书摘来自华章计算机<Unity着色器和屏幕特效>一书中的第2章,第2.2节,作者[美]杰米·迪恩(Jamie Dean),译 周翀,张薇,更多章节内容可以访问云栖社区"华章计 ...
- 《Unity着色器和屏幕特效开发秘笈》—— 3.4 创建BlinnPhong高光类型
本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈>一 书中的第3章,第3.4节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区"华章计算机&quo ...
- 《Unity着色器和屏幕特效开发秘笈》—— 2.1 引言
本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈>一 书中的第2章,第2.1节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区"华章计算机&quo ...
- 《Unity着色器和屏幕特效开发秘笈(原书第2版)》一2.9 打包和混合纹理
本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈(原书第2版)>一书中的第2章,第2.9节,作者 [英]艾伦朱科尼(Alan Zucconi) [美]肯尼斯拉默斯(Kenneth ...
- 《Unity着色器和屏幕特效开发秘笈》—— 1.7 创建渐变纹理来控制漫反射着色...
本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈>一 书中的第1章,第1.7节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区"华章计算机&quo ...
- Unity3d 屏幕特效实现类似死亡之后的全屏黑白效果
全屏特效 黑白(对于<着色器和屏幕特效开发秘籍>的学习) 可实现死亡效果或需要黑白特效的效果 原理是通过OnRenderImage()函数在摄像机渲染的时候,改变颜色(饱和度) 新建一个c ...
- 《Unity着色器和屏幕特效开发秘笈》—— 第3章 利用镜面反射让游戏闪耀起来...
本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈>一 书中的第3章,第3.1节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区"华章计算机&quo ...
- 【《Unity着色器和屏幕特效开发秘笈》】学习整理:关于屏幕特效【2】
一个简单的屏幕效果 在屏幕特效通用脚本的基础上,制作一个简单的灰度效果. 首先是使用的挂在摄像机上面的脚本: [ExecuteInEditMode] public class MyTestRender ...
- Unity 屏幕特效 之 简单地调整颜色的 色散效果 的实现
Unity 屏幕特效 之 简单地调整颜色的 色散效果 的实现 目录 Unity 屏幕特效 之 简单地调整颜色的 色散效果 的实现 一.简介
- Shader攻占笔记(八)屏幕特效
屏幕特效 前言 脚本基类 景深效果 脚本部分 着色器部分 碎屏效果 动态模糊 前言 [关于作业的狡辩] 本周内容与前几周相比,难度提高了一些,本章的shader需要配合相应的脚本使用.脚本基本上承担两 ...
最新文章
- 使用 sched_setaffinity 将线程绑到CPU核上运行
- R语言Hosmer-Lemeshow检验得到校准曲线的P值实战
- 分享一个 org.w3c.dom XML 封装
- spring.net nhibernate 分布布式事务(下)
- 用python实现自动填数生成表格v1.0
- 【2019暑假刷题笔记-图的存储和图的遍历】绪论(代码模板-总结自《算法笔记》)
- 【lucene系列学习二】Lucene实现高亮显示关键词
- 在CentOS7上安装配置Corosync高可用集群过程全记录
- java计算器如何实现运算_用java编写了一个模拟计算器的界面设计,怎么实现运算功能呢...
- 引脚悬空是什么电平_STM32单片机必须掌握的八种IO口模式和引脚配置方式
- HP/Aruba 2620系列交换机DHCP中继配置方法
- 基于Unity构建机器人的数字孪生平台系列2—四旋翼无人机三维模型
- 微商伙伴微信手机号过滤技巧
- 终端测试是硬件测试还是软件测试,移动终端软件测试基础知识
- 招商银行笔试题 公司年会
- android模拟触控power键
- inv在C语言是什么函数,机械原理中的inv 函数是什么意思?
- 【近3万字分享】《Android开发之路——10年老开发精心整理分享》
- 个人项目-网络电话呼叫客户端 (一)
- 【推荐】1657- 灵活可扩展,2023年值得尝试的13款富文本编辑器
热门文章
- CTF 小白教程《从0到1:CTFer成长之路》SQL - 2 解题过程
- 浙江计算机软件考试官网,浙江:全国计算机软件考试开始报名 11月8日开考
- EnhancedFor
- 计算机网络基础知识之应用层篇
- 小学计算机座位安排表,戳痛父母们的班级座位表,安排孩子怎么坐也是一门学问...
- 数据分析(入门篇)-第三章-Show出你的数据-Part2(水晶易表)
- git使用——15.搭建自己的gitlab服务器来存放我们的git项目
- c语言字符串的加减乘除,c语言加减乘除代码
- eNSP实验记录(一):路由器与交换机
- SQL Server 备份还原教程