Chapter 9

GLSL Data Types for VJs — Chapter 9

Learn GLSL float, bool, vec2, vec3, vec4 in plain English—stop type-mismatch compile errors when tweaking ISF uniforms or pasting StackOverflow GLSL. Live demo.

By

In Chapter 1 you learned what ISF is. In Chapter 7 you opened the .fs file and understood the JSON + GLSL split. In Chapter 8 you authored every ISF input type — sliders, color pickers, toggles, events, and XY pads — tuned for MIDI and OSC busking. Use the ISF for VJs manual index if you need to jump between modules.

You open a shader from the ISF library or copy a snippet from StackOverflow, paste it into ISF Editor, and the output goes black. The error bar says something like ERROR: 0:12: '' : wrong operand types - no operation '+' exists that takes a left-hand operand of type 'float' and a right operand of type 'int'. You stare at it. Nothing makes sense.

This chapter on GLSL data types for VJs fixes that. No programming background required. You will learn exactly what float, bool, int, vec2, vec3, and vec4 are, why the GPU cares so much about them, and what to do the next time you see a type error in your shader. After this chapter, those red error messages will tell you exactly what to fix instead of feeling like a wall.

GLSL data types float bool vec2 vec3 vec4 illustrated for VJs in plain English with ISF shader examples
GLSL data types float, bool, vec2, vec3, vec4: the building blocks that control every ISF shader, explained in plain English for VJs and DJs.

GLSL data types for VJs: float, bool, vec2, vec3, and vec4

Every value inside an ISF shader belongs to one of six core GLSL data types. Sliders map to float. Toggles map to bool. Color pickers arrive as vec4. Screen position lives in vec2. When you understand which container each value uses, compile errors stop being cryptic and start reading like plain instructions.

Why data types cause most shader errors

When you DJ, you know that a channel fader and an EQ knob do different jobs, even if they both look like something you can move. You do not try to plug a USB cable into an XLR port. Categories matter because different things work differently.

The GPU works the same way. It needs to know what kind of value every variable holds before it can use it. Is it a color? A position? An on/off switch? A speed value? Each one has a different type, and if you mix them incorrectly — even by accident — the shader refuses to compile. Not crashes. Refuses. It simply will not start.

This is actually a feature, not a flaw. The GPU checks everything before rendering a single pixel, so errors never make it to your output screen live. But it does mean that small mistakes in the code stop everything cold.

The good news: type errors are the most mechanical errors in GLSL. Once you understand the six types covered in this chapter, you can fix 80% of compile failures in under a minute.

What is a data type? (In plain English)

A data type is a label that tells the GPU what kind of information a variable holds. Think of it like the label on a container:

  • A container labeled float holds one number, like a speed slider set to 0.75.
  • A container labeled bool holds only true or false, like a mute button.
  • A container labeled vec3 holds three numbers at the same time, like a color (red=0.2, green=0.8, blue=0.5).

You cannot pour a liquid (float) into a container designed for a switch (bool). GLSL enforces these containers strictly. If you try to combine incompatible types, the compiler stops you before anything renders.

Every value in a GLSL shader belongs to one of these containers. Once you recognize the containers, the code starts to read almost like sentences.

float — The most important type for VJs

float is a number with a decimal point. It can be any number: positive, negative, very large, very small, or a fraction. The word "float" comes from "floating point," which is just the technical name for how computers store decimal numbers.

In ISF shaders, almost every parameter you control — speed, intensity, distortion amount, hue rotation — is a float. When you move a slider in Resolume or Magic Visuals and the visual changes, you are changing a float value somewhere in the shader.

ISF Editor showing a float uniform named mySpeed connected to a slider control in the playback UI
A float uniform named "mySpeed" in ISF Editor: the slider in the Playback UI maps directly to this single decimal number inside the shader.

What float means for you

Every time you see a slider in your ISF host software — a speed knob, a blur amount, a rotation angle — that slider controls a float. The number goes into the shader and the shader uses it to calculate something visual.

