unity shader api解析

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的逆转置矩阵,用于将法线从模型空间转换到观察空间

_Object2World将顶点方向矢量从模型空间变换到世界空间,矩阵。

_World2Object将顶点方向矢量从世界空间变换到模型空间,矩阵。

模型空间到世界空间的矩阵简称M矩阵,世界空间到View空间的矩阵简称V矩阵,View到Project空间的矩阵简称P矩阵。

_WorldSpaceCameraPos该摄像机在世界空间中的坐标

_ProjectionParams

_ScreenParams

_ZBufferParams

unity_OrthoParams

unity_Cameraprojection

unity_CameraInvProjection

unity_CameraWorldClipPlanes[6]摄像机在世界坐标下的6个裁剪面,分别是左右上下近远、

-------------------------------------------------------

表面着色器:

void surf (Input IN, inout SurfaceOutput o) {}表面着色器,unity特殊封装的着色器

Input IN:可以引用外部定义输入参数

inout SurfaceOutput o:输出参数

struct SurfaceOutput//普通光照

{

half3 Albedo;//纹理,反射率,是漫反射的颜色值

half3 Normal;//法线坐标

half3 Emission;//自发光颜色

half Specular;//高光,镜面反射系数

half Gloss;//光泽度

half Alpha;//alpha通道

}

-------------------------------------------------------

基于物理的光照模型:

金属工作流SurfaceOutputStandard 高光工作流SurfaceOutputStandardSpecular

half3,half4代表rgba或者xyz,可以分开用 Albedo.xy=1.或Albedo.ga=1

#pragma surface surfname lightModel op - 指出函数surfname 表面着色器。

lightModel的光照模型和可选op操作,还可以添加顶点修改函数vertex和颜色修改函数finalcolor。

#pragma surface surf CustomLambert vertex:myvert finalcolor:mycolor addshadow exclude_path:deferred exclude_path:prepass nometa

#pragma vertex name - 指出函数name 是顶点着色器。

#pragma fragment name - 指出函数name 是片段着色器。

#pragma fragmentoption option - 添加option 到编辑的OpenGL片段程序。参看ARB fragment program说明书了解被允许的选项列表。这个指示在顶点程序或者编辑到非OpenGL targets的程序没有影响。

#pragma multi_compile_builtin - 为了pixel-lit shaders;;这个将告知Unity去编辑大量的这个着色器程序数列以支持所有的照明种类,和所有的阴影选项。

#pragma multi_compile_builtin_noshadows - 对于pixel-lit 着色器,不接受阴影。这将告知Unity去编辑几个该着色器程序的数列来支持所有的照明种类。这比multi_compile_builtin pragma可以更快的编辑,而且结果着色器也更小。

#pragma target name - 那个着色器target 去编辑。细节参看shader targets。

#pragma only_renderers space separated names - 只为给定的渲染器编辑着色器。默认情况下,着色器为所有的渲染器被编辑。细节参看 renderers。

#pragma exclude_renderers space separated names - 不为给定的渲染器编辑着色器。默认情况下,着色器为所有的渲染器被编辑。细节参看 renderers。

-------------------------------------------------------

顶点着色器:

struct appdata_full {//vertex输入

float4 vertex : POSITION;//must

float4 tangent : TANGENT;

float3 normal : NORMAL;

float4 texcoord : TEXCOORD0;//该顶点的纹理坐标,第一组纹理坐标uv 也就是第一张贴图的坐标、为了实现多重纹理贴图,比如子弹打在墙上的弹痕等

float4 texcoord1 : TEXCOORD1;//n的数量和shadermodel版本有关

float4 texcoord2 : TEXCOORD2;

float4 texcoord3 : TEXCOORD3;

fixed4 color : COLOR;//顶点颜色

};

-------------------------------------------------------

片段着色器:

struct v2f{//vertec的输出和frag的输入

float4 vertex :SV_POSITION;//must

float3 color0:COLOR0;

float3 color1:COLOR1;

float4:texcoord:TEXCOORD0;//TEXCOORD0-TEXCOORD7自定义纹理坐标

}

