Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GDShader #7071

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lib/linguist/languages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2270,6 +2270,15 @@ GDScript:
tm_scope: source.gdscript
ace_mode: text
language_id: 123
GDShader:
type: programming
color: "#478CBF"
extensions:
- ".gdshader"
- ".gdshaderinc"
tm_scope: source.gdshader
ace_mode: glsl
language_id: 694638086
GEDCOM:
type: data
color: "#003058"
Expand Down
24 changes: 24 additions & 0 deletions samples/GDShader/dissolve.gdshader
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Taken from https://github.com/gdquest-demos/godot-shaders/blob/main/godot/Shaders/dissolve.gdshader

shader_type spatial;
render_mode depth_prepass_alpha, cull_disabled;

uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color;

uniform vec4 emission_color : source_color = vec4(1);
uniform float emission_amount;

uniform sampler2D dissolve_texture;
uniform float burn_size : hint_range(0, 2);
uniform float dissolve_amount : hint_range(0, 1);

void fragment() {
vec4 albedo_tex = texture(texture_albedo, UV);
ALBEDO = albedo.rgb * albedo_tex.rgb;

float sample = texture(dissolve_texture, UV).r;
float emission_value = 1.0 - smoothstep(dissolve_amount, dissolve_amount + burn_size, sample);
EMISSION = vec3(emission_value * emission_amount * emission_color.rgb);
ALPHA = smoothstep(dissolve_amount - burn_size, dissolve_amount, sample);
}
20 changes: 20 additions & 0 deletions samples/GDShader/first_shader.gdshader
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Taken directly from Godot Engine documentation
// https://docs.godotengine.org/en/stable/tutorials/shaders/your_first_shader/your_first_3d_shader.html

shader_type spatial;

uniform float height_scale = 0.5;
uniform sampler2D noise;
uniform sampler2D normalmap;

varying vec2 tex_position;

void vertex() {
tex_position = VERTEX.xz / 2.0 + 0.5;
float height = texture(noise, tex_position).x;
VERTEX.y += height * height_scale;
}

void fragment() {
NORMAL_MAP = texture(normalmap, tex_position).xyz;
}
30 changes: 30 additions & 0 deletions samples/GDShader/gaussian_blur.gdshader
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Taken from https://github.com/gdquest-demos/godot-shaders/blob/main/godot/Shaders/gaussian_blur.gdshader

shader_type canvas_item;

uniform vec2 blur_scale = vec2(1, 0);

const float SAMPLES = 71.0;
const float TAU = 6.283185307179586476925286766559;

float gaussian(float x) {
float x_squared = x * x;
float width = 1.0 / sqrt(TAU * SAMPLES);

return width * exp((x_squared / (2.0 * SAMPLES)) * -1.0);
}

void fragment() {
vec2 scale = TEXTURE_PIXEL_SIZE * blur_scale;

float total_weight = 0.0;
vec4 color = vec4(0.0);

for (int i = -int(SAMPLES) / 2; i < int(SAMPLES) / 2; ++i) {
float weight = gaussian(float(i));
color += texture(TEXTURE, UV + scale * vec2(float(i))) * weight;
total_weight += weight;
}

COLOR = color / total_weight;
}
10 changes: 10 additions & 0 deletions samples/GDShader/include.gdshaderinc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Taken directly from Godot Engine documentation
// https://docs.godotengine.org/en/stable/tutorials/shaders/shader_reference/shader_preprocessor.html

// fancy_color.gdshaderinc

// While technically allowed, there is usually no `shader_type` declaration in include files.

vec3 get_fancy_color() {
return vec3(0.3, 0.6, 0.9);
}
79 changes: 79 additions & 0 deletions samples/GDShader/stylized_grass.gdshader
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Shader from https://godotshaders.com/shader/stylized-grass-with-wind-and-deformation/
shader_type spatial;
render_mode cull_disabled, unshaded;

uniform float wind_speed = 0.2;
uniform float wind_strength = 2.0;
// How big, in world space, is the noise texture
// wind will tile every wind_texture_tile_size
uniform float wind_texture_tile_size = 20.0;
uniform float wind_vertical_strength = 0.3;
uniform vec2 wind_horizontal_direction = vec2(1.0,0.5);

uniform sampler2D color_ramp : hint_black_albedo;
// we need a tiling noise here!
uniform sampler2D wind_noise : hint_black;

uniform vec3 character_position;
uniform float character_radius = 3.0;
uniform sampler2D character_distance_falloff_curve : hint_black_albedo;
uniform float character_push_strength = 1.0;

