Shader "Reference/SurfaceShaderExplicae"
{
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
[Space][Header(Test Properties)]_Output("顶点外扩",Range(0,1)) = 0.1
[IntRange]_Tess("曲面细分",Range(1,32)) = 4
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
//[在CGPROGRAM 使用pragma surface 开启surface着色器, 编译后会生成相应Pass,所以不手写 "Pass" ] [如需增加手写Pass 规制同顶点片元]
CGPROGRAM
//[启用surface语法]
//#pragma [surface] [surf函数] [着色模式] [其它参数...]
#pragma surface surf Standard vertex:myvert addshadow tessellate:tessFixed
//Unity 内置着色模式 在相关cginc中 加前辍 Lighting 的函数 //前辍为函数格式必需,使用不需要加
//[Standard] 基于物体金属工作流 inout使用SurfaceOutputStandardSpecular //UnityPBSLighting.cginc
//[StandardSpecular] 基于物体高光工作流 inout使用SurfaceOutputStandardSpecular
//[Lambert] 简单漫反射 n * l inout使用SurfaceOutput //Lighting.cginc
//[BlinnPhong] 漫反射加高光n * l + n * (l + v) inout使用SurfaceOutput
//[可用自定函数]
//[vertex:VertexFunction] 自定义顶点修改函数
//[finalcolor:ColorFunction] 自定义最终颜色修改函数
//[finalgbuffer:ColorFunction] 更改 G 缓冲区内容的自定义延迟路径
//[finalprepass:ColorFunction]自定义预通道基本路径。
//[附加参数]
//[alpha]透明开启:auto :fade 简单光照使用 alpha:premul 物理光照使用
//[alpha:blend] 启用 Alpha 混合
//[alphatest:变量名] 透明剪切
//[keepalpha] 写入Alpha为1
//[decal:add] 附加帖花着色器
//[decal:blend]半透明贴花
//[addshadow] 生成阴影投射物通道。常用于自定义的顶点修改后产生阴影
//[fullforwardshadows] 为所有光源生成阴影,默认为单个主光
//[tessellate:TessFunction] DX11 GPU 曲面细分 有多种方式,具体参考帮助
//[interpolateview][halfasview] 在顶点中计算半角向量
//[softvegetation] 仅在开启 Soft Vegetation 时才渲染 应该是用于植物的
//[dualforward]双光照帖图[dithercrossfade]使表面着色器支持抖动效果
//[代码生成选项]
//[exclude_path:deferred] forward prepass 不生成指定的pass代码
//[noforwardadd] 禁用前向渲染附加通道
//[nometa] 禁用meta pass,该pass用于烘焙光照和动态全局光照
//[noshadow] 禁用所有阴影接受
//[noambient] 禁用环境光照或光照探针。
//[novertexlights] 在forward渲染禁用光照探针或顶点光源
//[nolppv] 禁用光照探针代理
//[nolightmap][nodynlightmap][nodirlightmap][noshadowmask] 禁用光照帖图,禁用动态全局光照,禁用光照方向帖图,禁用阴影遮罩
//[nofog] 关闭雾
#pragma target 4.6
//[输入到片元结构体] 同顶点片元着色器的 struct v2f ,surface 默认顶点输出为 appdata_full
struct Input
{
//unity内部实现变量
float2 uv_MainTex; //uv + 变量名 或 uv2
float4 color :COLOR; //[COLOR]语义输入顶点颜色,变量名随意
//[其它内部可用值]
float3 viewDir; //视图方向
float4 screenPos ; //屏幕空间位置 , 这不适用于GrabPass ,GrabPass 可在这定义 float4 grabUV;//顶点中计算 o.grabUV = ComputeGrabScreenPos(o.pos) pos为裁剪空间; 最后使用 tex2Dproj(_GrabPassTextureName,i.grabUV);
float3 worldPos ; //世界空间
float3 worldRefl ;INTERNAL_DATA //世界反射 有法线帖图时在surf中使用 WorldReflectionVector (IN, o.Normal) 得到最终值
float3 worldNormal;INTERNAL_DATA//世界法线 有法线帖图时在surf中使用 WorldNormalVector (IN, o.Normal) 得到最终值
//[其它自定义需要自己在vertex函数中实现]
float3 ccolor;
};
/*
[输出到光照结构体] surface 在 surf 中不计算光照,而是输出对应数据到Lighting中统一计算,必需用以下结构
struct SurfaceOutput [用于简单光照] Lighting.cginc
{
fixed3 Albedo; // 漫射颜色
fixed3 Normal; // 切线空间法线(如果已写入)
half Specular; // 0-1 范围内的镜面反射能力 --
fixed Gloss; // 镜面反射强度 --
fixed Alpha; // 透明度 Alpha
fixed3 Emission;
};
struct SurfaceOutputStandard [用于基于物理] UnityPBSLighting.cginc
{
fixed3 Albedo; // 漫射颜色
fixed3 Normal; // 切线空间法线(如果已写入)
half Metallic; // 0=非金属,1=金属()
half Smoothness; // 0=粗糙,1=平滑
half Occlusion; // 遮蔽(默认为 1)
fixed Alpha; // 透明度 Alpha
half3 Emission;
};
struct SurfaceOutputStandardSpecular
{
fixed3 Albedo; // 漫射颜色
fixed3 Normal; // 切线空间法线(如果已写入)
fixed3 Specular; // 镜面反射颜色()
half Smoothness; // 0=粗糙,1=平滑
half Occlusion; // 遮蔽(默认为 1)
fixed Alpha; // 透明度 Alpha
half3 Emission;
};
*/
//[同顶点片元,自定义变量需要声明]
sampler2D _MainTex;
half _Glossiness;
half _Metallic;
fixed4 _Color;
half _Output;
//[测试曲面细分]
half _Tess;
float4 tessFixed(){return _Tess;}
//[GPU Instancing 主要用于草树等只有少数数值不同的数量较大的材质] 也可用于顶点片元
// #pragma instancing_options assumeuniformscaling 如果模型不带缩放可以用这个
UNITY_INSTANCING_BUFFER_START(Props)
//[具体会改变的值]//例如场景中很多这个使用这个着色器的材质,只有_Color参数不同
//UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
UNITY_INSTANCING_BUFFER_END(Props)
//[自定义光照模型格式] UnityGI 定义在 UnityLightingCommon.cginc 包含灯光颜色,方向,间接diffuse 和 specular
//half4 Lighting<Name> (SSurfaceOutput s, half3 lightDir, half atten); 简单[Lambert]可以使用这个。
//half4 Lighting<Name> (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) 简单[BlinnPhong]可以使用这个。
//half4 Lighting<Name> (SurfaceOutput s, UnityGI gi); 在_不依赖于_视图方向的光照模型的前向渲染路径中使用此函数。
//half4 Lighting<Name> (SurfaceOutput s, half3 viewDir, UnityGI gi); 在_依赖于_视图方向的光照模型的前向渲染路径中使用此函数。
//half4 Lighting<Name>_Deferred (SurfaceOutput s, UnityGI gi, out half4 outDiffuseOcclusion, out half4 outSpecSmoothness, out half4 outNormal){} 在延迟光照路径中使用此函数。
//half4 Lighting<Name>_PrePass (SurfaceOutput s, half4 light);在光照预通道(旧版延迟)光照路径中使用此函数。
//half4 Lighting<Name>_GI (SurfaceOutput s, UnityGIInput data, inout UnityGI gi); 使用光照贴图数据和探针的解码
//[简单Lambert示例]
half4 LightingWrapLambert (SurfaceOutput s, half3 lightDir, half atten) {
half NdotL = dot (s.Normal, lightDir);
half diff = NdotL * 0.5 + 0.5;
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten);
c.a = s.Alpha;
return c;
}
//[自定义顶点函数格式]
void myvert (inout appdata_full v/*, out Input o*/) {
//UNITY_INITIALIZE_OUTPUT(Input,o); //[UNITY_INITIALIZE_OUTPUT] surface使用它初始化结构体变量
v.vertex.xyz += v.normal * _Output; //可以直接对顶点操作 其它类似wroldPos等信息程序会自动计算
}
//[自定义finalcolor格式, 输出到 SV_Target 前的操作 ]
void mycolor (Input IN, SurfaceOutputStandard o, inout fixed4 color)
{
}
//[surf 主要进行表面属性赋值 , 输出 o 到 Lighting 计算光照]
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
参考:Unity Shader surface 常用语句大全
标签:自定义,half4,Shader,surface,Unity,Lighting,half,光照,SurfaceOutput