SV_Tatget //frag的输出,输出float4的颜色

-------------------------------------------------------

光照:

1.逐顶点光照:在顶点着色器阶段计算光照,效率高但是效果不好,在边缘像素映射的时候插值可能会产生锯齿。

2.逐像素光照:在片元着色器阶段计算光照,计算量大,但是边缘表现效果好。

3.半兰伯特模型:处理无光照的地方,也让其有光,不然可能是全黑。经验模型。

#include "Lighting.cginc"

Tags { "LightMode"="ForwardBase" }

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

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

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

WorldSpaceLightDir()仅用于前向渲染,输入模型空间中的顶点坐标,返回世界空间中从该点到光源光照方向,没有归一化。

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

ObjSpaceLightDir()仅用于前向渲染,输入模型空间中的顶点坐标,返回模型空间中从该点到光源光照方向,没有归一化。

UnityObjectToWorldNormal(float3 v)把法线从模型空间转换到世界空间

UnityObjectToWorldDir(float3 v)把方向矢量从模型空间转换到世界空间

UnityWorldToObjectDir(float3 v)把方向矢量从世界空间转换到模型空间

_WorldSpaceLightPos0.xyz获取平行光光源方向,或者点光源的光源位置

_LightColor0.rgb获取当前pass的光源颜色和强度

UNITY_LIGHTMODEL_AMBIENT.xyz; 环境光

normalize(_WorldSpaceCameraPos.xyz - worldPos.xyz); 视觉方向 UnityWorldSpaceViewDir

-------------------------------------------------------

透明度测试AlphaTest:

只要有一个片元的透明度不满足条件就被裁剪,用来优化显示。

AlphaTest Greater AlphaValue//仅渲染 alpha 值大于 AlphaValue 的像素。AlphaValue :0-1

AlphaTest GEqual AlphaValue//仅渲染 alpha 值大于或等于 AlphaValue 的像素。

AlphaTest LessAlphaValue//仅渲染 alpha 值小于 AlphaValue 的像素。

AlphaTest LEqual AlphaValue//仅渲染 alpha 值小于或等于 AlphaValue 的像素。

AlphaTest Equal AlphaValue//仅渲染 alpha 值等于 AlphaValue 的像素。

AlphaTest NotEqual AlphaValue//仅渲染 alpha 值不等于 AlphaValue 的像素。

AlphaTest Always //渲染所有像素。这在功能上相当于 Alpha 测试关 (AlphaTest Off)。

AlphaTest Never//不渲染任何像素。

-------------------------------------------------------

模板测试:

Stencil如果开启了模板测试,GPU会首先会读取模板缓冲区的值,然后把该值和读取的参考值ref进行比较,比较方式由Comp指定,比如大于Greater就表示通过模板测试,

然后由Pass Fail ZFail去指定通过和不通过模板和深度测试后对缓冲区的值进行的Operation处理。

Stencil

{Ref 2 //设置模板参考值为2

Comp equal//比较方式,有8种比较方式。

Pass Operation //这个是当stencil测试和深度测试都通过的时候,进行的stencilOperation操作方法

Fail Operation //这个是在stencil测试通过的时候执行的stencilOperation方法

ZFail Operation//这个是在stencil测试通过,但是深度测试没有通过的时候执行的stencilOperation方法。

ReadMask readMask//readMask默认是255,一般不用该功能,设置隐码后 读取ref和buff值都需要与该码进行与操作。(0-255)

WriteMask writeMask//写操作进行与操作

}

Comp 的参数包括Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never

Operation的参数包括:

Keep保持

Zero归零

Replace拿比较的参考值替代原来buffer的值

IncrSat值增加1,但是不溢出,如果是255,就不再加

DecrSat值减少1,不溢出,到0就不再减

Invert翻转所有的位,所以1会变成254

