如何使3D文本着色器不发光?

8
在Unity中,如何防止我的3D文字在黑暗中发光?
例如,我正在使用以下着色器代码,但文本比其他物体更亮/自发光。切换到“灯光打开”可以消除发光,但也会消除材质颜色并变为黑色。
如何解决这个问题?非常感谢!
Shader "GUI/3D Text Shader - Cull Back" {
Properties {
    _MainTex ("Font Texture", 2D) = "white" {}
    _Color ("Text Color", Color) = (1,1,1,1)
}

SubShader {
    Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    Lighting Off Cull Back ZWrite Off Fog { Mode Off }
    Blend SrcAlpha OneMinusSrcAlpha
    Pass {
        Color [_Color]
        SetTexture [_MainTex] {
            combine primary, texture * primary
        }
    }
}

不是一个确切的答案,但如果您将其设计为片段着色器而不是使用内置方向,则可以获得更多控制权。https://docs.unity3d.com/Manual/SL-VertexFragmentShaderExamples.html - Absinthe
也许我读错了,但是从材质的检查器中无法调整_Color属性的亮度吗? - Lece
1
这确实会调整RGB的亮度,但它不会调整环境中的发射亮度。例如,考虑一个颜色为rgb(255,0,0)的文本,它是红色的;如果我的3D场景中没有任何光源,那么这个文本将不会显示(因为它是漆黑的)。这对于任何其他3D网格都可以正常工作,但是对于字体来说,它们现在将有效地“在黑暗中发光”。(随着颜色变得越来越暗,发光会减少,但问题仍然存在。) - Philipp Lenssen
我怀疑发光的辐射只是物体的未照明颜色与一个黑暗/光线不均匀的场景形成对比?一个照亮的着色器可以解决这个问题,然而Unity的TextMesh组件似乎不会生成网格法线,因此着色器的光照计算将会出错(如果有编译的话)。这就解释了为什么Lighting On输出黑色。没有访问TextMesh内部并受限于固定功能着色器的限制,一个自定义的着色器可能是你在这里唯一的选择。如果您愿意,我可以发布一个进行测试? - Lece
是的,准确地说,“发光”基本上只是该颜色的完美RGB在屏幕上显示,就好像它没有受到环境或3D渲染的影响,因此看起来像是闪闪发亮的。是的,很高兴测试您可能拥有的任何着色器! - Philipp Lenssen
1个回答

6

摘自评论,用于补充背景:

我怀疑发光只是物体未照明的颜色与暗/灯光变化的场景之间对比引起的?一个有光照的着色器可以解决这个问题,然而Unity的TextMesh组件似乎不会生成网格法线,因此着色器的光照计算将受损(如果有的话将被编译)。这就解释了为什么Lighting On会输出黑色。没有访问TextMesh内部的权限并受限于固定功能着色器的限制,自定义着色器可能是你唯一的选择。

以下是使用Lambert光照模型的基本表面着色器。在底层,它将编译成一个具有Unity的光照计算的标准顶点/片段着色器,自动注入。它已经被编写为可直接替换,所以只需将其添加到您的项目中,并将其拖放到您的材质上即可:

Shader "GUI/3D Text Shader - Lit"
{
    Properties
    {
        _Color ("Text Color", Color) = (1,1,1,1)
        _MainTex ("Font Texture", 2D) = "white" {}
    }

    SubShader
    {
        Tags {"RenderType"="Transparent" "Queue"="Transparent"}
        Cull Back

        CGPROGRAM   
        #pragma surface SS_Main Lambert vertex:VS_Main alpha:blend 
        #pragma target 3.0

        uniform fixed4 _Color;
        uniform sampler2D _MainTex;

        struct Output
        {
             float4 vertex    : POSITION;
             float3 normal    : NORMAL;     
             float4 texcoord  : TEXCOORD0;
             float4 texcoord1 : TEXCOORD1;
             float4 texcoord2 : TEXCOORD2;
        };

        struct Input
        {
            float2 uv_MainTex;
        };      

        void VS_Main (inout Output o) 
        {          
            // Generate normals for lighting.
            o.normal = float3(0, 0, -1);
        }

        void SS_Main (Input IN, inout SurfaceOutput o)
        {       
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = _Color.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
}

1
现在一切都正常了,并且已经标记为答案,非常感谢您的帮助!VR沙盒宇宙Anyland将不胜感激! - Philipp Lenssen
@PhilippLenssen 很好,不用谢!祝你的项目好运 :) - Lece

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接