Shader——消融效果
发布日期:2021-06-30 19:57:19 浏览次数:2 分类:技术文章

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

         

一:使用两种颜色混合消融

Shader "Custom/Dissolve"{    Properties    {        _MainTex ("Texture", 2D) = "white" {}//主贴图        _NoiseTex("Noise", 2D) = "white" {}//噪音贴图        _Threshold("Threshold", Range(0.0, 1.0)) = 0//消融程度        _EdgeLength("Edge Length", Range(0.0, 0.2)) = 0.1//边缘多长范围要显示边缘颜色        _EdgeFirstColor("First Edge Color", Color) = (1,1,1,1)//第一种颜色        _EdgeSecondColor("Second Edge Color", Color) = (1,1,1,1)//第二种颜色    }    SubShader    {        Tags { "Queue"="Geometry" "RenderType"="Opaque" }        Pass        {            Cull Off //要渲染背面保证效果正确            CGPROGRAM            #pragma vertex vert            #pragma fragment frag                        #include "UnityCG.cginc"            struct appdata            {                float4 vertex : POSITION;                float2 uv : TEXCOORD0;            };            struct v2f            {                float4 vertex : SV_POSITION;                float2 uvMainTex : TEXCOORD0;                float2 uvNoiseTex : TEXCOORD1;            };            sampler2D _MainTex;            float4 _MainTex_ST;            sampler2D _NoiseTex;            float4 _NoiseTex_ST;            float _Threshold;            float _EdgeLength;            fixed4 _EdgeFirstColor;            fixed4 _EdgeSecondColor;                        v2f vert (appdata v)            {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                o.uvMainTex = TRANSFORM_TEX(v.uv, _MainTex);                o.uvNoiseTex = TRANSFORM_TEX(v.uv, _NoiseTex);                return o;            }                        fixed4 frag (v2f i) : SV_Target            {                //镂空                fixed cutout = tex2D(_NoiseTex, i.uvNoiseTex).r;                clip(cutout - _Threshold);                float degree = saturate((cutout - _Threshold) / _EdgeLength);                fixed4 edgeColor = lerp(_EdgeFirstColor, _EdgeSecondColor, degree);                fixed4 col = tex2D(_MainTex, i.uvMainTex);                fixed4 finalColor = lerp(edgeColor, col, degree);                return fixed4(finalColor.rgb, 1);            }            ENDCG        }    }}

二:使用渐变纹理消融

Shader "Custom/Dissolve"{    Properties    {        _MainTex ("Texture", 2D) = "white" {}//主贴图        _NoiseTex("Noise", 2D) = "white" {}//噪音贴图        _Threshold("Threshold", Range(0.0, 1.0)) = 0//消融程度        _EdgeLength("Edge Length", Range(0.0, 0.2)) = 0.1//边缘多长范围要显示边缘颜色        _RampTex("Ramp", 2D) = "white" {}//渐变贴图    }    SubShader    {        Tags { "Queue"="Geometry" "RenderType"="Opaque" }        Pass        {            Cull Off //要渲染背面保证效果正确            CGPROGRAM            #pragma vertex vert            #pragma fragment frag                        #include "UnityCG.cginc"            struct appdata            {                float4 vertex : POSITION;                float2 uv : TEXCOORD0;            };            struct v2f            {                float4 vertex : SV_POSITION;                float2 uvMainTex : TEXCOORD0;                float2 uvNoiseTex : TEXCOORD1;                float2 uvRampTex : TEXCOORD2;            };            sampler2D _MainTex;            float4 _MainTex_ST;            sampler2D _NoiseTex;            float4 _NoiseTex_ST;            float _Threshold;            float _EdgeLength;            sampler2D _RampTex;            float4 _RampTex_ST;                        v2f vert (appdata v)            {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                o.uvMainTex = TRANSFORM_TEX(v.uv, _MainTex);                o.uvNoiseTex = TRANSFORM_TEX(v.uv, _NoiseTex);                o.uvRampTex = TRANSFORM_TEX(v.uv, _RampTex);                return o;            }                        fixed4 frag (v2f i) : SV_Target            {                //镂空                fixed cutout = tex2D(_NoiseTex, i.uvNoiseTex).r;                clip(cutout - _Threshold);                float degree = saturate((cutout - _Threshold) / _EdgeLength);                fixed4 edgeColor = tex2D(_RampTex, float2(degree, degree));                fixed4 col = tex2D(_MainTex, i.uvMainTex);                fixed4 finalColor = lerp(edgeColor, col, degree);                return fixed4(finalColor.rgb, 1);            }            ENDCG        }    }}

三:从指定方向开始消融

Shader "Custom/Dissolve"{    Properties    {        _MainTex ("Texture", 2D) = "white" {}//主贴图        _NoiseTex("Noise", 2D) = "white" {}//噪音贴图        _Threshold("Threshold", Range(0.0, 1.0)) = 0//消融的程度        _EdgeLength("Edge Length", Range(0.0, 0.2)) = 0.1//边缘多长范围要显示边缘颜色        _RampTex("Ramp", 2D) = "white" {}//渐变贴图        _Direction("Direction", Int) = 1 //1表示从X正方向开始,其他值则从X负方向        _MinBorderX("Min Border X", Float) = -0.5//X方向的最小边界(代码动态获取)        _MaxBorderX("Max Border X", Float) = 0.5//X方向的最大边界(代码动态获取)        _DistanceEffect("Distance Effect", Range(0.0, 1.0)) = 0.5//最大距离的值对整个消融过程的影响程度    }    SubShader    {        Tags { "Queue"="Geometry" "RenderType"="Opaque" }        Pass        {            Cull Off             CGPROGRAM            #pragma vertex vert            #pragma fragment frag                        #include "UnityCG.cginc"            struct appdata            {                float4 vertex : POSITION;                float2 uv : TEXCOORD0;            };            struct v2f            {                float4 vertex : SV_POSITION;                float2 uvMainTex : TEXCOORD0;                float2 uvNoiseTex : TEXCOORD1;                float2 uvRampTex : TEXCOORD2;                float objPosX : TEXCOORD3;            };            sampler2D _MainTex;            float4 _MainTex_ST;            sampler2D _NoiseTex;            float4 _NoiseTex_ST;            float _Threshold;            float _EdgeLength;            sampler2D _RampTex;            float4 _RampTex_ST;            int _Direction;            float _MinBorderX;            float _MaxBorderX;            float _DistanceEffect;                        v2f vert (appdata v)            {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                o.uvMainTex = TRANSFORM_TEX(v.uv, _MainTex);                o.uvNoiseTex = TRANSFORM_TEX(v.uv, _NoiseTex);                o.uvRampTex = TRANSFORM_TEX(v.uv, _RampTex);                o.objPosX = v.vertex.x;                return o;            }                        fixed4 frag (v2f i) : SV_Target            {                float range = _MaxBorderX - _MinBorderX;                float border = _MinBorderX;                if(_Direction == 1) //1表示从X正方向开始,其他值则从负方向                    border = _MaxBorderX;                float dist = abs(i.objPosX - border);                float normalizedDist = saturate(dist / range);                fixed cutout = tex2D(_NoiseTex, i.uvNoiseTex).r * (1 - _DistanceEffect) + normalizedDist * _DistanceEffect;                clip(cutout - _Threshold);                float degree = saturate((cutout - _Threshold) / _EdgeLength);                fixed4 edgeColor = tex2D(_RampTex, float2(degree, degree));                fixed4 col = tex2D(_MainTex, i.uvMainTex);                fixed4 finalColor = lerp(edgeColor, col, degree);                return fixed4(finalColor.rgb, 1);            }            ENDCG        }    }}

脚本动态获取X方向的最大最小边界:

using UnityEngine;public class GetDissolveBorder : MonoBehaviour{    void Start()    {        Material mat = GetComponent
().material; float minX, maxX; CalculateMinMaxX(out minX, out maxX); mat.SetFloat("_MinBorderX", minX); mat.SetFloat("_MaxBorderX", maxX); } ///
/// 获取X方向的最大最小边界 /// ///
///
private void CalculateMinMaxX(out float minX, out float maxX) { Vector3[] vertices = GetComponent
().mesh.vertices; minX = maxX = vertices[0].x; for (int i = 1; i < vertices.Length; i++) { float x = vertices[i].x; if (x < minX) { minX = x; } if (x > maxX) { maxX = x; } } }}

四:从指定点开始消融

Shader "Custom/Dissolve"{    Properties    {        _MainTex ("Texture", 2D) = "white" {}//主贴图        _NoiseTex("Noise", 2D) = "white" {}//噪音贴图        _Threshold("Threshold", Range(0.0, 1.0)) = 0//消融程度        _EdgeLength("Edge Length", Range(0.0, 0.2)) = 0.1//边缘多长范围要显示边缘颜色        _RampTex("Ramp", 2D) = "white" {}//渐变贴图        _StartPoint("Start Point", Vector) = (0, 0, 0, 0)//开始消融的位置        _MaxDistance("Max Distance", Float) = 0//最大距离的值        _DistanceEffect("Distance Effect", Range(0.0, 1.0)) = 0.5//最大距离的值对整个消融过程的影响程度    }    SubShader    {        Tags { "Queue"="Geometry" "RenderType"="Opaque" }        Pass        {            Cull Off             CGPROGRAM            #pragma vertex vert            #pragma fragment frag                        #include "UnityCG.cginc"            struct appdata            {                float4 vertex : POSITION;                float2 uv : TEXCOORD0;            };            struct v2f            {                float4 vertex : SV_POSITION;                float2 uvMainTex : TEXCOORD0;                float2 uvNoiseTex : TEXCOORD1;                float2 uvRampTex : TEXCOORD2;                float3 objPos : TEXCOORD3;                float3 objStartPos : TEXCOORD4;            };            sampler2D _MainTex;            float4 _MainTex_ST;            sampler2D _NoiseTex;            float4 _NoiseTex_ST;            float _Threshold;            float _EdgeLength;            sampler2D _RampTex;            float4 _RampTex_ST;            float _MaxDistance;            float4 _StartPoint;            float _DistanceEffect;                        v2f vert (appdata v)            {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                o.uvMainTex = TRANSFORM_TEX(v.uv, _MainTex);                o.uvNoiseTex = TRANSFORM_TEX(v.uv, _NoiseTex);                o.uvRampTex = TRANSFORM_TEX(v.uv, _RampTex);                o.objPos = v.vertex;                o.objStartPos = mul(unity_WorldToObject, _StartPoint);                return o;            }                        fixed4 frag (v2f i) : SV_Target            {                float dist = length(i.objPos.xyz - i.objStartPos.xyz);                float normalizedDist = saturate(dist / _MaxDistance);                fixed cutout = tex2D(_NoiseTex, i.uvNoiseTex).r * (1 - _DistanceEffect) + normalizedDist * _DistanceEffect;                clip(cutout - _Threshold);                float degree = saturate((cutout - _Threshold) / _EdgeLength);                fixed4 edgeColor = tex2D(_RampTex, float2(degree, degree));                fixed4 col = tex2D(_MainTex, i.uvMainTex);                fixed4 finalColor = lerp(edgeColor, col, degree);                return fixed4(finalColor.rgb, 1);            }            ENDCG        }    }}

五:UI的消融

Shader "UIEffect/Dissolve"{    Properties    {        _MainTex("Main Texture", 2D) = "defaulttexture" {}        _NoiseTex("噪声云图", 2D) = "defaulttexture" {}        _DissolveTex ("边缘色", 2D) = "defaulttexture" {}        _dissolve("消融值", Range(0, 1)) = 0        //MASK SUPPORT ADD        _StencilComp ("Stencil Comparison", Float) = 8        _Stencil ("Stencil ID", Float) = 0        _StencilOp ("Stencil Operation", Float) = 0        _StencilWriteMask ("Stencil Write Mask", Float) = 255        _StencilReadMask ("Stencil Read Mask", Float) = 255        _ColorMask ("Color Mask", Float) = 15        //MASK SUPPORT END    }    SubShader    {       Tags{            "Queue" = "Transparent"            "IgnoreProjector" = "True"            "RenderType" = "Transparent"        }         Cull Off ZWrite Off ZTest Always        Blend One OneMinusSrcAlpha        //MASK SUPPORT ADD        Stencil        {            Ref [_Stencil]            Comp [_StencilComp]            Pass [_StencilOp]             ReadMask [_StencilReadMask]            WriteMask [_StencilWriteMask]        }        ColorMask [_ColorMask]        //MASK SUPPORT END        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;            };             v2f vert (appdata v)            {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                o.uv = v.uv;                return o;            }             sampler2D _MainTex;            sampler2D _DissolveTex;            sampler2D _NoiseTex;                    float _dissolve;              fixed4 frag (v2f i) : SV_Target            {                fixed4 MainCol = tex2D(_MainTex, i.uv);                MainCol.rgb *= MainCol.a;                // 随机阈值                fixed randValue = tex2D(_NoiseTex, i.uv).r;                   float cutout = 0.6 - 1.2 * _dissolve + randValue;                clip(cutout - 0.5);                       float weight = 1.0 - clamp(8 * cutout - 4, 0.0, 1.0);                float2 burnUV = float2(weight, 0);                fixed3 edgeColor = weight * tex2D(_DissolveTex, burnUV ).xyz;                edgeColor = step(0.05, MainCol.a) * edgeColor;                 // // 需要剔除的部分                    fixed3 finalCol = MainCol.rgb + edgeColor;                   return fixed4(finalCol, MainCol.a);            }            ENDCG        }    }}

转载地址:https://liuhaowen.blog.csdn.net/article/details/105090210 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Shader——3D流光效果
下一篇:使用ADB安装Apk到手机

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月14日 17时56分30秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章