- 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);
- }
