Unity3d 贴花环绕网布

Unity3d 贴花环绕网布,unity3d,decal,Unity3d,Decal,我正在做纹身模拟程序,我需要知道是否有一种方法可以让贴花(纹身)缠绕在目标网格上,比如说有一个纹身从腿的一侧到另一侧,或者后面的事件 您可以使用Unity的官方预览工具使用贴花投影仪 下面是我如何使用它将一个“塔图”投射到一个桶上。当然,您可以将其应用于您的模型。 (儿童贴花投影仪,使tatoo跟随模型) 导入渲染管道-高清软件包的最佳方法是,选择它作为模板。如果它是一个现有的项目,这可能会帮助你 一旦你成功地设置了软件包,按照下面的步骤操作,你就可以将tatoos投射到你想要的任何地方。不是

我正在做纹身模拟程序,我需要知道是否有一种方法可以让贴花(纹身)缠绕在目标网格上,比如说有一个纹身从腿的一侧到另一侧,或者后面的事件


您可以使用Unity的官方预览工具使用贴花投影仪

下面是我如何使用它将一个“塔图”投射到一个桶上。当然,您可以将其应用于您的模型。 (儿童贴花投影仪,使tatoo跟随模型)

导入渲染管道-高清软件包的最佳方法是,选择它作为模板。如果它是一个现有的项目,这可能会帮助你


一旦你成功地设置了软件包,按照下面的步骤操作,你就可以将tatoos投射到你想要的任何地方。

不是在运行时,而是使用投影贴花,否

这里你需要的是一个程序纹身图。将其视为另一种纹理,如光照贴图。您可能需要一个自定义着色器,但可以使用标准着色器的次级反照率通道来完成

棘手的部分是对这种纹理进行书写。我将概述基本算法,但由您来实现:

您需要能够做的第一件事是在代码中展开网格的三角形。您需要标识UV贴图上哪些边是连续的,哪些边是分离的。接下来,您需要一种识别纹身和初始变换的方法。首先,您需要在纹身源纹理上定义一个原点,纹身源纹理将围绕该原点旋转。然后,您需要定义一个引用源纹理的结构,以及在目标纹理中应用它的UV位置(矢量2)/旋转(浮动)/缩放(浮动)

一旦你将纹身存储在该格式中,你就可以开始为皮肤构建纹身面具纹理。如果您的皮肤uv具有一致的像素密度,这会容易得多,因为您可以主要在uv空间中工作,但如果没有,则需要重新投影以获得每个tri的比例。但是,基本上,从包含原点的主体三角形开始,然后正常地绘制到该三角形上。从那里,你知道每个顶点和三角形的边在纹身源纹理上的位置。因此,循环遍历每个相邻的三角形(我推荐一种宽度优先的递归方法),并从您已经知道的边开始继续。如果所有三个顶点都落在源纹理的矩形之外,则可以在那里停止。否则,继续处理下一个三角形的邻居。确保在计算邻居时使用3D网格,以免卡在接缝处

当纹身完全缠绕并重叠时,该算法将有一个边缘情况需要处理,但有几种不同的方法可以处理


一旦你把所有的纹身都写在纹身的纹理上,就把它涂到皮肤材料上,瞧!这不仅可以将所有计算从实时渲染中移出,还可以让您完全控制纹身的应用方式。

我已经使用自定义着色器完成了类似的操作。我想它会满足你的要求。Mine根据iPad游戏原型的等级和单位类型动态呈现旗帜。具体如何操作取决于项目中的设置方式,但我的图是这样的-第一个图像是显示网格的线框,第二个是打开着色器,显示它们根据等级和单位添加颜色和徽标。我刚刚加入了顶旗的着色器,因为它添加了与纹身相似的单位标志:

请注意,可以将多个着色器附着到特定网格

徽标只是一个透明的图像,添加到着色器中,并作为着色器中的纹理引用:

你可以看到我们还有一张图片,它有一些阴影纹理,用作横幅的背景

