美文网首页
UnityShader学习——surface Shader(2)

UnityShader学习——surface Shader(2)

作者: Cheney_ | 来源:发表于2022-07-08 11:00 被阅读0次

Suface shader中不需要编写Pass通道

属性

Shader "Custom/shaderTwo"

{

    Properties  //属性

    {

        _Color ("颜色值", Color) = (1,1,1,1)

        _MainTex ("主纹理", 2D) = "white" {}

        _Glossiness ("高光光泽度", Range(0,1)) = 0.5

        _Metallic ("材质金属光泽", Range(0,1)) = 0.0

    }

    SubShader

    {

        Tags { "RenderType"="Opaque" }  // Tags描述一个渲染类型  Opaque描述一个不透明物体

        LOD 200  //层级细节

        CGPROGRAM  //代码块 

        // Physically based Standard lighting model, and enable shadows on all light types

        #pragma surface surf Standard fullforwardshadows  //#pragma编译指令  Standard基于物理的光照  fullforwardshadows描述关于阴影的设置

        // Use shader model 3.0 target, to get nicer looking lighting  使用着色器3.0目标,以获得更好的外观照明

        #pragma target 3.0  //使用硬件的target 3.0 

        sampler2D _MainTex;    //纹理变量声明

        struct Input  //结构体

        {

            float2 uv_MainTex;  //纹理坐标  可搜索帮助文档Surface Shader input structure  主纹理的纹理坐标

        };

        half _Glossiness;

        half _Metallic;

        fixed4 _Color;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.  Add instancing support for this shader.You need to check "Enable Instancing' on materials that use the shader.

      //添加对此阴影的实例支持,您需要检查使用着色器的材料上的“启用实例”。

        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.

        // #pragma instancing_options assumeuniformscaling

        UNITY_INSTANCING_BUFFER_START(Props)

            // put more per-instance properties here

        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)  //surface函数  inout既是输入也是输出  SurfaceOutputStandard基于物理的光照模型 PBS特性

        {

            // Albedo comes from a texture tinted by color

            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;  //声明一个颜色值

            o.Albedo = c.rgb;  //Albedo基本漫反射,基本镜面高光颜色值

            // Metallic and smoothness come from slider variables  金属和光滑性来自滑动变量。

            o.Metallic = _Metallic;

            o.Smoothness = _Glossiness;

            o.Alpha = c.a;

        }

        ENDCG

    }

    FallBack "Diffuse" 

}

Properties里面包含的是shader的属性。以_MainTex为例, _MainTex表示变量名,Albedo(RGB)是在编辑器里显示的名称,2D是它的类型,表示它是一个纹理,white是默认值。

表面着色器的属性类型:

Range (min, max)

创建 Float 属性,以滑动条的形式便于在最大值和最小值之间进行调节创建色块,

Color

可以在 Inspector 面板上通过拾色器获取颜色值 = (float,float,float,float)

2D

创建纹理属性,允许直接拖曳一个纹理

Rect

创建一个非 2 次方的纹理属性,作为 2D GUI 元素

Cube

在 Inspector 面板上创建一个立方贴图属性,允许用户直接拖曳立方贴图作为着色器属性

Float

在 Inspector 面板上创建一个非滑动条的 float 属性

Vector

创建一个拥有 4个float值的属性,可以用于标记方向或颜色 

SubShader是子着色器,一个着色器中可以包含多个SubShader。子着色器这是代码的主体,计算着色的时候,平台会按顺序选择一个可以使用的子着色器进行执行,如果所有的子着色器都无法使用,则会执行最后FallBack里指定的着色器。

我们来看SubShader的主体:

Tags(标签)标记了着色器的一些特性。

常用的Tag有:

RenderType:渲染类型,常用就是Opaque(不透明)和Transparent(透明)。

IgnoreProjector:是否忽略投影器,True or False。

ForceNoShadowCasting:是否强制无阴影,True or False。

Queue:渲染队列,内置值Background=1000,Geometry=2000,AlphaTest=2450,Transparent=3000,Overlay=4000,但是并不限于这些值,你可以填写自己的值,或者写成"Queue"="Transparent+10"也是可以的。

LOD是Level of Details的缩写,表示着色器的细节层级,高于Unity的最大LOD(Quality Settings里设置)的shader将不可用。在调低画质时,可以根据这个值舍弃掉一部分shader。

紧接着是CGPROGRAM,它与ENDCG对应,表明在二者范围内是一段Cg(C for graphics)代码。

#pragmasurface surf Lambert

这一行表明我们使用的是一个表面着色器,方法名称是surf,光照模型是Lambert。

然后是

sampler2D_MainTex;

sampler2D对应于Properties里面的2D,是2D贴图的数据结构。而_MainTex也对应于Properties里面的_MainTex,保存了编辑器(或者代码)里设置的贴图。二者必须是同名,才能将贴图数据链接起来。简而言之,下面的_MainTex是上面的_MainTex在Cg代码里的代理。

然后是一个结构(struct)定义:

structInput{

float2 uv_MainTex;

};

这个结构是为surf方法定义了输入参数的数据结构。

float2表示这是一个二维的浮点型坐标。

其他的内置类型还包括:

half:半精度浮点型,范围[-60000,60000]

fixed:低精度定点型,范围[-2,2]

int:整型

bool:布尔型

sample*d:纹理类型

uv_MainTex表示_MainTex的纹理坐标(参考百度百科UV坐标),这是一种命名约定。

最后是surf方法:

voidsurf(Input IN, inout SurfaceOutput o){

fixed4 c = tex2D (_MainTex, IN.uv_MainTex);

o.Albedo = c.rgb;

o.Alpha = c.a;

}

Input结构是我们在上面定义的。

SurfaceOutput的数据结构:

structSurfaceOutput {

half3 Albedo;//像素的颜色

half3 Normal;//像素的法向值

half3 Emission;//像素的发散颜色

half Specular;//像素的镜面高光

half Gloss;//像素的发光强度

half Alpha;//像素的透明度

};

surf方法主体第一行:

fixed4 c = tex2D (_MainTex, IN.uv_MainTex);

使用tex2D方法从_MainTex里面取出指定纹理坐标(IN.uv_MainTex)的色彩值。

取出来色彩值之后,很简单,将c的rgb分量赋值给输出o的Albedo,把c的a分量赋值给输出o的Alpha。

那么我们已经可以读懂一个最简单的shader了,那么是不是应该自己再写一个:

Shader"Custom/TestColor"{

Properties {

_Color ("Color", Color) = (1,1,1,1)

}

SubShader {

Tags {"RenderType"="Opaque"}

LOD200

CGPROGRAM

#pragma surface surf Lambert

fixed4 _Color;

structInput{

float2 uv_MainTex;

};

voidsurf(Input IN, inout SurfaceOutput o){

o.Albedo = _Color.rgb;

o.Alpha = _Color.a;

}

ENDCG

}

FallBack"Diffuse"

}

在Unity编辑器里新建一个材质,将材质的shader设置成我们新写的TestColor。然后在场景里面加入一个Cube,并将Cube的材质设置为我们新建的材质。

这样我们就完成了一个最简单的单色材质,可以通过调节材质的颜色来调节Cube的颜色了。

相关文章

网友评论

      本文标题:UnityShader学习——surface Shader(2)

      本文链接:https://www.haomeiwen.com/subject/opvbbrtx.html