shader脚本声明 multi_compile多条件编译开关
Shader "Custom/MultiShader"
{
Properties//绑定到编辑器属性面板上的变量;
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader//子着色器
{
Tags { "RenderType"="Opaque" } //shader标签=队列渲染
//设置subShader子着色器LOD值,Shader脚本每次只会根据情况来选择一个可执行的SubShader子着色器
// (也就是一直找到第一个<= Shader脚本.maximumLOD的 那个SubShader子着色器执行,如果都没有 就“降级处理”
LOD 100
Pass
{
CGPROGRAM//CG代码开始
#pragma vertex vert//命名vert为顶点Shader入口
#pragma fragment frag//命名frag为(片元)像素Shader入口
#pragma multi_compile MY_multi_1 MY_multi_2 //定义多条件编译shader开关
//#pragma multi_compile_fog 注释掉 雾应用
#include "UnityCG.cginc"
struct appdata//已经bind语义的结构体
{
float4 vertex : POSITION;//bind纹理位置 xyzw
float2 uv : TEXCOORD0; //bind第一张纹理图的uv
};
struct v2f//已经bind语义的结构体
{
float2 uv : TEXCOORD0; //bind第一张纹理图的uv
//UNITY_FOG_COORDS(1) 注释掉 雾统一坐标
float4 vertex : SV_POSITION;//内置向量xyzw bind 位置Pos
};
sampler2D _MainTex;//为了使用属性块内的属性 命名1个同名的_MainTex(2d纹理图)
float4 _MainTex_ST; //因为使用了TRANSFORM_TEX 所以要这个额外float4 _XXX_ST变量名 来让转换坐标操作符合规范
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);//把纹理图位置xyzw转世界坐标 mul(UNITY_MATRIX_MVP,v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);//根据流水线uv坐标 计算出对应的_MainTex纹理图 的真正UV坐标(1.流水线uv坐标,2.纹理图)
//UNITY_TRANSFER_FOG(o,o.vertex); 注释掉 雾的操作
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col;
//fixed4 col = tex2D(_MainTex, i.uv);//获得纹理颜色
//UNITY_APPLY_FOG(i.fogCoord, col); 注释掉 雾应用
#ifdef MY_multi_1 //多条件编译开关
col = fixed4(1.0,0.0,0.0,1.0); //红色
#endif
#ifdef MY_multi_2 //多条件编译开关
col = fixed4(0.0,0.0,1.0,1.0); //蓝色
#endif
return col;
}
ENDCG //CG代码结束
}
}
}
用C#脚本控制multi_compile多条件编译开关, 让shader脚本编译对应cg代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 挂在Grab_Or_Multi_Cube物体上;
/// 用C#脚本控制multi_compile多条件编译开关 让shader脚本编译对应cg代码
/// </summary>
public class MultiShader : MonoBehaviour {
// Use this for initialization
void Start () {
Shader.EnableKeyword("MY_multi_1"); //启用 multi_compile多编译条件 “MY_multi_1”
Shader.DisableKeyword("MY_multi_2");//禁用 multi_compile多编译条件 “MY_multi_2”
}
// Update is called once per frame
void Update () {
}
}