博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单的勾边算法
阅读量:7021 次
发布时间:2019-06-28

本文共 4572 字,大约阅读时间需要 15 分钟。

   下述代码列出了几种勾边的实现思路,实际游戏中在屏幕空间扩展法线的方案,基本上就够用了:

Shader "Shader/Outline" {    Properties    {        _MainTex("MainTex", 2D) = "white" {}        _Color("Color", Color) = (1, 1, 1, 1)        _OutLine("OutLine", Float) = 0.1        _OutLineColor("OutLineColor", Color) = (1, 1, 1, 1)        _Factor("Factor", Range(0, 1)) = 0.5    }    SubShader     {        Tags { "Queue" = "Opaque" }        Pass        {            Cull Front            ZWrite on            CGPROGRAM                        #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"                        struct v2f            {                float4 pos : SV_POSITION;                float3 color : COLOR0;                float2 uv : TEXCOORD0;            };                        sampler2D _MainTex;            float4 _MainTex_ST;            float4 _Color;            float _OutLine;            float4 _OutLineColor;            float _Factor;            v2f vert(appdata_base v)            {                /* // 沿法线方向扩展(问题:近粗远细 深度覆盖 发现分离)                v2f o;                v.vertex.xyz += v.normal * _OutLine;                o.pos = mul (UNITY_MATRIX_MVP, v.vertex);                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);                return o;                */                /* // 在视空间挤出(问题:法线分离问题)                v2f o;                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);                float3 norm = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);                float2 offset = TransformViewToProjection(norm.xy);                o.pos.xy += offset * o.pos.z * _OutLine;                return o;                */                /*                // 使用顶点位置作为挤出方向(问题:等于从几何中心缩放,不一致)                v2f o;                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);                float3 dir = normalize(v.vertex.xyz);                dir = mul((float3x3)UNITY_MATRIX_IT_MV, dir);                float2 offset = TransformViewToProjection(dir.xy);                o.pos.xy += offset * o.pos.z * _OutLine;                return o;                */                // 在发现和顶点方向间插值                v2f o;                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);                float3 dir = normalize(v.vertex.xyz);                float3 dir2 = v.normal;                dir = lerp(dir2, dir, _Factor);                dir = mul((float3x3)UNITY_MATRIX_IT_MV, dir);                float2 offset = TransformViewToProjection(dir.xy);                o.pos.xy += offset * o.pos.z * _OutLine;                return o;            }            half4 frag(v2f i) : COLOR            {                return _OutLineColor;            }                        ENDCG        }  Pass {...}}

  通过offset操作,来实现描边的效果:

Shader "Shader/OutLine_Offset" {    Properties    {        _MainTex("MainTex", 2D) = "white" {}        _Color("Color", Color) = (1, 1, 1, 1)        _OutLine("OutLine", Float) = 0.1    }    SubShader     {        Tags { "Queue" = "Opaque" }        Pass        {            Cull Front            Offset -1,-1            CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"            struct v2f            {                float4 pos : SV_POSITION;            };            float4 _OutLine;            v2f vert(appdata_base v)            {                v2f o;                o.pos = mul (UNITY_MATRIX_MVP, v.vertex);                return o;            }            half4 frag(v2f i) : COLOR            {                return _OutLine;            }            ENDCG        }        Pass        {            Offset 2,-1            CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"            struct v2f            {                float4 pos : SV_POSITION;                float3 color : COLOR0;                float2 uv : TEXCOORD0;            };            sampler2D _MainTex;            float4 _MainTex_ST;            float4 _Color;            v2f vert(appdata_base v)            {                v2f o;                o.pos = mul (UNITY_MATRIX_MVP, v.vertex);                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);                return o;            }            half4 frag(v2f i) : COLOR            {                float4 mainColor = tex2D(_MainTex, i.uv);                float4 finalColor = mainColor * _Color;                return finalColor;            }            ENDCG        }    }     FallBack "VertexLit"}

  这个方法不是太实用,只是一种实现思路。

  使用的方案是UnityPro提供的AssetsPackage中现成的ToonShader。

  http://wiki.unity3d.com/index.php/Silhouette-Outlined_Diffuse

转载地址:http://babxl.baihongyu.com/

你可能感兴趣的文章
网络 tcp 和 udp
查看>>
正则表达式
查看>>
人工智能强势来袭,我们普通人怎么做?清华教授给你支招!
查看>>
python爬虫爬取各大平台女主播图片
查看>>
企业级 SpringCloud 教程 (四) 断路器(Hystrix)
查看>>
阿里云MVP:开发者的超能力,用技术创造更好世界
查看>>
Spring Cloud Config-快速开始
查看>>
Web功能测试的4种类型
查看>>
HashMap的工作原理
查看>>
Linux下自动备份Oracle数据库
查看>>
[git] warning: LF will be replaced by CRLF
查看>>
部署VCAS 6.5时,卡在80%安装RPM的问题解决办法
查看>>
docker简洁用法
查看>>
Linux-其他命令--其它命令:mtools、man、unendcode、uudecode
查看>>
SCCM2012 安装主站点连接到管理中心报错“试图执行未经授权的操作”
查看>>
2012 新的征程开始
查看>>
我的友情链接
查看>>
使用Strongswan搭建IPSec/IKEv2 ***和window、android、ios、mac如何使用***
查看>>
DBVERIFY 工具的使用
查看>>
JQuery正则表达式
查看>>