IncrWrap值增加1,会溢出,所以255会变成0

DecrWrap值减少1,会溢出,所以0会变成255

clip(x) //x的任何分量小于0 被裁剪掉

discard//舍弃当前片元

ZWrite Off//关闭深入写入

ColorMask RGB|A|0 //设置颜色通道的写掩码,为0表示该pass不进行颜色输出。

-------------------------------------------------------

深度测试ZTEST:

一个片元离摄像机的远近,渲染后会进行深度写入,通常会判断缓存深度和当前片元深度 可知前后关系。

ZTest Always //指的是直接将当前像素颜色(不是深度)写进颜色缓冲区中 相当于ZTest Off

ZTest Never//而Never指的是不要将当前像素颜色写进颜色缓冲区中,相当于消失。

ZTest Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off,默认值为LEqual 即当物体深度小于或等于缓存深度值时(越远深度越大),该物体渲染,就是默认的先后顺序渲染。

透明度混合AlphaBlending:

该片元需要关闭深度写入,不关闭深度测试。会导致片元之间深度穿插。可以采用2个pass,第一个pass只用来做深度写入ZWrite On,第二个pass只用来输出颜色ZWrite Off,这样深度和颜色效果才会正确

Blend Off//关闭混合,只有blend打开后ps输出a通道才有意义

Blend SrcFactor DstFactor//用同样的因子对rgba进行混合(默认都开启混合)第一个参数对源颜色(当前片元颜色,ps输出的颜色)*SrcFactor混合,

第二个参数对目标颜色(当前读到的缓冲区颜色)*DstFactor混合,混合后默认相加后会重新写入缓冲区(相加后超过1的自动截断到1)。混合包括RABG值。结果都是源颜色和目标颜色与各自因子相乘后再加起来作为输出颜色。

shader里边的向量相乘不同于点乘叉乘,相当于各项分别相乘。

Blend SrcFactor DstFactor,SrcFactorA DstFactorA//把rgb和a的混合因子分开。

混合因子

One //因子是1

Zero //因子是0

SrcColor//因子为源颜色值,当前片元颜色,对应rgba分量分别与SrcColor分量相乘

SrcCAlpha//因子为源颜色透明值值,对应rgba分别与SrcCAlpha相乘。

DstColor//因子为目标颜色值,当前读到的缓冲区颜色

DstAlpha//因子为目标颜色透明值值

OneMinusSrcColor//因子为1-源颜色

OneMinusSrcAlpha//因子为1-源alpha

OneMinusDstColor//因子为1-目标颜色

OneMinusDstAlpha//因子为1-目标alpha

例子:

Blend SrcAlpha OneMinusSrcAlpha// Alpha混合,正常的透明度混合

Blend OneMinusDstColor One //柔和相加Soft Additive

Blend One One // Additive相加 线性减淡

Blend One OneMinusDstColor // Soft Additive比较柔和的相加

Blend DstColor Zero // Multiplicative乘法

Blend DstColor SrcColor // 2x Multiplicative2倍乘法

BlendOp OP//对源和目标颜色进行其他操作,而不是默认的相加,op操作包括:

Add //相加

Sub//源颜色减目标颜色

RevSub//目标颜色减源颜色

Min //使用2者较小的值

Min //使用2者较大的值

chen

BlendOp Min

Blend One One //组合变暗

-------------------------------------------------------

双面渲染:

一般采用多个pass分别渲染正面和背面

Cull Back|Front|Off

Cull Back默认的背对相机图元不渲染

Cull Front朝向相机图元不渲染,只显示背面

Cull Off关闭剔除功能 全部渲染 性能低,但是可以实现比如看见物体内部结构。

不透明物体有深度测试,先渲前后没有关系,但是先渲染近的效率会更高,因为远的会被深度测试自动剔除不用渲染。

透明物体一般要先渲远的,再渲近的才能保证视觉顺序正确。

------------------------------------------

SubShader的Tag{}标签类型:

