永远相信美好的事情即将发生 😊!

Unity Shader 入门精要(冯乐乐著)学习笔记(4)——开始Unity Shader学习

学习 Mavis 25℃ 0评论

创建一个最简单的顶点/片元着色器

使用unity版本如下:

第一步:去掉初始的天空盒子,只是为了得到更加原始的效果:

第二步:创建Shader文件和材质(前面提到过材质是shader 的载体),并将shader赋给材质(路径可以点开shader查看,也可以自己修改好路径后再赋值)。

第三步:创建物体调整到合适位置,并将材质赋值给物体,这样可以观察到shader 的效果(在没修改过shader 的情况下可以看到默认的效果:标准表面着色器)。

第四步:修改shader,达到自己想要的效果,在这里实现一个最简单的,代码(很多内容在第二篇笔记完整代码中有详细注释)如下:

Shader "Custom/SimpleShader"
{
    SubShader
    {
       Pass{
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            float4 vert(float4 v:POSITION):SV_POSITION{
                return UnityObjectToClipPos(v);//模型空间到裁剪空间,即MVP矩阵,等同于mul(UNITY_MATRIX_MVP,*)
            }
            fixed4 frag():SV_Target{
                return fixed4(1.0,1.0,1.0,1.0);//返回一个颜色并存储到了渲染目标中(由语义SV_Target表示)
            }
            ENDCG
       }
    }
}

 

效果:

通过语义来限定输入输出。可以使用结构体来丰富着色器的输入输出,通过语义填充到结构体内的数据是由材质的Mesh Render 提供的,在每帧调用Draw Call的时候,Mesh Render组件会负责渲染的模型数据发送给Unity Shader。也可以通过结构体来完成顶点着色器和片元着色器之间的通信。需要注意的是顶点着色器中,必须包含一个由SV_POSITION限定的变量,这样渲染器才能得到裁剪空间下的顶点坐标。顶点着色器是逐顶点调用的,而片元着色器是逐片元,所以片元着色器的输入是把顶点着色器的输出进行插值得到的。

在Properties语义中限定的属性可以在选择该shader的材质的面板上进行调节。ShaderLab属性类型(左)和Cg中变量类型(右)之间的匹配关系:

Cg变量前加上uniform关键字代表提供一些初始值如何指定和存储的信息,且在unity shader中是可以省略的。

Unity提供的内置文件和变量

内置的包含文件:#include “filename”   ,文件后缀为.cginc

还提供了一些内置的变量:坐标变换、摄相机参数,用于访问时间、光照、雾效和环境光等目的的变量。大多位于内置文件中。

Cg/HLSL语义

需要注意在DirectX以后,有了新的语义类型:系统数值语义,就是以SV开头的,这类值具有特定含义,要注意使用。

常用语义:

需要注意一个语义可以使用的寄存器只能处理4个浮点值(float),因此矩阵类型可采用分成多个变量的形式。

Debug

第一种方法:假彩色图像(false-color image)——用于可视化一些数据,主要是把需要调试的变量映射到[0,1],然后把他们作为颜色输出到屏幕上,然后通过像素颜色来判断这个值的正确性。

一维数据可以选择一个单独的颜色分量进行输出,其他分量=0。如果是多维数据,则可以选择对每一维数据进行单独调试,或者选择多个颜色分量进行输出。

Shader "Custom/FalseColor" 
{ 
    SubShader 
    { 
        Pass{ 
            CGPROGRAM 
            #pragma vertex vert 
            #pragma fragment frag 
            #include "UnityCG.cginc" 
            struct v2f{ 
                 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); 
                 return o; 
            } 
            fixed4 frag(v2f i):SV_Target
            { return i.color; } 
            ENDCG 
        } 
    } 
}

效果:

第二种方法:利用Visual Studio——Graphics Debugger,可以查看每个像素的最终颜色、位置等信息,还可以对顶点着色器和片元着色器进行单步调试。(仅可在DirectX11平台运行)

根据官方文档进行安装:https://docs.unity3d.com/Manual/SL-DebuggingD3D11ShadersWithVS.html

第三种方法:帧调试器

 

渲染平台的差异

在开启了抗锯齿并使用了渲染到纹理技术时,unity不会自动处理翻转问题来消除平台间的差异。这种问题在只处理一张渲染图像的时候也没有影响,但是在处理多张渲染图像的时候要注意,在开启了抗锯齿以后,这些图像在竖直方向上的朝向可能是不同的(该问题仅出现于DirectX中)。

不同平台对shader语义要求也不同,DirectX更严格。还要注意语义差异,例如尽量使用系统数值语义。

注意

  1. Cg/HLSL中三种精度的数值类型:float、half、fixed(-2.0~+2.0)
  2. 规范语法
  3. 避免不必要的计算
  4. 慎用分支和循环语句
  5. 不要除0

Mavis , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Unity Shader 入门精要(冯乐乐著)学习笔记(4)——开始Unity Shader学习
喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址