Unity Shader 学习之旅-初探
Posted firepad-magic
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Shader 学习之旅-初探相关的知识,希望对你有一定的参考价值。
Unity Shader 学习之旅-初探
美丽的梦和美丽的诗一样 都是可遇而不可求的——席慕蓉
最简单的顶点片元着色器
顶点片元着色器基本结构
Unity Shader基本结构:Shader ,Properties,SubShder,Fallback等。
结构
-
- Shader "ShaderName"{
- Properties{
- //属性,暴露在inspector面板上
- }
-
- SubShader{
- //针对显卡A的SubShader
- Pass{
- //设置渲染状态和标签
-
- CGPROGRAM
- //该代码的编译指令,如:
-
-
-
- //CG代码
-
-
- ENDCG
- //其他设置
- }
- }
-
- SubShader{
- //针对显卡B的SubShader
- }
-
- //上述SubShader都失败后调用回调的Unity Shader
- Fallback "VertexLit"
- }
一个简单的示例
- Shader "UnityShaderBoook/SimplerShader"{
-
- //Properties并非必须,此shader中不声明任何材质属性
- SubShader{
-
- Pass{
-
- CGPROGRAM
- //编译命令,指定顶点/片元着色器处理函数
-
-
-
- //顶点着色器代码,逐个顶点执行
- //使用POSITION语义指定函数的输入参数v为顶点的位置信息
- //SV_POSITION语义指明函数的返回值为顶点着色器输出的是裁剪空间中的位置
- //UnityObjectToClipPos则是Unity内置的模型-观察-投影矩阵,帮我们完成操作(mul(UNITY_MATRIX_MVP,*)‘ 现已更新为‘UnityObjectToClipPos(*)‘)
- float4 vert(float4 v:POSITION):SV_POSITION{
- return UnityObjectToClipPos(v);
- }
-
- //片元着色器,逐个面片执行
- //此片元着色器没有任何输入参数
- //SV_TARGET语义指定函数输出颜色存储一个渲染目标上
- //这里仅仅简单的返回表示白色的fixed4的变量
- fixed4 frag():SV_TARGET{
- return fixed4(1.0,1.0,1.0,1.0);
- }
-
- ENDCG
- }
- }
-
-
- }
当我们把使用该shader的材质赋给场景物体时,物体仅仅表现出单纯的白色。我们在shader中没有赋予它更丰富的内容,如法线,纹理等,所以他不会表现出任何深度,阴影等,当然也不会受到光照的影响。
注意:
- POSITION和SV_POSITION都是CG/HLSL中的语义,他们是不可省略的,这些语义用来告诉系统输入值和输出值的含义。POSTION告诉Unity这里将模型的顶点数据传入到v参数,而SV_POSITION则告诉Unity顶点着色器输出的是裁剪空间中的顶点坐标。
- UnityObjectToClipPos(v) 是mul(UNITY_MATRIX_MVP,v)更新后的函数,他是Unity内置函数,用来帮我们进行顶点坐标从模型空间转换到裁剪空间的转换。
- SV_TARGET 是HLSL中的系统语义,它输出的是一个float4类型的变量,它等同于告诉渲染器,把用户的输出颜色存储到一个渲染目标中,有时也使用COLOR代替,考虑到平台的通用性最好使用SV_TARGET。
- 模型空间:模型空间我们可以理解为模型自身的局部坐标,一个模型上的顶点位置信息,都是依托自身的局部坐标的,但当我们把它放到场景中的时候,就需要我们转换这些信息来使用。
- 裁剪空间:可以简单的理解为Unity中摄像机视椎体包围的空间,不在其空间内的信息将会被剔除,保留的信息后续会被投影到屏幕上被看到。
顶点着色器与片元着色器之间通信
片元着色器是无法直接获取陈模型的顶点信息的,这时就需要我们通过使用结构体作为媒介,有顶点着色器向片元着色器传递一些数据,如:模型法线,纹理坐标等。
示例
- // Upgrade NOTE: replaced ‘mul(UNITY_MATRIX_MVP,*)‘ with ‘UnityObjectToClipPos(*)‘
-
- Shader "UnityShaderBoook/vert2frag"{
- Properties {
- _Color ("Color Tint", Color) = (1, 1, 1, 1)
- }
- //Properties并非必须,此shader中不声明任何材质属性
- SubShader{
-
-
- Pass{
-
- CGPROGRAM
- //编译命令,指定顶点/片元着色器处理函数
-
-
-
- uniform fixed4 _Color;
- //结构体用于指定向顶点着色器传递的信息
- struct a2v{
- float4 vertex:POSITION;//模型的顶点坐标
- float4 normal:NORMAL;//模型的法线信息
- float4 texcoord:TEXCOORD0;//模型的第一套纹理
- };
-
- //结构体指定了顶点着色器向片元着色器传出的信息
- struct v2f{
- float4 pos:SV_POSITION;//裁剪空间中的坐标信息
- fixed3 color:COLOR0;//COLOR0语义可用来存储颜色信息
- };
-
- v2f vert(a2v v) {
- v2f o;
- o.pos = UnityObjectToClipPos(v.vertex);
- o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);
- return o;
- }
-
-
- //接收传入的信息
- fixed4 frag(v2f i):SV_TARGET{
- fixed3 c = i.color;
- c *= _Color.rgb;
- return fixed4(c, 1.0);
- }
-
- ENDCG
- }
- }
-
-
- }
注意: 顶点着色器是逐个顶点调用的,片元着色器是逐片元调用的。片元着色器中的输入实际是吧顶点着色器的输出插值后得到的结果。
以上是关于Unity Shader 学习之旅-初探的主要内容,如果未能解决你的问题,请参考以下文章
我的OpenGL学习进阶之旅 C++ 长行字符串多行书写的方法以及如何书写正确的OpenGL Shader着色器代码
我的OpenGL学习进阶之旅 C++ 长行字符串多行书写的方法以及如何书写正确的OpenGL Shader着色器代码
我的OpenGL学习进阶之旅解决着色器语法错误:The shader uses varying u_Color, but previous shader does not write to it
我的OpenGL学习进阶之旅解决着色器语法错误:The shader uses varying u_Color, but previous shader does not write to it
我的OpenGL学习进阶之旅解决着色器语法错误:The shader uses varying u_Color, but previous shader does not write to it