【实现100个unity特效之7】shader实现3D物品闪光和描边效果

最终效果

在这里插入图片描述

shader代码

Shader "SurvivalTemplatePro/Interactable"
{
	Properties
	{
		_ASEOutlineColor( "Outline Color", Color ) = (0.8962264,0.7633126,0.2832412,0)
		_ASEOutlineWidth( "Outline Width", Float ) = 0.01
		_Cutoff( "Mask Clip Value", Float ) = 0.5
		_Color("Base Color", Color) = (1,1,1,0)
		_MainTex("Base Color Map", 2D) = "white" {}
		_MaskMap("Mask Map", 2D) = "white" {}
		[Normal]_BumpMap("Normal Map", 2D) = "bump" {}
		_LineMap("Line Map", 2D) = "white" {}
		[HDR]_LineColor("Line Color", Color) = (1.991077,1.306363,0.3513666,1)
		_LineAlpha("Line Alpha", Range( 0 , 1)) = 1
		_LineSize("Line Size", Range( 0.1 , 2)) = 1
		_LineSpeed("Line Speed", Range( 0.1 , 2)) = 1
		[HideInInspector] _texcoord( "", 2D ) = "white" {}
		[HideInInspector] __dirty( "", Int ) = 1
	}

	SubShader
	{
		Tags{ }
		Cull Front
		CGPROGRAM
		#pragma target 3.0
		#pragma surface outlineSurf Outline  keepalpha noshadow noambient novertexlights nolightmap nodynlightmap nodirlightmap nometa noforwardadd vertex:outlineVertexDataFunc 
		
		
		
		
		struct Input {
			half filler;
		};
		float4 _ASEOutlineColor;
		float _ASEOutlineWidth;
		void outlineVertexDataFunc( inout appdata_full v, out Input o )
		{
			UNITY_INITIALIZE_OUTPUT( Input, o );
			v.vertex.xyz += ( v.normal * _ASEOutlineWidth );
		}
		inline half4 LightingOutline( SurfaceOutput s, half3 lightDir, half atten ) { return half4 ( 0,0,0, s.Alpha); }
		void outlineSurf( Input i, inout SurfaceOutput o )
		{
			o.Emission = _ASEOutlineColor.rgb;
			o.Alpha = 1;
		}
		ENDCG
		

		Tags{ "RenderType" = "TransparentCutout"  "Queue" = "Geometry+0" "IsEmissive" = "true"  }
		Cull Back
		CGPROGRAM
		#include "UnityShaderVariables.cginc"
		#pragma target 3.0
		#pragma surface surf Standard keepalpha addshadow fullforwardshadows exclude_path:deferred 
		struct Input
		{
			float2 uv_texcoord;
			float3 worldPos;
		};

		uniform sampler2D _BumpMap;
		uniform float4 _BumpMap_ST;
		uniform float4 _Color;
		uniform sampler2D _MainTex;
		uniform float4 _MainTex_ST;
		uniform float _LineAlpha;
		uniform sampler2D _LineMap;
		uniform float _LineSpeed;
		uniform float _LineSize;
		uniform float4 _LineColor;
		uniform sampler2D _MaskMap;
		uniform float4 _MaskMap_ST;
		uniform float _Cutoff = 0.5;

		void surf( Input i , inout SurfaceOutputStandard o )
		{
			float2 uv_BumpMap = i.uv_texcoord * _BumpMap_ST.xy + _BumpMap_ST.zw;
			float3 tex2DNode2 = UnpackNormal( tex2D( _BumpMap, uv_BumpMap ) );
			float3 NormalMap266 = tex2DNode2;
			o.Normal = NormalMap266;
			float2 uv_MainTex = i.uv_texcoord * _MainTex_ST.xy + _MainTex_ST.zw;
			float4 tex2DNode1 = tex2D( _MainTex, uv_MainTex );
			o.Albedo = ( _Color * tex2DNode1 ).rgb;
			float2 temp_cast_1 = (_LineSpeed).xx;
			float3 ase_vertex3Pos = mul( unity_WorldToObject, float4( i.worldPos , 1 ) );
			float2 temp_cast_2 = (( ase_vertex3Pos.x * _LineSize )).xx;
			float2 panner243 = ( _Time.y * temp_cast_1 + temp_cast_2);
			float4 temp_output_119_0 = ( tex2D( _LineMap, panner243 ) * _LineColor );
			float3 desaturateInitialColor282 = float3( (tex2DNode2).xy ,  0.0 );
			float desaturateDot282 = dot( desaturateInitialColor282, float3( 0.299, 0.587, 0.114 ));
			float3 desaturateVar282 = lerp( desaturateInitialColor282, desaturateDot282.xxx, 1.0 );
			float4 lerpResult248 = lerp( float4( 0,0,0,0 ) , ( float4( 0,0,0,0 ) * temp_output_119_0 ) , float4( saturate( desaturateVar282 ) , 0.0 ));
			float2 uv_MaskMap = i.uv_texcoord * _MaskMap_ST.xy + _MaskMap_ST.zw;
			float4 tex2DNode3 = tex2D( _MaskMap, uv_MaskMap );
			float4 lerpResult278 = lerp( float4( 0,0,0,0 ) , ( lerpResult248 + ( temp_output_119_0 * float4( 0.245283,0.245283,0.245283,0 ) ) ) , tex2DNode3.g);
			float4 Line32 = ( _LineAlpha * lerpResult278 );
			o.Emission = Line32.rgb;
			o.Metallic = tex2DNode3.r;
			o.Smoothness = tex2DNode3.a;
			o.Occlusion = tex2DNode3.g;
			o.Alpha = 1;
			clip( tex2DNode1.a - _Cutoff );
		}

		ENDCG
	}
	Fallback "Diffuse"
}

