unity3d - 在 Unity 中为对象的不同部分分配不同颜色的着色器
问题描述
我有一组具有不同颜色段的数据,例如
item1:[红色:3个单位,蓝色:5个单位,绿色:4个单位,白色:5个单位](共17个单位)
item2:【红色:4个,绿色:2个,白色:2个】(共8个)
- 项目N:...
我在 Unity 中创建了相对于单位总数的大小的对象,例如
- 第 1 项:----------------- (17)
- 项目2:--------(8)
我想根据它们的分布为所有对象着色,例如
- 项目1:rrr|bbbbb|gggg|wwwww
- 项目2:rrrr|gg|ww
目标
我希望做的是实例化一个带有着色器的项目,该着色器适当地采用每种颜色的单位数和颜色段。
到目前为止我所做的
我创建了 m 个较小的段对象,其中 m 是每个项目的段数。然后,我适当地为这些段对象着色并将它们彼此相邻放置,使它们看起来像一个多色项目。
为什么我认为这很糟糕
这是一个可行的解决方案,但可能有数千个项目和数千个段,我相信减少这一步会大大提高性能。
我对着色器没有任何经验,但这感觉应该是一个已经解决的问题,我不想重新发明轮子。也就是说,如果我的问题不存在确切的解决方案,那么实现一些类似功能的着色器代码也将是完美的。
示例照片
更新:当前着色器代码和说明
我在网上找到了一个着色器,它为条形着色,将它分成两部分 -> 健康和损害。然后我将该代码修改为包含三个部分,健康、损害和防护,以使我更接近理想的堆叠条类型。我还有一个 C# 脚本调用
GetComponent<MeshRenderer>().material.SetFloat("_LifePercent", percent);
GetComponent<MeshRenderer>().material.SetFloat("_DamagesPercent", percent);
GetComponent<MeshRenderer>().material.SetFloat("_ShieldPercent", percent);
着色器
Shader "Sprites/HealthBar"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
[Header(Life)]_LifeColor ("Main Color", Color) = (0.2,1,0.2,1)
_LifePercent ("Life Percent", Float) = 1
[Header(Damages)]_DamagesColor ("Damages color", Color) = (1,1,0,1)
_DamagesPercent ("Damages Percent", Float) = 0
[Header(Shield)]_ShieldColor ("Shield color", Color) = (.2, .2, 1, 0)
_ShieldPercent ("Shield Percent", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _LifeColor;
half _LifePercent;
fixed4 _DamagesColor;
half _DamagesPercent;
fixed4 _ShieldColor;
half _ShieldPercent;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.texcoord;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = tex2D(_MainTex, IN.texcoord);
if ( IN.texcoord.x > _LifePercent + _DamagesPercent + _ShieldPercent )
{
c.a = 0;
}
else if ( IN.texcoord.x < _LifePercent )
{
c *= _LifeColor;
}
else if ( IN.texcoord.x < _LifePercent + _ShieldPercent && IN.texcoord.x > _LifePercent )
{
c *= _ShieldColor;
}
// if we weren't in the previous two segments we're now in the damages segment
else
{
c *= _DamagesColor;
}
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}
这是我修改之前的shader的来源: unity life bar shader
应用了材质/着色器的对象似乎只有 mainTex,任何地方都没有颜色。我也不完全理解我在fixed4“c”上执行的操作。我错过了什么?
解决方案
我花了更多时间阅读教程,特别是来自统一的棋盘教程:统一顶点/片段示例
这就是我现在所拥有的,它的工作方式与我期望的差不多:
Shader "Sprites/HealthBar"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
[Header(Life)]_LifeColor ("Main Color", Color) = (0.2,1,0.2,1)
_LifePercent ("Life Percent", Float) = 1
[Header(Damages)]_DamagesColor ("Damages color", Color) = (1,1,0,1)
_DamagesPercent ("Damages Percent", Float) = 0
[Header(Shield)]_ShieldColor ("Shield color", Color) = (.2, .2, 1, 0)
_ShieldPercent ("Shield Percent", Float) = 0
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
fixed4 _LifeColor;
half _LifePercent;
fixed4 _DamagesColor;
half _DamagesPercent;
fixed4 _ShieldColor;
half _ShieldPercent;
v2f vert(float4 pos : POSITION, float2 uv : TEXCOORD0)
{
v2f o;
o.vertex = UnityObjectToClipPos(pos);
o.uv = uv * 100;
return o;
}
fixed4 frag(v2f IN) : SV_Target
{
float2 c = IN.uv;
fixed4 cout;
if (c.y < _LifePercent){
cout = _LifeColor;
}
else if (c.y > _LifePercent && c.y < _DamagesPercent + _LifePercent){
cout = _DamagesColor;
}
else {
cout = _ShieldColor;
}
return cout;
}
ENDCG
}
}
}
推荐阅读
- node.js - 在 JSON 中附加每个元素的坐标
- python - 在 Python 中是否有可能有一个函数来创建许多具有递增更改名称的新变量
- c++ - 从 txt 文件初始化 uint8_t 数组
- c++ - 转换函数,std::is_base_of 和虚假的不完整类型:替换失败是一个错误
- url - 什么时候一个字符等同于它在 URL 中的百分比编码版本?
- javafx - 将 CheckBox 列添加到现有的 TableView
- android - 如何在 Android 上获取日历提醒
- python - 在 Python 中使用 Tkinter 在弹出窗口上打开图像
- python-3.x - 如何让 zbar 检测深色背景的二维码?
- python - Python OpenCV 在播放时选择视频/流上的 ROI