../

Shaders

The Godot 4.x shading language (.gdshader): shader types, render modes, processor functions, built-ins per type, uniforms and hints, screen and depth textures, varyings, global and instance uniforms, driving parameters from GDScript, materials, visual shaders and how it differs from GLSL. For raw GLSL see WebGL; tweening shader parameters is in UI, animation & audio.

Shader types

shader_typeApplies toProcessor functions
canvas_item2D: Sprite2D, Control, Polygon2D, TileMapLayer ... (any CanvasItem material)vertex(), fragment(), light()
spatial3D meshes: MeshInstance3D, CSG*, GPUParticles3D draw passesvertex(), fragment(), light()
particlesGPUParticles2D / 3D process materialstart(), process()
skySky resource in a WorldEnvironmentsky()
fogFogVolume nodes (volumetric fog, Forward+ only)fog()
 GDScript / inspector
   ShaderMaterial ── shader: .gdshader
        │  set_shader_parameter("u", v)
        ▼
 vertex()    once per vertex: move VERTEX, set varyings
        │    (canvas_item: local space; spatial: model space)
        ▼
 rasterise   varyings interpolated
        ▼
 fragment()  once per pixel: COLOR (2D) or ALBEDO,
        │    ROUGHNESS, NORMAL_MAP ... (3D)
        ▼
 light()     once per pixel per light (optional):
             LIGHT (2D) or DIFFUSE_LIGHT / SPECULAR_LIGHT (3D)

Anatomy of a shader

tint.gdshader
shader_type canvas_item;          // required, first
render_mode blend_mix, unshaded;  // optional flags
 
uniform vec4 tint : source_color = vec4(1.0);
uniform float amount : hint_range(0.0, 1.0) = 0.5;
 
varying vec2 world_pos;           // vertex -> fragment
 
const float PI_2 = 6.2831853;
 
float wave(float x) {             // helper functions
    return 0.5 + 0.5 * sin(x * PI_2);
}
 
void vertex() {
    world_pos = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy;
}
 
void fragment() {
    // COLOR = TEXTURE sample x vertex color x modulate
    vec3 c = mix(COLOR.rgb, tint.rgb, amount);
    COLOR.rgb = c * wave(TIME + world_pos.x * 0.01);
}

Omitted processor functions keep Godot's defaults. Write shaders in the built-in editor (errors inline, and 4.7 adds inline previews) or any editor with a .gdshader plugin; .gdshaderinc files hold shared code for #include "res://shaders/common.gdshaderinc".

Render modes

canvas_item modeEffect
blend_mix (default), blend_add, blend_sub, blend_mul, blend_premul_alpha, blend_disabledblending
unshadedignore 2D lights
light_onlydraw only where lit (light-reveal effects)
skip_vertex_transformtransform VERTEX yourself
world_vertex_coordsVERTEX is in world space in vertex()
spatial modeEffect
blend_*as above (transparent pipeline except blend_mix with no ALPHA)
unshadedno lighting: output is ALBEDO (plus EMISSION)
cull_back (default), cull_front, cull_disabledface culling; disabled for foliage and double-sided cards
depth_draw_opaque (default), depth_draw_always, depth_draw_neverdepth writes
depth_prepass_alphatransparent objects that still sort correctly
depth_test_disableddraw on top (x-ray, gizmos)
diffuse_burley (default), diffuse_lambert, diffuse_lambert_wrap, diffuse_toondiffuse model
specular_schlick_ggx (default), specular_toon, specular_disabledspecular model
shadows_disabled, ambient_light_disabled, fog_disabledper-material opt-outs
shadow_to_opacityshadow catcher for AR / compositing
vertex_lightingper-vertex lighting (retro look, low-end)
world_vertex_coords, skip_vertex_transformvertex space control
alpha_to_coverage, alpha_to_coverage_and_oneMSAA-friendly cutouts
wireframedebug
particle_trailsfor trail meshes

CanvasItem built-ins

