You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
4.6 KiB

2 years ago
//--------------------------- 【描边】 - 法线扩张---------------------
//create by 长生但酒狂
Shader "lcl/shader3D/outLine3D_swell"
{
//---------------------------【属性】---------------------------
Properties
{
// 主纹理
_MainTex("Texture", 2D) = "white" {}
// 主颜色
_Color("Color",Color) = (1,1,1,1)
// 描边强度
_power("power",Range(0,0.2)) = 0.05
// 描边颜色
_lineColor("lineColor",Color) = (1,1,1,1)
}
// ------------------------【CG代码】---------------------------
CGINCLUDE
#include "UnityCG.cginc"
#include "Lighting.cginc"
//顶点着色器输入结构体
struct appdata
{
float4 vertex : POSITION;//顶点坐标
float2 uv : TEXCOORD0;//纹理坐标
float3 normal:NORMAL;//法线
};
//顶点着色器输出结构体
struct v2f
{
float4 vertex : SV_POSITION;//像素坐标
float2 uv : TEXCOORD0;//纹理坐标
float3 worldNormalDir:COLOR0;//世界空间里的法线方向
float3 worldPos:COLOR1;//世界空间里的坐标
};
// ------------------------【变量声明】---------------------------
//纹理
sampler2D _MainTex;
//内置的变量,纹理中的单像素尺寸
float4 _MainTex_TexelSize;
//主颜色
float4 _Color;
//描边强度
float _power;
//描边颜色
float4 _lineColor;
// ------------------------【背面-顶点着色器】---------------------------
v2f vert_back(appdata v)
{
v2f o;
//法线方向
v.normal = normalize(v.normal);
//顶点沿着法线方向扩张
v.vertex.xyz += v.normal * _power;
//由模型空间坐标系转换到裁剪空间
o.vertex = UnityObjectToClipPos(v.vertex);
//输出结果
return o;
}
// ------------------------【背面-片元着色器】---------------------------
fixed4 frag_back(v2f i) : SV_Target
{
//直接输出颜色
return _lineColor;
}
// ------------------------【正面-顶点着色器】---------------------------
v2f vert_front(appdata v)
{
//正常渲染
v2f o;
o.uv = v.uv;
//法线从模型空间坐标系转换到世界坐标系
o.worldNormalDir = mul(v.normal, (float3x3) unity_WorldToObject);
//顶点从模型空间坐标系转换到世界坐标系
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
//归一化
v.normal = normalize(v.normal);
//由模型空间坐标系转换到裁剪空间
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
// ------------------------【正面-片元着色器】---------------------------
fixed4 frag_front(v2f i) : SV_Target
{
//正常渲染
//纹理颜色值
fixed4 col = tex2D(_MainTex, i.uv);
//环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _Color.xyz;
//视角方向
float3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
//法线方向
float3 normaleDir = normalize(i.worldNormalDir);
//光照方向归一化
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
//半兰伯特模型
fixed3 lambert = 0.5 * dot(normaleDir, worldLightDir) + 0.5;
//漫反射
fixed3 diffuse = lambert * _Color.xyz * _LightColor0.xyz + ambient;
//最终结果
fixed3 result = diffuse * col.xyz;
return float4(result,1);
}
ENDCG
// ------------------------【子着色器】---------------------------
SubShader
{
//透明度混合模式
Blend SrcAlpha OneMinusSrcAlpha
//渲染队列
Tags{ "Queue" = "Transparent" }
// ------------------------【背面通道】---------------------------
Pass
{
//剔除正面
Cull Front
//防止背面模型穿透正面模型
//关闭深度写入为了让正面的pass完全覆盖背面同时要把渲染队列改成Transparent此时物体渲染顺序是从后到前的
ZWrite Off
CGPROGRAM
#pragma vertex vert_back
#pragma fragment frag_back
ENDCG
}
// ------------------------【正面通道】---------------------------
Pass
{
//剔除背面
Cull Back
CGPROGRAM
#pragma vertex vert_front
#pragma fragment frag_front
ENDCG
}
}
}