Unity Shader模型描边效果

描边效果

关于描边效果有很多种,单顶点Shader比较常见了就有三种,分别是视角空间法线外拓,裁剪空间法线外拓,以及模型空间法线外拓,这里只详细介绍一种性能相较最好的一种描边效果,模型法线外拓描边效果

描边原理:

通过两个Pass通道,先渲染模型的背面,可以绘制偏大一些,然后在进行正常的模型绘制,这样正常的模型就会覆盖在事先画好的背面颜色上,通过调整渲染的背面图形大小,来实现描边的粗细。

下图为效果图:
在这里插入图片描述
1.Cull Front 剔除模型正面

至于为什么只渲染背面,不对正面进行渲染,下面两张图可以给出最好的解释。

下图是不渲染正面,只渲染背面的效果。

可以看到当有另一个模型穿插进去的时候,该模型属于正常状态。

在这里插入图片描述
2.下图是正反两面都渲染的的效果。

可以看到,当有另一个模型穿插进去的时候,该模型的描边,就暴露的出来,这显然是不正确的,所以为了避免不必要的问题, 我们需要在描边的一开始就正确的使用渲染方式 Cull Front 剔除正面 。
在这里插入图片描述
核心算法:

      //物体顶点法线外拓
      v.vertex.xyz+=normalize(v.normal)*_Outline/10;
;

附上源码:
Shader脚本 漫反射+描边

Shader "Unlit/ModelOutLine"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Diffuse("Color",Color) =(1,1,1,1)
        _OutLineColor("OutlineColor",Color)=(1,1,1,1)
        _Outline("Outline",Range(0,1))=1
    }
    SubShader
    {
        Tags {"Queue"= "Geometry+1000" "RenderType"="Opaque" }
        Pass
        {
           //不渲染正面 防止模型穿插导致 描边暴露
            Cull Front 

            CGPROGRAM
            #pragma vertex vert 
            #pragma fragment frag 
            #include "UnityCG.cginc"

            float4 _OutLineColor;
            float _Outline;
            
            struct v2f
            {
                float4 vertex:SV_POSITION;
            };

            v2f vert(appdata_base v)
            {
                //物体顶点法线外拓
                v.vertex.xyz+=normalize(v.normal)*_Outline/10;
                
                v2f o;
                o.vertex=UnityObjectToClipPos(v.vertex);
                return o;
            };

            fixed4  frag(v2f i):SV_TARGET
            {
                return fixed4(_OutLineColor);
            };

            ENDCG
        }

        Pass
        {
            Tags { "LightModel" = "ForwardBase" }
            CGPROGRAM 
            #pragma vertex vert
            #pragma fragment frag 
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _Diffuse;

            struct v2f
            {
                float4 vertex:SV_POSITION;
                float2 uv:TEXCOORD0;
                float3 worldLightNormal:TEXCOORD1;
                float3 worldNormal:TEXCOORD2;


            };

            v2f vert(appdata_base v)
            {
                v2f o;
                o.vertex=UnityObjectToClipPos(v.vertex);
                o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
                float3 worldPos=mul(unity_ObjectToWorld,v.vertex);
                o.worldLightNormal=UnityWorldSpaceLightDir(worldPos);
                o.worldNormal=UnityObjectToWorldNormal(v.normal);
                return o;
            };

            fixed4 frag(v2f i):SV_TARGET
            {
                float3 worldNormalDir=normalize(i.worldNormal);
                float3 WorldLightDir=normalize(i.worldLightNormal);

                float3 texColor=tex2D(_MainTex,i.uv);

                float ambient=UNITY_LIGHTMODEL_AMBIENT.rgb*texColor.rgb;

                float3 diffuse=_LightColor0.rgb*_Diffuse.rgb*texColor.rgb*(dot(worldNormalDir,WorldLightDir)*0.5+0.5);
                float3 color=diffuse+ambient;
                
                return fixed4(color,1);
            };

            ENDCG

        }
        
    }
    Fallback "Diffuse"
}

下面列出三种顶点着色器描边方式:

物体空间法线外拓 性能最好

 			v2f vert(appdata_base v)
            {
                //物体顶点法线外拓
                v.vertex.xyz+=normalize(v.normal)*_Outline/10;
                v2f o;
                o.vertex=UnityObjectToClipPos(v.vertex);
                return o;
            };

视角空间法线外拓

			v2f vert(appdata_base v)
            {
                //视角空间法线外拓
				float4 pos = mul(UNITY_MATRIX_V, mul(unity_ObjectToWorld, v.vertex));
				float3 normal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV,v.normal));
				pos = pos + float4(normal,0) * _Outline;
				o.vertex =  mul(UNITY_MATRIX_P, pos);
				o.vertex=UnityObjectToClipPos(v.vertex);
                return o;
            };

