表面着色器示例一(Unity4.X版本)
Shader "Custom/BasicDiffuse"
{
Properties
{
_MainTex("Base(RGB)",2D) = "white"{}
}
SubShader
{
Tags{"RenderType" = "Opaque"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
void surf(Input IN,inout SurfaceOutput o)
{
half4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
表面着色器示例(Unity5.X后提供的Standard Surface Shader)
Shader "Custom/NewSurfaceShader" {
//属性
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
//标识渲染类型为不透明物体
Tags { "RenderType"="Opaque" }
//LOD是 ( Level of Detail ) 的缩写,表示细节级别。
//可以给不同的 SubShader 指定不同的LOD属性。
//可以用设置 lod 的方法来控制游戏画面的渲染质量。
//在Unity3D->Edit->Project Setting->Quality中的Maximum LODLevel可以设置最大LOD等级,Shader的LOD值是小于所设定的LOD值,才会被编译使用。Maximum LODLevel的等级可以设置7个级别,例如设置为1,则表示把最大LOD值设置为100,等级2,则最大LOD值为200,以此类推,若设置为0,则表示不进行LOD判断,任何LOD值的Shader都会被使用。
LOD 200
//使用CG语言编写
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
//基于物理的标准照明模型,并在所有灯光类型上启用阴影
//格式:#pragma + surface + 函数名 + 光照模型
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
//使用shader model 3.0 target,获得更漂亮的灯光效果
#pragma target 3.0
//声明纹理变量,与同名属性相关联
sampler2D _MainTex;
//结构体:用于描述对于uv的一个纹理坐标
struct Input {
float2 uv_MainTex;//必须以uv或uv2开头+Properties中对应贴图属性名相同
};
//声明变量,与同名属性相关联
half _Glossiness;
half _Metallic;
fixed4 _Color;
// 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)
//函数:参数一:上面定义的结构体。参数二:基于物理的光照模型。 inout特性:输入输出。
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
//反照率来自于由颜色着色的纹理,使用纹理坐标对纹理进行采样得到颜色
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
//将上面得到的颜色的值赋予o
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
//金属和平滑度来自滑块变量
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
//获取设置透明度值
o.Alpha = c.a;
}
//结束CG
ENDCG
}
//如果上面的SubShader不能正常执行渲染,就使用Diffuse渲染
FallBack "Diffuse"
}
基于示例一更改
Shader "Custom/BasicDiffuse"
{
Properties
{
_EmissiveColor("Emissive Color",color) = (1,1,1,1)
_AmbientColor("Ambient Color",color) = (1,1,1,1)
_MySliderValue("This is a Slider",Range(0,10)) = 2.5
}
SubShader
{
Tags{"RenderType" = "Opaque"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert
float4 _EmissiveColor;
float4 _AmbientColor;
float _MySliderValue;
struct Input
{
float2 uv_MainTex;
};
void surf(Input IN,inout SurfaceOutput o)
{
float4 c;
c = pow((_EmissiveColor + _AmbientColor), _MySliderValue);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
效果可以在Unity中检验。
这里:
pow(arg1,arg2)是自带函数,相当于数学公式中的power(求幂),参数1代表底数,参数2代表指数。
https://developer.download.nvidia.cn/CgTutorial/cg_tutorial_appendix_e.html
(Cg教程)
实现原理:
当在Properties块中声明一个新的属性后,便为着色器提供了一种从材质Inspector面板上获得调整后属性值的方法,这些值保存在对应的变量名里。
为了能在SubShader{}里使用这些值,需要创建与这些属性同名的变量,Unity会自动将二者关联起来,它们拥有相同的数据。
当在SubShader里创建好变量后,就可以在surf()函数里使用它们了。
在上面的例子中,就是将_EmissiveColor和_AmbientColor进行叠加,然后用_MySliderValue对叠加后的值进行乘方运算。
基于示例一更改
Shader "Custom/TestShader" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" "queue" = "transparent"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert fullforwardshadows alpha
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
对于有alpha通道的纹理贴图,实现透明处理。
再次更改,去除阴影:
Shader "Custom/TestShader" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" "queue" = "transparent"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert alpha
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
}