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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年04月14日 17时56分30秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
大厂经典面试题:Redis为什么这么快?
2019-04-30
精通Spring?请吃我一狗腿!
2019-04-30
培训班老师说可以用这个干掉一大批面试者
2019-04-30
靠这本,在某宝花了399大洋的宝典,熬夜七天,吊打面试官,终进大厂
2019-04-30
阿里四面,居然栽在一道排序算法上
2019-04-30
【Java编码规范】《阿里巴巴Java开发手册(正式版)》发布!
2019-04-30
如何在二三线城市月薪过万(一)看完这篇后端简历优化,包你面试不断
2019-04-30
阿里P8大神教你十分钟构建好SpringBoot + SSM框架 成功晋升
2019-04-30
Linux运维-搭建高可用Redis缓存
2019-04-30
膜拜!阿里内部都在强推的K8S(kubernetes)学习指南,不能再详细了
2019-04-30
Linux 常用命令
2019-04-30
递归及应用
2019-04-30
Android之Handler机制篇
2019-04-30
Android之网络协议篇
2019-04-30
Android之RecyclerView篇
2019-04-30
Android之Retrofit基本用法篇
2019-04-30