Как я могу создать «шаткую поверхность» или «shaller shuder» в Unity?
В моей игре мне нужно создать динамические водяные лужи, но я не могу найти учебник, который показывает, как я могу сделать такой эффект (пример которого показан ниже). Как я могу это сделать?
1 ответ
Отражение
Чтобы создать мокрый шейдер, сначала нужно иметь отражение.
Вы можете использовать Reflection Probe или MirrorReflection3 , но я использую фальшивое отражение (Cube Map) здесь, потому что шейдер можно использовать на мобильных устройствах.
Шейдер "Smkgames /TransparentCubeMap" {
Свойства {
_Цвет («Цвет», Цвет) = (1,1,1,1)
_Cube ("Cubemap", CUBE) = "" {}
_Metallic («Metallic», Range (0,1)) = 1
_Smoothness («Гладкость», Диапазон (0,1)) = 1
_Alpha («Alpha», Range (0,1)) = 1
}
SubShader {
Теги {"RenderType" = "Прозрачный" "Очередь" = "Прозрачный"}
LOD 200
Проходить {
ColorMask 0
}
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
CGPROGRAM
#pragma surface surf Стандартные fullforwardshadows alpha: fade
struct Input {
float2 uv_MainTex;
float3 worldRefl;
};
sampler2D _MainTex;
samplerCUBE _Cube;
float4 _Color;
float _Metallic;
float _Smoothness;
float4 _EmissionColor;
float _Alpha;
void surf (вход IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb * 0.5 * _Color;
o.Emission = texCUBE (_Cube, IN.worldRefl) .rgb * _Color;
o.Metallic = _Metallic;
o.Smoothness = _Smoothness;
o.Alpha = _Alpha;
}
ENDCG
}
Резервный «Диффузный»
}
Искажение
Чтобы добавить искажение к вашему отражению, вы можете умножить нормальную карту и worldRefl
:
float3 distortion = tex2D (_Distortion, IN.uv_Distortion);
o.Emission = texCUBE (_Cube, IN.worldRefl * искажение) .rgb
Процедурная форма
Вы можете использовать шум для создания процедурной формы:
Вот учебник Fractal Brownian Motion (FBM) .
Shader "Smkgames /FbmNoise"
{
свойства
{
_TileAndOffset («Плитка и смещение», Вектор) = (1,1,0,0)
}
SubShader
{
Теги {"RenderType" = "Непрозрачный"}
LOD 100
Проходить
{
CGPROGRAM
#pragma vertex vert
#pragma фрагмент фрагмент
//Делаем туманную работу
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex: POSITION;
float2 uv: TEXCOORD0;
};
struct v2f
{
float2 uv: TEXCOORD0;
UNITY_FOG_COORDS (1)
float4 vertex: SV_POSITION;
};
float4 _TileAndOffset;
float _Step, _Min, _Ma;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos (v.vertex);
o.uv = v.uv * _TileAndOffset.xy + _TileAndOffset.zw;
UNITY_TRANSFER_FOG (о, o.vertex);
return o;
}
//Автор @patriciogv - 2015
//http://patriciogonzalezvivo.com
float random (in float2 st) {
return frac (sin (точка (st.xy,
float2 (12.9898,78.233))) *
43758,5453123);
}
//Основано на Morgan McGuire @ morgan3d
//https://www.shadertoy.com/view/4dS3Wd
поплавковый шум (в float2 st) {
float2 i = floor (st);
float2 f = frac (st);
//Четыре угла в 2D плитки
float a = random (i);
float b = random (i + float2 (1.0, 0.0));
float c = random (i + float2 (0.0, 1.0));
float d = random (i + float2 (1.0, 1.0));
float2 u = f * f * (3.0 - 2.0 * f);
return lerp (a, b, u.x) +
(c - a) * u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
#define OCTAVES 6
float fbm (in float2 st) {
//Начальные значения
float value = 0.0;
амплитуда плавания = .5;
частота вращения = 0;
//
//Петля октав
для (int i = 0; i <OCTAVES; i ++) {
значение + = амплитуда * шум (st);
st * = 2;
амплитуда * = .5;
}
возвращаемое значение;
}
fixed4 frag (v2f i): SV_Target
{
float2 st = i.uv;
float3 color = float3 (0,0,0);
color + = fbm (st * 3.0);
return float4 (цвет, 1.0);
}
ENDCG
}
}
}
Вышеупомянутый FBM не должен использоваться непосредственно в вашем шейдере, поскольку он имеет много графических расчетов и снижает производительность. Вместо прямого использования вы можете сделать результат текстурой с RenderTexture .
Shadertoy использует несколько проходов , по одному на« буфер ». Как видно из названия, этот проход сохраняет результаты в буфере, который является только текстурой. Unity также позволит вам визуализировать текстуры.
Создание маски
Вы можете сделать густую и гладкую маску с помощью следующих функций:
Выходы 1, если [A]
меньше или равно [B]
, в противном случае выдает 0.
Смешивается плавно между двумя значениями, основываясь на том, где третье значение находится в этом диапазоне, выводя значения между 0 и 1. Думайте об этом как зажатый обратный ерп с сглаженным выходным значением.
Результат
/* Внимание: не используйте этот шейдер, потому что это только для предварительного просмотра.
Он имеет много графических расчетов, поэтому, если вы хотите использовать это в своей игре, вы должны
удалить функции шума FBM или визуализировать их текстурой, или вы можете использовать текстуру FBM
* /
//Создано Сейедом Мортезой Камали
Shader "Smkgames /WetShader" {
Свойства {
_MainTex («MainTex», 2D) = «белый» {}
_Distortion («Искажение», 2D) = «удар» {}
_Cube ("Cubemap", CUBE) = "" {}
_BumpMap ("Bumpmap", 2D) = "bump" {}
_Metallic («Metallic», Range (0,1)) = 0
_Smoothness («Гладкость», Диапазон (0,1)) = 1
_ReflectAlpha («ReflectAlpha», Range (0,1)) = 1
scaleX («Шкала UV.X», Float) = 10.0
scaleY ("UV.Y scale", Float) = 10.0
_Smooth ("Smooth", Float) = 0.4
_Intensity ("Интенсивность", Float) = 1
}
SubShader {
Теги {"RenderType" = "Прозрачный" "Очередь" = "Прозрачный"}
LOD 200
Проходить{
ColorMask 0
}
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
CGPROGRAM
#pragma surface surf Стандартные fullforwardshadows alpha: fade
struct Input {
float2 uv_MainTex;
float2 uv_Distortion;
float3 worldRefl;
float2 uv_BumpMap;
INTERNAL_DATA
};
sampler2D _MainTex, _Distortion;
samplerCUBE _Cube;
float _Metallic, _Smoothness;
float4 _EmissionColor;
sampler2D _NormalMap;
равномерная фиксированная шкала X, масштабY, _Smooth, _Intensity, _Alpha, _ReflectAlpha;
static const float2x2 m = float2x2 (-0.5, 0.8, 1.7, 0.2);
float hash (float2 n)
{
return frac (sin (точка (n, float2 (95.43583, 93.323197))) * 65536.32);
}
поплавковый шум (float2 p)
{
float2 i = floor (p);
float2 u = frac (p);
u = u * u * (3.0 - 2.0 * u);
float2 d = float2 (1.0, 0.0);
float r = lerp (lerp (hash (i), hash (i + d.xy), u.x), lerp (hash (i + d.yx), hash (i + d.xx), u.x), u.y);
return r * r;
}
float fbm (float2 p)
{
float f = 0.0;
f + = 0,500000 * (0,5 + 0,5 * шум (p));
return f;
}
float fbm2 (float2 p)
{
float f = 0.0;
f + = 0,500000 * (0,6 + 0,45 * шум (p)); p = p * 2,02; p = mul (p, m);
f + = 0.250000 * (0.6 + 0.36 * noise (p));
return f;
}
void surf (вход IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Metallic = _Metallic;
o.Smoothness = _Smoothness;
o.Alpha = 1;
float t = fbm2 (float2 (IN.uv_MainTex.x * scaleX, IN.uv_MainTex.y * scaleY));
float fbmMask = step (t, _Smooth) * _ Интенсивность;
float3 distortion = tex2D (_Distortion, IN.uv_Distortion);
o.Emission = texCUBE (_Cube, IN.worldRefl * искажение) .rgb * _ReflectAlpha * fbmMask;
o.Albedo = float4 (1.0, 1.0, 1.0, 1.0) * tex2Dlod (_MainTex, float4 (IN.uv_MainTex, 0.0, 0.0));
}
ENDCG
}
Резервный «Диффузный»
}
Использование карт
Физическое обоснование затенения
Вот полезные определения:
Шероховатость Описывает микроповерхность объекта. Белый 1.0 грубый, а черный 0.0 - гладкий. Микроповерхность, если она шероховатая, может привести к рассеянию световых лучей и сделать подсветку более тусклой и более широкой. Такое же количество световой энергии отражается как входящее в поверхность. Эта карта имеет самую художественную свободу. Здесь нет неправильных ответов. Эта карта дает активу самый характер, поскольку он действительно описывает поверхность, например. царапины, отпечатки пальцев, пятна, грязь и т. д.
Glossiness Эта карта является обратной картой шероховатости. Белый 1.0 является гладким, а 0,0 - черным. Описывает микроповерхность объекта. Микроповерхность, если она шероховатая, может привести к рассеянию световых лучей и сделать подсветку более тусклой и более широкой. Такое же количество световой энергии отражается как входящее в поверхность. Эта карта имеет самую художественную свободу. Здесь нет неправильных ответов. Эта карта дает активу самый характер, поскольку он действительно описывает поверхность, например. царапины, отпечатки пальцев,пятна, грязь и т. д.
Зеркальное Эта карта содержит информацию отражения как для металлических, так и для диэлектрических (неметаллических) поверхностей. Это ключевое различие в рабочих процессах с металлом /грубым и spec /gloss. Те же правила применяются. Вы должны использовать измеренные значения для металлов, и большинство диэлектриков будет падать с диапазоном 0,04-4%. Если на металле есть грязь, необходимо также снизить значение отражательной способности. Тем не менее, вы можете добавлять разные значения в зеркальную карту для диэлектрических материалов, поскольку у вас есть контроль над созданием карты.
Шероховатость
Я не знаю, почему, но стандартный шейдер Unity не имеет карты гладкости, поэтому я написал базовый шейдер и добавил эту карту.
Шейдер "Smkgames /SimpleSurface" {
Свойства {
_Цвет («Цвет», Цвет) = (1,1,1,1)
_MainTex («Альбедо (RGB)», 2D) = «белый» {}
_GlossMap («GlossMap», 2D) = «белый» {}
_Glossiness («Smoothness», Float) = 1.5
_Metallic («Metallic», Float) = 0,5
_MetallicMap («MetallicMap», 2D) = «белый» {}
}
SubShader {
Теги {"RenderType" = "Непрозрачный"}
LOD 200
CGPROGRAM
#pragma surface surf Стандартные fullforwardshadows
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
половина _Glossiness, _Metallic;
fixed4 _Color;
sampler2D _GlossMap, _MetallicMap;
UNITY_INSTANCING_CBUFFER_START (реквизит)
UNITY_INSTANCING_CBUFFER_END
void surf (вход IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic * tex2D (_MetallicMap, IN.uv_MainTex);
o.Smoothness = _Glossiness * tex2D (_GlossMap, IN.uv_MainTex);
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Я думаю, что Unity не имеет шероховатости, он имеет только металлический, но альфа-канал имеет шероховатость, а красный - металлический. Вы можете изменить интенсивность с плавностью.
Полезные ссылки
https://80.lv/articles /как к создать мокрому-грязь-в-вещества-дизайнер /