Queue:渲染顺序,保证渲染顺序小的先渲 大的后渲

RenderType:Unity可以运行时替换符合特定RenderType的所有Shader,着色器分类

ForceNoShadowCasting:值为”true”时,表示不接受阴影。

IgnoreProjector:值为”true”时,表示不接受Projector组件的投影。常用语半透明物体

DisableBatching:是否对subshader进行批处理,当shader中需要对顶点进行偏移的时候,该项设置为true

CanUseSpriteAtlas:当该subshader用于sprite时 该标签设为false

PreviewType:指明材质面包怎么预览材质 比如 "PreviewType"="Plane"

LightMode : 渲染路径 ,pass的标签类型

-------------------------------------------------------

渲染队列:

"Queue"="Transparent"

Background:1000 //该声明的物体最先被渲染

Geometry:2000//默认的不透明物体使用的渲染队列

AlphaTest:2450//透明度测试,默认不透明物体渲染完后就渲染该物体

Transparent:3000//透明物体,在Geometry和AlphaTest后渲染,保证不透明物体渲染完了再渲染透明的。

Overlay:4000//该队列用来实现叠加效果,该物体会在最后被渲染。

------

RenderType:

Opaque:绝大部分不透明的物体都使用这个;

Transparent:绝大部分透明的物体、包括粒子特效都使用这个;

Background:天空盒都使用这个;

Overlay:GUI、镜头光晕都使用这个

-------------------------------------------------------

渲染路径:

Tag{ "LightMode" = "ForwardBase"}//为每个pass指定渲染路径

LightMode包括:

Always:所有渲染路径该pass都会渲染,但不计算光照

ForwardBase:前向渲染,该pass会计算环境光,最重要的平行光,逐顶点光和 Lightmaps

ForwardAdd:前向渲染,该pass会计算额外的逐像素光源,每个pass对应一个光源。光源多该pass会被多次调用 效率变低。

Deferred:延时渲染,该Pass会渲染G-buffer

ShadowCaster:把物体的深度信息渲染到阴影映射纹理或深度纹理中

PrepassBase:遗留的延迟渲染,该pass会渲染法线和高光反射的指数部分、

PrepassFinal:遗留的延迟渲染,该pass通过合并纹理 光照 自发光来渲染得到最后的颜色

Vertex:遗留的顶点照明渲染

-------------------------------------------------------

前向渲染:

包括ForwardBase类型渲染常用光照和ForwardAdd额外光照

#pragma multicompile_fwdbase //ForwardBase中用来保证光照衰减等参数正确赋值。

#pragma multicompile_fwdadd //ForwardAdd中用来保证可以访问到正确的光照变量.

#pragma multicompile_fwdadd_fullshadows //ForwardAdd中用来计算阴影效果

USING_DIRECTIONAL_LIGHT//平行光的宏定义

_LightColor0//该pass的桌像素光照颜色

_WorldSpaceLightPos0//获取平行光光源方向,或者点光源的光源位置

_LightMatrix0//世界空间到光源空间(光源位置为坐标原点的坐标系)的变换矩阵

_LightTexture0//光照衰减纹理

...........

tips:光源的RendeMode参数设置为Important unity会自动采用像素光源,如果不重要就是顶点光源。还有qualitysetting里边的PixelLIghtCount,超过这个数也会用顶点光照

-------------------------------------------------------

光照衰减:

float3 lightCoord = mul(_LightMatrix0, float4(i.worldPos, 1)).xyz;

fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;//UNITY_ATTEN_CHANNEL获得衰减值所在的分量

float shadow=SHADOW_ATTENUATION(i);//负值使用SHADOW_COORDS对相关纹理进行采样,返回值为阴影。关闭阴影的状态是等于1

return fixed4(ambient + (diffuse + specular) * atten * shadow, 1.0);//atten为衰减,shadow为阴影

------计算别人投到自己身上的阴影和衰减