When you write 0.5 in GLSL, that is a float. When you write 1.0, that is also a float. Notice the decimal point. The GPU always needs it. If you write just 1 without the decimal point, the GPU reads it as a different type called int. This one difference causes more red screens for non-programmers than anything else in GLSL.

// Correct: these are all floats
float speed = 1.0;
float intensity = 0.75;
float angle = 3.14159;

// Wrong: missing decimal point makes it an int, not a float
float speed = 1;   // ERROR in GLSL — even though it "looks" like 1.0

float: Common mistakes VJs make

The most common mistake when tweaking copied GLSL code is forgetting the decimal point on whole numbers. If you see a number like 2 or 10 used in a float calculation, the shader will compile fine in some environments but fail in others. The safest habit: always write float numbers with a decimal point, even when the value is a whole number. Write 2.0, not 2. Write 10.0, not 10.

The second common mistake: trying to add a float and an int directly without converting. The GPU does not do automatic conversion between these types the way most calculators do.

// This causes a compile error:
float mySpeed = 1.5;
int myCount = 3;
float result = mySpeed + myCount; // ERROR: cannot add float + int

// Fix: convert int to float using float()
float result = mySpeed + float(myCount); // OK

Guided experiment: float

Open ISF Editor and create a new Generator shader. Replace the content with this:

/*{
  "DESCRIPTION": "float experiment for VJs",
  "INPUTS": [
    {
      "NAME": "mySpeed",
      "TYPE": "float",
      "DEFAULT": 1.0,
      "MIN": 0.0,
      "MAX": 5.0
    }
  ]
}*/

void main() {
  vec2 uv = isf_FragNormCoord;
  float brightness = abs(sin(uv.x * 10.0 + TIME * mySpeed));
  gl_FragColor = vec4(brightness, brightness * 0.5, 0.2, 1.0);
}

Move the mySpeed slider. Watch the animation speed change. That slider is your float in action. Now try changing 10.0 to just 10 and watch the error bar appear. Change it back to 10.0 and the error disappears. You just witnessed a type error caused by the missing decimal point — and you fixed it.

bool — The on/off switch

bool is short for boolean, which is a fancy word for a value that can only be one of two things: true or false. That is all. Nothing in between.

In ISF shaders, a bool uniform becomes a toggle button or checkbox in your host software. You use it to switch shader features on or off: mirror mode on/off, invert colors yes/no, show grid yes/no.

ISF Editor playback UI showing a bool uniform rendered as a checkbox toggle for enabling and disabling a shader effect
A bool uniform in ISF creates a toggle checkbox in the playback UI: true enables the effect, false disables it.

What bool means for you

A bool is a switch. You use it in shader code with if statements: "if this bool is true, do this visual thing; if it is false, do the other thing." For VJs this is incredibly useful for creating shaders that have two distinct modes you can flip live.

/*{
  "INPUTS": [
    {
      "NAME": "mirrorMode",
      "TYPE": "bool",
      "DEFAULT": false
    }
  ]
}*/

void main() {
  vec2 uv = isf_FragNormCoord;

  if (mirrorMode) {
    uv.x = abs(uv.x * 2.0 - 1.0);
  }

  gl_FragColor = vec4(uv.x, uv.y, 0.5, 1.0);
}

bool: Common mistakes VJs make

The most common bool mistake when copying code from StackOverflow examples: the example uses int values (0 and 1) for true/false instead of proper booleans. Some older GLSL examples do this. If you paste that code and use it with a proper bool uniform, you will get a type error because bool and int are not interchangeable.

// Old style you might find on StackOverflow (some GLSL versions):
uniform int invertColors; // 0 or 1
if (invertColors == 1) { ... }

// ISF style (correct for modern ISF shaders):
uniform bool invertColors; // true or false
if (invertColors) { ... }

When you copy code from StackOverflow and it uses int for switches, the fix is simple: replace int myFlag with bool myFlag and replace == 1 comparisons with just using the bool directly.

Guided experiment: bool

Add a bool to your previous float experiment. This time add a mirroring toggle:

/*{
  "DESCRIPTION": "bool + float experiment",
  "INPUTS": [
    {
      "NAME": "mySpeed",
      "TYPE": "float",
      "DEFAULT": 1.0,
      "MIN": 0.0,
      "MAX": 5.0
    },
    {
      "NAME": "mirror",
      "TYPE": "bool",
      "DEFAULT": false
    }
  ]
}*/

void main() {
  vec2 uv = isf_FragNormCoord;

  if (mirror) {
    uv.x = abs(uv.x * 2.0 - 1.0);
  }

  float brightness = abs(sin(uv.x * 10.0 + TIME * mySpeed));
  gl_FragColor = vec4(brightness, brightness * 0.5, 0.2, 1.0);
}

Toggle the mirror checkbox in the Playback UI. The symmetry flips on and off instantly. You just used a bool to create a live performance switch with zero extra complexity.

int — The whole number counter

int is a whole number. No decimal point. No fractions. Just a complete integer: 1, 2, 5, 100, -3. The GPU stores these differently than floats and treats them differently in math operations.

In ISF shaders, int is less common than float for live controls, but you will see it used for things that count: number of repetitions, number of layers, number of iterations in a loop, or a mode selector (mode 1, mode 2, mode 3).

ISF Editor showing an int uniform used as a repetition counter controlling the number of visual layers in a generative shader
An int uniform in ISF controls discrete values like repetition count or mode selection — values that cannot be fractional.

What int means for you

You use int in GLSL when you need a counter, a number of repetitions, or when you are selecting between a fixed set of modes. The important thing to remember: int and float cannot be mixed in math operations directly. If you have an int and need to use it in a float calculation (which happens constantly), convert it with float(myInt).

/*{
  "INPUTS": [
    {
      "NAME": "layers",
      "TYPE": "long",
      "DEFAULT": 4,
      "MIN": 1,
      "MAX": 12,
      "VALUES": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
      "LABELS": ["1","2","3","4","5","6","7","8","9","10","11","12"]
    }
  ]
}*/

void main() {
  vec2 uv = isf_FragNormCoord;
  float total = 0.0;

  for (int i = 0; i < layers; i++) {
    float fi = float(i);
    total += sin(uv.x * (fi + 1.0) * 3.14 + TIME);
  }

  total = total / float(layers);
  gl_FragColor = vec4(abs(total), abs(total) * 0.6, 0.3, 1.0);
}

Note: in ISF JSON, the equivalent of int for user controls is called "TYPE": "long". Inside GLSL code you still declare and use it as int. This naming difference between JSON and GLSL is covered in detail in Chapter 7: JSON vs GLSL in ISF Shaders.

Guided experiment: int

Create a fresh shader and experiment with the loop count. Start with layers set to 1, then move it to 8 and notice how the visual complexity stacks. This is you controlling an int live. Also try deliberately removing float() from the division and watch the type error appear.

vec2 — Position, size, and 2D coordinates

vec2 is a container that holds exactly two floats at the same time. Think of it as a pair of values that belong together. The most common example in VJ shaders: screen coordinates. Every pixel on your screen has an X position and a Y position. Instead of writing them as two separate variables, GLSL packs them into one vec2.

When you read vec2 uv = isf_FragNormCoord; in a shader, that single line is giving you the position of the current pixel being processed: uv.x is the horizontal position (0.0 at left, 1.0 at right) and uv.y is the vertical position (0.0 at bottom, 1.0 at top).

Visual diagram showing vec2 UV coordinate space in a shader with X axis horizontal and Y axis vertical labeled 0.0 to 1.0
vec2 in a shader: the uv variable holds the current pixel's X and Y position simultaneously, the foundation of every visual effect you create.

What vec2 means for you

Every visual effect you build will use vec2 for coordinates. When you see code that adds distortion or shifts position, it is almost always manipulating a vec2. You can also use vec2 as a uniform input in ISF — for example, a "center point" parameter that lets the user pick an XY position where an effect is centered.

In the ISF JSON header, vec2 inputs are declared as "TYPE": "point2D". In the GLSL code, they arrive as a vec2.

/*{
  "INPUTS": [
    {
      "NAME": "center",
      "TYPE": "point2D",
      "DEFAULT": [0.5, 0.5]
    },
    {
      "NAME": "zoom",
      "TYPE": "float",
      "DEFAULT": 2.0,
      "MIN": 0.1,
      "MAX": 10.0
    }
  ]
}*/