varying float debug_wind;

void vertex() {

vec3 world_vert = (WORLD_MATRIX * vec4(VERTEX, 1.0)).xyz;

vec2 normalized_wind_direction = normalize(wind_horizontal_direction);
vec2 world_uv = world_vert.xz / wind_texture_tile_size + normalized_wind_direction * TIME * wind_speed;
// we displace only the top part of the mesh
// note that this means that the mesh needs to have UV in a way that the bottom of UV space
// is at the top of the mesh
float displacement_affect = (1.0 - UV.y);
float wind_noise_intensity = (textureLod(wind_noise, world_uv , 0.0).r - 0.5);

// We convert the direction of the wind into vertex space from world space
// if we used it directly in vertex space, rotated blades of grass wouldn't behave properly
vec2 vert_space_horizontal_dir = (inverse(WORLD_MATRIX) * vec4(wind_horizontal_direction, 0.0,0.0)).xy;
vert_space_horizontal_dir = normalize(vert_space_horizontal_dir);

vec3 bump_wind = vec3(
wind_noise_intensity * vert_space_horizontal_dir.x,
1.0 - wind_noise_intensity,
wind_noise_intensity * vert_space_horizontal_dir.y
);
normalize(bump_wind);
bump_wind *= vec3(
wind_strength,
wind_vertical_strength,
wind_strength
);
VERTEX += bump_wind * displacement_affect;

// At the moment the blades are pushed away in a perfectly circular manner.
// We could distort the distance to the character based on a noise, to break a bit the
// circular shape. We could distort the falloff by sampling in a noise based on the xz coordinates.
// The task is left to the reader

vec3 dir_to_character = character_position - WORLD_MATRIX[3].xyz;
// uncomment the following line to have a horizontal only character push
// dir_to_character.y = 0.0;
float distance_to_character = length(dir_to_character);
float falloff = 1.0 - smoothstep(0.0, 1.0, distance_to_character/character_radius);
// Because we operate in vertex space, we need to convert the direction to the character
// in vertex space. Otherwise, it wouldn't work for rotated blades of grass.
// comment the next line to observe how the blades are not all facing away from the character.
dir_to_character = (inverse(WORLD_MATRIX) * vec4(dir_to_character, 0.0)).xyz;
dir_to_character = normalize(dir_to_character);

// sample the curve based on how far we are from the character, in normalized coordinates
float falloff_curve = texture(character_distance_falloff_curve, vec2(falloff)).x;
// direction to character is inverted because we want to point away from it
VERTEX += normalize(-dir_to_character) * falloff_curve * character_push_strength * displacement_affect;

}

void fragment() {
ALBEDO = texture(color_ramp, vec2(1.0 - UV.y, 0)).rgb ;
}
199 changes: 199 additions & 0 deletions samples/GDShader/toon_water.gdshader
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
// Original shader - https://godotshaders.com/shader/wind-waker-water-no-textures-needed/
// Wind Waker style water - NekotoArts
// Adapted from https://www.shadertoy.com/view/3tKBDz
// After which I added in some fractal Brownian motion
// as well as vertex displacement

shader_type spatial;

uniform vec4 WATER_COL : hint_color = vec4(0.04, 0.38, 0.88, 1.0);
uniform vec4 WATER2_COL : hint_color = vec4(0.04, 0.35, 0.78, 1.0);
uniform vec4 FOAM_COL : hint_color = vec4(0.8125, 0.9609, 0.9648, 1.0);
uniform float distortion_speed = 2.0;
uniform vec2 tile = vec2(5.0, 5.0);
uniform float height = 2.0;
uniform vec2 wave_size = vec2(2.0, 2.0);
uniform float wave_speed = 1.5;

const float M_2PI = 6.283185307;
const float M_6PI = 18.84955592;

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) {
int octaves = 6;
float amplitude = 0.5;
float frequency = 3.0;
float value = 0.0;

for(int i = 0; i < octaves; i++) {
value += amplitude * noise(frequency * uv);
amplitude *= 0.5;
frequency *= 2.0;
}
return value;
}

float circ(vec2 pos, vec2 c, float s)
{
c = abs(pos - c);
c = min(c, 1.0 - c);

return smoothstep(0.0, 0.002, sqrt(s) - sqrt(dot(c, c))) * -1.0;
}