Built-inStageMeaning
VERTEXvertex (inout)local position (world with world_vertex_coords)
UVvertex, fragment0 to 1 texture coordinates
COLORvertexvertex color times modulate and self_modulate
COLORfragment (inout)incoming: vertex COLOR times the TEXTURE sample; output color
TEXTUREfragmentthe node's texture (sampler2D)
TEXTURE_PIXEL_SIZEfragment1.0 / texture size (one texel in UV units)
SCREEN_UVfragment0 to 1 across the viewport
SCREEN_PIXEL_SIZEfragment1.0 / viewport size
FRAGCOORDfragmentwindow pixel coordinates
NORMAL, NORMAL_MAP, NORMAL_MAP_DEPTHfragmentnormal for 2D lighting
MODEL_MATRIX, CANVAS_MATRIX, SCREEN_MATRIXvertexlocal to world, world to canvas, canvas to clip
INSTANCE_CUSTOMvertexper-instance data (MultiMesh, particles)
POINT_COORD, POINT_SIZEpoint primitives
LIGHT, LIGHT_COLOR, LIGHT_ENERGY, LIGHT_POSITION, LIGHT_DIRECTION, SHADOW_MODULATElightper-light inputs and output
TIME, PI, TAU, Eallglobal time (seconds) and constants

Spatial built-ins

Built-inStageMeaning
VERTEXvertex: model space; fragment: view spaceposition
NORMAL, TANGENT, BINORMALvertex: model; fragment: view spaceframe
UV, UV2, COLORvertex, fragmentmesh attributes
POSITIONvertex (out)override clip-space position
MODEL_MATRIX, VIEW_MATRIX, INV_VIEW_MATRIX, PROJECTION_MATRIX, INV_PROJECTION_MATRIXalltransforms
NODE_POSITION_WORLD, CAMERA_POSITION_WORLD, CAMERA_DIRECTION_WORLDallhandy world positions
INSTANCE_ID, INSTANCE_CUSTOM, VERTEX_IDvertexinstancing data
VIEWfragmentdirection from the fragment to the camera (view space)
SCREEN_UV, FRAGCOORD, FRONT_FACINGfragmentscreen position, facing
ALBEDOfragment (out)base color (vec3)
ALPHA, ALPHA_SCISSOR_THRESHOLDfragment (out)transparency; scissor for cutouts without sorting
METALLIC, ROUGHNESS, SPECULARfragment (out)PBR parameters (0 to 1)
EMISSIONfragment (out)glow color (HDR; drives Glow)
NORMAL_MAP, NORMAL_MAP_DEPTHfragment (out)tangent-space normal map sample and strength
AO, AO_LIGHT_AFFECTfragment (out)ambient occlusion
RIM, RIM_TINT, CLEARCOAT, CLEARCOAT_GLOSS, ANISOTROPY, SSS_STRENGTH, BACKLIGHTfragment (out)advanced PBR
DEPTHfragment (out)custom depth (disables early-z)
LIGHT, LIGHT_COLOR, ATTENUATION, DIFFUSE_LIGHT, SPECULAR_LIGHTlightper-light (LIGHT_COLOR includes energy times PI)
shader_type spatial;
 
uniform sampler2D albedo_tex : source_color,
    filter_linear_mipmap_anisotropic;
uniform sampler2D normal_tex : hint_normal;
uniform float rough : hint_range(0.0, 1.0) = 0.6;
 
void fragment() {
    ALBEDO = texture(albedo_tex, UV).rgb;
    NORMAL_MAP = texture(normal_tex, UV).rgb;
    ROUGHNESS = rough;
    METALLIC = 0.0;
    // world-space normal from the view-space one
    vec3 wn = (INV_VIEW_MATRIX * vec4(NORMAL, 0.0)).xyz;
    EMISSION = vec3(0.2, 0.6, 1.0) * max(wn.y, 0.0) * 0.2;
}
 
void light() {            // replaces built-in lighting
    float ndl = max(dot(NORMAL, LIGHT), 0.0);
    float toon = step(0.5, ndl);   // two-band toon
    DIFFUSE_LIGHT += toon * ATTENUATION * LIGHT_COLOR / PI;
}

Particles, sky & fog

particles.gdshader
shader_type particles;
uniform float spread = 2.0;
 
void start() {              // when a particle (re)spawns
    uint s = NUMBER;        // per-particle seed
    float a = float(s % 360u) * 0.01745;
    VELOCITY = vec3(cos(a), 4.0, sin(a)) * spread;
    COLOR = vec4(1.0);
    CUSTOM.y = 0.0;         // our own age counter
    TRANSFORM = EMISSION_TRANSFORM;
}
 
