Unity Shader Lab - HLSL

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Shader Lab - HLSL相关的知识,希望对你有一定的参考价值。

参考技术A 从应用阶段传递模型数据给顶点着色器时 常用的语义

命令                               实例                         说明

POSITION                                                     模型空间中的顶点位置,一般是float4类型

NORMAL                                                       顶点法线,float3类型

TANGENT                                                     顶点切线 float4

TEXCOORD0~N                                           该顶点纹理坐标,0是第一组,一般是flkoat2 或float4类型

COLOR                                                         顶点颜色,通常是fixed4或float4类型

命令                                      说明

UNITY_MATRIX_MVP         当前的模型观察投影矩阵,用于将顶点/方向矢量从模型空间变换到裁剪空间

UNITY_MATRIX_MV            当前的模型观察矩阵,用于将顶点/方向矢量从模型空间变换到观察空间

UNITY_MATRIX_V               当前的观察矩阵,用于将顶点/方向矢量从世界空间变换到观察空间

UNITY_MATRIX_P               当前的投影矩阵,用于将顶点/方向矢量从观察空间变换到裁剪空间

UNITY_MATRIX_VP             当前的观察投影矩阵,用于将顶点/方向矢量从世界空间变换到裁剪空间

UNITY_MATRIX_T_MV        UNITY_MATRIX_MV 的转置矩阵

UNITY_MATRIX_IT_MV       UNITY_MATRIX_MV的逆转置矩阵,用于将法线从模型空间变换到观察空间,也可以用于得到UNITY_MATRIX_MV的逆矩阵

_Object2World                      当前的模型矩阵,用于将顶点/方向矢量从模型空间变换到世界空间

_World2Object                      _Object2World的逆转矩阵,用于将顶点/方向矢量从世界空间变换到模型空间

命令                                                                    说明

float4 UnityObjectToClipPos(float3 pos)            将一个点从object空间转换成相机在均匀坐标下的剪辑空间。这就相当于 mul(UNITY_MATRIX_MVP, float4(pos, 1.0)), 应该在它的位置上使用。

float3 UnityObjectToViewPos(float3 pos)           将一个点从object空间转换为view空间。这就相当于mul(UNITY_MATRIX_MV, float4(pos, 1.0)).xyz, 应该在它的位置上使用。

命令                                                       说明

float3 _WorldSpaceCameraPos           该摄像机在世界空间中的位置

float4 _ProjectionParams                     x=1.0 或-1.0(使用反转的投影矩阵渲染时是负数),y=Near,z=Far,w= 1.0+1.0/Far, 其中near和far分别是近裁剪平面和远裁剪平面与摄像机的距离

float4 _ScreenParams                          x=width,y=height,z=1.0+1.0/width,w=1.0+1.0/height, 其中width和height分别是该摄像机的渲染目标 (render target)的像素宽度和高度

float4 _ZBufferParams                         x=1-Far/near,yFar/Near, 最x/Far,wy/Far,该变量用于线性化Z缓存中的深度值

floart4 unity_OrhoParams                    x=width,y=height,z无意义,w=1.0(该相机是正交相机)或w=0.0(透视相机),其中width和height是正交投影相机的宽和高

float4x4 unity_CameraProjection        该摄像机的投影矩阵

floart4x4 unity_CameraInvProjection  该摄像机的投影矩阵的逆矩阵

float4 unity_CameraWorldClipPlanes 该摄像机的6个裁剪屏幕在世界空间下的等式,按左右上下近远的顺序裁剪平面

UnityCG.cginc 该文件中包含了很多即成的参数方法。使用十分方便

引入文件

CGPROGRAM

#include "UnityCG.cginc"

ENDCG

命令 参数 实例 说明

appdata_base        顶点位置、顶点法线、第一组纹理坐标      float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord: TEXCOORD0; 可用于顶点着色器的输入

appdata_tan           顶点位置、顶点切线、顶点法线、第一组纹理坐标         float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; 可用于顶点着色器的输入

appdata_full          顶点位置、顶点切线、顶点法线、四组(或更多)纹理坐标      float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; float4 texcoord1 : TEXCOORD1; float4 texcoord2 : TEXCOORD2; float4 texcoord3 : TEXCOORD3; #if defined(SHADER_API_XBOX360) half4 texcoord4 : TEXCOORD4; half4 texcoord5 : TEXCOORD5; #endif fixed4 color : COLOR; 可用于顶点着色器的输入

appdata_img          可用于顶点着色器的输入          float4 vertex : POSITION; half2 texcoord : TEXCOORD0; 可用于顶点着色器的输入

v2f_img                   裁剪空间中的位置、纹理坐标 可用于顶点着色器的输出

命令                                                                说明

float4 WorldSpaceViewDir(float4 v)               输入一个模型空间中的顶点位置,返回世界空间中从该点到摄像机的观察方向

