Unity3d开发(一)ShaderLab 入门 语法格式


文章作者:松阳

本文出自 阿修罗道,禁止用于商业用途,转载请注明出处。  

原文链接:http://blog.csdn.net/fansongy/article/details/48633189

width="150" height="210" frameborder="0" scrolling="no" src="http://widget.weibo.com/relationship/bulkfollow.php?language=zh_cn&uids=2080045857&wide=1&color=FFFFFF,FFFFFF,0082CB,666666&showtitle=0&showinfo=1&sense=0&verified=1&count=1&refer=http%3A%2F%2Fwww.himigame.com%2Fandroid-game%2F1521.html&dpc=1" style="font-size: 14px; font-weight: bold; border-width: 0px; margin: 0px; padding: 0px; font-family: arial, helvetica, clean, sans-serif; line-height: 16px;">







Ahead

好长时间没更新博客了,究其原因,是我想尝试Wiki这种形式来整理知识。总体来说,它还是不错的,不过不适合我。所以,还是回归博客吧。

Shader Lab

ShaderLab 是Unity3d自己封装的一个调用CG/HLSL/GLSL的接口。相关信息可以参考:圣典翻译的新手

基本格式

shaderLab 代码一般遵循以下格式:

Shader "MyShader/ShaderName" 
{
    Properties {
        _Color ("Main Color", Color) = (1,1,1,0.5)
        _MainTex ("Texture", 2D) = "white" { }
    }
    SubShader 
    {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            
            //--snip--
            struct v2f {
                float4 pos :SV_POSITION;
                float3 color : COLOR0;
            };
            
            v2f lv1(appdata_base v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                o.color = v.normal * 0.5 +0.5;
                return o;
            }
            
            half4 lv2(v2f i) : COLOR
            {
                return half4(i.color,1);
            }
            
            ENDCG
        }
    }
    FallBack "VertexLit"
}

属性设置

Properties {
    `InnerName` ( `showName`,`type`) = `defaultValue`
}

其中类型与默认值对应如下:

  • Color (r,g,b,a)
  • Range(min,max) 2.4
  • 2D "white" {}
  • Float 2.4

surface shader

以下内容详细可以参考此处

定义

使用 #pragma surface 这个指令可用编写表面着色器。

#pragma surface surfaceFunction lightModel [optionalparams]

所需参数:

  • surfaceFunction - 表示Cg函数中有表面着色器(surface shader)代码。这个函数的格式应该是这样:

    void surf (Input IN,inout SurfaceOutput o)

    Input是你自己定义的结构。Input结构中应该包含所有纹理坐标(texture coordinates)和和表面函数(surfaceFunction)所需要的额外的必需变量。

  • lightModel -在光照模式中使用。内置的是Lambert (diffuse)和 BlinnPhong (specular)。如果想编写自己的光照模式,请参考:自定义光照模式。

cginc

对于预定义的宏和函数,Unity将她们放进了许多包含文件中。在Mac上,它的目录为 Contents/CGIncludes/xxx.cginc 例如常用的:UnityCG.cginc, lighting.cginc 等。当然我们也可以自己编写。将文件后缀更改成.cginc然后在shader中使用#include "YourCGInclude.cginc"即可。

INPUT

Input 这个输入结构通常拥有着色器需要的所有纹理坐标(texture coordinates)。纹理坐标(Texture coordinates)必须被命名为“uv”后接纹理(texture)名字。(或者uv2开始,使用第二纹理坐标集)

例如:

Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BumpMap ("Bumpmap", 2D) = "bump" {}
}

struct Input {
        float2 uv_MainTex;
        float2 uv_BumpMap;
};

  sampler2D _MainTex;
  sampler2D _BumpMap;

OUTPUT

struct SurfaceOutput {
    half3 Albedo;       //反射率
    half3 Normal;       //法线
    half3 Emission;     //自发光,用于增强物体自身的亮度,使之看起来好像可以自己发光
    half Specular;      //镜面
    half Gloss;         //光泽
    half Alpha;         //透明
};

subshader Tag

使用Tags可以为subshader指定属性:

Tags { "TagName1" = "Value1" "TagName2" = "Value2" }

详细的属性使用可以参考Unity手册中 subshader tags章节。

脚本中调用

在脚本中可以动态设置shader的值,例如:

[ExecuteInEditMode]
public class caller : MonoBehaviour {
    public Color diffColor;

    void Update()
    {
        renderer.sharedMaterial.SetColor("_color",diffColor);
    }
}

其中,shader中有名为_color的uniform变量 例如:

Shader "Learn/ColorShader" {
    Properties {
    }
    SubShader {
        Tags { "Queue"= "Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha
        
        Pass{
            CGPROGRAM
            #pragma vertex v2f
            #pragma fragment frag
            
            #include "UnityCG.cginc"
             
            uniform fixed4 _color;
            
            struct InputVertex
            {
                float4 pos : POSITION;
            } ;
            
            struct Output
            {
                float4 pos :SV_POSITION;
                float4 col :COLOR0;
            } ;
              
            Output v2f(InputVertex input)
            {
                Output o;
                o.pos = mul(UNITY_MATRIX_MVP,input.pos);
                o.col = _color;
                return o;
            }
            
            half4 frag(Output o): COLOR
            {
//              return half4(1.0,0.4,0.4,1);
                return o.col;
            }
        
            ENDCG
        }
    }  
    FallBack "Diffuse"
}

自定义光照

#pragma surface surf `FuncName`
  • half4 LightingFuncName (SurfaceOutput s, half3 lightDir, half atten) {}
  • half4 LightingFuncName (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {}
  • half4 LightingFuncName (SurfaceOutput s, half4 light) {}

如果你觉得这篇文章对你有帮助,可以顺手点个,不但不会喜当爹,还能让更多人能看到它... 

你可能感兴趣的:(Unity3d,Unity3d,开发杂谈)