Spatial

package
v0.0.0-...-357ca8a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2025 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package Spatial provides the spatial shader pipeline used for shading 3D objects.

Index

Constants

This section is empty.

Variables

View Source
var (
	OutputIsSRGB = gpu.NewBoolExpression(gpu.New(gpu.Identifier("OUTPUT_IS_SRGB")))
	ClipSpaceFar = gpu.NewFloatExpression(gpu.New(gpu.Identifier("CLIP_SPACE_FAR")))
)

Globals are available everywhere, including custom functions.

Functions

This section is empty.

Types

type AmbientOcclusion

type AmbientOcclusion struct {
	Strength    float.X `gd:"AO"`       // Strength of ambient occlusion. For use with pre-baked AO.
	LightEffect float.X `gd:"AO_LIGHT"` // How much ambient occlusion affects direct light (range of [0.0, 1.0], default 0.0).
}

type Fragment

type Fragment struct {
	VertexPosition        vec3.XYZ         `gd:"VERTEX"`                   // Position of the vertex, in model space. In world space if world_vertex_coords is used.
	Position              vec3.XYZ         `gd:"POSITION"`                 // If written to, overrides final vertex position in clip space.
	Normal                vec3.XYZ         `gd:"NORMAL"`                   // Normal in model space. In world space if world_vertex_coords is used.
	Tangent               vec3.XYZ         `gd:"TANGENT"`                  // Tangent in model space. In world space if world_vertex_coords is used.
	Binormal              vec3.XYZ         `gd:"BINORMAL"`                 // Binormal in model space. In world space if world_vertex_coords is used.
	UV                    vec2.XY          `gd:"UV"`                       // UV main channel.
	UV2                   vec2.XY          `gd:"UV2"`                      // UV secondary channel.
	Color                 vec4.RGBA        `gd:"COLOR"`                    // Color from vertices.
	Roughness             float.X          `gd:"ROUGHNESS"`                // Roughness for vertex lighting.
	PointSize             float.X          `gd:"POINT_SIZE"`               // Point size for point rendering.
	ModelViewMatrix       mat4.ColumnMajor `gd:"MODEL_VIEW_MATRIX"`        // Model/local space to view space transform (use if possible).
	ModelViewNormalMatrix mat4.ColumnMajor `gd:"MODEL_VIEW_NORMAL_MATRIX"` //
	ProjectionMatrix      mat4.ColumnMajor `gd:"PROJECTION_MATRIX"`        // View space to clip space transform.
}

func (Fragment) Backlight

func (frag Fragment) Backlight() vec3.XYZ

