[Personaje de dibujos animados de ShaderLab Guilty Gear_Estilo 2D_"Sol Badguy"_Representación de personajes (Parte 2)]

Insertar descripción de la imagen aquí

Efecto inicial del personaje:

Insertar descripción de la imagen aquí

Representación básicaSimpleBas

Shader "SimpleBase"
{
    
    
    Properties
    {
    
    
        [Header(BaseColor)]
        _MainTex ("BaseTex", 2D) = "white" {
    
    }
        [Space(20)]
        [Header(ILM)]
        _ILMTex("ILMTex",2D) = "white"{
    
    }
        [Space(20)]
        [Header(SSS)]
        _SssTex("SssTex",2D) = "white"{
    
    }
        [Space(20)]
        [Header(Detail)]
        _DetailTex("DetailTex",2D) = "white"{
    
    }
    }
    SubShader
    {
    
    
        Tags {
    
     "RenderType"="Opaque" }
        LOD 100

        Pass
        {
    
    
            Tags{
    
    "LightMode"="ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
                float2 uv1 : TEXCOORD1;
                float4 tangent :TEXCOORD2;
                half3 normal : NORMAL;
                half4 color : COLOR;
            };

            struct v2f
            {
    
    
                float4 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                half4 vertexColor : TEXCOORD1;
                half3 worldNormal : TEXCOORD2;
                float3 worldPos : TEXCOORD3;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _ILMTex;
            sampler2D _SssTex;
            sampler2D _DetailTex;

            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv.xy = TRANSFORM_TEX(v.uv0, _MainTex);
                o.uv.zw = v.uv1;
                o.vertexColor = v.color;
                o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
                o.worldNormal = mul(v.normal,(float3x3)unity_WorldToObject);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                fixed4 ilm = tex2D(_ILMTex,i.uv.xy);
                fixed4 baseColor = tex2D(_MainTex, i.uv.xy);
                fixed4 sssColor = tex2D(_SssTex,i.uv.xy);
                fixed3 detail = tex2D(_DetailTex,i.uv.zw);
                half ao = saturate((i.vertexColor.r - 0.7) * 50);
                half3 worldNormal = normalize(i.worldNormal);
                half3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
                half3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
                half3 halfDir = normalize(worldLightDir + worldViewDir);
                half NdotH = saturate(dot(halfDir,worldNormal));
                half NdotL = dot(worldLightDir,worldNormal);
                half sssFactor = saturate((NdotL * 0.5 + 0.5 - i.vertexColor.b * 0.5) * 50) * ao;
                fixed4 finalColor = 1;
                finalColor.rgb = lerp(sssColor,baseColor,sssFactor) * detail * ilm.a;
                return finalColor;
            }
            ENDCG
        }
    }
}

Análisis de recursos

Modelo

Color de vértice:

Canal B gris del modelo
Insertar descripción de la imagen aquí

Recursos de textura

Insertar descripción de la imagen aquí

SOL_base_Efecto de bloque de color básico:

Insertar descripción de la imagen aquí

Entre ellos, el efecto del canal SOL_base_A:

Insertar descripción de la imagen aquí

  • Entre ellos, el canal A consiste en dibujar en negro el área del patrón de texto del personaje.
SOL_ilm: como sigue

Insertar descripción de la imagen aquí

Distribución regional en el modelo SOL_ilm

como sigue:
Insertar descripción de la imagen aquí

- De izquierda a derecha, RGBA.
  • Canal R: controla la intensidad general de las luces.

  • Canal G: controla el valor de compensación de la iluminación NdotL, como las arrugas.

  • Canal B: controla el tamaño, rango o forma del resaltado.

  • Un canal: la línea de dibujo interior del modelo de personaje.

  • Color de vértice:

  • Canal R: AO, también controla la compensación de iluminación NdotL.

SOL_Sss: como sigue

Insertar descripción de la imagen aquí

El efecto de SOL_ilm en el modelo.

Insertar descripción de la imagen aquí

El color obtenido multiplicando el valor de SSSTexture y el color de la luz ambiental determina el color de la sombra. Color de luz clave para
zonas brillantes Color de luz ambiental para zonas oscuras

mejoramiento

Imagen de cuerpo completo antes de la optimización.

Insertar descripción de la imagen aquí

Imagen de cuerpo entero optimizada

Insertar descripción de la imagen aquí

cuadro comparativo facial

Insertar descripción de la imagen aquí

Cuadro comparativo de brazadas con cinturón y brazo

Insertar descripción de la imagen aquí

Cuadro comparativo

Por favor agregue la descripción de la imagen.

Código de renderizado

