es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo aplico un mapa de relieve a solo un lado mientras uso Triplanar?

Estoy utilizando unity.

Utilicé Triplanar para hacer que la parte superior del cubo sea un terreno de nieve y las demás caras sean un terreno de acantilado.

Aquí tengo que insertar un mapa de normales.

Sin embargo, si se aplica el mapa de normales, la imagen del acantilado queda cubierta por la imagen del terreno de nieve.

El fenómeno se muestra en la siguiente imagen. aquí

Propiedades {
[NoScaleOffset] MainTex (“TopTex”, 2D) = “white” {}
_MainTexUV(“tileU, tileV, offsetU, offsetV”, vector) = (1, 1, 0, 0)
[NoScaleOffset] MainTex2(“sideTex”, 2D) = “white” {}
_MainTex2UV(“tileU, tileV, offsetU, offsetV”, vector) = (1, 1, 0, 0)
_Bumpmap (“NormalMap”, 2D) = “bump” {}
}

SubShader {
Tags { “RenderType”=”Opaque” }
}

CGPROGRAM
#pragma surface surf Standard fullforwardshadows

sampler2D _MainTex;
sampler2D _MainTex2;
sampler2D _Bumpmap;

float4 _MainTexUV;
float4 _MainTex2UV;

struct Input {
float2 uv_Bumpmap;
float3 worldPos;
float3 worldNormal;
INTERNAL_DATA
};

void surf (Input IN, inout SurfaceOutputStandard o) {
float2 topUV = float2(IN.worldPos.x, IN.worldPos.z);
float2 frontUV = float2(IN.worldPos.x, IN.worldPos.y);
float2 sideUV = float2(IN.worldPos.z, IN.worldPos.y);

o.Normal = UnpackNormal(tex2D(_Bumpmap, IN.uv_Bumpmap));

float4 topTex = tex2D(_MainTex, topUV * _MainTexUV.xy + _MainTexUV.zw);
float4 frontTex = tex2D (_MainTex2, frontUV * _MainTex2UV.xy + _MainTex2UV.zw);
float4 sideTex = tex2D (_MainTex2, sideUV * _MainTex2UV.xy + _MainTex2UV.zw);

o.Albedo = lerp(topTex, frontTex, abs(IN.worldNormal.z));
o.Albedo = lerp(o.Albedo, sideTex, abs(IN.worldNormal.x));
o.Alpha = 1;

}
ENDCG

Fallback “Diffuse”

¿Por qué sucede esto?

Además, ¿cómo puedo aplicar el mapa de normales solo a un lado?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    La razón por la cual la imagen del terreno nevado cubre la cara del acantilado cuando se aplica el mapa de normales es que el código del shader mezcla la textura de albedo del terreno nevado y del acantilado basándose en la dirección normal de la superficie. Dado que el mapa de normales afecta la dirección normal de la superficie, también afecta la mezcla en esas áreas, lo que resulta en que la textura de nieve cubra partes de la textura de acantilado.

    Para aplicar el mapa de normales solo a un lado, es necesario modificar el código del shader en la función “surf”. En lugar de interpolar entre las tres texturas basándose en el valor absoluto de la normal del mundo, se puede usar una declaración condicional para verificar la dirección de la normal de la superficie y aplicar el mapa de normales solo al lado deseado. Por ejemplo, si se desea aplicar el mapa de normales solo al terreno de nieve en la parte superior, se puede modificar el código de la siguiente manera:

    void surf (Input IN, inout SurfaceOutputStandard o)
    {
        float2 topUV = float2(IN.worldPos.x, IN.worldPos.z);
        float2 frontUV = float2(IN.worldPos.x, IN.worldPos.y);
        float2 sideUV = float2(IN.worldPos.z, IN.worldPos.y);
    
        float4 topTex = tex2D(_MainTex, topUV * _MainTexUV.xy + _MainTexUV.zw);
        float4 frontTex = tex2D (_MainTex2, frontUV * _MainTex2UV.xy + _MainTex2UV.zw);
        float4 sideTex = tex2D (_MainTex2, sideUV * _MainTex2UV.xy + _MainTex2UV.zw);
    
        if (IN.worldNormal.y > 0) // aplicar el mapa de normales solo al terreno de nieve en la parte superior
        {
            o.Normal = UnpackNormal(tex2D(_Bumpmap, IN.uv_Bumpmap));
            o.Albedo = topTex;
        }
        else // aplicar el cálculo normal regular al terreno de acantilado en los lados
        {
            o.Normal = UnpackNormal(tex2D(_Bumpmap, IN.uv_Bumpmap));
            o.Albedo = lerp(sideTex, frontTex, abs(IN.worldNormal.z));
            o.Albedo = lerp(o.Albedo, topTex, abs(IN.worldNormal.y));
        }
        o.Alpha = 1;
    }
    

    En este caso, el código del shader aplica el mapa de normales solo al terreno de nieve en la parte superior, como se especifica en la declaración condicional if (IN.worldNormal.y > 0). Para el terreno de acantilado en los lados, utiliza el cálculo normal regular para mezclar las texturas de albedo.

Comments are closed.