裁剪空间法线外拓

			v2f vert(appdata_base v)
            {
               //裁剪空间法线外拓
				o.vertex = UnityObjectToClipPos(v.vertex);
				float3 normal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV,v.normal));
				float2 viewNoraml = TransformViewToProjection(normal.xy);
				o.vertex.xy += viewNoraml * _Outline;
				return o;
            };
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: Unity3D是一款非常流行的游戏开发引擎,它提供了丰富的功能和工具,使开发人员能够轻松创建各种类型的游戏。其中一个强大的功能就是模型描边shader,它可以增强游戏中的视觉效果模型描边shader是一种特殊的着色器程序,用于给游戏中的3D模型添加轮廓线。通过描边shader,我们可以让模型的边缘线条更加清晰、醒目,让物体在场景中更加凸显出来。 使用Unity3D的模型描边shader非常方便。首先,我们需要将描边shader应用于相应的质上。然后,通过调整一些参数,如描边宽度、颜色等,可以实现不同的效果。在游戏运行时,模型的边缘线条就会被自动描绘出来,使得物体在场景中更加鲜明。 这个功能对于游戏开发人员来说非常实用。通过使用模型描边shader,我们可以增强游戏中物体的可视性,使它们在复杂的环境中更容易被玩家注意到。而且,模型描边shader还可以用于创建一些特殊效果,如描边发光等,让游戏更加生动有趣。 总的来说,Unity3D的模型描边shader是一个非常方便实用的功能。它提供了丰富的定制选项,使开发人员能够轻松地改善游戏的视觉效果。无论是用于增强物体的可视性,还是为游戏添加特殊效果模型描边shader都是一个非常有用的工具,可以使游戏更加出色。 ### 回答2: Unity3D模型描边Shader是一种非常方便实用且强大的技术。该Shader能够为模型的边缘添加一个特殊的描边效果,从而使模型在视觉上更加突出和立体。 使用Unity3D模型描边Shader非常方便。开发者只需将该Shader应用于目标模型质中,然后调整描边效果的参数即可。这些参数包括描边的颜色、宽度、锐度等。通过简单的参数调整,开发者可以获得不同效果描边效果。 此外,Unity3D模型描边Shader还具有强大的功能。开发者可以根据需要自定义描边的样式,如添加渐变效果、使用图片纹理等。这样,描边效果不再局限于简单的线条,而是可以根据需求进行更加丰富多样的设计。 使用Unity3D模型描边Shader可以带来许多好处。首先,它能够增强模型的可视性,使其在游戏或应用中更加突出。其次,描边效果能够帮助玩家或用户更好地理解模型的形状和结构。再次,通过调整描边的参数,开发者可以在远近不同的场景中实现不同的效果,提升用户体验。 总之,Unity3D模型描边Shader是一种非常方便实用且强大的技术。它不仅能够为模型增加视觉效果,还能够提升用户体验,使游戏或应用的视觉呈现更加出色和吸引人。 ### 回答3: Unity3D模型描边Shader是一种非常方便实用且强大的功能。这个Shader可以在模型的边缘添加一条描边效果,使得模型在场景中更加突出和鲜明。 使用Unity3D模型描边Shader非常简单。首先,我们需要在Unity中创建一个质,并将该质的Shader类型设置为描边Shader。接下来,我们可以调整描边的颜色、宽度和透明度等属性,以满足我们的需求。 当我们将这个质应用到模型上时,模型的边缘将自动显示出描边效果。不仅如此,Unity还提供了一些额外的功能,如控制描边的深度和三维感以及添加高光效果等。 使用Unity3D模型描边Shader的好处不仅仅是增加模型的视觉效果,它还可以提高游戏的性能。相较于其他方法,使用Shader进行描边可以在不增加更多几何体或复制模型的情况下实现,从而减少显卡的负载。 此外,Unity3D模型描边Shader还可以很容易地与其他特效和Shader进行结合。我们可以通过修改Shader代码来实现更多的效果,如闪烁、动态描边和不同颜色的描边等。这使得我们可以根据具体的游戏需求来定制和优化描边效果。 综上所述,Unity3D模型描边Shader是一项非常方便实用且强大的功能。它可以轻松地为模型添加描边效果,提高游戏的视觉效果和性能。无论是开发者还是玩家,都可以从中受益并创造出更加出色的游戏作品。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铸梦xy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值