// Foam pattern for the water constructed out of a series of circles
float waterlayer(vec2 uv)
{
uv = mod(uv, 1.0); // Clamp to [0..1]

float ret = 1.0;
ret += circ(uv, vec2(0.37378, 0.277169), 0.0268181);
ret += circ(uv, vec2(0.0317477, 0.540372), 0.0193742);
ret += circ(uv, vec2(0.430044, 0.882218), 0.0232337);
ret += circ(uv, vec2(0.641033, 0.695106), 0.0117864);
ret += circ(uv, vec2(0.0146398, 0.0791346), 0.0299458);
ret += circ(uv, vec2(0.43871, 0.394445), 0.0289087);
ret += circ(uv, vec2(0.909446, 0.878141), 0.028466);
ret += circ(uv, vec2(0.310149, 0.686637), 0.0128496);
ret += circ(uv, vec2(0.928617, 0.195986), 0.0152041);
ret += circ(uv, vec2(0.0438506, 0.868153), 0.0268601);
ret += circ(uv, vec2(0.308619, 0.194937), 0.00806102);
ret += circ(uv, vec2(0.349922, 0.449714), 0.00928667);
ret += circ(uv, vec2(0.0449556, 0.953415), 0.023126);
ret += circ(uv, vec2(0.117761, 0.503309), 0.0151272);
ret += circ(uv, vec2(0.563517, 0.244991), 0.0292322);
ret += circ(uv, vec2(0.566936, 0.954457), 0.00981141);
ret += circ(uv, vec2(0.0489944, 0.200931), 0.0178746);
ret += circ(uv, vec2(0.569297, 0.624893), 0.0132408);
ret += circ(uv, vec2(0.298347, 0.710972), 0.0114426);
ret += circ(uv, vec2(0.878141, 0.771279), 0.00322719);
ret += circ(uv, vec2(0.150995, 0.376221), 0.00216157);
ret += circ(uv, vec2(0.119673, 0.541984), 0.0124621);
ret += circ(uv, vec2(0.629598, 0.295629), 0.0198736);
ret += circ(uv, vec2(0.334357, 0.266278), 0.0187145);
ret += circ(uv, vec2(0.918044, 0.968163), 0.0182928);
ret += circ(uv, vec2(0.965445, 0.505026), 0.006348);
ret += circ(uv, vec2(0.514847, 0.865444), 0.00623523);
ret += circ(uv, vec2(0.710575, 0.0415131), 0.00322689);
ret += circ(uv, vec2(0.71403, 0.576945), 0.0215641);
ret += circ(uv, vec2(0.748873, 0.413325), 0.0110795);
ret += circ(uv, vec2(0.0623365, 0.896713), 0.0236203);
ret += circ(uv, vec2(0.980482, 0.473849), 0.00573439);
ret += circ(uv, vec2(0.647463, 0.654349), 0.0188713);
ret += circ(uv, vec2(0.651406, 0.981297), 0.00710875);
ret += circ(uv, vec2(0.428928, 0.382426), 0.0298806);
ret += circ(uv, vec2(0.811545, 0.62568), 0.00265539);
ret += circ(uv, vec2(0.400787, 0.74162), 0.00486609);
ret += circ(uv, vec2(0.331283, 0.418536), 0.00598028);
ret += circ(uv, vec2(0.894762, 0.0657997), 0.00760375);
ret += circ(uv, vec2(0.525104, 0.572233), 0.0141796);
ret += circ(uv, vec2(0.431526, 0.911372), 0.0213234);
ret += circ(uv, vec2(0.658212, 0.910553), 0.000741023);
ret += circ(uv, vec2(0.514523, 0.243263), 0.0270685);
ret += circ(uv, vec2(0.0249494, 0.252872), 0.00876653);
ret += circ(uv, vec2(0.502214, 0.47269), 0.0234534);
ret += circ(uv, vec2(0.693271, 0.431469), 0.0246533);
ret += circ(uv, vec2(0.415, 0.884418), 0.0271696);
ret += circ(uv, vec2(0.149073, 0.41204), 0.00497198);
ret += circ(uv, vec2(0.533816, 0.897634), 0.00650833);
ret += circ(uv, vec2(0.0409132, 0.83406), 0.0191398);
ret += circ(uv, vec2(0.638585, 0.646019), 0.0206129);
ret += circ(uv, vec2(0.660342, 0.966541), 0.0053511);
ret += circ(uv, vec2(0.513783, 0.142233), 0.00471653);
ret += circ(uv, vec2(0.124305, 0.644263), 0.00116724);
ret += circ(uv, vec2(0.99871, 0.583864), 0.0107329);
ret += circ(uv, vec2(0.894879, 0.233289), 0.00667092);
ret += circ(uv, vec2(0.246286, 0.682766), 0.00411623);
ret += circ(uv, vec2(0.0761895, 0.16327), 0.0145935);
ret += circ(uv, vec2(0.949386, 0.802936), 0.0100873);
ret += circ(uv, vec2(0.480122, 0.196554), 0.0110185);
ret += circ(uv, vec2(0.896854, 0.803707), 0.013969);
ret += circ(uv, vec2(0.292865, 0.762973), 0.00566413);
ret += circ(uv, vec2(0.0995585, 0.117457), 0.00869407);
ret += circ(uv, vec2(0.377713, 0.00335442), 0.0063147);
ret += circ(uv, vec2(0.506365, 0.531118), 0.0144016);
ret += circ(uv, vec2(0.408806, 0.894771), 0.0243923);
ret += circ(uv, vec2(0.143579, 0.85138), 0.00418529);
ret += circ(uv, vec2(0.0902811, 0.181775), 0.0108896);
ret += circ(uv, vec2(0.780695, 0.394644), 0.00475475);
ret += circ(uv, vec2(0.298036, 0.625531), 0.00325285);
ret += circ(uv, vec2(0.218423, 0.714537), 0.00157212);
ret += circ(uv, vec2(0.658836, 0.159556), 0.00225897);
ret += circ(uv, vec2(0.987324, 0.146545), 0.0288391);
ret += circ(uv, vec2(0.222646, 0.251694), 0.00092276);
ret += circ(uv, vec2(0.159826, 0.528063), 0.00605293);
return max(ret, 0.0);
}