void process() {            // every frame per particle
    VELOCITY.y -= 9.8 * DELTA;
    TRANSFORM[3].xyz += VELOCITY * DELTA;
    CUSTOM.y += DELTA / LIFETIME;   // 0 -> 1 over life
    COLOR.a = 1.0 - CUSTOM.y;
}
TypeKey built-ins
particlesTRANSFORM, VELOCITY, COLOR, CUSTOM, ACTIVE, LIFETIME, DELTA, NUMBER, INDEX, EMISSION_TRANSFORM, RANDOM_SEED
skyEYEDIR, SKY_COORDS, POSITION, LIGHT0_DIRECTION, LIGHT0_COLOR, LIGHT0_ENERGY, RADIANCE, AT_CUBEMAP_PASS; outputs COLOR, ALPHA, FOG
fogWORLD_POSITION, OBJECT_POSITION, UVW, SIZE, SDF; outputs DENSITY, ALBEDO, EMISSION

Most particle effects need no shader: ParticleProcessMaterial covers emission shapes, curves, color ramps and turbulence, and can be converted to a ShaderMaterial to customize.

gradient_sky.gdshader
shader_type sky;
uniform vec3 top : source_color = vec3(0.2, 0.4, 0.9);
uniform vec3 horizon : source_color = vec3(0.9, 0.8, 0.7);
 
void sky() {
    float t = clamp(EYEDIR.y, 0.0, 1.0);
    COLOR = mix(horizon, top, pow(t, 0.5));
    // sun disc from the first DirectionalLight3D
    float sun = dot(EYEDIR, LIGHT0_DIRECTION);
    COLOR += LIGHT0_COLOR * smoothstep(0.998, 1.0, sun);
}

Uniforms & hints

uniform float speed = 1.0;                    // default
uniform vec4 color : source_color;           // sRGB picker
uniform float fade : hint_range(0.0, 1.0, 0.01) = 1.0;
uniform int mode : hint_enum("Add", "Mul") = 0;
uniform sampler2D tex : source_color, filter_nearest,
    repeat_enable;
uniform sampler2D mask : hint_default_white;
uniform float weights[4];                     // arrays
 
group_uniforms Wind;                          // inspector
uniform float wind_strength = 0.1;
uniform float wind_speed = 1.0;
group_uniforms;
HintUse
source_colorcolor or albedo texture: converted from sRGB, color picker in the inspector
hint_range(min, max[, step])slider for float / int
hint_enum("A", "B")int dropdown
hint_normalnormal map (no sRGB, normal-map compression)
hint_default_white, hint_default_black, hint_default_transparentwhat an empty sampler reads as
hint_anisotropy, hint_roughness_*special texture roles
filter_nearest, filter_linear, filter_*_mipmap, filter_*_mipmap_anisotropicsampling filter (pixel art: filter_nearest)
repeat_enable, repeat_disablewrap or clamp (scrolling textures need repeat_enable)
hint_screen_texture, hint_depth_texture, hint_normal_roughness_texturescreen buffers
instance_index(n)fixed slot for an instance uniform

Colors without source_color are treated as linear data, so a picked color looks washed out or too dark: always add source_color to color uniforms and albedo textures.

Global & instance uniforms

KindDeclaredSet fromUse
Regularuniform float x;the material: set_shader_parameterper material (shared by every node using it)
Instanceinstance uniform vec4 tint : source_color;the node: set_instance_shader_parameterper node without duplicating materials; scalars and vectors only, 16 per shader
Globalglobal uniform vec3 player_pos;Project Settings > Shader Globals, or RenderingServerone value for every shader (wind, player position, time of day)
# Instance uniform on a GeometryInstance3D
$Crate.set_instance_shader_parameter("tint", Color.RED)
 
# Global uniform (declare it in Project Settings first)
func _process(_d: float) -> void:
    RenderingServer.global_shader_parameter_set(
        "player_pos", $Player.global_position)

Instance uniforms are the fix for "I changed one enemy's material and all of them flashed", without duplicate() or Local to Scene.

Varyings, consts & functions