void main() {
  vec2 uv = isf_FragNormCoord;
  vec2 offset = uv - center;
  float dist = length(offset) * zoom;
  float ring = abs(sin(dist * 6.28 - TIME * 2.0));

  gl_FragColor = vec4(ring, ring * 0.4, 0.8, 1.0);
}

vec2 swizzling: The shortcut VJs use

GLSL has a shortcut called "swizzling" that lets you access the parts of a vector using letters. For vec2, the two parts are called .x and .y. You can also use .r and .g (as if it were a color) — the GPU treats them identically.

vec2 uv = isf_FragNormCoord;

float horizontal = uv.x;
float vertical   = uv.y;

uv.x = 1.0 - uv.x;
uv = uv.yx;

That last line — uv.yx — is swizzling. It reads the Y first, then the X, and packs them into a new vec2. This is a technique you will see constantly in shaders copied from StackOverflow or Shadertoy.

Guided experiment: vec2

Try the center point example above. Drag the center point in your ISF host's playback UI and watch the ring effect follow your drag. Then try swapping uv for uv.yx in the distance calculation and observe how the visual rotates 90 degrees. You are directly manipulating coordinates with swizzling.

vec3 — Color and 3D position

vec3 holds three floats at the same time. In VJ shaders it is most commonly used for two things: RGB color values (red, green, blue — three numbers) and 3D coordinates (x, y, z — three numbers).

If you see vec3 in the middle of shader code, it is very likely a color. If you see it in a vertex shader or 3D context, it is probably a position in space. For the kind of ISF shaders VJs use most, it is almost always a color.

ISF shader showing vec3 used as an RGB color value with three float components mapped to red green and blue channels
vec3 as a color: three floats packed together to represent red, green, and blue. Every pixel color you tweak in a shader lives in a vec3.

What vec3 means for you

When you want to define or manipulate a color in GLSL, you work with vec3. When you see a "color" input in ISF JSON ("TYPE": "color"), it actually arrives in the shader as a vec4 (with an alpha channel), but the RGB part — the actual hue and saturation — is always three floats: red, green, blue, each ranging from 0.0 (off) to 1.0 (full).

vec3 + rgb: The color connection

GLSL lets you access the components of a vec3 using either .x .y .z or .r .g .b. Both work identically. The .r .g .b notation is preferred when you are thinking about the vector as a color, because it makes the code self-documenting.

vec3 myColor = vec3(1.0, 0.5, 0.0);

float redAmount   = myColor.r;
float greenAmount = myColor.g;
float blueAmount  = myColor.b;

vec3 shifted = vec3(myColor.g, myColor.b, myColor.r);

vec3 colorA = vec3(1.0, 0.0, 0.2);
vec3 colorB = vec3(0.0, 0.5, 1.0);
vec3 blended = mix(colorA, colorB, 0.5);

The mix() function is one of the most powerful tools in VJ shaders. It blends between two values (any type: float, vec2, vec3, vec4) based on a third value between 0.0 and 1.0. You will use it constantly for smooth color transitions.

Guided experiment: vec3

Create a shader that lets you control two colors and blend between them:

/*{
  "DESCRIPTION": "vec3 color blend experiment",
  "INPUTS": [
    {
      "NAME": "colorA",
      "TYPE": "color",
      "DEFAULT": [1.0, 0.2, 0.0, 1.0]
    },
    {
      "NAME": "colorB",
      "TYPE": "color",
      "DEFAULT": [0.0, 0.4, 1.0, 1.0]
    },
    {
      "NAME": "blendSpeed",
      "TYPE": "float",
      "DEFAULT": 0.5,
      "MIN": 0.0,
      "MAX": 3.0
    }
  ]
}*/

void main() {
  vec2 uv = isf_FragNormCoord;
  float t = (sin(TIME * blendSpeed + uv.x * 3.14) + 1.0) * 0.5;
  vec3 blended = mix(colorA.rgb, colorB.rgb, t);

  gl_FragColor = vec4(blended, 1.0);
}

