Как сделать радиальный градиент скайбокса в Unity?
Хорошо, я новичок в скайбоксе, и у меня возникают некоторые проблемы при попытке получить РАДИАЛЬНЫЙ градиентный скайбокс. У меня есть шейдер с радиальным градиентом, однако, когда я ставлю его в качестве скайбокса, часть, которая интерполирует два цвета, слишком сильно увеличена, что означает, что вы вообще не можете определить его градиент.
Я думаю, это потому, что это шейдер, который не предназначен для скайбоксов. Затем я нашел шейдер для скайбокса с линейным градиентом, который работает как линейный градиент, но мне нужно, чтобы он был радиальным, как от центрального цвета наружу.
Я искал везде, но не могу найти шейдер радиального градиента SKYBOX. Мой вопрос - как можно превратить линейный градиентный шейдер в радиальный для скайбокса? Или как я могу заставить мой существующий радиальный градиент работать для скайбоксов?
Я не писал это, но это код для линейного градиента 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
}
}
}
Как это -
2 ответа
Код шейдера, который вы указали, рисует радиальный градиент только вдоль оси y. Если вы переверните ось, изменив линию
float p = normalize (i.texcoord).y;
в
float p = normalize (i.texcoord).x;
Редактировать:
Поскольку вы действительно хотите повернуть градиент, вы можете сделать следующее в вершинном шейдере (1,57 - это пи /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
}
}
}
Для создания примера изображения вам не нужно вообще использовать скайбокс.
- Создать плоскую плоскость или квад
- Добавьте шейдер радиального градиента или текстуру радиального градиента к нему
- Убедитесь, что используемый вами шейдер "не горит"
- Отключить отбрасывание теней и получение теней в сетке
- Переместите и измерьте размер плоскости так, чтобы она сидела в нужном месте на сцене
- При желании привязать его к камере или создать скрипт "follow", если вы всегда хотите, чтобы он был на виду
- Установите его на другой слой прорисовки, чтобы он действовал как скайбокс и не взаимодействовал со слоями прорисовки, в которые включена остальная часть вашей игры.
- Убедитесь, что слой рисования является самым низким в порядке слоя, так что он всегда ниже всего