如何在Unity中制作径向渐变天空盒?

3

嗯,我是新手,对于天空盒还有一些问题需要解决,我试图实现一个从中心开始向外扩散的径向渐变天空盒。我有一个径向渐变着色器,但是当我将其作为天空盒时,两个颜色之间的过渡部分太放大了,意味着你几乎看不到渐变效果。

enter image description here

我认为这是因为它是一个并非用于天空盒的着色器。然后我发现了一个用于线性渐变天空盒的着色器,它的渐变效果是线性的,但我需要的是径向渐变,就像从中心颜色向外扩散。

我已经到处寻找径向渐变SKYBOX着色器,但找不到。我的问题是,如何将线性渐变着色器转化为针对天空盒的径向渐变着色器?或者,如何让我现有的径向渐变着色器适用于天空盒?

下面是线性渐变天空盒的代码(非本人编写):

Shader "Custom/Horizontal Skybox"
{
    Properties
    {
        _Color1 ("Top Color", Color) = (1, 1, 1, 0)
        _Color2 ("Horizon Color", Color) = (1, 1, 1, 0)
        _Color3 ("Bottom Color", Color) = (1, 1, 1, 0)
        _Exponent1 ("Exponent Factor for Top Half", Float) = 1.0
        _Exponent2 ("Exponent Factor for Bottom Half", Float) = 1.0
        _Intensity ("Intensity Amplifier", Float) = 1.0
    }

    CGINCLUDE

    #include "UnityCG.cginc"

    struct appdata
    {
        float4 position : POSITION;
        float3 texcoord : TEXCOORD0;
    };

    struct v2f
    {
        float4 position : SV_POSITION;
        float3 texcoord : TEXCOORD0;
    };

    half4 _Color1;
    half4 _Color2;
    half4 _Color3;
    half _Intensity;
    half _Exponent1;
    half _Exponent2;

    v2f vert (appdata v)
    {
        v2f o;
        o.position = mul (UNITY_MATRIX_MVP, v.position);
        o.texcoord = v.texcoord;
        return o;
    }

    half4 frag (v2f i) : COLOR
    {
        float p = normalize (i.texcoord).y;
        float p1 = 1.0f - pow (min (1.0f, 1.0f - p), _Exponent1);
        float p3 = 1.0f - pow (min (1.0f, 1.0f + p), _Exponent2);
        float p2 = 1.0f - p1 - p3;
        return (_Color1 * p1 + _Color2 * p2 + _Color3 * p3) * _Intensity;
    }

    ENDCG

    SubShader
    {
        Tags { "RenderType"="Background" "Queue"="Background" }
        Pass
        {
            ZWrite Off
            Cull Off
            Fog { Mode Off }
            CGPROGRAM
            #pragma fragmentoption ARB_precision_hint_fastest
            #pragma vertex vert
            #pragma fragment frag
            ENDCG
        }
    } 
}

像这样 -

输入图片描述

输入图片描述


你需要解释一下你想要的外观。你想让天空盒的每一面都有一个径向渐变吗?还是只想要一个带有单个径向渐变的天空,总是在同一个位置? - Soviut
我会在我的问题中举一个例子 - 只是一个停留在同一位置的径向。 - blue
2个回答

2
为了创建示例图像,您不需要使用天空盒。
  • 创建一个平面或四边形
  • 将径向渐变着色器或径向渐变的纹理添加到其上
  • 确保您使用的任何着色器都是“未照明”的
  • 在网格组件上禁用阴影投射和接收阴影
  • 移动和调整平面的大小,使其位于场景中所需的位置
  • 如果您希望它始终处于视图中,请选择将其作为相机的子级或创建“跟随”脚本
  • 将其设置为不同的绘制层,以便它像天空盒一样运行,并且不会与游戏的其他绘制层交互
  • 确保该绘制层是层次顺序中最低的,以便它始终位于所有内容下方

我认为这是一个更好的解决方案... 我打算试一试。 - Daniele

1
您提供的着色器代码确实绘制了径向渐变,但仅沿y轴方向。如果通过更改行来翻转轴,则可以解决该问题。
float p = normalize (i.texcoord).y;

float p = normalize (i.texcoord).x;

编辑:

由于您实际上想要旋转渐变,您可以在顶点着色器中执行以下操作(1.57是pi/2)。

v2f vert (appdata v)
{
    v2f o;
    float sinX = sin ( 1.57 );
    float cosX = cos ( 1.57 );
    float sinY = sin ( 1.57 );
    float2x2 rotationMatrix = float2x2( cosX, -sinX, sinY, cosX);
    o.position = mul (UNITY_MATRIX_MVP, v.position);
    o.texcoord.xz = mul(v.texcoord.xz, rotationMatrix);
    o.texcoord.y = v.texcoord.y;
    return o;
}

编辑2:

完整代码:

Shader "Custom/Horizontal Skybox"
{
    Properties
    {
        _Color1 ("Top Color", Color) = (1, 1, 1, 0)
        _Color2 ("Horizon Color", Color) = (1, 1, 1, 0)
        _Color3 ("Bottom Color", Color) = (1, 1, 1, 0)
        _Exponent1 ("Exponent Factor for Top Half", Float) = 1.0
        _Exponent2 ("Exponent Factor for Bottom Half", Float) = 1.0
        _Intensity ("Intensity Amplifier", Float) = 1.0
        _Angle ("Angle", Float) = 0.0
    }

    CGINCLUDE

    #include "UnityCG.cginc"

    struct appdata
    {
        float4 position : POSITION;
        float3 texcoord : TEXCOORD0;
    };

    struct v2f
    {
        float4 position : SV_POSITION;
        float3 texcoord : TEXCOORD0;
    };

    half4 _Color1;
    half4 _Color2;
    half4 _Color3;
    half _Intensity;
    half _Exponent1;
    half _Exponent2;
    half _Angle;

    v2f vert (appdata v)
    {
        v2f o;
        float sinX = sin ( _Angle );
        float cosX = cos ( _Angle );
        float sinY = sin ( _Angle );
        float2x2 rotationMatrix = float2x2( cosX, -sinX, sinY, cosX);
        o.position = mul (UNITY_MATRIX_MVP, v.position);
        o.texcoord.xz = mul(v.texcoord.xz, rotationMatrix);
        o.texcoord.y = v.texcoord.y;
        return o;
    }

    half4 frag (v2f i) : COLOR
    {
        float p = normalize (i.texcoord).x;
        float p1 = 1.0f - pow (min (1.0f, 1.0f - p), _Exponent1);
        float p3 = 1.0f - pow (min (1.0f, 1.0f + p), _Exponent2);
        float p2 = 1.0f - p1 - p3;
        return (_Color1 * p1 + _Color2 * p2 + _Color3 * p3) * _Intensity;
    }

    ENDCG

    SubShader
    {
        Tags { "RenderType"="Background" "Queue"="Background" }
        Pass
        {
            ZWrite Off
            Cull Off
            Fog { Mode Off }
            CGPROGRAM
            #pragma fragmentoption ARB_precision_hint_fastest
            #pragma vertex vert
            #pragma fragment frag
            ENDCG
        }
    }
}

好的,谢谢。但是对我来说,当我改为x而不是y时,我得到的只是一个垂直渐变,而不是径向渐变(请参见我的问题中的图片)。 - blue
还有,你所说的那个角度参数是什么? - blue
你的视图是2D模式吗?那会让它看起来像是一个线性渐变。 - Jephron
不,我的游戏在我点击播放时,看起来是垂直线性的。 - blue

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