Change the two colors in the Playback UI and move the blendSpeed slider. The blend oscillates between them. Notice how we used colorA.rgb to extract just the three color channels from the vec4 input. That is swizzling at work again.

vec4 — Color with transparency

vec4 holds four floats at the same time. In ISF shaders for VJs, this almost always means a color plus its transparency: red, green, blue, alpha. Alpha is the transparency channel — 0.0 means completely invisible, 1.0 means completely opaque.

You will see vec4 in every single ISF shader you ever look at, because the final output line of every fragment shader is always:

gl_FragColor = vec4(red, green, blue, alpha);
Code view of ISF shader showing gl_FragColor equals vec4 with red green blue and alpha channels labeled
vec4 and gl_FragColor: every ISF shader ends with this line. The four values are red, green, blue, and alpha — the complete description of one pixel's color.

What vec4 means for you

You will use vec4 in two main ways:

First, as the final output of your shader. Every pixel you draw must end up assigned to gl_FragColor, which is a vec4. If you forget the alpha (fourth value), your shader will either fail to compile or render with unexpected transparency.

Second, as the type for color inputs in ISF. When you declare a "TYPE": "color" input in ISF JSON, the uniform inside the GLSL code is a vec4. This is why you see .rgb used to extract just the color part when you only want the three color channels.

gl_FragColor: Why it is always vec4

The GPU needs to know four things about every pixel: how much red, how much green, how much blue, and how transparent. It requires all four, always. This is why gl_FragColor is always a vec4 and not a vec3. Even if your visual is 100% opaque and you never want any transparency, you still have to write the alpha:

gl_FragColor = vec4(red, green, blue, 1.0);

vec3 myColor = vec3(0.8, 0.3, 0.5);
gl_FragColor = vec4(myColor, 1.0);

uniform vec4 userColor;
gl_FragColor = vec4(userColor.rgb, userColor.a * 0.8);

Guided experiment: vec4

Try setting alpha to something less than 1.0 and observe the transparency in ISF Editor using the Display Alpha button. Then try using vec4(myColor.rgb, 0.0) and notice the output becomes invisible. This is the alpha channel working. Knowing how to control transparency with vec4 is essential when building shaders designed to layer over other content in Resolume or VDMX.

Mixing types: The rules that save you from red screens

Now you know the six main types. The most common source of compile errors is not understanding how they can (and cannot) be mixed together. Here are the rules that matter most for VJs.

Side-by-side comparison of wrong and correct GLSL type mixing showing error code and fixed version with float conversion
Type mixing in GLSL: wrong on the left (int + float causes a compile error), correct on the right (convert int to float first using float()).

The golden rule of GLSL types

GLSL requires that both sides of any math operation are the same type. You cannot add a float and an int. You cannot multiply a vec3 by a vec4. You cannot assign a vec2 to a float variable. Every time the compiler sees mismatched types in an operation, it stops and gives you an error.

Operation Valid? Why
float + float Yes Same type on both sides
float + int No Different types — convert int with float()
vec3 * float Yes Special rule: scalars can multiply vectors
vec3 + float Yes Special rule: scalar is applied to all components
vec3 + vec4 No Different size vectors — extract .rgb or .xyz first
vec2 * vec2 Yes Component-wise multiplication — both same type
bool + float No bool is not numeric — use if/else instead
float assigned to vec2 No Size mismatch — wrap as vec2(myFloat, myFloat)

How to convert between types

GLSL gives you explicit conversion functions. These are your main tools when error messages say "wrong operand types":

int count = 5;
float fCount = float(count);

float amount = 3.9;
int iAmount = int(amount);

float slider = 0.7;
bool isActive = bool(slider);

bool toggle = true;
float asNum = float(toggle);

float brightness = 0.8;
vec3 gray = vec3(brightness);

vec4 fullColor = vec4(1.0, 0.5, 0.2, 1.0);
vec3 rgbOnly = fullColor.rgb;

StackOverflow's most common type traps for VJs

