Unity中Shader指令优化

文章目录

  • 前言
  • 一、解析一下不同运算所需的指令数
    • 1、常数基本运算
    • 2、变量基本运算
    • 3、条件语句、循环 和 函数


前言

上一篇文章中,我们解析了Shader解析后的代码。我们在这篇文章中来看怎么实现Shader指令优化

  • Unity中Shader指令优化(编译后指令解析)

一、解析一下不同运算所需的指令数

1、常数基本运算

在DirectX平台,常数运算是不占指令数的。但是,稳妥起见我们最好自己计算好常数计算的结果。防止其他平台认为常数运算需要占指令。

  • Shader片元着色器中:

fixed4 frag (v2f i) : SV_Target
{
//常数基本计算
return 2 * 3;
}

  • 编译后只有一个赋值给输出结果的指令:

ps_4_0
dcl_output o0.xyzw
0: mov o0.xyzw, l(6.000000,6.000000,6.000000,6.000000)
1: ret

定义临时存储变量,也是不消耗指令数的,对性能没有影响

  • Shader片元着色器中:

fixed4 frag (v2f i) : SV_Target
{
//常数基本计算
fixed4 c = 0.2 * 3 / sin(4);
fixed4 c1 = c;
return c1;
}

  • 编译后同样只有一个赋值给输出结果的指令:

ps_4_0
dcl_output o0.xyzw
0: mov o0.xyzw, l(-0.792809,-0.792809,-0.792809,-0.792809)
1: ret

2、变量基本运算

变量的基本运算,是会使用GPU计算指令的。因为变量在计算前是未知的,会预留计算指令

  • Shader中:
  1. 属性面板定义一个四维向量

_Value(“Value”,Vector) = (0,0,0,0)

  1. 片元着色器中,使用该变量进行 加法 计算

fixed4 frag (v2f i) : SV_Target
{
//2、变量基本运算
float a = _Value.x;
float b = _Value.y;
float c = _Value.z;
float d = _Value.w;
float e = 1 + a;
return e;
}

  • 编译后(使用了加指令):

ps_4_0
dcl_constantbuffer CB0[3], immediateIndexed
dcl_output o0.xyzw
0: add o0.xyzw, cb0[2].xxxx, l(1.000000, 1.000000, 1.000000, 1.000000)
1: ret

  1. 变量进行减法运算

e = 1 - a;

  • 编译后(使用了加指令):

ps_4_0
dcl_constantbuffer CB0[3], immediateIndexed
dcl_output o0.xyzw
0: add o0.xyzw, -cb0[2].xxxx, l(1.000000, 1.000000, 1.000000, 1.000000)
1: ret

  1. 变量进行乘法运算(这里测试乘法,别使用 1 或 2,会自动转化为加法)

e = 3 * a

  • 编译后(使用了乘指令):

ps_4_0
dcl_constantbuffer CB0[3], immediateIndexed
dcl_output o0.xyzw
0: mul o0.xyzw, cb0[2].xxxx, l(3.000000, 3.000000, 3.000000, 3.000000)
1: ret

  1. 变量进行除法运算

e = 3 / a

  • 编译后(使用了除法指令):

ps_4_0
dcl_constantbuffer CB0[3], immediateIndexed
dcl_output o0.xyzw
0: div o0.xyzw, l(3.000000, 3.000000, 3.000000, 3.000000), cb0[2].xxxx
1: ret

  1. 变量进行多个相同运算

e = 3 * a * b;

  • 编译后:

ps_4_0
dcl_constantbuffer CB0[3], immediateIndexed
dcl_output o0.xyzw
dcl_temps 1
0: mul r0.x, cb0[2].x, cb0[2].y
1: mul o0.xyzw, r0.xxxx, l(3.000000, 3.000000, 3.000000, 3.000000)
2: ret

  1. 变量进行乘加运算,对性能优化特别重要(特殊)

e = 3 * a + b;

  • 编译后,会使用乘加指令(把乘法和加法合并成一个指令)

ps_4_0
dcl_constantbuffer CB0[3], immediateIndexed
dcl_output o0.xyzw
0: mad o0.xyzw, cb0[2].xxxx, l(3.000000, 3.000000, 3.000000, 3.000000), cb0[2].yyyy
1: ret

3、条件语句、循环 和 函数

  1. 条件语句

if(i.uv.x < 0.5)
{
i.uv.x = 1;
}
else
{
i.uv.x = 0;
}
return i.uv.x;

在这里插入图片描述

  • 编译后:

在这里插入图片描述

  1. 循环语句

float e = 0;
for(int i = 0;i < 5;i++)
{
e += 0.1;
}
return e;

  • 编译后:

在这里插入图片描述

  1. mad指令优化:

优化前:

float e = (a + b) * (a - b);
return e;

  • 编译后:

在这里插入图片描述
优化后:

float e = a * a * (-b * b);
return e;

  • 编译后:

在这里插入图片描述

  1. 透过编译后的代码来直观的看出函数的内部执行(这里使用 normalize 来测试)

一维向量(常数):

float e = normalize(a);
return e;

  • 编译后:

在这里插入图片描述
多维向量归一化(编译后会使用点乘)

float e = normalize(_Value);
return e;

  • 编译后:

在这里插入图片描述

  1. abs(如果abs传入的是单一参数,就不会多用指令。但是传入式子,会多用指令)

传入式子:

float e = abs(a * b);
return e;

  • 编译后:

在这里插入图片描述
传入单一参数:

float e = abs(a) * abs(b);
return e;

  • 编译后:

在这里插入图片描述

  1. 负号可以适当的移到变量中

移动前:

float e = -dot(a,a);
return e;

  • 编译后:

在这里插入图片描述

移动后:

float e = dot(-a,a);
return e;

  • 编译后:

在这里插入图片描述

  1. 尽量把同一维度的向量进行结合运算

结合前:

float3 e = _Value.xyz * a * b * _Value.yzw * c * d;
return fixed4(e,1);

  • 编译后:

在这里插入图片描述

结合后:

float3 e = (_Value.xyz * _Value.yzw) * (a * b * c * d);
return fixed4(e,1);

  • 编译后:

在这里插入图片描述

  1. asin / atan / acos开销很大,尽量不要使用 (这里使用asin测试)

float e = asin(a);
return e;

  • 编译后
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/207678.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qml ParticleSystem3D使用介绍

作者:令狐掌门 技术交流QQ群:675120140 csdn博客:https://mingshiqiang.blog.csdn.net/ 在 Qt Quick 3D 中,ParticleSystem3D 是用来创建和控制3D粒子系统的元素。粒子系统是图形编程中用于模拟液体、烟雾、火、星空等现象的技术,它通过生成大量小粒子来模拟这些效果。Par…

MySQL表的操作『增删改查』

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; MySQL 学习 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 &#x1f381;软件版本&#xff1a; MySQL 5.7.44 文章目录 1.创建表1.1.创建时指定属性 2.查看表2.1.查看表结构2.2.查看建表信息…

GLM: 自回归空白填充的多任务预训练语言模型

当前&#xff0c;ChatGLM-6B 在自然语言处理领域日益流行。其卓越的技术特点和强大的语言建模能力使其成为对话语言模型中的佼佼者。让我们深入了解 ChatGLM-6B 的技术特点&#xff0c;探索它在对话模型中的创新之处。 GLM: 自回归空白填充的多任务预训练语言模型 ChatGLM-6B 技…

万界星空科技生产管理mes系统种的工艺确认流程

MES工艺流程是制造执行系统的核心部分&#xff0c;它涵盖了整个生产过程&#xff0c;包括物料管理、生产计划、生产执行、质量管理、维修保养等方面&#xff0c;可以有效地提高生产效率和产品质量。 一、确认追溯模型&#xff1a; 以工艺文件为确认对象&#xff0c;以产品生产…

解决ansible批量加入新IP涉及known_hosts报错的问题

我们把一批新的IP加入到ansible的hosts文件&#xff0c;比如/etc/ansible/hosts&#xff0c;往往会有这样的提示&#xff0c; 因为本机的~/.ssh/known_hosts文件中并有fingerprint key串&#xff0c;使用ssh连接目标主机时&#xff0c;一般会提示是否将key字符串加入到~/.ssh/…

文字识别(OCR)专题——基于NCNN轻量级PaddleOCRv4模型C++推理

前言 PaddleOCR 提供了基于深度学习的文本检测、识别和方向检测等功能。其主要推荐的 PP-OCR 算法在国内外的企业开发者中得到广泛应用。在短短的几年时间里&#xff0c;PP-OCR 的累计 Star 数已经超过了32.2k&#xff0c;常常出现在 GitHub Trending 和 Paperswithcode 的日榜…

2.qml 3D-View3D类学习

本章我们来学习View3D类。 View3D是用来渲染3D场景并显示在2D平面的类&#xff0c;并且该类可以放在QML2D下继承于Item子类的任何场景中&#xff0c;比如将View3D放在Rectangle中: Rectangle {width: 200 height: 200color: "red"View3D { anchors.fill: parent…

瞻芯电子荣获“汽车芯片50强”奖,展现技术水平

023年11月28日&#xff0c;瞻芯电子在北京举办的“芯向亦庄”汽车芯片大赛中脱颖而出&#xff0c;凭借其车规级碳化硅(SiC)MOSFET产品的卓越性能和创新特点&#xff0c;荣获“汽车芯片50强”奖项&#xff0c;展现了瞻芯电子在汽车芯片领域的技术水平和发展潜力。 芯向亦庄2023汽…

Inkscape 图片生成Gcode

