c# - Unity - 粒子效果:如何使着色器在所需的时间播放
问题描述
最近我一直在尝试 VFX 的运气。我遇到了我非常喜欢的效果,滚动着色器。
我以这篇文章为基础并设法与它的创建者取得了联系,所以向他大喊大叫,他引导我朝着正确的方向前进以达到预期的效果。
后来,我意识到我有一些错误,如果有人可以帮助我,我将不胜感激。
效果只是纹理在某个网格中滚动,并带有 alpha 纹理。
第一个问题:效果没有颜色......它旋转并且alpha蒙版固定但颜色不显示。
第二个问题:我正在使用这个着色器来完成效果的特定部分,使用粒子系统。我使用了 Color Over Lifetime 选项,但它仍然会在整个效果开始后立即激活。使用“启动延迟”选项,它可以工作。
在某种程度上,这个问题是通过这种方式解决的,尽管我想知道我怎么能慢慢地看起来像生命中的颜色。
最后的问题更像是一个奖金。
有没有办法让网格在着色器效果旁边从下到上慢慢出现?
当前着色器代码
Shader "Custom/ScrollingShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_AlphaMaskTex ("AlphaMask", 2D) = "white" {}
_ScrollSpd ("Scroll Speeds", vector) = (-5, -20, 0, 0)
[HDR] _Color ("Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
// No culling or depth
Cull back ZWrite Off ZTest Always Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float2 alphauv : TEXCOORD1;
float4 vertex : SV_POSITION;
};
float4 _MainTex_ST;
float4 _AlphaMaskTex_ST;
float4 _ScrollSpd;
v2f vert (appdata v)
{
/* v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex).xy + frac(_Time.y * float2(_ScrollSpd.x, _ScrollSpd.y));
return o; */
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex).xy + frac(_Time.y * float2(_ScrollSpd.x, _ScrollSpd.y));
o.alphauv = TRANSFORM_TEX(v.uv, _AlphaMaskTex).xy;
return o;
}
sampler2D _MainTex;
sampler2D _AlphaMaskTex;
float4 _Color;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
fixed4 colA = tex2D(_AlphaMaskTex, i.alphauv);
col = tex2D(_MainTex, i.uv) * _Color;
col.a = tex2D(_AlphaMaskTex, i.uv).r;
col = tex2D(_MainTex, i.uv) * tex2D(_AlphaMaskTex, i.alphauv).r;
return col;
}
ENDCG
}
}
}
与应用材料一起使用的网格:
在此先感谢您,如果您有不明白的地方,请把它带给我,以便我更好地解释。
非常感谢!!
解决方案
关于你的第一个问题:在第 68 行
col = tex2D(_MainTex, i.uv) * _Color;
您正在尝试通过将纹理与颜色相乘来设置颜色。在第 72 行
col = tex2D(_MainTex, i.uv) * tex2D(_AlphaMaskTex, i.alphauv).r;
您只是在覆盖现有的颜色值。因此,只要您的基础纹理是灰度的,效果中就不会有颜色。我猜你想要这样的东西:
col = tex2D(_MainTex, i.uv) * _Color;
//col.a = tex2D(_AlphaMaskTex, i.alphauv).r; //<-- Edit1
col.a = tex2D(_AlphaMaskTex, i.alphauv).r * _Color.a; //<-- Edit2 fade in
关于你的第二个问题:我不完全理解你想要达到的目标。我也不是粒子系统的专家。但是,只要您正在绘制粒子,着色器就会被执行,并且通过引用 _Time 它将被动画化。生命周期内的颜色可用作着色器的输入。所以你可以用它作为一个值来改变你的着色器行为。您可以做各种有趣的事情,例如,如果您想在一段时间后开始为粒子设置动画,您可以设置颜色在生命周期内从 0 alpha 混合到 1 alpha,然后检查着色器中的 alpha 值,如果它更大超过 0.5 你开始为你的 uv 设置动画。生命周期中的颜色功能似乎是将数据传递给着色器的好方法。
不幸的是,我并不真正了解您要达到的目标,因此我无法提供更多帮助。也许你可以详细说明你的第二个问题?
关于你的第三个问题:
这是完全可能的。在片段着色器中,您可以将 uvs 视为从下到上和从左到右的渐变。因此,如果您使用 uv.y 并将其与您的 alpha 颜色相乘,您将混合您的粒子。现在,您可以使用从颜色随时间变化函数中获得的颜色对其进行动画处理。我还没有尝试过,但你可以这样做:
col.a = clamp(col.a * i.uv.y + _Color.a, 0.0f, 1.0f); //<- Edit
就像我说过的,我没有对此进行测试,您最喜欢为此添加一些偏移量。如果您正在苦苦挣扎,我可以看看是否可以给您一个运行示例。
推荐阅读
- python - 如何在 python 3.7 中安装 Urduhack?
- java - 如何在 Java 中暂停和恢复线程?
- chart.js - chart.js 和时间戳作为可读日期
- php - PHP函数从未分隔的编码值字符串创建图表
- python - 使用 argparser 将参数传递给入口点 python 脚本
- c# - 如何确定 EF Core 中是否拥有 ClrType?
- python - 为什么 pandas.core.series.Series 有时无法在 Python 中转换为火炬张量?
- java - 从 api 数组或矩阵 java android studio 中提取 json 数据
- c - 如何检查虚拟地址属于用户数据空间还是用户代码空间?
- elasticsearch - 无法在 Kibana 中检索包含特定符号的数据