unity shader中常用的几种texture纹理blend混合方式

10 篇文章 3 订阅

最近在做一个武器皮肤的系统,为了让每个玩家都获得一种独一无二的武器,我们决定给皮肤做变体生成,那么这张皮肤就不能直接用一张美术给的贴图,而要通过一些可变的参数,让每个皮肤产生不一样的效果。因此我们需要使用多张不一样的贴图根据一系列参数,混合成一张皮肤贴图。但是混合的方式多种多样,怎么才能实现比较好的效果呢,经过一段时间的学习跟实践开发,以及对一些其他游戏的研究,大致纹理的混合有以下的一些方式:

方式一:

        最常见的混合方式就是alpha混合,通常alpha混合的是带透明度的物体:

 我们混合2张贴图的时候,通常:F源 + F目标 = 1, 这样保证我们混合的颜色不会超过1.

下面演示一下:

有以下2张贴图:

基于这两张贴图使用alpha混合,结果如下:

 

方式二:

        通过颜色插值进行混合,需要指定一个混合系数:

        cPaint.rgb = lerp(cBase.rgb, cPaint, _BlendAmt);

还是上面2张贴图,示例:

 

方式3:

        高度混合,即每张图附加一张高度图,每一个像素,高度大的地方显示,高度小的地方不显示,高度相差不多的地方,可以使用欧冠平滑过渡的方式。这种混合方式常用于地形。下面具体介绍一下:

        使用两张纹理:

        两张高度图:

使用一下方法,对两张图进行处理:

float heightblend(float input1, float height1, float input2, float height2)
{
    float height_start = max(height1, height2) - _HeightblendFactor;
    float level1 = max(height1 - height_start, 0);
    float level2 = max(height2 - height_start, 0);
    return ((input1 * level1) + (input2 * level2)) / (level1 + level2);
}
Properties
{
    _Texture1("Texture 1", 2D) = "white" {}
    _Height1("Heightmap 1", 2D) = "white" {}
    _Texture2("Texture 2", 2D) = "white" {}
    _Height2("Heightmap 2", 2D) = "white" {}
    _HeightblendFactor("Heightmap Blending Factor", Float) = 0.05
}

// .....

void surf(Input IN, inout SurfaceOutput o)
{
    float2 uv = IN.uv_Texture1;

    float3 v1 = tex2D(_Texture1, uv).rgb;
    float h1 = tex2D(_Height1, uv).r;

    float3 v2 = tex2D(_Texture2, uv).rgb;
    float h2 = tex2D(_Height2, uv).r;

    o.Albedo = heightblend (v1, h1, v2, h2);
}

下面的图片展示了_HeightblendFactor不同的效果。这些参数从极低的0.01(左侧)到最大值1.0(右侧)运行。

如上图显示,_HeightblendFactor越大,两张图融合平滑过渡的地方会越多。

方式4:

        heightLerp.

float heightlerp(float input1, float height1, float input2, float height2, float lerp)
{
	lerp = clamp(lerp, 0, 1);
	return heightblend(input1, height1 * (1 - lerp), input2, height2 * lerp);
}

跟上面方法使用的数据一样,额外的方法以完全相同的方式工作,只不过增加了一个参数lerp,作为像alpha blend一样的数去处理一下height的值,然后再进行heightblend,比方说下面我们使用uv.x作为lerp,效果如下:

可以看到uv.x较小的左侧,会因为lerp的值比较小,而导致height1 * (1 - lerp)比较大,因此都显示的是沙子的一边,右侧反之。

方式5:

        smoothstep函数:

float smoothstep(float a, float b, float x)
{
    float t = saturate((x - a)/(b - a));
    return t*t*(3.0 - (2.0*t));
}

这个函数会在浮点a 与浮点b 之间平滑过渡,函数图:

图来源于https://blog.csdn.net/u010333737/article/details/82859246

从这样可以看出来,我们的混合系数可以使用smoothstep方法,产生一个平滑过渡的blend系数。

 

height混合提供了一些常用接口,可以下载:

百度云地址https://pan.baidu.com/s/18gQGJU-0u5ydGFA4IABuxg   提取码:pkgu

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于在 Unity 实现树木摇动的效果,您可以使用 Shader 来实现。下面是一个简单的示例,展示了如何使用 Shader 实现树木摇动的效果: 首先,创建一个新的 Shader 文件,然后在其添加以下代码: ``` Shader "Custom/TreeWind" { Properties { _MainTex ("Tree Texture", 2D) = "white" {} _WindStrength ("Wind Strength", Range(0, 1)) = 0.5 _WindSpeed ("Wind Speed", Range(0, 10)) = 2.0 } SubShader { Tags { "Queue"="Transparent" "RenderType"="Transparent" } Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; float _WindStrength; float _WindSpeed; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { // 计算风的影响 float windOffset = sin(_Time.y * _WindSpeed + IN.uv_MainTex.x) * _WindStrength; // 根据风的偏移来更新纹理坐标 float2 newUV = IN.uv_MainTex + float2(windOffset, 0); // 从树纹理采样颜色 fixed4 c = tex2D(_MainTex, newUV); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" } ``` 在这个示例,我们使用了一个简单的 Lambert 表面着色器来实现树木的着色效果。_MainTex 属性用于传递树的纹理,_WindStrength 和 _WindSpeed 属性控制风的强度和速度。 在 surf 函数,我们首先计算风的偏移量,然后将其添加到纹理坐标上。最后,我们从树纹理采样颜色,并将其作为表面输出的颜色。 保存 Shader 文件后,将其添加到树木的材质,并将树木模型的纹理赋给 _MainTex 属性。您还可以调整 _WindStrength 和 _WindSpeed 属性来控制树木摇动的效果。 希望这个示例能帮助到您!如果您有任何其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值