Shader "SOL"
{
    
    
    Properties
    {
    
    
        [Header(BaseColor)]
        _MainTex ("BaseTex", 2D) = "white" {
    
    }
        [Space(20)]
        [Header(ILM)]
        _ILMTex("ILMTex",2D) = "gray"{
    
    }
        [Space(20)]
        [Header(SSS)]
        _SssTex("SssTex",2D) = "black"{
    
    }
        [Space(20)]
        [Header(Detail)]
        _DetailTex("DetailTex",2D) = "white"{
    
    }
        _ToonThreshold("ToonThreshold",Range(0,1)) = 0.5
        _ToonHardness("ToonHardness",Float) = 20.0
        _SpecColor("spec color", Color) = (1,1,1,1)
        _SpecSize("Spec Size",Range(0,1)) = 1
        [Space(20)]
        [Header(OutLine)]
        _OutlineColor("Outline Color", Color) = (0,0,0,0)
        _Outlinewidth("Outline Width",Range(0,1)) = 1
    }
    SubShader
    {
    
    
        Tags {
    
     "RenderType"="Opaque" }
        LOD 100
        Pass
        {
    
    
            Tags{
    
    "LightMode"="ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
                float2 uv1 : TEXCOORD1;
                half3 normal : NORMAL;
                half4 color : COLOR;
            };

            struct v2f
            {
    
    
                float4 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                half4 vertexColor : TEXCOORD1;
                half3 worldNormal : TEXCOORD2;
                float3 worldPos : TEXCOORD3;
            };

            sampler2D _MainTex;
            sampler2D _ILMTex;
            sampler2D _SssTex;
            sampler2D _DetailTex;

            half _ToonThreshold;
            half _ToonHardness;
            half _SpecSize;

            //没有定义"float4 _SpecColor" 是因为在#include "UnityLightingCommon.cginc"文件里已经被声明。
            // float4 _SpecColor;

            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = float4 (v.uv0,v.uv1);
                o.vertexColor = v.color;
                o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
                o.worldNormal = mul(v.normal,(float3x3)unity_WorldToObject);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                half2 uv1 = i.uv.xy;
                half2 uv2 = i.uv.zw;
                //贴图采样、亮部和暗部的颜色、控制高光的强度
                fixed4 ilm = tex2D(_ILMTex,i.uv.xy);
                half spec_intensity = ilm.r;//控制高光强度
                half diffuse_control = ilm.g * 2.0 - 1.0;//光照偏移
                half spec_size = ilm.b;//控制高光形状
                half inner_line = ilm.a;//内描线
                fixed4 baseColor = tex2D(_MainTex, i.uv.xy);//亮部的颜色
                fixed4 sssColor = tex2D(_SssTex,i.uv.xy);//暗部的颜色
                fixed3 detail = tex2D(_DetailTex,i.uv.zw);//细节线条
                //顶点处理
                half ao = saturate((i.vertexColor.r - 0.7) * 50);
                //向量
                half3 worldNormal = normalize(i.worldNormal);
                half3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
                half3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
                //漫反射
                half NdotL = dot(worldLightDir,worldNormal);
                half halflambert = (NdotL + 1.0) * 0.5;
                half lambertterm = halflambert * ao + diffuse_control;
                half toondiffuse = saturate ((lambertterm - _ToonThreshold) * _ToonHardness);
                half3 finaldiffuse  = lerp(sssColor ,baseColor,toondiffuse);

                //高光
                float NdotV = (dot(worldNormal,worldViewDir) + 1.0) * 0.5;
                float spec_term = NdotV * ao + diffuse_control;
                spec_term = halflambert * 0.9 + spec_term * 0.1;
                half toon_spec = saturate((spec_term - (1.0 - spec_size * _SpecSize)) * 500);
                half3 speccolor = (_SpecColor.xyz + baseColor) * 0.5;
                half3 finaspec = toon_spec * speccolor * spec_intensity;

                //描线
                half3 inner_line_Color = lerp(baseColor * 0.2 , float3(1.0,1.0,1.0),inner_line);
                half3 ditailcolor = tex2D(_DetailTex , uv2);
                ditailcolor = lerp(baseColor * 0.2, float3(1.0,1.0,1.0),ditailcolor);
                half3 finalline = inner_line_Color * inner_line_Color * ditailcolor;

                fixed3 finalColor = (finaldiffuse + finaspec) * finalline;
                return float4(finalColor,1.0);
            }
            ENDCG
        }
        Pass
        {
    
    
            Cull Front
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase
            #include "UnityCG.cginc"
            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
                half3 normal : NORMAL;
                half4 color : COLOR;
            };
            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                half4 vertexColor : TEXCOORD1;
                half3 worldNormal : TEXCOORD2;
                float3 worldPos : TEXCOORD3;
            };
            sampler2D _MainTex;
            float4 _OutlineColor;
            float _Outlinewidth;

            v2f vert (appdata v)
            {
    
    
                v2f o;
                float3 pos_VS = UnityObjectToViewPos(v.vertex);
                float3 normal_WS = UnityObjectToWorldNormal(v.normal);
                float3 outline_dir = normalize(mul((float3x3)UNITY_MATRIX_V,normal_WS));
                o.vertexColor = v.color;
                pos_VS += outline_dir * _Outlinewidth * 0.001 * v.color.a;
                o.pos = mul(UNITY_MATRIX_P,float4(pos_VS,1.0));
                o.uv = v.uv0;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                fixed3 baseColor = tex2D(_MainTex, i.uv.xy).xyz;
                half maxComponent = max(max(baseColor.r,baseColor.g),baseColor.b) - 0.004;
                half3 saturatedColor = step(maxComponent.rrr,baseColor) * baseColor;
                saturatedColor = lerp(baseColor.rgb,saturatedColor,0.6);
                half3 outlineColor = 0.8 * saturatedColor * baseColor * _OutlineColor.xyz;
                return float4(outlineColor,1.0);
            }
            ENDCG
        }
    }
}

Enlace de referencia de representación de tarjetas:

Zenji Nishikawa: El secreto de los "gráficos 3D en tiempo real de pura animación de dibujos animados"
[Traducción] El secreto de los "gráficos 3D en tiempo real de pura animación de dibujos animados" realizado en los "gráficos de juegos experimentales" de Zenji Nishikawa "GUILTY GEAR Xrd -SIGN- ", Parte 1 (1)

Supongo que te gusta

Origin blog.csdn.net/xukaibo111/article/details/133418246
Recomendado
Clasificación