{"id":13996,"date":"2026-05-14T06:21:49","date_gmt":"2026-05-14T06:21:49","guid":{"rendered":"https:\/\/3dcoat.com\/documentation\/?post_type=manual_documentation&#038;p=13996"},"modified":"2026-05-14T06:25:08","modified_gmt":"2026-05-14T06:25:08","slug":"nodegraph-language-ngl","status":"publish","type":"manual_documentation","link":"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/","title":{"rendered":"NodeGraph Language (NGL)"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\" id=\"nodegraph-language-ngl-rules\"><\/h1>\n\n\n\n<p>NGL is a material description language based on the GLSL shader language. It is used in 3DCoat to create nodes for materials, effects, deformations, and more.<\/p>\n\n\n\n<p>The language includes a preprocessor that handles custom defines and provides additional features needed for node description.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"code-structure\">Code Structure<\/h2>\n\n\n\n<p>Unlike standard GLSL, NGL offers flexibility in how you structure your code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"implicit-main\">Implicit Main<\/h3>\n\n\n\n<p>You are not required to define a main function. You can write your shader code directly in the global scope, similar to Python scripts.<\/p>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>in vec3 Color;\nout vec3 Result;\n\n\/\/ Direct code execution\nResult = Color * 2.0;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"explicit-main-with-arguments\">Explicit Main with Arguments<\/h3>\n\n\n\n<p>If you prefer to define a main function, you can declare your&nbsp;<code>in<\/code>&nbsp;and&nbsp;<code>out<\/code>&nbsp;properties directly as arguments to the function. This keeps the global namespace clean and groups property definitions with the main logic.<\/p>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void main(\n    in vec3 FragCoord(value= 1, knot= ioFragCoord, expression= R=(V*K), min= -10.0, max= 10.0),\n    in float Scale,\n    out float Closest,\n    out float SecondClosest,\n    out float CellID\n) {\n    \/\/ Shader logic here\n    vec3 p = floor(FragCoord * Scale);\n    \/\/ ...\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"properties\">Properties<\/h2>\n\n\n\n<p>To create incoming or outgoing properties, you can simply prefix the variable with&nbsp;<code>in<\/code>&nbsp;or&nbsp;<code>out<\/code>. Properties can be global variables (as seen above) or arguments of the main function.<\/p>\n\n\n\n<p>Syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>in type VariableName;\nout type VariableName;\n<\/code><\/pre>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>in vec3 Color;\nout vec4 Result;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"property-options\">Property Options<\/h3>\n\n\n\n<p>Additional options for each property can be specified in round brackets after the variable declaration.<\/p>\n\n\n\n<p>Syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>in type VariableName(option1 = value1, option2 = value2, ...);\n<\/code><\/pre>\n\n\n\n<p>Available Options:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>value<\/code>: Default value for the property.<\/li>\n\n\n\n<li><code>knot<\/code>: Specifies a knot type (e.g.,\u00a0<code>ioFragCoord<\/code>).<\/li>\n\n\n\n<li><code>expression<\/code>: Defines a custom expression for the property value (e.g.,\u00a0<code>R=V*D(K.x)<\/code>).<\/li>\n\n\n\n<li><code>min<\/code>: Minimum allowed value.<\/li>\n\n\n\n<li><code>max<\/code>: Maximum allowed value.<\/li>\n\n\n\n<li><code>AllowCurve<\/code>: (Boolean) Allows curve control. Default is false.<\/li>\n\n\n\n<li><code>AllowTexture<\/code>: (Boolean) Allows texture input. Default is false.<\/li>\n<\/ul>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>in vec3 FragCoord(value = 1, knot = ioFragCoord, expression = R=V*D(K.x), min = -10.0, max = 10.0, AllowCurve = false, AllowTexture = false);\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"expressions\">Expressions<\/h2>\n\n\n\n<p>Expressions allow you to define custom logic for property values directly in the declaration. They share the same features as NGL but are designed for compactness. You cannot create new&nbsp;<code>in<\/code>&nbsp;or&nbsp;<code>out<\/code>&nbsp;properties within an expression.<\/p>\n\n\n\n<p>Shorthand Variables:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>R<\/code>: (<code>vec4<\/code>) Result variable. The output of the expression is written here.<\/li>\n\n\n\n<li><code>V<\/code>: (<code>vec4<\/code>) Input value. The value entered by the user in the Node Inspector.<\/li>\n\n\n\n<li><code>K<\/code>: (<code>vec4<\/code>) Knot value. The value connected to the property from another node. Defaults to\u00a0<code>vec4(1,1,1,1)<\/code>\u00a0if nothing is connected.<\/li>\n<\/ul>\n\n\n\n<p>Shorthand Functions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>DC(value)<\/code>: Deform Curve. Applies the curve (configurable by the user for this property) to a vec4 or color value.<\/li>\n\n\n\n<li><code>D(value)<\/code>: Deform Curve (Scalar). Applies the curve to a float value or a single scalar.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"accessing-other-properties\">Accessing Other Properties<\/h3>\n\n\n\n<p>You can access the values of other properties (including custom user-created properties not defined in the code) using dot notation:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>OtherProp.V<\/code>: The value of\u00a0<code>OtherProp<\/code>\u00a0defined in the Inspector (User Value).<\/li>\n\n\n\n<li><code>OtherProp.K<\/code>: The value connected to\u00a0<code>OtherProp<\/code>\u00a0from another node (Knot Value).<\/li>\n<\/ul>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Result = UserValue * AnotherPropertyValue * AnotherPropertyConnectedValue\nin float Scale(expression = R = V * AnotherProp.V * AnotherProp.K);\n<\/code><\/pre>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Result = UserValue * DeformCurve(ConnectedValue.x)\nin float Scale(expression = R=V*D(K.x));\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"math-operations--type-casting\">Math Operations &amp; Type Casting<\/h2>\n\n\n\n<p>When writing equations involving&nbsp;<strong>addition<\/strong>&nbsp;or&nbsp;<strong>subtraction<\/strong>&nbsp;between a&nbsp;<code>float<\/code>&nbsp;and a vector of any size (e.g.,&nbsp;<code>vec3<\/code>,&nbsp;<code>vec4<\/code>,&nbsp;<code>color<\/code>), you&nbsp;<strong>MUST ALWAYS<\/strong>&nbsp;explicitly cast the&nbsp;<code>float<\/code>&nbsp;to the corresponding vector type. Failure to do so will result in GLSL compilation errors in 3DCoat.&nbsp;<em>(Note: Multiplication and division are usually fine, but addition\/subtraction strictly require matching types).<\/em><\/p>\n\n\n\n<p>Example (Incorrect):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vec3 myColor = vec3(1.0, 0.5, 0.2);\nfloat bias = 0.1;\n\n\/\/ This will cause a compilation error in NGL!\nvec3 result = myColor + bias; \n<\/code><\/pre>\n\n\n\n<p>Example (Correct):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vec3 myColor = vec3(1.0, 0.5, 0.2);\nfloat bias = 0.1;\n\n\/\/ Correct: explicitly cast the float to a vec3\nvec3 result = myColor + vec3(bias);\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"special-data-types\">Special Data Types<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"color\">color<\/h3>\n\n\n\n<p>The&nbsp;<code>color<\/code>&nbsp;type is essentially a&nbsp;<code>vec4<\/code>, handled by the preprocessor.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In the Editor: It appears as a color picker with a specialized UI, rather than four separate float sliders.<\/li>\n\n\n\n<li>Usage: Use it exactly like a\u00a0<code>vec4<\/code>\u00a0in your code.<\/li>\n<\/ul>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>in color DiffuseColor;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"one2dcurve\">One2DCurve<\/h3>\n\n\n\n<p>The&nbsp;<code>One2DCurve<\/code>&nbsp;type represents a custom 1D correction curve defined by the user in the UI.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In the Editor: It is accessed via a curve editor.<\/li>\n\n\n\n<li>Usage: In code, it acts as a fixed array of 256 floats (<code>float[256]<\/code>). You can access values using an index from 0 to 255.<\/li>\n<\/ul>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>in One2DCurve MyCurve;\n\n\/\/ access value at index 128\nfloat midValue = MyCurve&#91;128];\n\n\/\/ map 0.0-1.0 to 0-255 range\nfloat value = MyCurve&#91;int(inputVal * 255.0)];\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"property-modifiers-and-accessors\">Property Modifiers and Accessors<\/h2>\n\n\n\n<p>For&nbsp;<code>in<\/code>&nbsp;properties, you can access additional attributes and modifiers using dot notation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"inv\">.INV<\/h3>\n\n\n\n<p>Checks if the user has inverted the input property.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Usage:\u00a0<code>PropertyName.INV<\/code>\u00a0returns a boolean (or integer 0\/1).<\/li>\n\n\n\n<li>Context: Use this to manually apply inversion logic if needed, for example, when the input controls a texture lookup rather than a direct value.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"dc\">.DC()<\/h3>\n\n\n\n<p>Accesses the \u201cDeform Curve\u201d function associated with the property. Users can adjust an input\u2019s curve in the UI. By default, this is applied to the input value. However, if you are using the input to control something else (like a texture coordinate or a fetched texture sample), you can apply the same curve modification to that new value.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Syntax:\u00a0<code>PropertyName.DC(value)<\/code><\/li>\n<\/ul>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Apply the same curve configured for 'Color' input to a texture sample\nvec4 texColor = texture(MyMap, uv);\nvec4 correctedColor = Color.DC(texColor);\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"material-object\">Material Object<\/h2>\n\n\n\n<p>The&nbsp;<code>Material<\/code>&nbsp;type is a specialized structure used to represent a full PBR material. Under the hood, it is packed into an array of 7 vectors:&nbsp;<code>vec4[7]<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"structure-and-packing\">Structure and Packing<\/h3>\n\n\n\n<p>To allow mixing different material types (e.g., Glass vs. Metal) and to optimize storage, multiple properties may share the same scalar value in the underlying vectors. For example, a generic \u201cscalar\u201d might represent Refraction in the 0.0-0.5 range and Metalness in the 0.5-1.0 range.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"accessing-properties\">Accessing Properties<\/h3>\n\n\n\n<p>You can access unpacked properties using the&nbsp;<code>io<\/code>&nbsp;prefix on the&nbsp;<code>Material<\/code>&nbsp;object properties.<\/p>\n\n\n\n<p>Syntax:&nbsp;<code>materialInstance.ioPropertyName<\/code><\/p>\n\n\n\n<p>Available Properties:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ioAlbedoColor (vec3)<\/li>\n\n\n\n<li>ioEmissive (vec3)<\/li>\n\n\n\n<li>ioOpacity (float)<\/li>\n\n\n\n<li>ioIridescence (float)<\/li>\n\n\n\n<li>ioAnisotropy (float)<\/li>\n\n\n\n<li>ioClearCoat (float)<\/li>\n\n\n\n<li>ioIOR (float)<\/li>\n\n\n\n<li>ioClearCoatRoughness (float)<\/li>\n\n\n\n<li>ioVolume (float)<\/li>\n\n\n\n<li>ioMicroprotrusionsRoughness (float)<\/li>\n\n\n\n<li>ioReflectionColor (vec3)<\/li>\n\n\n\n<li>ioRefractionBlur (float)<\/li>\n\n\n\n<li>ioSpecularEdgePower (float)<\/li>\n\n\n\n<li>ioEmissiveColor (vec3)<\/li>\n\n\n\n<li>ioSubSurfaceColor (vec3)<\/li>\n\n\n\n<li>ioSpecularEdgeColor (vec3)<\/li>\n\n\n\n<li>ioMicroprotrusionsColor (vec3)<\/li>\n\n\n\n<li>ioDiffuseSSS (float)<\/li>\n\n\n\n<li>ioSpecularSSS (float)<\/li>\n\n\n\n<li>ioRefractionChromatic (float)<\/li>\n\n\n\n<li>ioAmbientOcclusion (float)<\/li>\n\n\n\n<li>ioClearCoatEdgePower (float)<\/li>\n\n\n\n<li>ioMicroprotrusions (float)<\/li>\n\n\n\n<li>ioTSNormal (Color) &#8211; Tangent Space Normal<\/li>\n\n\n\n<li>ioMetalness (float)<\/li>\n\n\n\n<li>ioRefraction (float)<\/li>\n\n\n\n<li>ioRefractionMetalness (float)<\/li>\n\n\n\n<li>ioGloss (float)<\/li>\n\n\n\n<li>ioRoughness (float)<\/li>\n\n\n\n<li>ioVelvet (float)<\/li>\n<\/ul>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>out Material result;\n\/\/ ...\nresult.ioAlbedoColor = vec3(1.0, 0.0, 0.0);\nresult.ioMetalness = 1.0;\nresult.ioRoughness = 0.2;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"implicit-material-properties\">Implicit Material Properties<\/h3>\n\n\n\n<p>If you write&nbsp;<code>io<\/code>&nbsp;+&nbsp;<code>[PropertyName]<\/code>&nbsp;(for example&nbsp;<code>ioAlbedoColor<\/code>,&nbsp;<code>ioGloss<\/code>,&nbsp;<code>ioMetalness<\/code>) directly without a material object instance, the values will be written to or read from the default material to which the node scheme is applied. (Note:&nbsp;<code>ioPropertyName<\/code>&nbsp;itself is not a real variable, it just represents the naming schema). You&nbsp;<strong>do not need to declare these variables<\/strong>; they are present in the node graph by default.<\/p>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Directly writing to default material properties\nioAlbedoColor = vec3(1.0, 0.0, 0.0);\nioMetalness = 1.0;\nioGloss = 0.8;\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"global-built-in-variables\">Global Built-in Variables<\/h2>\n\n\n\n<p>NGL provides a set of global built-in variables that are always available out of the box. You can use them anywhere in your code, but&nbsp;<strong>you must not declare them<\/strong>&nbsp;(e.g., using&nbsp;<code>in<\/code>&nbsp;or&nbsp;<code>out<\/code>), as this will lead to a re-declaration compilation error.<\/p>\n\n\n\n<p>Available global variables:<br \/><code>ioResolution<\/code>,\u00a0<code>ioMaskLayer<\/code>,\u00a0<code>ioLayerColor<\/code>,\u00a0<code>ioLayerBytes<\/code>,\u00a0<code>ioLayerFloat<\/code>,\u00a0<code>ioTime<\/code>,\u00a0<code>ioTimeDelta<\/code>,\u00a0<br \/><code>ioFrame<\/code>,\u00a0<code>ioMouse<\/code>,\u00a0<code>ioDate<\/code>,\u00a0<code>ioReplaceAlpha<\/code>,\u00a0<code>ioFragCoord<\/code>,\u00a0<code>ioUV<\/code>,\u00a0<code>ioPosition<\/code>,\u00a0<code>ioGlobalPosition<\/code>,\u00a0<br \/><code>ioNormal<\/code>,\u00a0<code>ioGlobalNormal<\/code>,\u00a0<code>ioFragCoord_DX<\/code>,\u00a0<code>ioUV_DX<\/code>,\u00a0<code>ioPosition_DX<\/code>,\u00a0<code>ioNormal_DX<\/code>,\u00a0<br \/><code>ioFragCoord_DY<\/code>,\u00a0<code>ioUV_DY<\/code>,\u00a0<code>ioPosition_DY<\/code>,\u00a0<code>ioNormal_DY<\/code>,\u00a0<code>ioSpecularMask<\/code>,\u00a0<code>ioCavity<\/code>,\u00a0<br \/><code>ioOcclusion<\/code>,\u00a0<code>ioCameraPosition<\/code>,\u00a0<code>ioRayDir<\/code>,\u00a0<code>ioLightDir<\/code>,\u00a0<code>ioIteration<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"global-functions-mixmtl\">Global Functions: mixMTL<\/h3>\n\n\n\n<p>A global helper function to correctly mix two materials. It handles the packed structure of the&nbsp;<code>Material<\/code>&nbsp;type to ensure all properties (even those sharing scalars) are interpolated correctly.<\/p>\n\n\n\n<p>Syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Material mixMTL(Material m1, Material m2, float t);\n<\/code><\/pre>\n\n\n\n<p>Parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>m1<\/code>: The first material.<\/li>\n\n\n\n<li><code>m2<\/code>: The second material.<\/li>\n\n\n\n<li><code>t<\/code>: Interpolation factor (0.0 to 1.0).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"preprocessor-directives\">Preprocessor Directives<\/h2>\n\n\n\n<p>NGL supports custom preprocessor directives to generate different source code based on settings or to create UI elements.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"enum\"><a href=\"tag:\/\/enum\">#enum<\/a><\/h3>\n\n\n\n<p>Creates a dropdown menu in the node settings.<br \/>Syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#enum DEFINE_NAME OPTION1 OPTION2 OPTION3 ...\n<\/code><\/pre>\n\n\n\n<p>In this case,&nbsp;<code>DEFINE_NAME<\/code>&nbsp;will be replaced by the selected element from the list. This is particularly useful for creating generic types or switching keywords.<\/p>\n\n\n\n<p>Example 1 (Type switching):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#enum genType float vec2 vec3 vec4\n\n\/\/ genType will be replaced by the selected type (e.g. float, vec2, etc.)\nin genType Value;\n<\/code><\/pre>\n\n\n\n<p>Example 2 (Photoshop-like layer blending):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ NGL Node for Photoshop-like layer blending \n#enum BlendMode Normal Multiply Screen Overlay Darken Lighten ColorDodge ColorBurn HardLight SoftLight Difference Exclusion \n\nin color Base(value=vec4(0.5, 0.5, 0.5, 1.0));\nin color Blend(value=vec4(0.5, 0.5, 0.5, 1.0));\nin float Opacity(value=1.0, min=0.0, max=1.0);\nout color Result;\n\nvec3 Normal(vec3 b, vec3 a) { return a; } \nvec3 Multiply(vec3 b, vec3 a) { return b * a; } \nvec3 Screen(vec3 b, vec3 a) { return 1.0 - (1.0 - b) * (1.0 - a); } \nvec3 Overlay(vec3 b, vec3 a) { \n    vec3 mult = 2.0 * b * a; \n    vec3 screen = 1.0 - 2.0 * (1.0 - b) * (1.0 - a); \n    return mix(mult, screen, step(0.5, b)); \n} \nvec3 Darken(vec3 b, vec3 a) { return min(b, a); } \nvec3 Lighten(vec3 b, vec3 a) { return max(b, a); } \nvec3 ColorDodge(vec3 b, vec3 a) { \n    return mix(min(vec3(1.0), b \/ max(1.0 - a, vec3(0.00001))), vec3(1.0), step(1.0, a)); \n} \nvec3 ColorBurn(vec3 b, vec3 a) { \n    return mix(max(vec3(0.0), 1.0 - (1.0 - b) \/ max(a, vec3(0.00001))), vec3(0.0), step(a, vec3(0.0))); \n} \nvec3 HardLight(vec3 b, vec3 a) { \n    vec3 mult = 2.0 * b * a; \n    vec3 screen = 1.0 - 2.0 * (1.0 - b) * (1.0 - a); \n    return mix(mult, screen, step(0.5, a)); \n} \nvec3 SoftLight(vec3 b, vec3 a) { \n    vec3 darken = b - (1.0 - 2.0 * a) * b * (1.0 - b); \n    vec3 lighten = b + (2.0 * a - 1.0) * (sqrt(b) - b); \n    return mix(darken, lighten, step(0.5, a)); \n} \nvec3 Difference(vec3 b, vec3 a) { return abs(b - a); } \nvec3 Exclusion(vec3 b, vec3 a) { return b + a - 2.0 * b * a; } \n\n\/\/ Clamping to avoid artifacts on overbright colors \nvec3 baseCol = clamp(Base.rgb, 0.0, 1.0); \nvec3 blendCol = clamp(Blend.rgb, 0.0, 1.0); \n \n\/\/ Selecting blending math via #enum substitution \nvec3 blended = BlendMode(baseCol, blendCol); \n \n\/\/ Opacity and Alpha factoring \nfloat totalBlendFactor = clamp(Blend.a * Opacity, 0.0, 1.0); \n \nvec3 finalColor = mix(Base.rgb, blended, totalBlendFactor); \nfloat finalAlpha = max(Base.a, Blend.a * Opacity); \n \nResult = vec4(finalColor, finalAlpha); \n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"int\"><a href=\"tag:\/\/int\">#int<\/a><\/h3>\n\n\n\n<p>Allows you to set an integer value via the UI.<br \/>Syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#int DEFINE_NAME DEFAULT_VALUE MIN_VALUE MAX_VALUE\n<\/code><\/pre>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#int ITERATIONS 5 0 10\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"bool\"><a href=\"tag:\/\/bool\">#bool<\/a><\/h3>\n\n\n\n<p>Creates a checkbox in the settings.<br \/>Syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#bool DEFINE_NAME\n<\/code><\/pre>\n\n\n\n<p>You can check if it is enabled using&nbsp;<code>#if<\/code>.<\/p>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#bool ENABLE_SHADOWS\n\n#if ENABLE_SHADOWS\n    \/\/ Shadow calculation code\n#endif\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"sampler\"><a href=\"tag:\/\/sampler\">#sampler<\/a><\/h3>\n\n\n\n<p>Provides direct access to a bitmap texture and Sampler2D.<br \/>Syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#sampler DEFINE_NAME\n<\/code><\/pre>\n\n\n\n<p>This allows users to load textures, and you can use&nbsp;<code>DEFINE_NAME<\/code>&nbsp;as a Sampler2D in your code.<\/p>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#sampler AlbedoMap\n\nvoid main() {\n    vec4 color = texture(AlbedoMap, uv);\n}<\/code><\/pre>\n","protected":false},"author":6,"featured_media":0,"parent":13980,"menu_order":0,"template":"","manualdocumentationcategory":[9,193],"manual_doc_tag":[],"class_list":["post-13996","manual_documentation","type-manual_documentation","status-publish","hentry","manualdocumentationcategory-manual","manualdocumentationcategory-nodes"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>NodeGraph Language (NGL) - 3DCoat Documentation<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"NodeGraph Language (NGL) - 3DCoat Documentation\" \/>\n<meta property=\"og:description\" content=\"NGL is a material description language based on the GLSL shader language. It is used in 3DCoat to crea...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/\" \/>\n<meta property=\"og:site_name\" content=\"3DCoat Documentation\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/3DCoat\" \/>\n<meta property=\"article:modified_time\" content=\"2026-05-14T06:25:08+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@3DCoatOfficial\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/\",\"url\":\"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/\",\"name\":\"NodeGraph Language (NGL) - 3DCoat Documentation\",\"isPartOf\":{\"@id\":\"https:\/\/3dcoat.com\/documentation\/#website\"},\"datePublished\":\"2026-05-14T06:21:49+00:00\",\"dateModified\":\"2026-05-14T06:25:08+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/3dcoat.com\/documentation\/nl_NL\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Node System\",\"item\":\"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"NodeGraph Language (NGL)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/3dcoat.com\/documentation\/#website\",\"url\":\"https:\/\/3dcoat.com\/documentation\/\",\"name\":\"3DCoat Documentation\",\"description\":\"Information about starting to use and learning how to use all the features of the 3DCoat.\",\"publisher\":{\"@id\":\"https:\/\/3dcoat.com\/documentation\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/3dcoat.com\/documentation\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/3dcoat.com\/documentation\/#organization\",\"name\":\"Pilgway\",\"url\":\"https:\/\/3dcoat.com\/documentation\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/3dcoat.com\/documentation\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/3dcoat.com\/documentation\/wp-content\/uploads\/2022\/09\/logo3DCoatWhite-1.png\",\"contentUrl\":\"https:\/\/3dcoat.com\/documentation\/wp-content\/uploads\/2022\/09\/logo3DCoatWhite-1.png\",\"width\":876,\"height\":190,\"caption\":\"Pilgway\"},\"image\":{\"@id\":\"https:\/\/3dcoat.com\/documentation\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/3DCoat\",\"https:\/\/x.com\/3DCoatOfficial\",\"https:\/\/www.youtube.com\/c\/PILGWAY3DCoat\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"NodeGraph Language (NGL) - 3DCoat Documentation","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/","og_locale":"en_US","og_type":"article","og_title":"NodeGraph Language (NGL) - 3DCoat Documentation","og_description":"NGL is a material description language based on the GLSL shader language. It is used in 3DCoat to crea...","og_url":"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/","og_site_name":"3DCoat Documentation","article_publisher":"https:\/\/www.facebook.com\/3DCoat","article_modified_time":"2026-05-14T06:25:08+00:00","twitter_card":"summary_large_image","twitter_site":"@3DCoatOfficial","twitter_misc":{"Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/","url":"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/","name":"NodeGraph Language (NGL) - 3DCoat Documentation","isPartOf":{"@id":"https:\/\/3dcoat.com\/documentation\/#website"},"datePublished":"2026-05-14T06:21:49+00:00","dateModified":"2026-05-14T06:25:08+00:00","breadcrumb":{"@id":"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/nodegraph-language-ngl\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/3dcoat.com\/documentation\/nl_NL\/"},{"@type":"ListItem","position":2,"name":"Node System","item":"https:\/\/3dcoat.com\/documentation\/manual\/nodesystem\/"},{"@type":"ListItem","position":3,"name":"NodeGraph Language (NGL)"}]},{"@type":"WebSite","@id":"https:\/\/3dcoat.com\/documentation\/#website","url":"https:\/\/3dcoat.com\/documentation\/","name":"3DCoat Documentation","description":"Information about starting to use and learning how to use all the features of the 3DCoat.","publisher":{"@id":"https:\/\/3dcoat.com\/documentation\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/3dcoat.com\/documentation\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/3dcoat.com\/documentation\/#organization","name":"Pilgway","url":"https:\/\/3dcoat.com\/documentation\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/3dcoat.com\/documentation\/#\/schema\/logo\/image\/","url":"https:\/\/3dcoat.com\/documentation\/wp-content\/uploads\/2022\/09\/logo3DCoatWhite-1.png","contentUrl":"https:\/\/3dcoat.com\/documentation\/wp-content\/uploads\/2022\/09\/logo3DCoatWhite-1.png","width":876,"height":190,"caption":"Pilgway"},"image":{"@id":"https:\/\/3dcoat.com\/documentation\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/3DCoat","https:\/\/x.com\/3DCoatOfficial","https:\/\/www.youtube.com\/c\/PILGWAY3DCoat"]}]}},"_links":{"self":[{"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/manual_documentation\/13996","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/manual_documentation"}],"about":[{"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/types\/manual_documentation"}],"author":[{"embeddable":true,"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/users\/6"}],"version-history":[{"count":2,"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/manual_documentation\/13996\/revisions"}],"predecessor-version":[{"id":13999,"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/manual_documentation\/13996\/revisions\/13999"}],"up":[{"embeddable":true,"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/manual_documentation\/13980"}],"wp:attachment":[{"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/media?parent=13996"}],"wp:term":[{"taxonomy":"manualdocumentationcategory","embeddable":true,"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/manualdocumentationcategory?post=13996"},{"taxonomy":"manual_doc_tag","embeddable":true,"href":"https:\/\/3dcoat.com\/documentation\/wp-json\/wp\/v2\/manual_doc_tag?post=13996"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}