FeatureSyntax / note
Varyingvarying vec3 world_pos; written in vertex(), read in fragment() or light()
Interpolationvarying flat int id; (no interpolation), smooth (default)
Constantsconst float K = 2.0; (any type except samplers)
Functionsdefined before use; in, out, inout parameters; overloads allowed
Structsstruct Hit { float d; vec3 n; }; global scope
Arraysfloat a[3] = float[](1.0, 2.0, 3.0);, uniform arrays
Preprocessor#define, #ifdef, #if, #include (.gdshaderinc)
Discarddiscard; in fragment() (cutouts; costs early-z on some GPUs)
DerivativesdFdx, dFdy, fwidth for anti-aliased edges
Texture functionstexture, textureLod, texelFetch, textureSize
shader_type spatial;
varying vec3 world_pos;
 
void vertex() {
    world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
}
 
void fragment() {
    // world-space checkerboard, independent of UVs
    vec3 cell = floor(world_pos);
    float c = mod(cell.x + cell.y + cell.z, 2.0);
    ALBEDO = mix(vec3(0.2), vec3(0.8), c);
}

Screen & depth textures

blur_under.gdshader (2D)
shader_type canvas_item;
uniform sampler2D screen_tex : hint_screen_texture,
    filter_linear_mipmap;
uniform float blur : hint_range(0.0, 5.0) = 2.0;
 
void fragment() {
    // mipmapped screen texture: cheap frosted-glass blur
    COLOR = textureLod(screen_tex, SCREEN_UV, blur);
}
depth_fade.gdshader (3D)
shader_type spatial;
render_mode unshaded, blend_mix;
uniform sampler2D depth_tex : hint_depth_texture,
    repeat_disable, filter_nearest;
 
void fragment() {
    float d = textureLod(depth_tex, SCREEN_UV, 0.0).r;
    // Forward+ / Mobile (reverse-Z). Compatibility:
    // vec3 ndc = vec3(SCREEN_UV, d) * 2.0 - 1.0;
    vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, d);
    vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
    view.xyz /= view.w;
    float scene_depth = -view.z;         // meters
    float my_depth = -VERTEX.z;          // view space
    float edge = clamp(scene_depth - my_depth, 0.0, 1.0);
    ALBEDO = vec3(1.0);
    ALPHA = 1.0 - edge;      // foam where water meets ground
}
FactDetail
Screen texturecopy of what was drawn so far; canvas_item and spatial
Transparent-only (3D)the screen texture in 3D contains opaque geometry only; other transparent objects are missing
Overlapping 2D readersthe copy happens once per canvas; add a BackBufferCopy node between effects that must see each other
Depth texture3D only; non-linear, reconstruct with INV_PROJECTION_MATRIX as above
Normal-roughnesshint_normal_roughness_texture, Forward+ only
Full-screen post effecta ColorRect (full rect) in a CanvasLayer with a canvas_item shader reading the screen texture

Parameters from GDScript

@onready var mat := $Sprite2D.material as ShaderMaterial
 
func _ready() -> void:
    mat.set_shader_parameter("amount", 0.5)
    mat.set_shader_parameter("tex", preload("res://n.png"))
    print(mat.get_shader_parameter("amount"))
 
func flash() -> void:
    var t := create_tween()
    t.tween_property(mat, "shader_parameter/amount",
        0.0, 0.25).from(1.0)
 
# 3D mesh: material slots
var m := $Mesh.get_active_material(0) as ShaderMaterial
$Mesh.set_surface_override_material(0, m.duplicate())
FactDetail
Nameset_shader_parameter (Godot 3 was set_shader_param)
Property path"shader_parameter/<name>" works with tweens, AnimationPlayer tracks and set()
Sharingmaterials are Resources: every node using the same material sees the change
Per-node optionsinstance uniforms; Resource > Local to Scene on the material; material.duplicate()
Texturespass Texture2D resources (NoiseTexture2D, GradientTexture1D, ViewportTexture ...)
CanvasItemmaterial property; use_parent_material lets children share the parent's
GeometryInstance3Dmaterial_override (all surfaces), material_overlay (extra pass), set_surface_override_material(i, m)

Materials

