【问题标题】:How to make radial gradient skybox in Unity?如何在 Unity 中制作径向渐变天空盒?
【发布时间】:2017-01-07 22:09:28
【问题描述】:

好的,我是天空盒的新手,在尝试实现径向渐变天空盒时遇到了一些问题。我有一个径向渐变着色器,但是当我把它作为天空盒时,在两种颜色之间插值的部分被放大了,这意味着你根本无法真正分辨出它的渐变。

我认为这是因为它的着色器不适用于天空盒。然后我找到了一个线性渐变天空盒的着色器,它可以作为线性渐变,但我需要它是径向的,比如从中心颜色向外。

我到处找,但找不到径向渐变 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
        }
    } 
}

像这样 -

【问题讨论】:

  • 你需要解释你想要的外观。你想让天空盒的每一边都有一个径向渐变吗?或者您只是想要一个始终在同一个位置的具有单一径向渐变的天空?
  • 在我的问题中举一个例子 - 只是一个保持在同一个地方的径向

标签: c# unity3d radial-gradients skybox


【解决方案1】:

要创建示例图像,您根本不需要使用天空盒。

  • 创建平面或四边形
  • 向其添加径向渐变着色器或径向渐变纹理
  • 确保您使用的任何着色器都是“未点亮的”
  • 在网格组件上禁用阴影投射和阴影接收
  • 移动飞机并调整其大小,使其位于场景中您想要的位置
  • 可以选择将其作为摄像头的父项,或者创建一个“跟随”脚本(如果您始终希望看到它)
  • 将其设置在不同的绘图层上,使其像天空盒一样发挥作用,并且不会与游戏其余部分所在的绘图层交互
  • 确保绘制层在层顺序中是最低的,以便它始终位于所有内容的下方

【讨论】:

  • 我认为这是一个更好的解决方案...我要试一试。
【解决方案2】:

您提供的着色器代码确实绘制了径向渐变,仅沿 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 时,我只是得到一个垂直渐变,而不是径向渐变(请参阅我的图片问题)
  • 还有那个角度参数是什么?
  • 您的视图是否处于 2D 模式?这会让它看起来是一个线性渐变。
  • 不,在我的游戏中,当我点击播放时,它看起来是垂直的线性
猜你喜欢
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 1970-01-01
  • 1970-01-01
  • 2019-06-10
相关资源
最近更新 更多