线状映射图片
在这里插入图片描述
配置,按该shader新增材质
在这里插入图片描述
Outline Width控制描边
Line Speed控制闪光速度
当然,还可以修改对应的颜色

代码控制物品描边显示隐藏

using UnityEngine;

//拾取脚本
public class PickUpController : MonoBehaviour
{
    public float maxDistance = 3f; // 最大检测距离
    public LayerMask layerMask; // 检测层级

    public GameObject uiText; // 显示物品名称的 UI 文本组件

    Transform lastHitInfo;
    void Start()
    {
        uiText.SetActive(false); // 初始状态下 UI 文本组件不可见
    }

    void Update()
    {
        // 从相机屏幕中心向前发射一条射线
        Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));

        RaycastHit hitInfo;
        if (Physics.Raycast(ray, out hitInfo, maxDistance, layerMask))
        {
            lastHitInfo = hitInfo.transform;
            uiText.SetActive(true);

            //设置物品描边
            SetOutline(lastHitInfo, 0.01f);

            //hitInfo.transform.CompareTag("PickUpItem") 需要的话可以再加标签判断
            if (Input.GetKeyDown(KeyCode.E))
            {
                PickUpItem(lastHitInfo);
            }
        }
        else
        {
            uiText.SetActive(false);
            if (lastHitInfo != null) SetOutline(lastHitInfo, 0f);
        }

    }

    // 拾取物体逻辑
    void PickUpItem(Transform item)
    {
        //。。。
    }

    //设置物品描边
    void SetOutline(Transform obj, float width)
    {
        Renderer renderer = obj.GetComponent<Renderer>();
        if (renderer != null)
        {
            Material material = renderer.material;
            material.SetFloat("_ASEOutlineWidth", width);
        }

        foreach (Transform child in obj)
        {
            SetOutline(child, width);
        }
    }
}

效果演示
在这里插入图片描述

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

在这里插入图片描述

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Unity实现描边效果,可以通过编写Shader实现。具体实现方法如下: 1. 首先,在Shader中需要先声明一个描边颜色的变量: ```csharp // 描边颜色 _Color ("Outline Color", Color) = (0,0,0,1) ``` 2. 接着,需要在Shader中将表面进行放大,然后将描边颜色填充到放大后的表面上: ```csharp // 放大表面,并填充描边颜色 float2 borderOffset[4] = {float2(1,0), float2(-1,0), float2(0,1), float2(0,-1)}; float border = _OutlineWidth * (1.0 / _ScreenParams.z); float4 borderColor = _Color; float4 c; for (int i = 0; i < 4; i++) { c = tex2D(_MainTex, i.uv + border * borderOffset[i]); borderColor.a *= c.a; o.Normal += borderColor.a * borderOffset[i]; } ``` 这里,`borderOffset`表示描边的偏移量,`border`表示描边的宽度,`borderColor`表示描边的颜色,`c`表示当前像素点的颜色值。在循环中,依次对当前像素点的上、下、左、右四个方向进行采样,并将采样到的颜色值和描边颜色进行叠加。 3. 最后,在Shader中将表面的颜色和描边颜色进行混合: ```csharp // 混合表面颜色和描边颜色 o.Albedo = lerp(_Color.rgb, o.Albedo, o.Normal); ``` 这里使用了`lerp`函数来对表面颜色和描边颜色进行混合,根据描边的程度不同,可以调整`_Color`的alpha值来控制描边的显示程度。 综上所述,完整的描边Shader代码如下: ```csharp Shader "Custom/Outline" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color ("Outline Color", Color) = (0,0,0,1) _OutlineWidth ("Outline Width", Range(0, 2)) = 1 _ScreenParams ("Screen Params", Vector) = (0,0,0,0) } SubShader { Tags {"Queue"="Transparent" "RenderType"="Transparent"} LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float4 Normal : TEXCOORD1; }; sampler2D _MainTex; float4 _Color; float _OutlineWidth; float4 _ScreenParams; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; o.Normal = float4(0,0,0,0); return o; } fixed4 frag (v2f i) : SV_Target { float2 borderOffset[4] = {float2(1,0), float2(-1,0), float2(0,1), float2(0,-1)}; float border = _OutlineWidth * (1.0 / _ScreenParams.z); float4 borderColor = _Color; float4 c; for (int j = 0; j < 4; j++) { c = tex2D(_MainTex, i.uv + border * borderOffset[j]); borderColor.a *= c.a; i.Normal += borderColor.a * borderOffset[j]; } i.Normal.a = 1.0; i.Normal = normalize(i.Normal); fixed4 col = tex2D(_MainTex, i.uv); col.rgb = lerp(_Color.rgb, col.rgb, i.Normal); col.a = col.a * i.Normal.a; return col; } ENDCG } } FallBack "Diffuse" } ``` 使用该Shader,你可以在游戏中对需要描边的物体进行材质替换,从而实现描边效果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

向宇it

创作不易,感谢你的鼓励

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

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

打赏作者

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

抵扣说明:

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

余额充值