StackOverflow and Shadertoy examples are invaluable when learning shaders. But they are written for different contexts — sometimes older GLSL versions, sometimes desktop OpenGL, sometimes WebGL — and small differences in how types work across versions cause silent failures when you paste them into ISF.

ISF Editor showing a black screen error after pasting a Shadertoy GLSL snippet with type mismatches highlighted in the error bar
The classic copy-paste red screen: Shadertoy and StackOverflow snippets often use variable names or type combinations that need minor adjustment for ISF.

Trap 1: Integer literals in float math. Shadertoy examples frequently write sin(uv.x * 2) instead of sin(uv.x * 2.0). In strict GLSL (which ISF uses) it fails because 2 is an int and uv.x is a float. Fix: add .0 to every whole number in a float calculation.

float r = sin(uv.x * 2.0 + TIME);

Trap 2: Shadertoy's iTime vs ISF's TIME. Shadertoy uses iTime and iResolution. ISF uses TIME and RENDERSIZE. When pasting from Shadertoy, do a find-and-replace: iTimeTIME, iResolutionRENDERSIZE, fragCoordisf_FragNormCoord * RENDERSIZE.

Trap 3: Missing precision specifier. Some GLSL examples from web contexts assume precision mediump float; is declared somewhere. In ISF it usually is, but if you get unexpected errors about precision, add this line at the very top of your GLSL code, before any other code:

precision mediump float;

Trap 4: vec4 color vs vec3 color confusion. Many StackOverflow examples define color as vec3 and then assign it directly to the output as gl_FragColor = myColor;. In modern GLSL, gl_FragColor is vec4, so this fails. Fix: wrap it — gl_FragColor = vec4(myColor, 1.0);

ISF JSON types vs GLSL types — The connection

One of the most confusing things for VJs first reading ISF code is that the same concept has different names in the JSON header (the metadata section) versus the GLSL code (the rendering section). This table maps them directly. For a deeper dive into the relationship between JSON and GLSL in ISF, read Chapter 7: JSON vs GLSL in ISF Shaders.

Side-by-side mapping of ISF JSON input types on the left and their corresponding GLSL data types on the right for float bool vec2 vec3 vec4
ISF JSON types vs GLSL types: the same parameter has different names in the JSON header and the GLSL code. This table is the bridge between both worlds.
ISF JSON "TYPE" GLSL variable type What it controls in your set
"float" float Slider: speed, intensity, zoom, blur
"bool" bool Toggle/checkbox: mirror, invert, enable effect
"long" int Dropdown or integer slider: mode, repeat count
"point2D" vec2 XY drag point: center, offset, focus
"color" vec4 Color picker: primary color, tint, glow
"image" sampler2D Texture input: video, image, another shader

The practical implication: if you add a "TYPE": "color" input in your ISF JSON and then try to use it as a vec3 in GLSL without extracting the .rgb, you will get a type mismatch because color inputs arrive as vec4. Always use myColorInput.rgb when you need a vec3 from a color input.

Live shader preview — Data types in action

The shader below uses float, vec2, vec3, and vec4 together in one generative pattern. Three float sliders control speed, zoom, and hue shift — the same types you mapped to JSON inputs in Chapter 8, now driving the math directly inside GLSL.

float speed · float zoom · float hue — control the shader live

Every slider above is a float uniform. The visual reacts in real time because the GPU recalculates all pixels every frame using those float values. This is GLSL data types doing their job.

Play with every control and observe how each type changes a different dimension of the visual. Set speed to zero and the pattern freezes on the current frame — a deliberate performance tool. Raise zoom to tighten the rings. Drag hue shift to rotate the palette without touching GLSL.

Quick reference tables

Use these tables as a cheat sheet during your shader sessions. Screenshot them or keep this tab open when you are editing in ISF Editor.

GLSL data types at a glance

Type Holds Example value VJ use case
float 1 decimal number 0.75 Speed, intensity, zoom, blur
bool true or false true Mirror toggle, invert switch, enable/disable
int 1 whole number 4 Repeat count, mode selector, loop limit
vec2 2 floats vec2(0.5, 0.3) Screen position, UV coordinates, drag point
vec3 3 floats vec3(1.0, 0.5, 0.0) RGB color, 3D position
vec4 4 floats vec4(1.0, 0.5, 0.0, 1.0) RGBA color, gl_FragColor output