1.到网上找一张简单的图片&#xff0c;拖入软件中 2.文档属性单位改成毫米 3.路径--->提取位图轮廓-->使用边缘检测 4.删除原图片 5.路径-->笔廓转化成路径 6.转变完了效果如下 7.文件另存为--> gcode 就大功告成啦

0Ω电阻最大过流能力及作用用途

0Ω电阻最大过流能力及作用用途 0Ω电阻过流能力0Ω电阻的作用 0Ω电阻过流能力 0Ω电阻不一定是真正的0Ω电阻&#xff0c;0Ω电阻存在一定的阻值偏差&#xff0c;主要看生产电阻厂商做哪种了。厂商都是根据电阻标准文件 EN60115-2&#xff0c; 里头0Ω电阻实际最大阻值有 10…

【Redis缓存】RedisTemplate如何获取符合要求的key,批量获取key

RedisTemplate如何获取符合要求的key,批量获取key 一、方法/命令二、数据使用 一、方法/命令 如果使用命令的形式&#xff0c;输入以下命令即可 keys *如果使用RedisTemplate&#xff0c;则方法为 redisTemplate.keys()获取所有符合条件的key。 二、数据使用 redis中缓存了…

【Linux系统化学习】揭秘 命令行参数 | 环境变量

个人主页点击直达&#xff1a;小白不是程序媛 Linux专栏&#xff1a;Linux系统化学习 代码仓库&#xff1a;Gitee 目录 命令行参数 环境变量 PATH 查看PATH $PWD 查看环境变量PWD $HOME 查看系统支持的环境变量 获取环境变量 命令行参数 在C/C编程语言中我们有一个…

高并发下缓存失效问题-缓存穿透、缓存击穿、缓存雪崩、Redis分布式锁简单实现、Redisson实现分布式锁

文章目录 缓存基本使用范式暴露的几个问题缓存失效问题---缓存穿透缓存失效问题---缓存击穿一、单机锁正确的锁粒度不正确的锁粒度无法保证查询数据库次数是唯一 二、分布式锁getCatalogJsonData()分布式锁演进---基本原理分布式锁(加锁)演进一&#xff1a;删锁失败导致死锁分布…

负电源电压转换-TP7660H

负电源电压转换-TP7660H 简介引脚说明典型应用电路倍压与反压的应用电路 简介 TP7660H 是一款 DC/DC 电荷泵电压反转器专用集成电路。芯片能将输入范围为 2.5V&#xff5e;11V 的电压转换成相应的-2.5V&#xff5e;-11V 的输出&#xff0c;电压转换精度可达99.9%&#xff0c;电…

Docker的常用基本命令(基础命令)

文章目录 1. Docker简介2. Docker环境安装Linux安装 3. 配置镜像加速4. Docker镜像常用命令列出镜像列表搜索镜像下载镜像查看镜像版本删除镜像构建镜像推送镜像 5. Docker容器常用命令新建并启动容器列出容器停止容器启动容器进入容器删除容器&#xff08;慎用&#xff09;查看…

概率论与数理统计中常见的随机变量分布律、数学期望、方差及其介绍

1 离散型随机变量 1.1 0-1分布 设随机变量X的所有可能取值为0与1两个值&#xff0c;其分布律为 若分布律如上所示&#xff0c;则称X服从以P为参数的(0-1)分布或两点分布。记作X~ B(1&#xff0c;p) 0-1分布的分布律利用表格法表示为: X01P1-PP 0-1分布的数学期望E(X) 0 *…

面向对象编程的艺术:构建高效可扩展的软件

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

zabbix6.4.0配置邮件及企微机器人群聊告警

一、邮件告警 根据公司邮箱自行配置&#xff0c;电子邮件、用户账号密码填自己的邮箱账号密码 动作本次使用的默认的&#xff0c;如果为了更加美观可自行修改。 二、企业微信机器人告警 首先在企微上创建群聊&#xff0c;之后添加群聊机器人 将地址复制&#xff0c;后面用 …

使用NVM管理多个版本的node.js

1、nvm介绍&#xff1a; nvm全英文也叫node.js version management&#xff0c;是一个nodejs的版本管理工具。nvm是node.js版本管理工具&#xff0c;为了解决node.js各种版本存在不兼容现象可以通过它可以安装和切换不同版本的node.js 2、下载nvm地址&#xff1a; https://d…

测试用例设计方法六脉神剑——第一剑:入门试招,等价边界初探 | 京东物流技术团队

1 背景及问题 G.J.Myers在<软件测试技巧>中提出&#xff1a;测试是为了寻找错误而运行程序的过程&#xff0c;一个好的测试用例是指很可能找到迄今为止尚未发现的错误的测试&#xff0c; 一个成功的测试是揭示了迄今为止尚未发现的错误的测试。 对于新手来说&#xff0…