float4 UnityWorldSpaceViewDir(float4 v)       输入一个世界空间中的顶点位置,返回世界空间中从该点到摄像机的观察方向

float4 ObjSpaceViewDir(float4 v)                   输入一个模型空间中的顶点位置,返回模型空间中从该店到摄像机的观察方向

float4 WorldSpace LightDir(flaot4 v)              仅用于向前渲染。 输入一个模型空间中的顶点位置,返回世界空间中从该点到光源的光照方向。没有被归一化

float4 ObjectSpaceLightDir(float4 v)              仅用于向前渲染中,输入一个模型空间中的顶点位置, 返回模型空间中从该点到光源的光照方向。没有被归一化

float4 UnityWorldSpaceLightDir(float4 v)        仅用于向前渲染中,输入一个世界空间中的顶点位置, 返回世界空间中从该点到光源的光照方向。没有被归一化

float3 UnityObjectToWorldNormal(float3 norm)           把法线方向从模型空间中转换到世界空间中

float3 UnityObjectToWorldDir(float3 dir)           把方向矢量从模型空间中变换到世界空间中

float3 Unity WorldToObjectDir(float3 dir)          把方向矢量从世界空间变换到模型空间中

函数                                       说明 

radians(degree)                    角度变弧度(一般默认都用弧度)

degrees(radian)                    弧度变角度

sin(angle)                             三角函数

cos(angle)                            三角函数

tan(angle)                             三角函数

asin(x)                                  arc sine, 返回弧度 [-PI/2, PI/2];

acos(x)                                 arc cosine,返回弧度 [0, PI]

atan(y, x)                              arc tangent, 返回弧度 [-PI, PI];

atan(y/x)                               arc tangent, 返回弧度 [-PI/2, PI/2];

pow(x, y)                               x的y次方

exp(x)                                   指数, log(x)

exp2(x)                                 2的x次方, log2(x)

sqrt(x)                                  x的根号;

inversesqrt(x)                      x根号的倒数

abs(x)                                  绝对值

sign(x)                                 取当前数值的正负符号,返回 1, 0 或 -1 (x>0;x=0;x<0)

floor(x)                                 底部取整

ceil(x)                                  顶部取整

fract(x)                                 取小数部分

mod(x, y)                            取模, x - y*floor(x/y)

min(x, y)                             取最小值

max(x, y)                            取最大值

clamp(x, min, max)            min(max(x, min), max);

mix(x, y, a)                         x, y的线性混叠, x(1-a) + y*a;

step(edge, x)                    如 x smoothstep(edge0, edge1, x): threshod smooth transition时使用。 x<=edge0时为0.0, x>=edge1时为1.0

length(x)                           向量长度

distance(p0, p1)               两点距离, length(p0-p1);

dot(x, y)                            点积,各分量分别相乘 后 相加

cross(x, y)                        差积 x[1]*y[2]-y[1]*x[2], x[2]*y[0] - y[2]*x[0], x[0]*y[1] - y[0]*x[1]

normalize(x)                     归一化 length(x)=1;

faceforward(N, I, Nref)     如 dot(Nref, I)< 0则N, 否则 -N

reflect(I, N)                      I的反射方向 I -2*dot(N, I)*N, N必须先归一化

refract(I, N, eta)               折射 k=1.0-etaeta(1.0 - dot(N, I) * dot(N, I)); 如k<0.0 则0.0,否则 etaI - (etadot(N, I)+sqrt(k))*N

matrixCompMult(matX, matY)               矩阵相乘, 每个分量 自行相乘 r[j] = x[j]*y[j];

lessThan(vecX, vecY)               向量 每个分量比较 x < y

lessThanEqual(vecX, vecY)     向量 每个分量比较 x<=y

greaterThan(vecX, vecY)         向量 每个分量比较 x>y

greaterThanEqual(vecX, vecY) 向量 每个分量比较 x>=y

equal(vecX, vecY)                   向量 每个分量比较 x==y

notEqual(vecX, vexY)              向量 每个分量比较 x!=y

any(bvecX)                              只要有一个分量是true, 则true

all(bvecX)                                所有分量是true, 则true

not(bvecX)                               所有分量取反

ShaderlabVS                  https://marketplace.visualstudio.com/items?itemName=ShaderlabVS2019.ShaderlabVS

ShaderlabVSCode         https://marketplace.visualstudio.com/items?itemName=amlovey.shaderlabvscodefree#overview

HLSL Tools for Visual Studio      https://marketplace.visualstudio.com/items?itemName=TimGJones.HLSLToolsforVisualStudio

Shader语法_Unity3d的HLSL之的一些错误提示

学了12年英文,可能你还是不会说,唯一的方法就是去一个全英语的环境,那么你一个月的英语水平提高的速度将绝对比你学12年还快,什么时候去最好?怎么才能准备好,答案是,根本不用准备,而且越快越好!

Partice make Perfect

哪怕写错了,也要继续尝试写

不积跬步,无以致千里