// Procedural texture generation for the water
vec3 water(vec2 uv, vec3 cdir, float iTime)
{
uv *= vec2(0.25);
uv += fbm(uv) * 0.2;

// Parallax height distortion with two directional waves at
// slightly different angles.
vec2 a = 0.025 * cdir.xz / cdir.y; // Parallax offset
float h = sin(uv.x + iTime); // Height at UV
uv += a * h;
h = sin(0.841471 * uv.x - 0.540302 * uv.y + iTime);
uv += a * h;

// Texture distortion
float d1 = mod(uv.x + uv.y, M_2PI);
float d2 = mod((uv.x + uv.y + 0.25) * 1.3, M_6PI);
d1 = iTime * 0.07 + d1;
d2 = iTime * 0.5 + d2;
vec2 dist = vec2(
sin(d1) * 0.15 + sin(d2) * 0.05,
cos(d1) * 0.15 + cos(d2) * 0.05
);

vec3 ret = mix(WATER_COL.rgb, WATER2_COL.rgb, waterlayer(uv + dist.xy));
ret = mix(ret, FOAM_COL.rgb, waterlayer(vec2(1.0) - uv - dist.yx));
return ret;
}


void vertex(){
float time = TIME * wave_speed;
vec2 uv = UV * wave_size;
float d1 = mod(uv.x + uv.y, M_2PI);
float d2 = mod((uv.x + uv.y + 0.25) * 1.3, M_6PI);
d1 = time * 0.07 + d1;
d2 = time * 0.5 + d2;
vec2 dist = vec2(
sin(d1) * 0.15 + sin(d2) * 0.05,
cos(d1) * 0.15 + cos(d2) * 0.05
);
VERTEX.y += dist.y * height;
}

void fragment()
{
vec2 uv = UV;

ALBEDO = vec3(water(uv * tile, vec3(0,1,0), TIME * distortion_speed));
}
1 change: 1 addition & 0 deletions vendor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
- **GCC Machine Description:** [textmate/lisp.tmbundle](https://github.com/textmate/lisp.tmbundle)
- **GDB:** [quarnster/SublimeGDB](https://github.com/quarnster/SublimeGDB)
- **GDScript:** [godotengine/godot-vscode-plugin](https://github.com/godotengine/godot-vscode-plugin)
- **GDShader:** [godotengine/godot-vscode-plugin](https://github.com/godotengine/godot-vscode-plugin)
- **GEDCOM:** [fguitton/vscode-gedcom](https://github.com/fguitton/vscode-gedcom)
- **GLSL:** [euler0/sublime-glsl](https://github.com/euler0/sublime-glsl)
- **GN:** [devoncarew/language-gn](https://github.com/devoncarew/language-gn)
Expand Down
1 change: 1 addition & 0 deletions vendor/grammars/SublimeGodot
Submodule SublimeGodot added at 55cd3d