700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > unity shader 入门精要(冯乐乐著) 读书笔记(三)

unity shader 入门精要(冯乐乐著) 读书笔记(三)

时间:2020-05-06 05:08:11

相关推荐

unity shader 入门精要(冯乐乐著) 读书笔记(三)

unity的shader初体验

第一个实例代码

Shader "Unlit/Chapter5/SimpleShader"{Properties{//_MainTex ("Texture", 2D) = "white" {}//声明一个color类型的属性_Color("Color Tint",Color) = (1.0, 1.0, 1.0, 1.0)}SubShader{ Pass{CGPROGRAM#pragma vertex vert//vert即为函数名#pragma fragment frag//frag也为函数名//告诉unity哪个函数中包含了定点着色器的代码,哪个函数包含片元着色器代码// make fog work//在Cg代码中,我们需要定义一个与属性名称和类型都匹配的变量fixed4 _Color;//使用一个结构体来定义顶点着色器的输入struct a2v {//POSITION语义告诉unity用模型空间的定点坐标填充vertex变量float4 vertex : POSITION;//NORMAL语义告诉unity用模型空间的法线方向填充normal变量float3 normal : NORMAL;//TEXCOORD0语义告诉unity,用模型的第一套纹理坐标填充texcoord变量float4 texcoord : TEXCOORD0;};//使用一个结构体来定义顶点着色器的输出struct v2f {//SV_POSITION语义告诉unity,pos里包含了顶点裁剪空间中的位置信息float4 pos : SV_POSITION;//COLOR0语义可以用于存储颜色信息fixed3 color : COLOR0;};//unity支持的语义有:POSITION TANGENT NORMAL TEXCOORD0~3 COLOR等v2f vert(a2v v) {//声明输出结构v2f o;o.pos = UnityObjectToClipPos(v.vertex);//v.normal包含了顶点的法线方向,其分量范围在[-1.0, 1.0]//下面的代码吧分量范围映射到了[0.0 , 1.0]//存储到o.color中传递给片元着色器o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);return o;}fixed4 frag(v2f i) : SV_Target{//将插值后的i.color显示到屏幕上fixed3 c = i.color;//使用_Color属性来控制输出颜色c *= _Color.rgb;return fixed4(c, 1.0);}ENDCG}}}

在书的p106中有ShaderLab属性类型Cg变量类型的匹配关系

在书的p108中包含了CGInclude中主要的包含文件以及主要用处、UnityCG.cginc中的一些常用的结构体、一些常用的帮助函数

Unity提供的Cg/HLSL语义

输入结构体:a2v

输出结构体:v2f

对于一些语义在 a2v 和 v2f 中出现时的作用并不一样,例如:

TEXCOORD0在输入结构体中的作用为:把模型的第一组纹理坐标存储在该变量中

而在输出结构体中的作用为:修饰的变量含义可以由我们来决定

系统数值语义

这类语义一般以SV开头(system-value),在上述代码中我们使用了SV_POSITION语义去修饰顶点着色器的输出变量pos,这些语义描述的变量是不可以随便赋值的,渲染引擎会把用SV_POSITION修饰的变量经过光栅化后显示在屏幕上

注:为了让shader更具有跨平台性,最好对有特殊意义的变量我们最好使用以SV开头的语义进行修饰

p110页具有Unity在渲染阶段支持的常用语义

(appdata_full最多使用了6个坐标纹理组基本上包含了所有的模型数据

如何调试?

假彩色图像

用假彩色生成一种图像

因为颜色分量范围在[0,1]之间,我们要小心处理需要调试的变量的范围,可以将需要测试的变量范围*映射到[0,1]*之间,把它们作为颜色输出到屏幕上

例子:

Shader "Unity Shaders Book/Chapter 5/False Color"{Properties{//_MainTex ("Texture", 2D) = "white" {}}SubShader{//Tags { "RenderType"="Opaque" }//LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#include "UnityCG.cginc"struct v2f{//float2 uv : TEXCOORD0;//UNITY_FOG_COORDS(1)//float4 vertex : SV_POSITION;float4 pos : SV_POSITION;fixed4 color : COLOR0;};v2f vert (appdata_full v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);//可视化法线方向o.color = fixed4(v.normal * 0.5 + fixed3(0.5, 0.5, 0.5),1.0);//可视化切线方向o.color = fixed4(v.tangent.xyz * 0.5 + fixed3(0.5, 0.5, 0.5),1.0);//可视化副切线方向fixed3 binormal = cross(v.normal, v.tangent.xyz) * v.tangent.w;o.color = fixed4(binormal * 0.5 + fixed3(0.5, 0.5, 0.5), 1.0);//可视化第一组纹理坐标o.color = fixed4(v.texcoord.xy, 0.0, 1.0);//可视化第二组纹理坐标o.color = fixed4(v.texcoord1.xy, 0.0, 1.0);//可视化第一组纹理坐标的小数部分o.color = frac(v.texcoord);if (any(saturate(v.texcoord) - v.texcoord)){o.color.b = 0.5;}o.color.a = 1.0;//可视化第二组纹理坐标的小数部分o.color = frac(v.texcoord1);if (any(saturate(v.texcoord1) - v.texcoord1)) {o.color.b = 0.5;}o.color.a = 1.0;//可视化顶点颜色//o.color = v.color;return o;}fixed4 frag (v2f i) : SV_Target{return i.color;}ENDCG}}}

帧调试器

通过window->analyze->Frame Debugger即可启用帧调试器

可以用于查看渲染该帧时进行的各种渲染事件,

最上方的滑动条:重放渲染事件左侧区域显示所有事件的树状图,可以从每个事件了解渲染的整个过程右侧窗口体现事件的细节

内在功能其实是停止渲染查看各个渲染事件的结果,即运行到哪一步,就在哪一步停下来,供我们查看。

渲染平台差异

坐标差异

引起的一大原因是OpenGL与DirectX的屏幕空间出现不同,竖直方向的相反。

不过在平常情况下unity会为我们处理这种不同,只有在当我们打开了抗锯齿且进行了渲染到纹理的操作后,此时得到的图像不会被unity翻转,因此在采样这一环节就应该符合DirectX平台的规定。

UNITY_UV_STARTS_AT_TOP用于判断当前平台类型是否为DirectX类型

_MainTex_TexelSize.y是否小于0用来检验是否开了抗锯齿

语法差异

DirectX对Shader的语义会更加严格

语义差异

不同平台上有一些语义是不等价的

例如:SV_POSITION 和POSITION在一些平台上并不是等价的

书写Shader时保证简洁的一些建议

精度问题

float、half、fixed的精度在不同平台上的表现是不一样的,尽可能采用低精度,确保性能

在移动平台上要尽可能注意到精度的问题,因为移动平台的优化技术是非常重要的

语法规范

注意初始化问题(对DirectX平台的适配问题

避免不必要的计算

要小心需要的临时寄存器数目或指令数目超过当前可支持的数目,不同的Shader Target、不同的着色器阶段可使用的临时寄存器和指令数目是不同的,可以通过指定更高级别的ShaderTarget来消除这些错误。

p118有各个Shader Target支持的指令数目

慎用分支和循环语句

它们会降低GPU的并行处理操作!!!

如果必须要用那么:

分支判断语句中使用的条件变量最好是常数,即在Shader运行过程中不会发生变化;每个分支中包含的操作指令数尽可能少;分支点嵌套层数尽可能少。

不要除以0

这会导致一些不可预测的后果,平台不同时就会导致微妙的变化

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。