Unity标准shader 结构&语法 大全

标准shader结构(顶点片元)

Shader "Unlit/phong"{
    
    
	Properties{
    
    
	
	SubShader{
    
    
		【标签、状态】
		
		Pass{
    
    
			【name、标签、状态】
		
			CGPROGRAM
			【#include】
			【着色器声明】
			【struct】
			【属性声明】
			【vert】
			【frag】
			ENDCG
		}
		
		Pass{
    
    }
	}
	
	SubShader{
    
    }
	
	Fallback
	}
}




一些注意事项

  1. shaderlab不区分大小写!(尽管不区分,但是引用外部变量和函数时,大小写还是要写对啊!)

  2. shaderlab和hlsl很相似,但是不完全相同



Shader “位置”

  1. 这里表明文件所在的位置和名称
  2. 经实验,这里的名称及位置和真实的没有相互作用,仅在初始化时一致



Properties

 Properties
    {
    
    
    	_Name ("display name", Type) = DefaultValue

        数
        _Int ("Int", Int) = 2  
        _Float ("Float",Float) = 1.11
        _Gloss ("Gloss", Range(8,256)) = 20   //Range(a,b)会产生一个可拖动的条
        
        [IntRange] _Int("Int", Range(0, 255)) = 0  //[_IntRange]用于限定编辑器面板中只能调节为整数值
        
        
        向量
        _Diffuse ("Diffuse", Color) = (1,1,1,1)   //Color会产生调色盘
        _Vector ("Vector", Vector) = (1,2,3,4)
        
        
        纹理
        _2D("2D", 2D) = ""{
    
    } 
        _3D("3D", 3D) = ""{
    
    }
        _Cube("Cube", CUBE) = ""{
    
    } 
    }
  • 这里的属性会显示在材质面板,方便调节



SubShader

subshader{
    
    
	//标签 可选
	Tags {
    
    "tagname0" = "value0" "tagname1" = "value1"}
	//状态 可选
	RenderSetup
	
	Pass{
    
    
	}
	//other Passes
}
  1. subshader只会执行一个,即第一个可以在本机上运行的shader,如果都不行,就执行fallback(相当于if -> ifelse -> else
  2. 一般而言subshader的性能开销从上到下越来越高
  3. 大部分subshader都包含复数条Pass,但我们一般要求pass数量尽量少,以提高性能
  4. 此处声明的标签和状态会应用到该subshader中的所有pass



UsePass

	UsePass "ShaderName" + "/" + "PassName"
  • 这个就是Pass名的使用方式,直接引用一整个pass
  • 不用管大小写,shaderlab不区分
  • 不用担心UsePass中的vert/frag和当前Shader的vert/frag同名,这两部分是分开的
  • 相当于直接把Pass代码复制过去,但是Properties并没有,所以需要手动添加需要的Properties


GrabPass

抓取屏幕存储到纹理中,用于后续的pass处理

Pass

每一条pass都包含了完整的渲染流程

Pass{
    
    
	Name "mypass"  //Name的意义是可以在其他的shader中直接调用该pass
	Tags {
    
    "LightMode" = "ForwardBase"}
	Rendertype {
    
    "" = ""}
	
	CGPROGRAM
	#pragma vertex vert //指定两个着色器的名字
    #pragma fragment frag
 
    #include "UnityCG.cginc" //外接一些库
    #include "Lighting.cginc"
	
	float4 _Diffuse; //把properties中的值在pass中声明一下才能使用,注意变量类型
    float _Gloss;

	[vert]
	[frag]
	
	ENDCG
}
  • 如果着色器需要自定义函数,写在相应的着色器之前




Fallback

Fallback "name"
或关闭
FallBack Off 
  1. fallback一般是该对象渲染的最低限度,但也有其他用处
  2. fallback是和subshader同级的,不是和pass
  3. 在阴影纹理渲染中,unity要求每个一个用来透射阴影的Pass,而fallback会内置它,所以在渲染阴影时可以不特地创建一个阴影pass而直接选择fallback代替



特殊结构

CGINCLUDE结构

Subshader
{
    
    
		CGINCLUDE
		#include "UnityCG.cginc"
		
        【声明的property】
        
		【数据结构】

        【vert1】
        【vert2】

    	【frag1】
    	【frag2】
    	
		ENDCG
	
	
	
        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex 【vert1】
            #pragma fragment 【frag2】
            ENDCG
        }
 }
  • CGINCLUDE中可以写多个着色器,并且不需要提前声明

  • 这个东西存在的意义:减少重复编写,使结构简单
    (本质上是把include里面的代码复制到每一条Pass,和引用头文件相同)

  • 可以这么理解:将顶点/片元着色器视作大型的function,从Pass中抽象出来,写在CGINCLUDE里,之后的多个Pass需要同样的着色器时,只需要引用着色器就好了






猜你喜欢

转载自blog.csdn.net/dogman_/article/details/129593031