• 如何实现化妆功能


    如何实现化妆功能,更换眉毛,嘴唇,眼球,胡子等?

    即如下效果:

    首先是shader,这个实现起来想必非常简单,相当于把一张要替换的图片叠加到脸部纹理上,当然还要给定一个具体的纹理坐标。

    示例代码如下:

      1 Shader "America/Character/Tattoo/America-Diffuse-AlphaTest-Face"
      2 {
      3     Properties
      4     {
      5         _Color ("Main Color", Color) = (1,1,1,1)
      6         _MainTex ("Base (RGB)", 2D) = "white" {}
      7         _Ramp ("Toon Ramp (RGB)", 2D) = "gray" {}
      8         
      9         _OverlyingColor("Overlying Color", Color) = (0.5, 0.5, 0.5, 1)
     10 
     11         _TattooTex1 ("Tattoo 1 (RGBA)", 2D) = "black" {}
     12         _TattooPos1 ("Tattoo Position 1", Vector) = (0,0,1,1)
     13         _TattooTex2 ("Tattoo 2 (RGBA)", 2D) = "black" {}
     14         _TattooPos2 ("Tattoo Position 2", Vector) = (0,0,1,1)
     15         _TattooTex3 ("Tattoo 3 (RGBA)", 2D) = "black" {}
     16         _TattooPos3 ("Tattoo Position 3", Vector) = (0,0,1,1)
     17         _TattooTex4 ("Tattoo 4 (RGBA)", 2D) = "black" {}
     18         _TattooPos4 ("Tattoo Position 4", Vector) = (0,0,1,1)
     19     }
     20 
     21     SubShader
     22     {
     23         Tags 
     24         {
     25             "RenderType" = "Transparent"
     26             "IgnoreProjector" = "True"
     27             "Queue" = "Transparent+100"
     28         }
     29         LOD 200
     30         
     31         Pass
     32         {
     33             Tags
     34             {
     35                 "LightMode" = "ForwardBase"
     36             }
     37             Cull Off
     38 
     39             CGPROGRAM
     40             #pragma vertex vert
     41             #pragma fragment frag
     42             #pragma multi_compile_fwdbase
     43 
     44             #include "UnityCG.cginc"
     45             #include "AutoLight.cginc"
     46             #include "Lighting.cginc"
     47 
     48             #include "../AmericaCG.cginc"
     49 
     50             fixed4 _Color;
     51             sampler2D _MainTex;
     52             sampler2D _Ramp;
     53             fixed4 _OverlyingColor;
     54             
     55             sampler2D _TattooTex1;
     56             float4 _TattooPos1;
     57             sampler2D _TattooTex2;
     58             float4 _TattooPos2;
     59             sampler2D _TattooTex3;
     60             float4 _TattooPos3;
     61             sampler2D _TattooTex4;
     62             float4 _TattooPos4;
     63 
     64             struct appdata
     65             {
     66                 float4 vertex : POSITION;
     67                 float2 uv : TEXCOORD0;
     68                 float3 normal : NORMAL;
     69             };
     70 
     71             struct v2f
     72             {
     73                 float4 pos : SV_POSITION;
     74                 float2 uv : TEXCOORD0;
     75                 float3 worldPos : TEXCOORD1;
     76                 float3 worldNormal : TEXCOORD2;
     77             };
     78 
     79             v2f vert(appdata v)
     80             {
     81                 v2f o;
     82                 o.pos = UnityObjectToClipPos(v.vertex);
     83                 o.uv = v.uv;
     84                 o.worldPos = mul(unity_ObjectToWorld, v.vertex);
     85                 o.worldNormal = UnityObjectToWorldNormal(v.normal);
     86                 return o;
     87             }
     88 
     89             fixed4 frag(v2f i) : SV_TARGET
     90             {
     91                 fixed4 albedo = tex2D(_MainTex, i.uv);
     92                 
     93                 // 纹身
     94                 albedo = ApplyTattoo(i.uv, _TattooTex1, _TattooPos1, albedo);
     95                 albedo = ApplyTattoo(i.uv, _TattooTex2, _TattooPos2, albedo);
     96                 albedo = ApplyTattoo(i.uv, _TattooTex3, _TattooPos3, albedo);
     97                 albedo = ApplyTattoo(i.uv, _TattooTex4, _TattooPos4, albedo);
     98 
     99                 albedo *= _Color;
    100 
    101                 fixed3 ambient = albedo.rgb * UNITY_LIGHTMODEL_AMBIENT.rgb;
    102 
    103                 fixed3 worldLight = normalize(UnityWorldSpaceLightDir(i.worldPos));
    104                 float d = dot(worldLight, i.worldNormal) * 0.5 + 0.5;
    105                 fixed3 rampCol = tex2D(_Ramp, float2(d, d)).rgb;
    106                 fixed3 diffuse = albedo.rgb * _LightColor0.rgb * rampCol;
    107                 
    108                 fixed4 col = fixed4(ambient + diffuse * 2, albedo.a);
    109                 col.rgb = Overlay(col, _OverlyingColor);
    110 
    111                 return col;
    112             }
    113 
    114             ENDCG
    115         }
    116 
    117 
    118     } 
    119 
    120     Fallback "Diffuse"
    121 }

    其中,ApplyTattoo的实现如下:

    // 应用纹身
    fixed4 ApplyTattoo(float2 uv, sampler2D tattooTex, float4 tattooPos, fixed4 albedo)
    {
        if (uv.x >= tattooPos.x && uv.x <= tattooPos.x+tattooPos.z && uv.y >= tattooPos.y && uv.y <= tattooPos.y + tattooPos.w)
        {
            fixed tattooU = (uv.x - tattooPos.x) / tattooPos.z;
            fixed tattooV = (uv.y - tattooPos.y) / tattooPos.w;
            fixed2 tattooUV = fixed2(tattooU, tattooV);
            fixed4 tattooCol = tex2D(tattooTex, tattooUV);
            albedo.rgb = lerp(albedo.rgb, tattooCol.rgb, tattooCol.a);
        }
    
        return albedo;
    }

    转载请注明出处:https://www.cnblogs.com/jietian331/p/12659339.html

     材质球面板如下:

  • 相关阅读:
    LinkedListQueue
    LinkedListStack
    redis学习之——Redis事务(transactions)
    redis学习之——持久化RDB 和AOF
    redis学习之——redis.conf配置(基本)文件学习
    评估算法的核心指标
    Vector类
    List接口与ArrayList、LinkedList实现类
    Collection接口
    枚举类
  • 原文地址:https://www.cnblogs.com/jietian331/p/12659339.html
Copyright © 2020-2023  润新知