SHADOW_COORDS(n)//声明一个_ShadowCoord的阴影纹理坐标 ps输入坐标,n的值是声明TEXCOORD0-7坐标使用的个数

TRANSFER_SHADOW(o);//用于在顶点着色器中计算上一步声明中的阴影纹理坐标 并传向ps阶段。

float shadow=SHADOW_ATTENUATION(i);//负值使用SHADOW_COORDS对相关纹理进行采样,返回值为阴影。关闭阴影的状态是等于1

UNITY_LIGHT_ATTENUATION(atten,v2f i, i.worldPos);//计算别人投影到身上的阴影#include "AutoLight.cginc" Unity会将光照衰减和阴影相乘后存在第一个参数中,并自动声明atten变量。第二个参数结构体包含SHADOW_COORDS,第三个参数世界空间坐标

return fixed4((diffuse + specular) * atten, 1.0);//UNITY_LIGHT_ATTENUATION出的atten为衰减和阴影

-----计算阴影投影到别人身上,自己的阴影

V2F_SHADOW_CASTER//unity里边定义阴影投射需要定义的变量

TRANSFER_SHADOW_CASTER_NORMALOFFSET(0)//unity对顶点进行自动处理

SHADOW_CASTER_FRAGMENT(i)//unity自动完成阴影投射部分,把结果输出到深度图和阴影映射纹理中

--ds2的阴影采用的是屏幕后处理的方式去计算阴影,延迟渲染

2.顶点照明渲染:过时的渲染方式。效果差。

3.延迟渲染:通常2个pass,第一个pass计算哪些片元可见,第二个pass计算真实光照。

-------------------------------------------------------

1.反射o.worldRefl = reflect(-o.worldViewDir, o.worldNormal);//入射光线,表面法线

2.折射o.worldRefr = refract(-normalize(o.worldViewDir), normalize(o.worldNormal), _RefractRatio);//入射光线,表面法线,介质比

3.镜子效果:使用相机的RenderTexture来设置渲染纹理。o.uv.x = 1 - o.uv.x;坐标需要翻转一下。

4.玻璃效果:反射和折射使用cubemap进行采样 是天空盒的cubemap,然后反射需要采样的是周围环境的光照和纹理。

GrabPass { "_RefractionTex" }//会把屏幕输出到_RefractionTex的texture中, _RefractionTex_TexelSize 可以得到该纹理纹素大小,例如255*255的纹素是(1/255,1/255)

GrabPass{} //然后用_GrabTexture直接访问屏幕图像,但是这样效率比较低,推荐要上面需要声明的方法。

o.scrPos = ComputeGrabScreenPos(o.pos);//得到对应被抓取的屏幕图像的采样坐标

反射和折射需要显示环境的效果,所以需要对环境的cubemap进行采样。先用反射和折射的公式计算出光线,然后对环境贴图进行采样texCUBE(_Cubemap, i.worldRefl).rgb就可以得到具体效果了。

反射skybox 3d采样,折射屏幕抓取图像2d采样。

-------------------------------------------------------

时间变量:

_Time:float4 //t是自该场景加载开始所经过的时间,4个分量是(t/20,t,2t,3t)

_SinTime:float4//t是时间的正玄弦值,四个分量的值分别是(t/8,t/4,t/2,t)

_CosTime:float4//t是时间的余玄弦值,四个分量的值分别是(t/8,t/4,t/2,t)

unity_DeltaTime:float4// dt是时间增量,4个分量分别是(dt,1/dt,smoothDt,1/smoothDt)

序列帧动画:时间去控制uv坐标映射转换。uv坐标的xy是顶点坐标,映射到小格子里边,和UItexture的xy和宽高不一样。

背景偏移动画:时间控制uv坐标偏移。

水流动画:通过时间和正弦函数去控制顶点偏移,通过时间控制uv移动。设置DisableBatching=true

广告牌BillBoarding:根据视觉方向来旋转被纹理着色的多边形。顶点动画

-------------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/u014635337/article/details/88794002