阿诺德给物体加描边_Unity Shader教程之 物体描边效果的实现

ObjectOutline 脚本具体内容如下:

Shader "Custom/ObjectOutline" {

Properties{

_Diffuse("Diffuse", Color) = (1,1,1,1)

_OutlineCol("OutlineCol", Color) = (1,0,0,1)

_OutlineFactor("OutlineFactor", Range(0,1)) = 0.1

_MainTex("Base 2D", 2D) = "white"{}

}

//子着色器

SubShader

{

//描边使用两个Pass,第一个pass沿法线挤出一点,只输出描边的颜色

Pass

{

//剔除正面,只渲染背面,对于大多数模型适用,不过如果需要背面的,就有问题了

Cull Front

CGPROGRAM

//使用vert函数和frag函数

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

fixed4 _OutlineCol;

float _OutlineFactor;

struct v2f

{

float4 pos : SV_POSITION;

};

v2f vert(appdata_full v)

{

v2f o;

//在vertex阶段,每个顶点按照法线的方向偏移一部分,不过这种会造成近大远小的透视问题

//v.vertex.xyz += v.normal * _OutlineFactor;

o.pos = UnityObjectToClipPos(v.vertex);

//将法线方向转换到视空间

float3 vnormal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);

//将视空间法线xy坐标转化到投影空间,只有xy需要,z深度不需要了

float2 offset = TransformViewToProjection(vnormal.xy);

//在最终投影阶段输出进行偏移操作

o.pos.xy += offset * _OutlineFactor;

return o;

}

fixed4 frag(v2f i) : SV_Target

{

//这个Pass直接输出描边颜色

return _OutlineCol;

}

ENDCG

}

//正常着色的Pass

Pass

{

CGPROGRAM

//使用vert函数和frag函数

#pragma vertex vert

#pragma fragment frag

//引入头文件

#include "Lighting.cginc"

//定义Properties中的变量

fixed4 _Diffuse;

sampler2D _MainTex;

//使用了TRANSFROM_TEX宏就需要定义XXX_ST

float4 _MainTex_ST;

//定义结构体:vertex shader阶段输出的内容

struct v2f

{                  float4 pos : SV_POSITION;

float3 worldNormal : TEXCOORD0;

float2 uv : TEXCOORD1;

};

//定义顶点shader,参数直接使用appdata_base(包含position, noramal, texcoord)

v2f vert(appdata_base v)

{

v2f o;

o.pos = UnityObjectToClipPos(v.vertex);

//通过TRANSFORM_TEX宏转化纹理坐标,主要处理了Offset和Tiling的改变,默认时等同于o.uv = v.texcoord.xy;

o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);

o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);

return o;

}

//定义片元shader

fixed4 frag(v2f i) : SV_Target

{

//unity自身的diffuse也是带了环境光,这里我们也增加一下环境光

fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _Diffuse.xyz;

//归一化法线,即使在vert归一化也不行,从vert到frag阶段有差值处理,传入的法线方向并不是vertex shader直接传出的

fixed3 worldNormal = normalize(i.worldNormal);

//把光照方向归一化

fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);

//根据半兰伯特模型计算像素的光照信息

fixed3 lambert = 0.5 * dot(worldNormal, worldLightDir) + 0.5;

//最终输出颜色为lambert光强*材质diffuse颜色*光颜色

fixed3 diffuse = lambert * _Diffuse.xyz * _LightColor0.xyz + ambient;

//进行纹理采样

fixed4 color = tex2D(_MainTex, i.uv);

color.rgb = color.rgb* diffuse;

return fixed4(color);

}

ENDCG

}

}

//前面的Shader失效的话,使用默认的Diffuse

FallBack "Diffuse"

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值