这是我的第一个着色器,是前一段时间编写的,所以我确信它在各种方面都是次优的,但希望它足以让您开始使用(它在Unity 2018.3.x中仍然有效,尽管我不得不进行一些修改才能编译):

Shader“自定义/特鲁普夫拉格明明暗器”{
性质{
_背景色(“背景色”,颜色)=(0.78,0.2,0.2)//深红色
_MainTex(“背景(RGBA)”,2D)={}
_徽章文字(“徽章(RGBA)”,2D)={}
_等级(“等级(1-9)”,浮动=3.0
}
子阴影{
通过{
CGP程序
#pragma排除渲染器xbox360 ps3 flash
#布拉格目标3.0
#pragma顶点顶点
#布拉格碎片碎片
#包括“UnityCG.cginc”
结构appdata{
浮动4顶点:位置;
浮动4 texcoord:TEXCOORD0;
};
结构v2f{
浮动4位置:SV_位置;
float2uv:TEXCOORD0;
};
均匀取样器2D_MainTex;
统一采样器2D_徽标Tex;
均匀浮动3_背景色;
统一浮动(u)秩;;
v2f垂直(appdata v)
{
v2fo;
o、 pos=单位对象到lippos(v.顶点);
o、 uv=v.texcoord.xy;
返回o;
}
浮动4碎片(v2f英寸):颜色
{
浮色;
float4 backTextureColor=tex2D(_MainTex,IN.uv.xy);
float4徽章纹理颜色=tex2D(_徽章tex,IN.uv.xy);
//没有画出5级以上的正方形
如果(_秩>=6.0)
丢弃;
如果(_秩<5)//4及以下
{           
outColor=float4((徽标TextureColor.rgb*徽标TextureColor.a)+
((1.0-徽标TextureColor.a)*backTextureColor.rgb)*U BackColor.rgb),1);
//float4(_BackColor.rgb,1));
}
如果(_Rank>=5.0)//但不包括在上面的6中
{
//5只是纯色背景色与背景纹理的结合
outColor=float4(backTextureColor.rgb*_BackColor.rgb,1);
}
返色;
}
ENDCG
}}
}
着色器学习如何操作有点让人恼火,但p
Shader "Custom/TroopFlagEmblemShader" {

Properties {
    _BackColor ("Background Color", Color) = (0.78, 0.2, 0.2)       // scarlet  
    _MainTex ("Background (RGBA)", 2D) = "" {}
    _EmblemTex("Emblem (RGBA)", 2D) = "" {}
    _Rank ( "Rank (1-9)", Float ) = 3.0
}

SubShader {


Pass {

CGPROGRAM
#pragma exclude_renderers xbox360 ps3 flash
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

struct appdata {
    float4 vertex: POSITION;
    float4 texcoord: TEXCOORD0;
};

struct v2f {
    float4 pos: SV_POSITION;
    float2 uv: TEXCOORD0;
};


uniform sampler2D _MainTex;
uniform sampler2D _EmblemTex;
uniform float3 _BackColor;
uniform float _Rank;

v2f vert( appdata v ) 
{
    v2f o;

    o.pos = UnityObjectToClipPos( v.vertex );
    o.uv = v.texcoord.xy;

    return o;
}


float4 frag( v2f IN ) : COLOR
{
    float4 outColor;
    float4 backTextureColor = tex2D( _MainTex, IN.uv.xy );
    float4 emblemTextureColor = tex2D( _EmblemTex, IN.uv.xy );

        // not drawing the square at all above rank 5
    if ( _Rank >= 6.0 )
        discard;

    if ( _Rank < 5 )                                    // 4 and below 
    {           
        outColor = float4( (emblemTextureColor.rgb * emblemTextureColor.a) + 
                            (((1.0 - emblemTextureColor.a) * backTextureColor.rgb) * _BackColor.rgb) , 1 );

        // float4(_BackColor.rgb, 1 ));
    }
    else if ( _Rank >= 5.0 ) // but excluded from 6 above
    {
        // 5 is just solid backcolor combined with background texture
        outColor = float4( backTextureColor.rgb * _BackColor.rgb, 1 );
    }

    return outColor;
}
ENDCG
}}
}