本系列内容全部转载自Godot Shaders网站,原版为英文,此处多为浏览器机翻,仅做汇总学习使用。
本系列每期汇总10个Shader
访问:Godot Shaders
径向等离子体屏蔽段
用于创建 2D 方向护盾的着色器
如何使用:
只需创建着色器并将其应用于其材质即可。
shader_type canvas_item;
uniform float angle : hint_range(0.0, 6.283184);
uniform float spread_angle : hint_range(0.1, 3.141592);
uniform float progress : hint_range(0.0, 1.0);
uniform float border_energy_offset : hint_range(0.0, 1.0);
uniform vec4 color : hint_color;
uniform vec4 edges_color : hint_color;
uniform float edges_valueable : hint_range(0.0, 1.0);
uniform float edges_fade : hint_range(0.0, 1.0);
void fragment(){
vec2 center = vec2(0.5);
vec2 center_uv = normalize(UV - center);
float is = 1.0 - smoothstep(0.49*progress, 0.5*progress, distance(center, UV));
vec2 frst_border = vec2(cos(angle+spread_angle/2.0), sin(angle+spread_angle/2.0));
vec2 sec_boreder = vec2(cos(angle-spread_angle/2.0), sin(angle-spread_angle/2.0));
vec2 radial_center = vec2(cos(angle), sin(angle));
float posx = step(0.0, radial_center.x); // is radial_center.x positive
float posy = step(0.0, radial_center.y); // is radial_center.y positive
// using different formulas for different radial_center.x signs
float is2 = step(min(frst_border.x, sec_boreder.x), center_uv.x)*posx;
float is3 = step(center_uv.x, max(frst_border.x, sec_boreder.x))*(1.0 - posx);
// using different formulas for different radial_center.y signs
float is4 = step(min(frst_border.y, sec_boreder.y), center_uv.y)*posy;
float is5 = step(center_uv.y, max(frst_border.y, sec_boreder.y))*(1.0-posy);
// how close to frontier is
float border_factor = 1.0 - distance(2.0*(UV - center), center_uv);
border_factor = pow(border_factor, border_energy_offset*50.0); // speeding up center fading
// how close to radial center is
float radial_center_factor = 1.0 - distance(center_uv, radial_center)/distance(frst_border, radial_center);
// how close ro radial edges is
float edge_radial_factor = (1.0 - radial_center_factor) * edges_valueable;
// applying edge fading
float edge_fade_factor = mix(radial_center_factor, 1.0, 1.0-edges_fade);
COLOR.a = min(1.0, is2+is3)*min(1.0, is4+is5)*is*border_factor*mix(color.a, edges_color.a, edge_radial_factor)*edge_fade_factor;
COLOR.rgb = mix(color.rgb, edges_color.rgb, edge_radial_factor);
}
彩虹轮廓
与@ThePadDev(https://twitter.com/ThePadDev)一起制作。
简单的轮廓画布项着色器,通过正弦运动循环颜色。包括用于偏移和加快周期以及偏移颜色(具有建议范围)的参数。
/*
Rainbow outline by @Farfalk and @ThePadDev, July 2021
Apply to canvas items with transparent backgrounds.
Check that there is sufficient transparent background space for the outline!
CC0 License (but citation is welcome <3)
*/
shader_type canvas_item;
uniform float line_thickness : hint_range(0, 20) = 1.0; // thickness of the line
uniform float sin_frequency : hint_range(0.1, 2.0) = 0.5; // frequency of the rainbow
uniform float sin_offset : hint_range(0.0, 360.0) = 0.0; // offset of the rainbow, useful to differentiate objects using the same shader
uniform float light_offset : hint_range(0.0, 1.0) = 0.5; // this offsets all color channels; if set to 0 only red green and blue colors will be shown.
void fragment() {
vec2 size = TEXTURE_PIXEL_SIZE * line_thickness;
float outline = texture(TEXTURE, UV + vec2(-size.x, 0)).a;
outline += texture(TEXTURE, UV + vec2(0, size.y)).a;
outline += texture(TEXTURE, UV + vec2(size.x, 0)).a;
outline += texture(TEXTURE, UV + vec2(0, -size.y)).a;
outline += texture(TEXTURE, UV + vec2(-size.x, size.y)).a;
outline += texture(TEXTURE, UV + vec2(size.x, size.y)).a;
outline += texture(TEXTURE, UV + vec2(-size.x, -size.y)).a;
outline += texture(TEXTURE, UV + vec2(size.x, -size.y)).a;
outline = min(outline, 1.0);
vec4 animated_line_color = vec4(light_offset + sin(2.0*3.14*sin_frequency*TIME),
light_offset + sin(2.0*3.14*sin_frequency*TIME + radians(120.0)),
light_offset + sin(2.0*3.14*sin_frequency*TIME + radians(240.0)),
1.0);
vec4 color = texture(TEXTURE, UV);
COLOR = mix(color, animated_line_color, outline - color.a);
}
能量束
多功能着色器,用于制作能量束或激光。很多制服可以玩。包括一个"Progress"制服,如果你想激活或关闭光束动画(这将平滑地收缩和溶解光束,从而产生更好的效果)。
🎥 动画如下!
制服
光束 - 能量场应该有多少
个光束能量 - 光束看起来有多大能量,它们将如何上下
移动穿过度 - 噪声纹理的
紧凑程度频率 - 光束中"涟漪"的数量
速度 - 动画速度
Thickness – 主梁
的厚度外线厚度 – 轮廓颜色
的厚度光束差异 – 如果存在多个光束,则主梁与其他光束之间的厚度差异。越接近1,厚度差异越小。
发光/轮廓发光 – HDR 发光。与世界环境的发光功能一起使用
颜色 – 光束的颜色
外线颜色 – 轮廓的颜色
进度 – 使用此选项可打开或关闭光束。
指示
只需将着色器代码添加到 ColorRect 中即可。如果要压缩ColorRect的大小来补偿,否则噪点会非常紧张。noise_scale
发光 – 默认情况下,着色器使用"blend_add"渲染模式,该模式可创建发光效果。如果要将 HDR 发光与"世界环境发光"功能结合使用,请在第 11 行中删除,然后使用"发光/轮廓发光"参数来设置发光量。render_mode blend_add
/*
Shader from Godot Shaders - the free shader library.
godotshaders.com/shader/energy-beams
This shader is under CC0 license. Feel free to use, improve and
change this shader according to your needs and consider sharing
the modified result to godotshaders.com.
*/
shader_type canvas_item;
render_mode blend_add; // Remove this if you want to use HDR glow instead (use "Glow" and "Outline Glow" sliders)
uniform int beams = 2; // How many beams the energy field should have
uniform float energy = 3.0; // How much the beams will travel up and down
uniform int roughness : hint_range(1, 10) = 3; // How compact the noise texture will be
uniform int frequency = 10; // Amount of "ripples" in the beams
uniform float speed = 1.0; // Animation speed
uniform float thickness : hint_range(0.0, 0.1) = 0.006; // Thickness of the main beam
uniform float outline_thickness : hint_range(0.0, 0.1) = 0.03; //Thickness of the outline color
uniform float beam_difference : hint_range(0.0, 1.0) = 0.0; // The thickness difference between the main beam and the other, if there are more than one beam. The closer to 1 the smaller the thickness difference.
uniform float glow : hint_range(0.0, 3.0) = 0.0; // Use together with WorldEnvironment's Glow feature
uniform float outline_glow : hint_range(0.0, 3.0) = 0.0;
uniform vec4 color : hint_color = vec4(0.91, 1.0, 1.0, 1.0);
uniform vec4 outline_color : hint_color = vec4(0.5, 1.0, 0.96, 1.0);
uniform float progress : hint_range(0.0, 1.0) = 1.0;
uniform float y_offset : hint_range (-0.5, 0.5) = 0.0; // Position of the beam
uniform float fixed_edge_size : hint_range(0.0, 0.5) = 0.05; // How close to the edge should the beam be still before the animatino starts
uniform vec2 noise_scale = vec2(1.0); // If the object (for example the ColorRect or Sprite node) is compressed use this to compensate for the noise texture being compressed.
float random(vec2 uv) {
return fract(sin(dot(uv.xy,
vec2(12.9898,78.233))) *
43758.5453123);
}
float noise(vec2 uv) {
vec2 uv_index = floor(uv);
vec2 uv_fract = fract(uv);
// Four corners in 2D of a tile
float a = random(uv_index);
float b = random(uv_index + vec2(1.0, 0.0));
float c = random(uv_index + vec2(0.0, 1.0));
float d = random(uv_index + vec2(1.0, 1.0));
vec2 blur = smoothstep(0.0, 1.0, uv_fract);
return mix(a, b, blur.x) +
(c - a) * blur.y * (1.0 - blur.x) +
(d - b) * blur.x * blur.y;
}
float fbm(vec2 uv, float time) {
int octaves = roughness;
float amp = 0.01 * energy * progress;
float freq = float(frequency);
float value = 0.0;
for(int i = 0; i < octaves; i++) {
value += amp * noise(freq * vec2(uv.x, uv.y + time));
amp *= 0.5;
freq *= 2.0;
}
return value;
}
vec4 difference(vec4 base, vec4 blend){
return abs(base - blend);
}
vec4 bolt(vec2 uv, float time, float i)
{
// Setup the beam locking to the edges.
float falloff = smoothstep(0.0, fixed_edge_size, uv.x) * smoothstep(0.0, fixed_edge_size, 1.0 - uv.x);
// Use Fractal Brownian Motion to create a "cloud texture" and use Difference blend mode to make the beam
vec4 clouds = vec4(fbm((uv + vec2(i) ) * noise_scale, time * speed)) * falloff;
vec4 diff_clouds = difference(clouds, vec4(uv.y - 0.5 + y_offset + (uv.y * falloff * 0.02 * energy * progress)));
// Create a new noise to mask the beams on low "progress" values. To make a "turn-off" effect more visually interesting.
vec4 clouds2 = vec4(fbm((uv * 2.0) * noise_scale, time * 1.)) * 5.0;
diff_clouds += smoothstep(0.0, 0.8, clouds2) * 0.1 * (1.-progress);
// Set thickness of the beams. First beam is the Thickness size and all following beams are sized with beam_difference
float thickness2 = 1. - ( thickness / (min(i + beam_difference, 1.0) + (1.0-beam_difference))) * progress ;
vec4 beam = clamp(smoothstep(thickness2, thickness2 + 0.005 * progress, 1.0 - diff_clouds), vec4(0.0), vec4(1.0));
//Set the beam outlines
vec4 beam_outline;
float outline = thickness2 - (outline_thickness * progress);
beam_outline = clamp(smoothstep(outline, outline + 0.04, 1.0 - diff_clouds), 0.0, 1.0);
beam_outline = clamp(beam_outline - beam, 0.0, 1.0);
// Merge the beam and the outline and return to the fragment function
return (beam * (color + vec4(glow, glow, glow, 0.))) + (beam_outline * (outline_color + vec4(outline_glow, outline_glow, outline_glow, 0.)));
}
void fragment()
{
vec4 beam = vec4(0.0);
for (int i = 0; i < beams; i++){
beam = max(beam, bolt(UV, TIME, float(i)));
}
COLOR = beam;
}
传送效果
让一个物体在明亮的光芒中消失,就像它被传送走了一样。请参阅下面的动画中的效果。
发亮
添加着色器代码会使角色消失,但不会使效果发光。为此,您必须添加一个环境节点:
将环境节点添加到场景中
将背景>模式设置为"画布"
在"发光"下,选中"已启用"。
使用"强度","强度"和"混合模式"属性来获得所需的效果。(我使用屏幕混合模式。
您还可以将颜色设置为超过 1.0 的"原始"值,以调高发光效果(默认颜色按如下方式设置,采用青色色调)。
/*
Shader from Godot Shaders - the free shader library.
godotshaders.com/shader/teleport-effect
This shader is under CC0 license. Feel free to use, improve and
change this shader according to your needs and consider sharing
the modified result on godotshaders.com.
*/
shader_type canvas_item;
uniform float progress : hint_range(0.0, 1.0);
uniform float noise_desnity = 60;
uniform float beam_size : hint_range(0.01, 0.15);
uniform vec4 color : hint_color = vec4(0.0, 1.02, 1.2, 1.0);
// We are generating our own noise here. You could experiment with the
// built in SimplexNoise or your own noise texture for other effects.
vec2 random(vec2 uv){
uv = vec2( dot(uv, vec2(127.1,311.7) ),
dot(uv, vec2(269.5,183.3) ) );
return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
}
float noise(vec2 uv) {
vec2 uv_index = floor(uv);
vec2 uv_fract = fract(uv);
vec2 blur = smoothstep(0.0, 1.0, uv_fract);
return mix( mix( dot( random(uv_index + vec2(0.0,0.0) ), uv_fract - vec2(0.0,0.0) ),
dot( random(uv_index + vec2(1.0,0.0) ), uv_fract - vec2(1.0,0.0) ), blur.x),
mix( dot( random(uv_index + vec2(0.0,1.0) ), uv_fract - vec2(0.0,1.0) ),
dot( random(uv_index + vec2(1.0,1.0) ), uv_fract - vec2(1.0,1.0) ), blur.x), blur.y) * 0.5 + 0.5;
}
void fragment()
{
vec4 tex = texture(TEXTURE, UV);
float noise = noise(UV * noise_desnity) * UV.y;
float d1 = step(progress, noise);
float d2 = step(progress - beam_size, noise);
vec3 beam = vec3(d2 - d1) * color.rgb;
tex.rgb += beam;
tex.a *= d2;
COLOR = tex;
}
2D 透视
此着色器在 CanvasItems 上"伪造"了 3D 相机透视。以下实现可自行工作。但是,建议将旋转矩阵转换为均匀。
默认情况下,着色器至少适用于节点 Sprite 和 TextureRect。
额外提示:使用 fov 0.785398(45 度)和平面距离 1,您可以通过向顶点函数添加以下内容来使图像居中并提供足够的余量以进行完全旋转而无需剪切:
VERTEX += (UV - 0.5) / TEXTURE_PIXEL_SIZE;
如果纹理与实际的矩形大小不匹配,则可能需要使用制服插入纹理。
// Hey this is Hei! This shader "fakes" a 3D-camera perspective on CanvasItems.
// Known limitations:
// - Yaw doesn't work as intended with non-square images.
// License: MIT
shader_type canvas_item;
// Camera FOV (half) in radians
// You can also consider pre-calculating "0.5 / tan(fov)"
uniform float fov = 0.785398;
// How far the image plane is from camera
uniform float plane_distance = 1.0;
uniform float yaw : hint_range(-1.57, 1.57) = 0.0;
uniform float pitch : hint_range(-1.57, 1.57) = 0.0;
uniform float roll : hint_range(-1.57, 1.57) = 0.0;
// Consider changing this to a uniform and change it from code
varying mat3 rotmat;
// Creates rotation matrix
void vertex(){
float cos_a = cos(yaw);
float sin_a = sin(yaw);
float sin_b = sin(pitch);
float cos_b = cos(pitch);
float sin_c = sin(roll);
float cos_c = cos(roll);
rotmat[0][0] = cos_a * cos_b;
rotmat[0][1] = cos_a * sin_b * sin_c - sin_a * cos_c;
rotmat[0][2] = cos_a * sin_b * cos_c + sin_a * sin_c;
rotmat[1][0] = sin_a * cos_b;
rotmat[1][1] = sin_a * sin_b * sin_c + cos_a * cos_c;
rotmat[1][2] = sin_a * sin_b * cos_c - cos_a * sin_c;
rotmat[2][0] = -sin_b;
rotmat[2][1] = cos_b * sin_c;
rotmat[2][2] = cos_b * cos_c;
}
// Projects UV to an imaginary plane; I barely have clue myself how it works.
void fragment(){
vec3 from = vec3(0, 0, -plane_distance);
vec3 normal = rotmat * vec3(0.0, 0.0, 1.0);
vec3 segment = normalize(vec3(UV - 0.5, 0.5 / tan(fov)));
float dist = -dot(normal, from) / dot(normal, segment);
vec3 intersection = from + segment * dist;
vec2 uv = (inverse(rotmat) * intersection).xy + 0.5;
if (any(greaterThan(abs(uv - 0.5), vec2(0.5)))) discard;
COLOR = texture(TEXTURE, uv);
}
简单能量护盾
简单的3D着色器,用于创建受Guilty Gear Xrd的Faultless Defense启发的力场效果。
它被放在屏幕截图中的球体上,但它应该适用于任何类型的网格(将其应用于角色模型会产生类似幽灵的效果)
具有可调节的基色、发射颜色、发射强度和轮辋陡度参数。
shader_type spatial;
//Simple 3D shader to create a force-field effect inspired by Faultless Defense from Guilty Gear Xrd.
//In summary, it takes logic used for simple rim lighting and uses it to create the alpha instead.
render_mode blend_mix,depth_draw_always,cull_back,diffuse_burley,specular_schlick_ggx;//depth_test_disable;
uniform vec4 albedo : hint_color;
uniform vec4 emission_color : hint_color;
uniform sampler2D texture_albedo : hint_albedo;
uniform float emission_amount: hint_range(0.0, 16.0) = 5.0f;
uniform float rim_steepness : hint_range(0.0f, 16.0f) = 3.0f; //higher values mean a smaller rim.
uniform vec3 uv_scale;
uniform vec3 uv_offset;
void vertex() {
UV=UV*uv_scale.xy+uv_offset.xy;
}
void fragment() {
vec2 base_uv = UV;
vec4 albedo_tex = texture(texture_albedo,base_uv);
ALBEDO = albedo.rgb * albedo_tex.rgb;
EMISSION = emission_color.rgb * emission_amount;
float PI = 3.14159265359;
float NdotV = dot(NORMAL, VIEW);
float rim_light = pow(1.0 - NdotV, rim_steepness);
ALPHA = rim_light * emission_color.a / PI;
}
桑原着色器
这是从 https://www.shadertoy.com/view/MsXSz4 转换而来的着色器
Kuwahara 滤镜可用作精灵或后期处理效果。只需将其添加到 Sprite2D 或 TextureRect 节点并添加输入纹理即可。偏移量也可用于为画布着色。
查看有关此着色器的详细信息
shader_type canvas_item;
uniform int radius = 5;
uniform vec3 offset=vec3(0.0);
void fragment()
{
vec2 src_size = vec2 ( SCREEN_PIXEL_SIZE.x, SCREEN_PIXEL_SIZE.y);
vec2 uv = UV.xy;
float n = float((radius + 1) * (radius + 1));
vec3 m0 = offset; vec3 m1 = offset; vec3 m2 = offset; vec3 m3 = offset;
vec3 s0 = offset; vec3 s1 = offset; vec3 s2 = offset; vec3 s3 = offset;
vec3 c;
for (int j = -radius; j <= 0; ++j) {
for (int i = -radius; i <= 0; ++i) {
c = texture(TEXTURE, uv + vec2(float(i),float(j)) * src_size).rgb;
m0 += c;
s0 += c * c;
}
}
for (int j = -radius; j <= 0; ++j) {
for (int i = 0; i <= radius; ++i) {
c = texture(TEXTURE, uv + vec2(float(i),float(j)) * src_size).rgb;
m1 += c;
s1 += c * c;
}
}
for (int j = 0; j <= radius; ++j) {
for (int i = 0; i <= radius; ++i) {
c = texture(TEXTURE, uv + vec2(float(i),float(j)) * src_size).rgb;
m2 += c;
s2 += c * c;
}
}
for (int j = 0; j <= radius; ++j) {
for (int i = -radius; i <= 0; ++i) {
c = texture(TEXTURE, uv + vec2(float(i),float(j)) * src_size).rgb;
m3 += c;
s3 += c * c;
}
}
float min_sigma2 = 1e+2;
m0 /= n;
s0 = abs(s0 / n - m0 * m0);
float sigma2 = s0.r + s0.g + s0.b;
if (sigma2 < min_sigma2) {
min_sigma2 = sigma2;
COLOR = vec4(m0, 1.0);
}
m1 /= n;
s1 = abs(s1 / n - m1 * m1);
sigma2 = s1.r + s1.g + s1.b;
if (sigma2 < min_sigma2) {
min_sigma2 = sigma2;
COLOR = vec4(m1, 1.0);
}
m2 /= n;
s2 = abs(s2 / n - m2 * m2);
sigma2 = s2.r + s2.g + s2.b;
if (sigma2 < min_sigma2) {
min_sigma2 = sigma2;
COLOR = vec4(m2, 1.0);
}
m3 /= n;
s3 = abs(s3 / n - m3 * m3);
sigma2 = s3.r + s3.g + s3.b;
if (sigma2 < min_sigma2) {
min_sigma2 = sigma2;
COLOR = vec4(m3, 1.0);
}
}
镜头眩光着色器
这个着色器是从mu6k的镜头眩光着色器翻译并稍作修改的,以便在使用Godot 4的3D场景中工作。
着色器需要太阳在视口上的位置。这可以通过使用Camera3D.unproject_position来计算。
如果您使用带有定向光的程序天空来模拟太阳,屏幕截图中的代码可能会有所帮助(我使用的是Godot 4,因此gdscript代码可能略有不同)。
欢迎任何改进或修复。即使着色器已获得 MIT 许可,请考虑向原作者 (mu6k) 发送电子邮件。
// TRANSLATED & MODIFIED FROM: https://www.shadertoy.com/view/4sX3Rs
shader_type canvas_item;
render_mode blend_mix;
uniform vec2 sun_position = vec2(0.0);
uniform vec3 tint = vec3(1.4,1.2,1.0);
uniform sampler2D noise_texture;
float noise_float(float t, vec2 texResolution)
{
return texture(noise_texture,vec2(t,0.0)/texResolution).x;
}
float noise_vec2(vec2 t, vec2 texResolution)
{
return texture(noise_texture,t/texResolution).x;
}
vec3 lensflare(vec2 uv,vec2 pos, vec2 texResolution)
{
vec2 main = uv-pos;
vec2 uvd = uv*(length(uv));
float ang = atan(main.x,main.y);
float dist = length(main);
dist = pow(dist,0.1);
float n = noise_vec2(vec2(ang*16.0,dist*32.0), texResolution);
// Do not need an artificial sun
//float f0 = 1.0/(length(uv-pos)*16.0+1.0);
//f0 = f0 + f0*(sin(noise_float(sin(ang*2.+pos.x)*4.0 - cos(ang*3.+pos.y), texResolution)*16.)*.1 + dist*.1 + .8);
float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0;
float f2 = max(1.0/(1.0+32.0*pow(length(uvd+0.8*pos),2.0)),.0)*00.25;
float f22 = max(1.0/(1.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*00.23;
float f23 = max(1.0/(1.0+32.0*pow(length(uvd+0.9*pos),2.0)),.0)*00.21;
vec2 uvx = mix(uv,uvd,-0.5);
float f4 = max(0.01-pow(length(uvx+0.4*pos),2.4),.0)*6.0;
float f42 = max(0.01-pow(length(uvx+0.45*pos),2.4),.0)*5.0;
float f43 = max(0.01-pow(length(uvx+0.5*pos),2.4),.0)*3.0;
uvx = mix(uv,uvd,-.4);
float f5 = max(0.01-pow(length(uvx+0.2*pos),5.5),.0)*2.0;
float f52 = max(0.01-pow(length(uvx+0.4*pos),5.5),.0)*2.0;
float f53 = max(0.01-pow(length(uvx+0.6*pos),5.5),.0)*2.0;
uvx = mix(uv,uvd,-0.5);
float f6 = max(0.01-pow(length(uvx-0.3*pos),1.6),.0)*6.0;
float f62 = max(0.01-pow(length(uvx-0.325*pos),1.6),.0)*3.0;
float f63 = max(0.01-pow(length(uvx-0.35*pos),1.6),.0)*5.0;
vec3 c = vec3(.0);
c.r+=f2+f4+f5+f6; c.g+=f22+f42+f52+f62; c.b+=f23+f43+f53+f63;
c = c*1.3 - vec3(length(uvd)*.05);
// Do not need an artificial sun
//c+=vec3(f0);
return c;
}
vec3 cc(vec3 color, float factor,float factor2) // color modifier
{
float w = color.x+color.y+color.z;
return mix(color,vec3(w)*factor,w*factor2);
}
void fragment()
{
vec2 texResolution = 1.0 / TEXTURE_PIXEL_SIZE;
vec2 resolution = 1.0 / SCREEN_PIXEL_SIZE;
vec2 uv = FRAGCOORD.xy / resolution.xy - 0.5;
uv.x *= resolution.x/resolution.y; //fix aspect ratio
vec2 mouse = (sun_position.xy / resolution.xy) - vec2(0.5, 0.5);
mouse.x *= resolution.x / resolution.y; //fix aspect ratio
vec4 previousColor = texture(SCREEN_TEXTURE, SCREEN_UV);
vec3 color = previousColor.rgb;
color += tint * lensflare(uv, mouse.xy, texResolution);
color -= noise_vec2(FRAGCOORD.xy, texResolution)*.015;
color = cc(color,.5,.1);
COLOR = vec4(color,1.0);
}
星巢
这是一个从shadertoy中获取并"翻译"的着色器,用于Godot(至少3.x版本),基于Pablo Andrioli(Shadertoy上的用户"Kali")的"Star Nest"的各种"分支"。感谢他们。
我建议在彩色矩形中使用,视口的儿子和具有拉伸收缩的视口容器的孙子,因为处理成本高。
在视频中,我正在玩变量,以显示着色器的多功能性。
(它被拉伸了5)
如果需要的话,我想我会有一个Godot 4版本的"端口"。
shader_type canvas_item;
render_mode unshaded;
uniform int iterations = 20;
uniform float formuparam = 1.00;
uniform int volsteps = 20;
uniform float stepsize = 0.1;
uniform float zoom = 0.800;
uniform float tile = 0.5;
uniform float speed = 0.001;
uniform float brightness = 0.002;
uniform float darkmatter = 0.100;
uniform float distfading = 0.650;
uniform float saturation = 0.750;
uniform vec2 iResolution = vec2(192, 192);
uniform vec2 iMouse = vec2(0,0);
float SCurve (float value) {
if (value < 0.5)
{
return value * value * value * value * value * 16.0;
}
value -= 1.0;
return value * value * value * value * value * 16.0 + 1.0;
}
void fragment()
{
//get coords and direction
vec2 uv=FRAGCOORD.xy/iResolution.xy-.5;
uv.y*=iResolution.y/iResolution.x;
vec3 dir=vec3(uv*zoom,1.);
float time=TIME*speed+.25;
//mouse rotation
float a1=0.5+iMouse.x/iResolution.x*2.;
float a2=0.8+iMouse.y/iResolution.y*2.;
mat2 rot1=mat2(vec2(cos(a1),sin(a1)),vec2(-sin(a1),cos(a1)));
mat2 rot2=mat2(vec2(cos(a2),sin(a2)),vec2(-sin(a2),cos(a2)));
dir.xy*=rot1;
dir.xz*=rot2;
vec3 from=vec3(1.0,0.5,0.5);
from-=vec3(0.0,time,0.0);
from.xz*=rot1;
from.xy*=rot2;
//volumetric rendering
float s=0.1,fade=1.;
vec3 v=vec3(0.);
for (int r=0; r<volsteps; r++) {
vec3 p=from+s*dir*0.5;
p = abs(vec3(tile)-mod(p,vec3(tile*2.))); // tiling fold
float pa,a=pa=0.;
for (int i=0; i<iterations; i++) {
p=abs(p)/dot(p,p)-formuparam; // the magic formula
a+=abs(length(p)-pa); // absolute sum of average change
pa=length(p);
}
float dm=max(0.,darkmatter-a*a*.001); //dark matter
a = pow(a, 2.3); // add contrast
if (r>6) fade*=1.-dm; // dark matter, don't render near
//v+=vec3(dm,dm*.5,0.);
v+=fade;
v+=vec3(s,s*s,s*s*s*s)*a*brightness*fade; // coloring based on distance
fade*=distfading; // distance fading
s+=stepsize;
}
v=mix(vec3(length(v)),v,saturation); //color adjust
vec4 C = vec4(v*.01,1.);
C.r = pow(C.r, 0.35);
C.g = pow(C.g, 0.36);
C.b = pow(C.b, 0.38);
vec4 L = C;
COLOR.r = mix(L.r, SCurve(C.r), 0.7);
COLOR.g = mix(L.g, SCurve(C.g), 1.0);
COLOR.b = mix(L.b, SCurve(C.b), 0.2);
}
像素化
像素化着色器。对 X 和 Y 使用不同的因子,从而通过"像素大小"参数生成独立于纹理大小和精确像素大小的方形像素
shader_type canvas_item;
uniform int pixelSize = 4;
void fragment()
{
ivec2 size = textureSize(TEXTURE, 0);
int xRes = size.x;
int yRes = size.y;
float xFactor = float(xRes) / float(pixelSize);
float yFactor = float(yRes) / float(pixelSize);
float grid_uv_x = round(UV.x * xFactor) / xFactor;
float grid_uv_y = round(UV.y * yFactor) / yFactor;
vec4 text = texture(TEXTURE, vec2(grid_uv_x, grid_uv_y));
COLOR = text;
}