最近归纳了一下,Shader有几个重点:

Unity做了“”一些“”改版,并不是原生Shader

Shader是一门程序语言

Shader并没有专门的编辑器和Debugger,

Shader是用来控制GPU渲染的

针对以上几点,重点说说:

第一点:Shader被改的乱七八炸,这有点废话,虚幻不改,大牛不改?你平时写程序不改?就是很多人以为世界上只有一种英语。。。。

Unity用的人不少,学习的,培训的,实战的都一大堆,所以会很乱

第二点:这是一门编*程*语*言哦,这就好办了,shader我不懂,gpu压根没见过,但是编程我擅长哦。。。。

第三点:所有难懂的然后程序员又自认为好用的语言,就是都类似BAT,BASH等脚本,还要什么自行车

碰到的一些错误:

1.错误1

Shader error in 'Unlit/ImageEffect': Did not find shader kernel 'vert' to compile (on d3d11

A:可能原因

1.顶点和片元的函数名不统一

2.定义的时候写了分号

正确写法

CGPROGRAM
            #pragma  vertex vert
            #pragma  fragment frag//片元入口函数
            #include "UnityCG.cginc"//引用unity里面的CG库

2.错误2

Output variable vert_img contains a system-interpreted value (SV_POSITION) which must be written in every execution path of the shader.  Unconditional initialization may help.
Compiling Vertex program
Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_COLORSPACE_GAMMA UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_FULL_HDR

Output variable vert_img contains a system-interpreted value (SV_POSITION) which must be written in every execution path of the shader

这句英文的意思是 vert_img这个变量有问题,你可以按变量关键字搜索这个,

应该,就是我下面回复的,我的错在这行:struct app_data xxx:sv_position; 

解决方法,同下面错误5

而which must be written  in every execution path of shader 里的execution path(shader 执行路径)就是vert() 和frag() 这2个方法

3.错误3

undeclared identifier 'unity_WorldToLight'

这个小哥,解释不错

            #include "AutoLight.cginc"

但还必须

#ifdef POINT

或者

#ifdef SPOT

4.问题4

cannot map expression to vs_4_0 instruction set

 tex2D(_MainTex, f.uv) 采样函数

采样函数只能在frag函数里使用,没人跟萌新讲过有这回事啊,萌新全都写在vert函数中了,找了好久好久的bug都不知道问题出在哪里.
顺带一提,报错是这个cannot map expression to vs_4_0 instruction set

5.错误5‘vert’: output parameter ‘o’ not completely initialized:

需要添加UNITY_INITIALIZE_OUTPUT(Input, name)来进行初始化。

   void vert(inout appdata_full v, out Input o)
            
                //对输出进行初始化
                UNITY_INITIALIZE_OUTPUT(Input, o);
                //采集顶点色
                o.vertColor = v.color;
            

6.implicit tuncation of vetor type

就只是一个提示,虽然没有报错,原因可能有很多种,但核心就是错误的类型赋值,例如:vector3 == vector4就会出这个warning

//写这个代码的人,虽然只需要用到第一个R通道,但变量就是变量,该是什么类型就是什么类型
//half scatter = SAMPLE_TEXTURE2D(_Scattering, sampler_Scattering, input.uv);	
//改为half4
half4 scatter = SAMPLE_TEXTURE2D(_Scattering, sampler_Scattering, input.uv);	

 

新手如何编程

其实从上面的问题就不难看出,程序,编程的入门其实无他,

无非,就是细心细心再细心(哥完全没有),

很多,问题就是无非有无分号的问题,“;”很重要,如果不是分号问题,那么就是大小写问题

(经验所得,一般要超过2年的程序生涯才有可能避免和及时发现这个问题,编程的过程中充满各种变量定义,方法命名);

其实看一个人能不能区分大小写就知道他的码龄了,和树的年轮一样,贼准!

另外,就是所见即所得,就是你改一行代码,必须马上就能看到结果,对于一些应用类的开发尤其如此,而且新学一个语言确实这样,且不说“”不积跬步无以致远“”,就是一个小问题不处理好,后面大问题,莫名其妙的问题就会让你处理不过来。很多人以为程序员就是一天坐10天一直敲代码,我们还真偷笑,不是敲一行代码,摸鱼一小时吗?但背后逻辑就是所见即所得,大牛可以摸鱼,新手还是得好好锻炼

如何排查问题,大牛就是看一眼就知道什么问题了,是经验问题么?好像也不全是,但好像大部分情况是,如果遇到了经验意外的问题,天才也花半天处理,所以真正的大牛要能“预见问题,避开问题”

解决问题什么的是不可能解决的了

创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖

以上是关于Unity Shader Lab - HLSL的主要内容,如果未能解决你的问题,请参考以下文章

unity怎么编辑shader

unity shader怎么混合两张贴图

unity shader有啥好处

unity shader有啥用

unity用脚本怎么让shader重绘

unity shader 能加密吗