-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: rewrite force field shader for Godot 4.3 (#57)
* Update force field shader - Remove ball throwing from demo - Add comments and sliders - Change linear depth calculation * chore: proofread forcefield comments --------- Co-authored-by: Nathan Lovato <[email protected]>
- Loading branch information
1 parent
583be1f
commit 7d1d44a
Showing
5 changed files
with
116 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://cp7fpmko6heid"] | ||
|
||
[ext_resource type="Shader" path="res://Shaders/force_field.gdshader" id="1_hm6s7"] | ||
[ext_resource type="Texture2D" uid="uid://b2skoftifgi55" path="res://Demos/ForceField/hexagon_grid.png" id="2_tm5w2"] | ||
|
||
[resource] | ||
render_priority = 0 | ||
shader = ExtResource("1_hm6s7") | ||
shader_parameter/color = Color(0.607843, 0.219608, 1, 1) | ||
shader_parameter/pattern_scroll_speed = 0.025 | ||
shader_parameter/pattern_uv_scale = Vector2(6, 3) | ||
shader_parameter/pattern_texture = ExtResource("2_tm5w2") | ||
shader_parameter/fresnel_power = 4.0 | ||
shader_parameter/edge_intensity = 2.0 | ||
shader_parameter/center_intensity = 0.1 | ||
shader_parameter/pulsing_strength = 0.25 | ||
shader_parameter/pulsing_speed = 1.0 | ||
shader_parameter/scanline_frequency = 0.5 | ||
shader_parameter/scanline_width = 0.1 | ||
shader_parameter/scanline_intensity = 0.35 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,104 @@ | ||
shader_type spatial; | ||
render_mode depth_draw_opaque, cull_disabled, ambient_light_disabled, blend_add, shadows_disabled; | ||
|
||
group_uniforms ColorAndPattern; | ||
/** Base color. */ | ||
uniform vec4 color : source_color; | ||
uniform float fresnel_power = 1.0; | ||
uniform float edge_intensity = 2.0; | ||
uniform float fill_amount : hint_range(0, 1) = 0.1; | ||
/** The speed that the pattern scrolls. */ | ||
uniform float pattern_scroll_speed = 0.025; | ||
/** The scale of the pattern. Bigger values make the hexagons smaller. */ | ||
uniform vec2 pattern_uv_scale = vec2(6.0, 3.0); | ||
/** The texture of the pattern. */ | ||
uniform sampler2D pattern_texture : source_color; | ||
group_uniforms; | ||
|
||
group_uniforms Intensity; | ||
/** The thickness of the edges. Higher values mean thinner edges. */ | ||
uniform float fresnel_power: hint_range(0.5, 8.0) = 4.0; | ||
/** The intensity of the edges. Values over [code]1.0[/code] will glow, if you have Glow enabled on your environment. | ||
*/ | ||
uniform float edge_intensity: hint_range(0.0, 2.0) = 1.5; | ||
/** The intensity of the center. */ | ||
uniform float center_intensity : hint_range(0.0, 1.0) = 0.1; | ||
group_uniforms; | ||
|
||
group_uniforms Pulsing; | ||
/** Magnitude of the pulsing effect. | ||
* This is the amplitude of the sine wave used to move the vertices. The pulsing is additive and done in model space, so if you scale the mesh or the mesh instance, you'll need to adjust this value. | ||
*/ | ||
uniform float pulsing_strength = 0.25; | ||
/** Speed of the pulsing effect. Higher values are faster. | ||
* The frequency of the sine wave used to move the vertices. | ||
*/ | ||
uniform float pulsing_speed = 1.0; | ||
group_uniforms; | ||
|
||
uniform float scanline_period = 0.5; | ||
uniform float scanline_width : hint_range(0, 0.49) = 0.1; | ||
group_uniforms Scanlines; | ||
/** The frequency of the scanline effect. Higher values mean the scanlines repeat more often. | ||
*/ | ||
uniform float scanline_frequency = 0.5; | ||
/** The width of the scanlines. */ | ||
uniform float scanline_width : hint_range(0, 0.5) = 0.1; | ||
/** The intensity (brightness) of the scanlines. */ | ||
uniform float scanline_intensity = 0.35; | ||
group_uniforms; | ||
|
||
uniform float pattern_scroll_speed = 0.025; | ||
uniform vec2 pattern_uv_offset = vec2(6.0, 3.0); | ||
|
||
uniform sampler2D pattern_texture : source_color; | ||
uniform sampler2D DEPTH_TEXTURE: hint_depth_texture, filter_linear_mipmap; | ||
|
||
void vertex() { | ||
float pulse_distance = sin(TIME * pulsing_speed) * 0.1 * pulsing_strength; | ||
VERTEX += NORMAL * pulse_distance; | ||
} | ||
|
||
float get_linear_depth(sampler2D depth_texture, vec2 screen_uv, mat4 inv_projection_matrix, bool use_opengl_ndc) { | ||
float depth_raw = texture(depth_texture, screen_uv).x; | ||
vec3 ndc; | ||
if (use_opengl_ndc){ | ||
// Compatibility. Uses OpenGL NDC space: range of [-1,1] for NDC.xy, range of [-1,1] for NDC.z | ||
ndc = vec3(screen_uv, depth_raw) * 2.0 - 1.0; | ||
} else { | ||
// Forward+ or Mobile. Uses Vulkan NDC space: range of [-1,1] for NDC.xy, range of [0,1] for NDC.z | ||
ndc = vec3(screen_uv * 2.0 - 1.0, depth_raw); | ||
} | ||
vec4 position_view = inv_projection_matrix * vec4(ndc, 1.0); | ||
position_view.xyz /= position_view.w; | ||
return -position_view.z; | ||
} | ||
|
||
void fragment() { | ||
// Create a fresnel effect from the NORMAL and VIEW vectors. | ||
float fresnel = pow(1.0 - dot(NORMAL, VIEW), fresnel_power) * edge_intensity; | ||
|
||
// Add back transparency in the middle | ||
fresnel = fresnel + fill_amount; | ||
|
||
// Get the raw linear depth from the depth texture into a [-1, 1] range | ||
float depth = texture(DEPTH_TEXTURE, SCREEN_UV).r * 2.0 - 1.0; | ||
// Recreate linear depth of the intersecting geometry using projection matrix, and subtract the vertex of the sphere | ||
depth = PROJECTION_MATRIX[3][2] / (depth + PROJECTION_MATRIX[2][2]) + VERTEX.z; | ||
fresnel = fresnel + center_intensity; | ||
|
||
// Get the linear depth. | ||
float depth = get_linear_depth(DEPTH_TEXTURE, SCREEN_UV, INV_PROJECTION_MATRIX, OUTPUT_IS_SRGB); | ||
|
||
// Get the difference between the linear depth and the fragment's linear depth. | ||
// VERTEX is the interpolated position of each fragment, in view space. | ||
// VERTEX.z is the linear depth of each fragment. | ||
depth = depth + VERTEX.z; | ||
|
||
// Intensity intersection effect | ||
depth = pow(1.0 - clamp(depth, 0, 1), fresnel_power) * edge_intensity; | ||
// Calculate final alpha using fresnel and depth joined together | ||
|
||
// Calculate final alpha using fresnel and depth joined together. | ||
fresnel = fresnel + depth; | ||
// Calculate UV scrolling pattern | ||
|
||
// Calculate UV scrolling pattern. | ||
float scrolling_time = TIME * pattern_scroll_speed; | ||
vec4 pattern = texture(pattern_texture, (UV * pattern_uv_offset) + vec2(scrolling_time)); | ||
// Use pattern to cut holes in alpha | ||
vec4 pattern = texture(pattern_texture, (UV * pattern_uv_scale) + vec2(scrolling_time)); | ||
|
||
// Use pattern to cut holes in alpha. | ||
fresnel *= pattern.r; | ||
float uv_offset = mod(-TIME * scanline_period, 2.0) - 1.0; | ||
float scanline = smoothstep(0.5 - scanline_width, 0.5, UV.y + uv_offset) | ||
|
||
float uv_offset = mod(-TIME * scanline_frequency, 2.0) - 1.0; | ||
float scanline = smoothstep(0.5 - scanline_width, 0.5, UV.y + uv_offset) | ||
* (1.0 - smoothstep(0.5, 0.5 + scanline_width, UV.y + uv_offset)) * pattern.r; | ||
// Apply final color | ||
|
||
// Apply final color. | ||
ALBEDO = vec3(0); | ||
EMISSION = color.rgb; | ||
ALPHA = smoothstep(0.0, 1.0, fresnel + scanline * scanline_intensity); | ||
} | ||
} |