1.模型自身坐标位置与颜色的映射
Shader "Custom/RGBCube" {
SubShader
{
Pass {
CGPROGRAM
#pragma vertex vert //顶点着色器入口函数声明
#pragma fragment frag // 片段着色器入口函数声明
//顶点输出结构体
struct vertexOutput {
//声明结构体的成员pos,类型为float类型的4元向量,语义为SV_POSITION,col同理;
float4 pos : SV_POSITION;
float4 col : TEXCOORD0;
};
//顶点着色器入口函数vert,与pragma第一条声明匹配,返回类型为刚刚定义的顶点输出结构体
vertexOutput vert(float4 vertexPos : POSITION)
{
vertexOutput output; //这里不需要struct关键字
//顶点着色器将数据写入输出结构体中。
output.pos = mul(UNITY_MATRIX_MVP, vertexPos);
//mul是顶点变换函数,UNITY_MATRIX_MVP是unity的内建矩阵,vertexPos是这个函数的形参
//此行代码的作用为将形参vertexPos(本例即Cube对象的顶点向量)按照unity的内建矩阵进行顶点变换
output.col = vertexPos + float4(0.5, 0.5, 0.5, 0.0);
//这行代码是实现RGB立方体的关键
//因为我们的直角坐标系原点没有在顶点上而是在cube的几何中心,故其值域为{-0,5,-0.5,-0.5,1}至{0.5,0.5,0.5,1}
//但是这里接受的类型为float4,可见第四元应该是无意义的常数1
//意思是vertexPos的值域为{-0.5,-0.5,-0.5,1}至{0.5,0.5,0.5,1}
//而对这个值域进行+{0.5,0.5,0.5,0}的矢量相加才能得到RGB (A恒定为1)的所有颜色区间
return output;
//将输出结构体返回,进入下一个环节(简单理解为给片段着色器)
//ps:更细致的环节有顶点变换-->顶点着色-->几何元的构建-->光栅化几何元
//-->片段着色-->略
}
//片段着色器入口函数frag,与pragma第二条声明匹配,返回类型为float4语义为COLOR,
//这里除了颜色没有其他的输出,所以没有输出结构体
float4 frag(vertexOutput input) : COLOR
//此函数的形参类型为顶点着色器的输出结构体,没有语义
//原因就在于片段着色器位于顶点着色器的下一个环节,参数按照这个顺序传递
{
//由于col属性已经在顶点着色器中计算,直接返回进入下一环节
//下一环节是什么这里不探讨了
return input.col;
}
ENDCG
}
}
//如果以上SubShader渲染失败则回滚采用Diffuse
FallBack "Diffuse"
}
2.模型纹理坐标与颜色的映射
Shader "Custom/RGBCube" {
SubShader
{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vertexOutput {
float4 pos : SV_POSITION;
float4 col : TEXCOORD0;
};
vertexOutput vert(appdata_full input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.col = input.texcoord;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
return input.col;
}
ENDCG}
}
//如果以上SubShader渲染失败则回滚采用Diffuse
FallBack "Diffuse"
}
3.假彩色效果
Shader "Custom/RGBCube" {
SubShader
{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vertexOutput {
float4 pos : SV_POSITION;
float4 col : TEXCOORD0;
};
vertexOutput vert(appdata_full input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.col = float4(0.0, input.texcoord.y, 0.0, 1.0);
return output;
}
float4 frag(vertexOutput input) : COLOR
{
return input.col;
}
ENDCG}
}
//如果以上SubShader渲染失败则回滚采用Diffuse
FallBack "Diffuse"
}
4.法向量与颜色的映射
Shader "Custom/RGBCube" {
SubShader
{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vertexOutput {
float4 pos : SV_POSITION;
float4 col : TEXCOORD0;
};
vertexOutput vert(appdata_full input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.col = float4((input.normal + float3(1.0, 1.0, 1.0)) / 2.0, 1.0);
return output;
}
float4 frag(vertexOutput input) : COLOR
{
return input.col;
}
ENDCG}
}
//如果以上SubShader渲染失败则回滚采用Diffuse
FallBack "Diffuse"
}
5.裁剪效果
Shader "Custom/RGBCube" {
SubShader
{
Pass{
Cull Off // 关掉裁剪模式,作用后面再说
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vertexOutput {
float4 pos : SV_POSITION;
//由顶点着色器输出mesh信息中的纹理坐标,这个坐标是以对象为坐标系的
float4 posInObjectCoords : TEXCOORD0;
};
vertexOutput vert(appdata_full input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
//直接把texcoord传递给片段着色器
output.posInObjectCoords = input.texcoord;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
//当坐标的y值大于0.5的时候擦除片段
if (input.posInObjectCoords.y > 0.5)
{
discard;
}
//其余部分仍然按y值大小生成经度绿色球
return float4(0.0, input.posInObjectCoords.y , 0.0, 1.0);
}
ENDCG
}
}
//如果以上SubShader渲染失败则回滚采用Diffuse
FallBack "Diffuse"
}
6.内部裁剪与外部裁剪
Shader "Custom/RGBCube" {
SubShader
{
Pass{
Cull front // 外部剪裁,那么这个通道可以理解为是给篮球的内表面上色
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vertexOutput {
float4 pos : SV_POSITION;
//由顶点着色器输出mesh信息中的纹理坐标,这个坐标是以对象为坐标系的
float4 posInObjectCoords : TEXCOORD0;
};
vertexOutput vert(appdata_full input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
//直接把texcoord传递给片段着色器
output.posInObjectCoords = input.texcoord;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
//当坐标的y值大于0.5的时候擦除片段
if (input.posInObjectCoords.y > 0.5)
{
discard;
}
//其余部分仍然按y值大小生成经度绿色球
return float4(0.0, input.posInObjectCoords.y , 0.0, 1.0);
}
ENDCG
}
Pass{
Cull back //内部剪裁,那么这个通道可以理解为是给篮球的外表面上色
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vertexOutput {
float4 pos : SV_POSITION;
//由顶点着色器输出mesh信息中的纹理坐标,这个坐标是以对象为坐标系的
float4 posInObjectCoords : TEXCOORD0;
};
vertexOutput vert(appdata_full input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
//直接把texcoord传递给片段着色器
output.posInObjectCoords = input.texcoord;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
//当坐标的y值大于0.5的时候擦除片段
if (input.posInObjectCoords.y > 0.5)
{
discard;
}
//其余部分仍然按y值大小生成经度红色球
return float4(input.posInObjectCoords.y, 0.0 , 0.0, 1.0);
}
ENDCG
}
}
//如果以上SubShader渲染失败则回滚采用Diffuse
FallBack "Diffuse"
}
7.圆角矩形
Shader "Custom/RoundRect" {
Properties {
//两种内容模式,图片模式
_MainTex ("Base (RGB)", 2D) = "white" {}
//纯色模式
//_MainColor ("Color", COLOR) = (1,1,1,1)
//圆角半径,默认为0.1
_Radius("Radius",float) = 0.1
}
SubShader {
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
//获取3个属性 并传值到CG代码段
sampler2D _MainTex;
float _Radius;
float4 _MainColor;
struct vertexOutput {
float4 pos : SV_POSITION;
//由顶点着色器输出mesh信息中的纹理坐标,这个坐标是以对象为坐标系的
float4 posInObjectCoords : TEXCOORD0;
};
vertexOutput vert(appdata_full input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
//直接把texcoord传递给片段着色器
output.posInObjectCoords = input.texcoord;
return output;
}
//片段着色器入口函数
float4 frag(vertexOutput input) : COLOR
{
float4 c = tex2D(_MainTex, input.posInObjectCoords);//将图片信息按坐标转换成颜色
//float4 c=_MainColor; //纯色
//x,y两个变元,区间均为[0,1]
float x = input.posInObjectCoords.x;
float y = input.posInObjectCoords.y;
if (x < _Radius && y < _Radius)
{
if (pow((x - _Radius), 2) + pow(y - _Radius, 2) > pow(_Radius, 2))
discard;
}
else if (x < _Radius && y > (1 - _Radius))
{
if (pow((x - _Radius), 2) + pow(y - (1 - _Radius), 2) > pow(_Radius, 2))
discard;
}
else if (x > (1 - _Radius) && y < _Radius)
{
if (pow((x - (1 - _Radius)), 2) + pow(y - _Radius, 2) > pow(_Radius, 2))
discard;
}
else if (x > (1 - _Radius) && y > (1 - _Radius))
{
if (pow((x - (1 - _Radius)), 2) + pow(y - (1 - _Radius), 2) > pow(_Radius, 2))
discard;
}
return c;
}
ENDCG
}
}
FallBack "Diffuse"
}
8.漫反射
Shader "Esfog/Diffuse"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Pass
{
Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _LightColor0;
struct VertexOutput
{
float4 pos:SV_POSITION;
float2 uv_MainTex:TEXCOORD0;
float3 normal:TEXCOORD1;
};
VertexOutput vert(appdata_base input)
{
VertexOutput o;
o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
o.uv_MainTex = input.texcoord.xy;
o.normal = normalize(mul(float4(input.normal,0),_World2Object));
return o;
}
float4 frag(VertexOutput input):COLOR
{
float3 normalDir = normalize(input.normal);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 Kd = tex2D(_MainTex,input.uv_MainTex).xyz;
float3 diffuseReflection = Kd * _LightColor0.rgb * max(0,dot(normalDir,lightDir));
return float4(diffuseReflection,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
9.多光源漫反射
Shader "Esfog/Diffuse"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Pass
{
Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _LightColor0;
struct VertexOutput
{
float4 pos:SV_POSITION;
float2 uv_MainTex:TEXCOORD0;
float3 normal:TEXCOORD1;
};
VertexOutput vert(appdata_base input)
{
VertexOutput o;
o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
o.uv_MainTex = input.texcoord.xy;
o.normal = normalize(mul(float4(input.normal,0),_World2Object));
return o;
}
float4 frag(VertexOutput input):COLOR
{
float3 normalDir = normalize(input.normal);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 Kd = tex2D(_MainTex,input.uv_MainTex).xyz;
float3 diffuseReflection = Kd * _LightColor0.rgb * max(0,dot(normalDir,lightDir));
return float4(diffuseReflection,1);
}
ENDCG
}
Pass
{
Tags { "RenderType"="Opaque" "LightMode"="ForwardAdd"}
//此通道的片段着色器输出颜色时帧缓存已经有了颜色,所以需要混合
//混合模式为1比1
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _LightColor0;
struct VertexOutput
{
float4 pos:SV_POSITION;
float2 uv_MainTex:TEXCOORD0;
float3 normal:TEXCOORD1;
};
VertexOutput vert(appdata_base input)
{
VertexOutput o;
o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
o.uv_MainTex = input.texcoord.xy;
o.normal = normalize(mul(float4(input.normal,0),_World2Object));
return o;
}
float4 frag(VertexOutput input):COLOR
{
float3 normalDir = normalize(input.normal);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 Kd = tex2D(_MainTex,input.uv_MainTex).xyz;
float3 diffuseReflection = Kd * _LightColor0.rgb * max(0,dot(normalDir,lightDir));
return float4(diffuseReflection,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
10.逐顶点的镜面反射