MaterialUse
StandardMaterial3DPBR in the inspector: albedo, metallic, roughness, normal, emission, transparency, billboard, triplanar, proximity fade
ORMMaterial3Dsame, with one packed Occlusion/Roughness/Metallic texture
ShaderMaterialyour .gdshader or a VisualShader
CanvasItemMaterial2D blend modes, light mode, particle sprite-sheet animation, no code
ParticleProcessMaterialGPU particle behavior without code
PanoramaSkyMaterial, ProceduralSkyMaterial, PhysicalSkyMaterialsky without code
TipDetail
See the generated coderight-click a StandardMaterial3D > Convert to ShaderMaterial
Multi-passnext_pass on any material draws the mesh again (inverted-hull outlines)
Sortingrender_priority orders transparent materials
Stutterubershaders (4.4+) hide first-use compilation; the shader baker (4.5+) precompiles at export

Visual shaders

VisualShader is a node-graph resource for the same shader types. Create it via ShaderMaterial > New VisualShader. Useful for artists and quick iteration; an Expression node accepts inline shader code, and VisualShaderNodeCustom scripts (@tool + class_name) add reusable nodes. There is no automatic conversion to text, so pick one form per effect.

Differences from GLSL

GLSLGodot shading language
#version, precision headersshader_type first; precision qualifiers optional
in / out attributes, gl_Positionbuilt-ins: VERTEX, UV, NORMAL, POSITION
out vec4 fragColor / gl_FragColorCOLOR (2D) or ALBEDO + ALPHA (3D)
gl_FragCoordFRAGCOORD
uniform set with gl.uniform*uniform with hints and defaults, set with set_shader_parameter
varying (old) / out-in pairsvarying
implicit int to float in some driversnever: write 1.0, cast with float(i)
iTime (Shadertoy)TIME
iResolution1.0 / SCREEN_PIXEL_SIZE (2D) or VIEWPORT_SIZE (3D)
texture origin bottom-leftUV origin top-left, y down (2D)
manual lightingautomatic PBR; light() to customize, unshaded to skip

Porting Shadertoy: put the body in a canvas_item fragment() on a full-rect ColorRect, replace fragCoord / iResolution.xy with UV (flip y if needed) and write the result to COLOR.

Performance & debugging

TipWhy
Visualize intermediatesCOLOR = vec4(UV, 0.0, 1.0); or ALBEDO = NORMAL * 0.5 + 0.5; to see what a value holds
Prefer unshaded for effectsskips the lighting cost for sprites, UI and VFX that do not need lights
Watch 2D overdrawlarge transparent quads stacked on each other cost fill rate, especially on mobile and Web
Each screen-texture reader copies the screenshare one BackBufferCopy or one post-process pass instead of many readers
discard and DEPTH writesdisable early depth test optimizations; use ALPHA_SCISSOR_THRESHOLD for cutouts in 3D
Uniform branches are cheapif (mode == 1) on a uniform is coherent across pixels; data-dependent branches are not
Fewer dependent texture readsreading a texture at coordinates computed from another texture is slower
Compatibility rendererWeb and old GPUs: fewer features (no hint_normal_roughness_texture, no compute shaders) on an OpenGL backend
Pre-warm new materialsshow them once during a loading screen; ubershaders (4.4+) and the shader baker (4.5+) reduce first-use hitches
ProfileDebugger > Visual Profiler for GPU time per pass; Monitors for draw calls

Recipes

Flash white on hit

Use for damage feedback on sprites; tween amount from 1 to 0. Enable Local to Scene on the material, or use an instance uniform, so only the hit enemy flashes.

flash.gdshader
shader_type canvas_item;
uniform vec4 flash_color : source_color = vec4(1.0);
uniform float amount : hint_range(0.0, 1.0) = 0.0;
 
void fragment() {
    // COLOR already holds texture x modulate
    COLOR.rgb = mix(COLOR.rgb, flash_color.rgb, amount);
}
func hit() -> void:
    var m := $Sprite2D.material as ShaderMaterial
    create_tween().tween_property(
        m, "shader_parameter/amount", 0.0, 0.2).from(1.0)

Dissolve

Use for deaths, teleports and burning paper; assign a NoiseTexture2D to noise and animate progress.