Backlight color (works like direct light, but it's received even if the normal is slightly facing away from the light). If used, backlighting will be applied to the object. Can be used as a cheaper approximation of subsurface scattering.

func (Fragment) CameraDirectionWorld

func (frag Fragment) CameraDirectionWorld() vec3.XYZ

CameraDirectionWorld returns the camera direction in world space.

func (Fragment) CameraPositionWorld

func (frag Fragment) CameraPositionWorld() vec3.XYZ

CameraPositionWorld returns the camera position in world space.

func (Fragment) CameraVisibleLayers

func (frag Fragment) CameraVisibleLayers() uint.X

CameraVisibleLayers returns the cull layers of the camera rendering the current pass.

func (Fragment) EyeOffset

func (frag Fragment) EyeOffset() vec3.XYZ

EyeOffset for the eye being rendered. Only applicable for multiview rendering.

func (Fragment) Fragcoord

func (frag Fragment) Fragcoord() vec4.XYZW

Fragcoord returns the coordinate of pixel center in screen space. xy specifies position in window. Origin is lower left. z specifies fragment depth. It is also used as the output value for the fragment depth unless DEPTH is written to.

func (Fragment) FrontFacing

func (frag Fragment) FrontFacing() bool.X

FrontFacing returns true if the current face is front facing, false otherwise.

func (Fragment) InvProjectionMatrix

func (frag Fragment) InvProjectionMatrix() mat4.ColumnMajor

InvProjectionMatrix returns the clip space to view space transform.

func (Fragment) InvViewMatrix

func (frag Fragment) InvViewMatrix() mat4.ColumnMajor

InvViewMatrix returns the view space to world space transform.

func (Fragment) ModelMatrix

func (frag Fragment) ModelMatrix() mat4.ColumnMajor

ModelMatrix returns the model/local space to world space transform.

func (Fragment) ModelNormalMatrix

func (frag Fragment) ModelNormalMatrix() mat4.ColumnMajor

ModelNormalMatrix returns Model/local space to world space transform for normals. This is the same as MODEL_MATRIX by default unless the object is scaled non-uniformly, in which case this is set to transpose(inverse(mat3(MODEL_MATRIX))).

func (Fragment) NodePositionView

func (frag Fragment) NodePositionView() vec3.XYZ

NodePositionView returns the node position in view space.

func (Fragment) NodePositionWorld

func (frag Fragment) NodePositionWorld() vec3.XYZ

NodePositionWorld returns the node position in world space.

func (Fragment) PointCoord

func (frag Fragment) PointCoord() vec2.XY

PointCoord returns the point coordinate for drawing points with POINT_SIZE.

func (Fragment) ScreenUV

func (frag Fragment) ScreenUV() vec2.XY

ScreenUV returns the screen UV coordinate for current pixel.

func (Fragment) View

func (frag Fragment) View() vec3.XYZ

View returns the normalized vector from fragment position to camera (in view space). This is the same for both perspective and orthogonal cameras.

func (Fragment) ViewIndex

func (frag Fragment) ViewIndex() int.X

ViewIndex returns the view that we are rendering. Used to distinguish between views in multiview/stereo rendering. VIEW_MONO_LEFT (0) for Mono (not multiview) or left eye, VIEW_RIGHT (1) for right eye.

func (Fragment) ViewMatrix

func (frag Fragment) ViewMatrix() mat4.ColumnMajor

ViewMatrix returns the world space to view space transform.

func (Fragment) ViewMonoLeft

func (frag Fragment) ViewMonoLeft() int.X

ViewMonoLeft constant for Mono or left eye, always 0.

func (Fragment) ViewRight

func (frag Fragment) ViewRight() int.X

ViewRight constant for right eye, always 1.

func (Fragment) ViewportSize

func (frag Fragment) ViewportSize() vec2.XY

ViewportSize returns the size of the viewport (in pixels).

type Lighting

type Lighting struct {
	Diffuse  vec3.RGB `gd:"DIFFUSE"`  // Diffuse light result.
	Specular vec3.RGB `gd:"SPECULAR"` // Specular light result.
	Alpha    float.X  `gd:"ALPHA"`    // Alpha (range of [0.0, 1.0]). If written to, the material will go to the transparent pipeline.
}

type Material

type Material struct {
	LightVertexPosition    vec3.XYZ `gd:"LIGHT_VERTEX"`             // A writable version of VERTEX that can be used to alter light and shadows. Writing to this will not change the position of the fragment.
	Depth                  float.X  `gd:"DEPTH"`                    // Custom depth value (range of [0.0, 1.0]). If DEPTH is being written to in any shader branch, then you are responsible for setting the DEPTH for all other branches. Otherwise, the graphics API will leave them uninitialized.
	Normal                 vec3.XYZ `gd:"NORMAL"`                   // Normal that comes from the vertex() function, in view space. If skip_vertex_transform is enabled, it may not be in view space.
	Tangent                vec3.XYZ `gd:"TANGENT"`                  // Tangent that comes from the vertex() function, in view space. If skip_vertex_transform is enabled, it may not be in view space.
	Binormal               vec3.XYZ `gd:"BINORMAL"`                 // Binormal that comes from the vertex() function, in view space. If skip_vertex_transform is enabled, it may not be in view space.
	NormalMap              vec3.XYZ `gd:"NORMAL_MAP"`               // Set normal here if reading normal from a texture instead of NORMAL.
	NormalMapDepth         float.X  `gd:"NORMAL_MAP_DEPTH"`         // Depth from NORMAL_MAP. Defaults to 1.0.
	Albedo                 vec3.RGB `gd:"ALBEDO"`                   // Albedo (default white). Base color.
	Alpha                  float.X  `gd:"ALPHA"`                    // Alpha (range of [0.0, 1.0]). If read from or written to, the material will go to the transparent pipeline.
	AlphaScizzorThreshold  float.X  `gd:"ALPHA_SCISSOR_THRESHOLD"`  // If written to, values below a certain amount of alpha are discarded.
	AlphaHashScale         float.X  `gd:"ALPHA_HASH_SCALE"`         // Alpha hash scale when using the alpha hash transparency mode. Defaults to 1.0. Higher values result in more visible pixels in the dithering pattern.
	AlphaAntialiasingEdge  float.X  `gd:"ALPHA_ANTIALIASING_EDGE"`  // The threshold below which alpha to coverage antialiasing should be used. Defaults to 0.0. Requires the alpha_to_coverage render mode. Should be set to a value lower than ALPHA_SCISSOR_THRESHOLD to be effective.
	AlphaTextureCoordinate vec2.XY  `gd:"ALPHA_TEXTURE_COORDINATE"` // The texture coordinate to use for alpha-to-coverge antialiasing. Requires the alpha_to_coverage render mode. Typically set to UV * vec2(albedo_texture_size) where albedo_texture_size is the size of the albedo texture in pixels.
	PremultiplyAlphaFactor float.X  `gd:"PREMUL_ALPHA_FACTOR"`      // Premultiplied alpha factor. Only effective if render_mode blend_premul_alpha; is used. This should be written to when using a shaded material with premultiplied alpha blending for interaction with lighting. This is not required for unshaded materials.
	Metallic               float.X  `gd:"METALLIC"`                 // Metallic (range of [0.0, 1.0]).
	Specular               float.X  `gd:"SPECULAR"`                 // Specular (not physically accurate to change). Defaults to 0.5. 0.0 disables reflections.
	Roughness              float.X  `gd:"ROUGHNESS"`                // Roughness (range of [0.0, 1.0]).
	Rim                    float.X  `gd:"RIM"`                      // Rim (range of [0.0, 1.0]). If used, Godot calculates rim lighting. Rim size depends on ROUGHNESS.
	RimTint                float.X  `gd:"RIM_TINT"`                 // Rim Tint, range of 0.0 (white) to 1.0 (albedo). If used, Godot calculates rim lighting.
	ClearCoat              float.X  `gd:"CLEARCOAT"`                // Small specular blob added on top of the existing one. If used, Godot calculates clearcoat.
	ClearCoatGloss         float.X  `gd:"CLEARCOAT_GLOSS"`          // Gloss of clearcoat. If used, Godot calculates clearcoat.
	Anisotropy             float.X  `gd:"ANISOTROPY"`               // For distorting the specular blob according to tangent space.
	AnisotropyFlow         vec2.XY  `gd:"ANISOTROPY_FLOW"`          // Distortion direction, use with flowmaps.
	SubsurfaceScattering   SubsurfaceScattering
	Backlight              float.X `gd:"BACKLIGHT"` // Color of backlighting (works like direct light, but it's received even if the normal is slightly facing away from the light). If used, backlighting will be applied to the object. Can be used as a cheaper approximation of subsurface scattering.
	AmbientOcclusion       AmbientOcclusion
	Emission               vec3.RGB  `gd:"EMISSION"`   // Emission color (can go over (1.0, 1.0, 1.0) for HDR).
	Fog                    vec4.RGBA `gd:"FOG"`        // If written to, blends final pixel color with FOG.rgb based on FOG.a.
	Radiance               vec4.RGBA `gd:"RADIANCE"`   // If written to, blends environment map radiance with RADIANCE.rgb based on RADIANCE.a.
	Irradiance             vec4.RGBA `gd:"IRRADIANCE"` // If written to, blends environment map irradiance with IRRADIANCE.rgb based on IRRADIANCE.a.
}

func (Material) Attenuation

func (mat Material) Attenuation() float.X

Attenuation returns the attenuation based on distance or shadow.

func (Material) Fragcoord

func (mat Material) Fragcoord() vec4.XYZW

Fragcoord returns the coordinate of pixel center in screen space. xy specifies position in window. Origin is lower left. z specifies fragment depth. It is also used as the output value for the fragment depth unless DEPTH is written to.

func (Material) InverseModelMatrix

func (mat Material) InverseModelMatrix() mat4.ColumnMajor

InverseModelMatrix returns the inverse of the model/local space to world space transform.

func (Material) InverseProjectionMatrix

func (mat Material) InverseProjectionMatrix() mat4.ColumnMajor

InverseProjectionMatrix returns the clip space to view space transform.

func (Material) Light

func (mat Material) Light() vec3.XYZ

Light vector, in view space.

func (Material) LightColor

func (mat Material) LightColor() vec3.XYZ

LightColor multiplied by light energy multiplied by PI. The PI multiplication is present because physically-based lighting models include a division by PI.

func (Material) LightIsDirectional

func (mat Material) LightIsDirectional() bool.X

LightIsDirectional returns true if this pass is a DirectionalLight3D.

func (Material) ModelMatrix

func (mat Material) ModelMatrix() mat4.ColumnMajor

ModelMatrix returns the model/local space to world space transform.

func (Material) ProjectionMatrix

func (mat Material) ProjectionMatrix() mat4.ColumnMajor

ProjectionMatrix returns the view space to clip space transform.

func (Material) ScreenUV

func (mat Material) ScreenUV() vec2.XY

ScreenUV returns the screen UV coordinate for current pixel.

func (Material) SpecularAmount

func (mat Material) SpecularAmount() float.X

SpecularAmount for OmniLight3D and SpotLight3D, 2.0 multiplied by light_specular. For DirectionalLight3D, 1.0.

func (Material) View

func (mat Material) View() vec3.XYZ

View returns the normalized vector from fragment position to camera (in view space). This is the same for both perspective and orthogonal cameras.

func (Material) ViewMatrix

func (mat Material) ViewMatrix() mat4.ColumnMajor

ViewMatrix returns the world space to view space transform.

func (Material) ViewportSize

func (mat Material) ViewportSize() vec2.XY

ViewportSize returns the size of the viewport (in pixels).

type RenderMode

type RenderMode string
const (
	BlendMix                     RenderMode = "blend_mix"                 // Mix blend mode (alpha is transparency), default.
	BlendAdd                     RenderMode = "blend_add"                 // Additive blend mode.
	BlendSub                     RenderMode = "blend_sub"                 // Subtractive blend mode.
	BlendMul                     RenderMode = "blend_mul"                 // Multiplicative blend mode.
	BlendPremulAlpha             RenderMode = "blend_premul_alpha"        // Premultiplied alpha blend mode (fully transparent RenderMode = add, fully opaque RenderMode = mix).
	DepthDrawOpaque              RenderMode = "depth_draw_opaque"         // Only draw depth for opaque geometry (not transparent).
	DepthDrawAlways              RenderMode = "depth_draw_always"         // Always draw depth (opaque and transparent).
	DepthDrawNever               RenderMode = "depth_draw_never"          // Never draw depth.
	DepthPrepassAlpha            RenderMode = "depth_prepass_alpha"       // Do opaque depth pre-pass for transparent geometry.
	DepthTestDisabled            RenderMode = "depth_test_disabled"       // Disable depth testing.
	SubSurfaceScatteringModeSkin RenderMode = "sss_mode_skin"             // Subsurface Scattering mode for skin (optimizes visuals for human skin, e.g. boosted red channel).
	CullBack                     RenderMode = "cull_back"                 // Cull back-faces (default).
	CullFront                    RenderMode = "cull_front"                // Cull front-faces.
	CullDisabled                 RenderMode = "cull_disabled"             // Culling disabled (double sided).
	Unshaded                     RenderMode = "unshaded"                  // Result is just albedo. No lighting/shading happens in material, making it faster to render.
	Wireframe                    RenderMode = "wireframe"                 // Geometry draws using lines (useful for troubleshooting).
	DebugShadowSplits            RenderMode = "debug_shadow_splits"       // Directional shadows are drawn using different colors for each split (useful for troubleshooting).
	DiffuseBurley                RenderMode = "diffuse_burley"            // Burley (Disney PBS) for diffuse (default).
	DiffuseLambert               RenderMode = "diffuse_lambert"           // Lambert shading for diffuse.
	DiffuseLambertWrap           RenderMode = "diffuse_lambert_wrap"      // Lambert-wrap shading (roughness-dependent) for diffuse.
	DiffuseToon                  RenderMode = "diffuse_toon"              // Toon shading for diffuse.
	SpecularSchlickGGX           RenderMode = "specular_schlick_ggx"      // Schlick-GGX for direct light specular lobes (default).
	SpecularToon                 RenderMode = "specular_toon"             // Toon for direct light specular lobes.
	SpecularDisabled             RenderMode = "specular_disabled"         // Disable direct light specular lobes. Doesn't affect reflected light (use SPECULAR RenderMode = 0.0 instead).
	SkipVertexTransform          RenderMode = "skip_vertex_transform"     // VERTEX, NORMAL, TANGENT, and BITANGENT need to be transformed manually in the vertex() function.
	WorldVertexCoords            RenderMode = "world_vertex_coords"       // VERTEX, NORMAL, TANGENT, and BITANGENT are modified in world space instead of model space.
	EnsureCorrectNormals         RenderMode = "ensure_correct_normals"    // Use when non-uniform scale is applied to mesh (note: currently unimplemented).
	ShadowsDisabled              RenderMode = "shadows_disabled"          // Disable computing shadows in shader. The shader will not cast shadows, but can still receive them.
	AmbientLightDisabled         RenderMode = "ambient_light_disabled"    // Disable contribution from ambient light and radiance map.
	ShadowToOpacity              RenderMode = "shadow_to_opacity"         // Lighting modifies the alpha so shadowed areas are opaque and non-shadowed areas are transparent. Useful for overlaying shadows onto a camera feed in AR.
	VertexLighting               RenderMode = "vertex_lighting"           // Use vertex-based lighting instead of per-pixel lighting.
	ParticleTrails               RenderMode = "particle_trails"           // Enables the trails when used on particles geometry.
	AlphaToCoverage              RenderMode = "alpha_to_coverage"         // Alpha antialiasing mode, see here for more.
	AlphaToCoverageAndOne        RenderMode = "alpha_to_coverage_and_one" // Alpha antialiasing mode, see here for more.
	FogDisabled                  RenderMode = "fog_disabled"              // Disable receiving depth-based or volumetric fog. Useful for blend_add materials like particles.
)

type Shader

type Shader[T gdclass.Interface] struct {
	ShaderMaterial.Extension[T]
}

Shader used for shading 3D objects. They are the most complex type of shader that the engine offers. Spatial shaders are highly configurable with different render modes and different rendering options (e.g. Subsurface Scattering, Transmission, Ambient Occlusion, Rim lighting etc). Users can optionally write vertex, fragment, and light processor functions to affect how objects are drawn.

func (*Shader[T]) Fragment

func (*Shader[T]) Fragment(vertex Vertex) Fragment

func (*Shader[T]) GetPropertyList

func (s *Shader[T]) GetPropertyList() []Object.PropertyInfo

func (*Shader[T]) Lighting

func (*Shader[T]) Lighting(material Material) Lighting

func (*Shader[T]) Material

func (*Shader[T]) Material(fragment Fragment) Material

func (*Shader[T]) OnCreate

func (s *Shader[T]) OnCreate(value reflect.Value)

func (*Shader[T]) Pipeline

func (*Shader[T]) Pipeline() [3]string

func (*Shader[T]) RenderMode

func (*Shader[T]) RenderMode() []RenderMode

func (*Shader[T]) ShaderType

func (*Shader[T]) ShaderType() string

type SubsurfaceScattering

type SubsurfaceScattering struct {
	Strength           float.X   `gd:"SUBSURFACE_SCATTERING"` // Strength of subsurface scattering. If used, subsurface scattering will be applied to the object.
	TransmittanceColor vec4.RGBA `gd:"TRANSMITTANCE_COLOR"`   // Color of subsurface scattering transmittance. If used, subsurface scattering transmittance will be applied to the object.
	TransmittanceDepth float.X   `gd:"TRANSMITTANCE_DEPTH"`   // Depth of subsurface scattering transmittance. Higher values allow the effect to reach deeper into the object.
	TransmittanceBoost float.X   `gd:"TRANSMITTANCE_BOOST"`   // Boosts the subsurface scattering transmittance if set above 0.0. This makes the effect show up even on directly lit surfaces
}

type Vertex

type Vertex struct {
	ViewportSize          vec2.XY          `gd:"VIEWPORT_SIZE"`            // Size of viewport (in pixels).
	ViewMatrix            mat4.ColumnMajor `gd:"VIEW_MATRIX"`              // View matrix. Transforms from world space to camera space.
	InvViewMatrix         mat4.ColumnMajor `gd:"INV_VIEW_MATRIX"`          // View space to world space transform.
	MainCamInvViewMatrix  mat4.ColumnMajor `gd:"MAIN_CAM_INV_VIEW_MATRIX"` // View space to world space transform of camera used to draw the current viewport.
	InvProjectionMatrix   mat4.ColumnMajor `gd:"INV_PROJECTION_MATRIX"`    // Clip space to view space transform.
	NodePositionWorld     vec3.XYZ         `gd:"NODE_POSITION_WORLD"`      // Node position in world space.
	NodePositionView      vec3.XYZ         `gd:"NODE_POSITION_VIEW"`       // Node position in view space.
	CameraPositionWorld   vec3.XYZ         `gd:"CAMERA_POSITION_WORLD"`    // Camera position in world space.
	CameraPositionView    vec3.XYZ         `gd:"CAMERA_POSITION_VIEW"`     // Camera position in view space.
	CameraDirectionWorld  vec3.XYZ         `gd:"CAMERA_DIRECTION_WORLD"`   // Camera direction in world space.
	CameraVisibleLayers   uint.X           `gd:"CAMERA_VISIBLE_LAYERS"`    // Camera visible layers.
	InstanceID            int.X            `gd:"INSTANCE_ID"`              // InstanceID for instancing.
	InstanceCustom        vec4.XYZW        `gd:"INSTANCE_CUSTOM"`          // Instance custom data (for particles, mostly).
	ViewIndex             int.X            `gd:"VIEW_INDEX"`               // The view that we are rendering. VIEW_MONO_LEFT (0) for Mono (not multiview) or left eye, VIEW_RIGHT (1) for right eye.
	ViewMonoLeft          int.X            `gd:"VIEW_MONO_LEFT"`           // Constant for Mono or left eye, always 0.
	ViewRight             int.X            `gd:"VIEW_RIGHT"`               // Constant for right eye, always 1.
	EyeOffset             vec3.XYZ         `gd:"EYE_OFFSET"`               // Position offset for the eye being rendered. Only applicable for multiview rendering.
	Position              vec3.XYZ         `gd:"VERTEX"`                   // Position of the vertex, in model space. In world space if world_vertex_coords is used.
	VertexID              int.X            `gd:"VERTEX_ID"`                // The index of the current vertex in the vertex buffer.
	Normal                vec3.XYZ         `gd:"NORMAL"`                   // Normal in model space. In world space if world_vertex_coords is used.
	Tangent               vec3.XYZ         `gd:"TANGENT"`                  // Tangent in model space. In world space if world_vertex_coords is used.
	Binormal              vec3.XYZ         `gd:"BINORMAL"`                 // Binormal in model space. In world space if world_vertex_coords is used.
	UV                    vec2.XY          `gd:"UV"`                       // UV main channel.
	UV2                   vec2.XY          `gd:"UV2"`                      // UV secondary channel.
	Color                 vec4.RGBA        `gd:"COLOR"`                    // Color from vertices.
	PointSize             float.X          `gd:"POINT_SIZE"`               // Point size for point rendering.
	ModelViewMatrix       mat4.ColumnMajor `gd:"MODEL_VIEW_MATRIX"`        // Model/local space to view space transform (use if possible).
	ModelViewNormalMatrix mat4.ColumnMajor `gd:"MODEL_VIEW_NORMAL_MATRIX"` //
	ModelMatrix           mat4.ColumnMajor `gd:"MODEL_MATRIX"`             // Model/local space to world space transform.
	ModelNormalMatrix     mat4.ColumnMajor `gd:"MODEL_NORMAL_MATRIX"`      //
	ProjectionMatrix      mat4.ColumnMajor `gd:"PROJECTION_MATRIX"`        // View space to clip space transform.
	BoneIndices           uvec4.XYZW       `gd:"BONE_INDICES"`             //
	BoneWeights           vec4.XYZW        `gd:"BONE_WEIGHTS"`             //
	Custom0               vec4.XYZW        `gd:"CUSTOM0"`                  //
	Custom1               vec4.XYZW        `gd:"CUSTOM1"`                  //
	Custom2               vec4.XYZW        `gd:"CUSTOM2"`                  //
	Custom3               vec4.XYZW        `gd:"CUSTOM3"`                  //
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL