You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

自定义双面混合Shader显示异常:纹理暗淡、法线反射弱

解决你的纹理混合Shader问题

嘿,作为Shader新手能写出这样的代码已经很棒啦!咱们来看看你遇到的几个问题,一步步修复它们:

问题根源分析

你的Shader出现纹理暗淡、法线反射失效、金属度异常的核心原因是法线处理错误,还有一些小细节需要调整:

  • 你直接将法线纹理的颜色值(还乘以了_Color)赋值给o.Normal,但法线纹理的RGB是压缩的切线空间方向信息,必须用UnpackNormal函数转换才能被光照系统正确识别
  • 法线方向不能被颜色 tint,这会破坏法线的方向向量,导致光照计算完全出错
  • 冗余的UV声明可能会导致不必要的性能开销(如果不需要独立的UV缩放/偏移的话)

修正后的Shader代码

Shader "Custom/TextureBlend" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _Blend ("Texture Blend", Range(0,1)) = 0.0
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _MainTex2 ("Albedo 2 (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _BumpMap ("Bumpmap", 2D) = "bump" {}
        _BumpMap2 ("Bumpmap 2", 2D) = "bump" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        Cull Off // 实现双面显示
        ZTest LEqual

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _MainTex2;
        sampler2D _BumpMap;
        sampler2D _BumpMap2;

        struct Input {
            float2 uv_MainTex; // 复用该UV给所有纹理,若需独立UV可自行添加
        };

        half _Blend;
        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            // 混合两张Albedo纹理并叠加颜色
            fixed4 c = lerp(tex2D(_MainTex, IN.uv_MainTex), tex2D(_MainTex2, IN.uv_MainTex), _Blend) * _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;

            // 正确处理法线:先解包再混合
            fixed3 normal1 = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
            fixed3 normal2 = UnpackNormal(tex2D(_BumpMap2, IN.uv_MainTex));
            o.Normal = lerp(normal1, normal2, _Blend);

            // 金属度与光滑度设置
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

关键修改点说明

  1. 法线处理修复

    • 使用UnpackNormal函数分别解包两张法线纹理,得到正确的切线空间法线向量
    • 对解包后的法线向量进行lerp混合,而非混合纹理颜色后再处理
    • 移除了法线乘以_Color的错误操作——法线是方向信息,不能被颜色染色
  2. UV优化

    • 移除冗余的uv_MainTex2uv_BumpMap2,复用uv_MainTex给所有纹理(若需给第二张纹理单独设置UV缩放/偏移,可重新添加这些UV,并在Properties中补充对应的_MainTex2_ST等属性)
  3. 属性命名修正

    • _BumpMap2的属性名改为Bumpmap 2,避免与第一个法线图名称重复,在Inspector面板中更清晰

原问题效果参考

修复前自定义Shader与Standard Shader对比

使用自定义Shader与Standard Shader的平面对比

修复前金属度滑块右调后的异常效果

金属度滑块右调后的异常反射效果

修复后,你的Shader应该能和Standard Shader表现一致:法线反射正常、金属度调整无异常,同时保留双面显示的功能~

内容的提问来源于stack exchange,提问作者Rumata

火山引擎 最新活动