dissolve.gdshader
shader_type canvas_item;
uniform sampler2D noise : repeat_enable;
uniform float progress : hint_range(0.0, 1.0) = 0.0;
uniform float edge : hint_range(0.0, 0.2) = 0.05;
uniform vec4 edge_color : source_color =
    vec4(1.0, 0.5, 0.1, 1.0);
 
void fragment() {
    float n = texture(noise, UV).r;
    if (n < progress) {
        discard;
    }
    // glowing rim just above the cut-off
    float rim = 1.0 - step(progress + edge, n);
    COLOR.rgb = mix(COLOR.rgb, edge_color.rgb, rim);
}

Outline for 2D sprites

Use for selection and interaction highlights; the texture needs a transparent border at least width pixels wide.

outline.gdshader
shader_type canvas_item;
uniform vec4 line_color : source_color = vec4(1.0);
uniform float width : hint_range(0.0, 8.0) = 1.0;
 
void fragment() {
    vec2 o = TEXTURE_PIXEL_SIZE * width;
    float a = texture(TEXTURE, UV + vec2(o.x, 0.0)).a;
    a = max(a, texture(TEXTURE, UV - vec2(o.x, 0.0)).a);
    a = max(a, texture(TEXTURE, UV + vec2(0.0, o.y)).a);
    a = max(a, texture(TEXTURE, UV - vec2(0.0, o.y)).a);
    vec4 outline = vec4(line_color.rgb, a * line_color.a);
    COLOR = mix(outline, COLOR, COLOR.a);  // inside wins
}

Water with scrolling UVs

Use for 2D water, lava or force fields: scroll a noise texture and use it to distort what is behind.

water2d.gdshader
shader_type canvas_item;
uniform sampler2D screen_tex : hint_screen_texture,
    filter_linear;
uniform sampler2D noise : repeat_enable, filter_linear;
uniform vec2 scroll = vec2(0.05, 0.02);
uniform float distortion : hint_range(0.0, 0.05) = 0.01;
uniform vec4 tint : source_color = vec4(0.2, 0.5, 0.8, 0.5);
 
void fragment() {
    vec2 n = texture(noise, UV + TIME * scroll).rg - 0.5;
    vec2 n2 = texture(noise, UV * 1.7 - TIME * scroll).rg;
    vec2 off = (n + n2 - 0.5) * distortion;
    vec3 under = texture(screen_tex, SCREEN_UV + off).rgb;
    COLOR = vec4(mix(under, tint.rgb, tint.a), 1.0);
}

Vertex wind sway

Use for grass, leaves and flags in 3D; UV.y is 0 at the top of the quad, so the base stays planted.

foliage.gdshader
shader_type spatial;
render_mode cull_disabled;
uniform sampler2D albedo_tex : source_color,
    filter_linear_mipmap;
uniform float strength = 0.15;
uniform float speed = 1.5;
uniform vec2 wind_dir = vec2(1.0, 0.0);
 
void vertex() {
    vec3 w = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
    float t = TIME * speed + w.x * 0.4 + w.z * 0.3;
    float sway = sin(t) + 0.5 * sin(t * 2.3);
    float weight = 1.0 - UV.y;         // 0 at the root
    VERTEX.xz += wind_dir * sway * strength * weight;
}
 
void fragment() {
    vec4 c = texture(albedo_tex, UV);
    ALBEDO = c.rgb;
    ALPHA = c.a;
    ALPHA_SCISSOR_THRESHOLD = 0.5;     // no sorting cost
}

For 2D the same idea works in a canvas_item vertex(): VERTEX.x += sin(TIME + VERTEX.y) * k * (1.0 - UV.y);. Make wind_dir a global uniform (declared in Project Settings > Shader Globals) to drive every plant from one script.

Full-screen grayscale

Use for pause screens, death states and flashbacks: a ColorRect (full rect, mouse Ignore) in a top CanvasLayer.

grayscale.gdshader
shader_type canvas_item;
uniform sampler2D screen_tex : hint_screen_texture,
    filter_linear;
uniform float amount : hint_range(0.0, 1.0) = 1.0;
 
void fragment() {
    vec3 c = texture(screen_tex, SCREEN_UV).rgb;
    float l = dot(c, vec3(0.2126, 0.7152, 0.0722));
    COLOR = vec4(mix(c, vec3(l), amount), 1.0);
}

References