Swizzling reference

Type Position notation Color notation Example
vec2 .x .y .r .g uv.x, uv.yx (swap)
vec3 .x .y .z .r .g .b color.rgb, color.grb (shift hue)
vec4 .x .y .z .w .r .g .b .a color.rgba, color.rgb (drop alpha)

Type error quick fix guide

Error message contains Most likely cause Fix
"wrong operand types" Mixing float and int Add .0 to whole numbers, or use float(myInt)
"cannot convert from int to float" Assigning int literal to float variable Change = 1 to = 1.0
"no viable conversion" with vec3/vec4 Mismatched vector size Use .rgb to extract 3 components from vec4
Black screen, no error gl_FragColor not assigned Make sure your main() always assigns gl_FragColor
"undeclared identifier: iTime" Shadertoy code not converted Replace iTime with TIME
"undeclared identifier: iResolution" Shadertoy code not converted Replace iResolution with RENDERSIZE

Frequently Asked Questions

The most common reason is a type mismatch in the pasted code. StackOverflow and Shadertoy examples often use integer literals (like 2 or 10) in float math, which fails in strict ISF/GLSL. Open the error bar in ISF Editor, look at the line number in the error, and add .0 to any whole number being used with float variables. A second common issue is Shadertoy-specific variable names like iTime or iResolution — replace those with TIME and RENDERSIZE.

vec3 holds red, green, blue — the visible color. vec4 holds red, green, blue, and alpha — the color plus its transparency. In ISF, the final output (gl_FragColor) is always vec4, so you always need all four values. Color inputs from ISF JSON also arrive as vec4. When you only need the visible color part, use .rgb to extract the three components: myColor.rgb gives you a vec3 from a vec4.

The GPU is designed for massive parallel performance. Part of that speed comes from strict type enforcement: the GPU knows exactly how much memory each variable needs and what operations can apply to it before rendering begins. Automatic type conversion would add overhead and ambiguity. The strictness feels painful at first, but it guarantees predictable behavior across millions of parallel calculations happening simultaneously — which is what makes real-time visuals possible at all.

Yes, in ISF-compatible hosts that support point2D inputs, a vec2 uniform appears as a two-dimensional drag control (an XY pad) in the interface. MIDI mapping to XY pads depends on your host software — Resolume Arena, for example, supports mapping two MIDI CC values to the X and Y axes of a point2D parameter separately, giving you two-dimensional live control from a physical controller.

Yes. The ISF JSON type "long" maps to an int in GLSL and creates a dropdown menu or an integer-stepped slider in host software. You can define specific values and labels for each option, making it a mode selector with named choices. Use "long" when you want a discrete numeric control — things that can only be 1, 2, 3, or 4, for example. Use "float" for continuous controls with any value in a range.

Swizzling is GLSL shorthand for accessing and rearranging the components of a vector in one operation. For example, color.bgr on a vec3 returns a new vec3 with the red and blue channels swapped. You absolutely need to recognize it because it appears constantly in community shaders and StackOverflow examples. If you see something like uv.yx or color.grb, that is swizzling. Once you know what it does — rearrange components — the code becomes much more readable.

What comes next

You now have a solid grasp of GLSL data types: what each one holds, why they cannot be mixed carelessly, and how to fix the most common compile errors that appear after tweaking or copy-pasting shader code. The next chapter — Modify ISF Shader Code (GLSL Tweaks) — Chapter 10 — goes deeper into safe edits to speed ranges, default uniforms, and hard-coded colors in downloaded .fs files, with version-control tips so you can roll back after a bad tweak.

Technical Appendix

This appendix centralizes quick references for this chapter, including cited links and chapter navigation for faster study and review.

Technical shader thumbnail for GLSL Data Types for VJs — Chapter 9
Chapter 9 GLSL data types ISF shader thumbnail for VJs, showing float speed, zoom, and hue shift controls mapped to a live generative pattern output.

Referenced Links

Continue Reading