极坐标
float polar_coordinates(float2 uvs) {
struct SF {
static float remap_value_range(float input, float input_low, float input_high, float target_low, float target_high) {
return (input - input_low) / (input_high - input_low) * (target_high - target_low) + target_low;
}
};
float pi = acos(-1);
float2 uv = float2(SF::remap_value_range(uvs.x, 0, 1, -1, 1), SF::remap_value_range(uvs.y, 0, 1, -1, 1));
return SF::remap_value_range(atan2(uv.x, uv.y) / pi, -1, 1, 0, 1);
}
旋转
/**
* 旋转
* rotation_center - 旋转点
* rotation_angle - 旋转角度
*/
float2 rotate(float2 uvs, float2 rotation_center, float rotation_angle) {
float pi = acos(-1);
rotation_angle *= 2 * pi;
// 逆时针旋转
float2x2 mt = float2x2(
cos(rotation_angle), sin(rotation_angle),
-sin(rotation_angle), cos(rotation_angle)
);
/** 顺时针旋转
float2x2 mt = float2x2(
cos(rotation_angle), -sin(rotation_angle),
sin(rotation_angle), cos(rotation_angle)
);
*/
return mul(uvs + rotation_center * -1, mt) + rotation_center;
}
也可以使用 UE 自带的 CustomRotator 材质函数。
溶解
/**
* 溶解
* texture2d - 纹理
* texture2d_noise - 噪点纹理
* value - 溶解程度
* edge - 溶解边缘
* xyz - 溶解边缘颜色
* w - 溶解边缘宽度
*/
float4 dissolve(float2 uvs, Texture2D texture2d, float2 uvs_noise Texture2D texture2d_noise, float value, float4 edge) {
float3 texture_color = Texture2DSampleLevel(texture2d, texture2dSampler, uvs, 0).xyz;
// float3 texture_color = Texture2DSample(texture2d, Material.Texture2D_0Sampler, uvs).xyz;
float noise_value = Texture2DSampleLevel(texture2d_noise, texture2d_noiseSampler, uvs_noise, 1).x;
// float noise_value = Texture2DSample(texture2d_noise, Material.Texture2D_1Sampler, uvs_noise).x;
value = saturate(value) * 2 - 1 + noise_value;
float dissolve_value = value * step(value, 1) * step(saturate(1 - edge.w), value);
float3 dissolve_color = edge.xyz * dissolve_value;
value = saturate(value);
float alpha = 1 - floor(value);
texture_color = lerp(texture_color, 0, value);
float3 color = saturate(texture_color + dissolve_color);
return float4(color, alpha);
}
燃烧
/**
* 燃烧
* texture2d - 纹理
* texture2d_noise - 噪点纹理
* noise_scale - 噪点尺寸
* value - 燃烧程度
* edge - 燃烧边缘
* xyz - 燃烧边缘颜色
* w - 燃烧边缘宽度
*/
float4 burn(float2 uvs, Texture2D texture2d, Texture2D texture2d_noise, float noise_scale, float value, float4 edge) {
float3 texture_color = Texture2DSampleLevel(texture2d, texture2dSampler, uvs, 0).xyz;
// float3 texture_color = Texture2DSample(texture2d, Material.Texture2D_0Sampler, uvs).xyz;
float noise_value = Texture2DSampleLevel(texture2d_noise, texture2d_noiseSampler, uvs, 1).x * noise_scale;
// float noise_value = Texture2DSample(texture2d_noise, Material.Texture2D_1Sampler, uvs).x * noise_scale;
float progress = uvs.x + noise_value;
value *= 1 + noise_scale + edge.w;
float react_1 = step(value, progress);
float react_2 = step(value - edge.w, progress);
float react_3 = react_2 - react_1;
float3 color = edge.xyz * react_3 + texture_color * react_1;
return float4(color, react_2);
}
查找边缘
float3 find_edges(float2 uvs, Texture2D texture2d, float2 texture_size) {
float GX[3][3] = {
{-1, -2, -1},
{0, 0, 0},
{1, 2, 1}
};
float GY[3][3] = {
{-1, 0, 1},
{-2, 0, 2},
{-1, 0, 1}
};
float ex = 0.f;
float ey = 0.f;
for(int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
float2 uvs_offset = float2(uvs.x + x * texture_size.x, uvs.y + y * texture_size.y);
float3 pixel_color = Texture2DSampleLevel(texture2d, texture2dSampler, uvs_offset, 0);
ex += pixel_color * GX[x + 1][y + 1];
ey += pixel_color * GY[x + 1][y + 1];
}
}
return saturate(1 - (abs(ex) + abs(ey)));
}
浮雕
float3 emboss(float2 uvs, Texture2D texture2d, float2 texture_size, float value) {
float GX[3][3] = {
{-1, -2, -1},
{0, 0, 0},
{1, 2, 1}
};
float GY[3][3] = {
{-1, 0, 1},
{-2, 0, 2},
{-1, 0, 1}
};
float ex = 0.f;
float ey = 0.f;
for(int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
float2 uvs_offset = float2(uvs.x + x * texture_size.x, uvs.y + y * texture_size.y);
float3 pixel_color = Texture2DSampleLevel(texture2d, texture2dSampler, uvs_offset, 0);
ex += pixel_color * GX[x + 1][y + 1];
ey += pixel_color * GY[x + 1][y + 1];
}
}
return value + ex + ey;
}
去色
float3 desaturation(float3 color) {
float3 factor = float3(0.299, 0.587, 0.114);
return dot(color, factor);
}
也可以使用 UE 自带的 Desaturation 表达式。
抖动
float3 shake(float2 uvs, Texture2D texture2d, Texture2D texture2d_noise, float range, float value) {
float noise_value = Texture2DSampleLevel(texture2d_noise, texture2d_noiseSampler, float2(sin(value), cos(value)), 0).x;
noise_value *= range;
// 采样红色,右移
float texture_color_r = Texture2DSampleLevel(texture2d, texture2dSampler, float2(uvs.x + noise_value, uvs.y), 1).x;
// 采样绿色,不变
float texture_color_g = Texture2DSampleLevel(texture2d, texture2dSampler, uvs, 1).y;
// 采样蓝色,左移
float texture_color_b = Texture2DSampleLevel(texture2d, texture2dSampler, float2(uvs.x - noise_value, uvs.y), 1).z;
return float3(texture_color_r, texture_color_g, texture_color_b);
}