본문으로 건너뛰기
cccskills
무료GitHub에 공개

glsl-fundamentals

The GLSL itself - which dialect a shader is in, what precision means, the types and functions that exist, and the exact compiler messages a mistake produces. Read this before writing GLSL for any target, and before believing an error message.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md7.6 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

GLSL fundamentals

GLSL is not one language. It is a family, and the first thing to get right is which member of it you are writing. A shader that is correct in one is a wall of errors in another, and the errors never say "wrong dialect".

The five dialects this row tells apart

dialectlooks likecompiles here
es100no #version, gl_FragColor, precisionyes - WebGL 1
es300#version 300 es, your own out vec4yes - WebGL 2
shadertoyvoid mainImage(out vec4, in vec2), no #versionyes - wrapped in ES 3.00
shader-skillssame as Shadertoy, but iFrame is an intyes - wrapped in ES 3.00
desktop#version 330 core and up, no esno - static checks only

shader_verify detects the dialect and says which one it found. Believe it, and if it guessed wrong, pass dialect explicitly.

Desktop GLSL is not WebGL GLSL

If a source starts with #version 330 core (or 110, 120, 150, 450), it is desktop GLSL. ANGLE - the compiler behind every browser - does not accept it. The row answers v1-static and names glslangValidator as the tool that would compile it. Three constructs mark the boundary, and each is a compile error on the wrong side:

#version 300 es
precision highp float;
out vec4 fragColor;
void main() { fragColor = vec4(1.0); }

That is a complete ES 3.00 fragment shader: it compiles as written. Its ES 1.00 twin is below - note gl_FragColor and the required precision statement.

precision highp float;
uniform float u_time;
void main() {
  float d = length(gl_FragCoord.xy / 256.0 - 0.5);
  gl_FragColor = vec4(vec3(smoothstep(0.4, 0.35, d)), 1.0);
}

gl_FragColor does not exist in #version 300 es. varying became in/out. texture2D became texture. attribute became in. Those four renames are most of what a "port to WebGL2" actually is.

Precision is not optional

A WebGL 1 fragment shader with no precision qualifier does not compile: ERROR: 0:1: '' : No precision specified for (float). Every es100 fragment starts with precision highp float; (or mediump). Vertex shaders have a default precision, which is why skipping it there works.

highp is what you want for coordinates and time; mediump is fine for colour and cheaper on mobile. Do not use highp inside a loop on hardware you have not tested - it is the first thing to drop for performance.

Types and the arithmetic traps

precision highp float;
float asFloat(int value) {
  return float(value);        // explicit conversion: `float x = 1;` is an error in ES 3.00
}
vec3 swapChannels(vec3 col) {
  col.rg = col.gr;            // swizzles assign in both directions
  return col;
}
mat2 rotate(float angle) {
  // mat2 is COLUMN-major: these four numbers are columns (a,b) and (c,d)
  return mat2(cos(angle), sin(angle), -sin(angle), cos(angle));
}
void main() {
  vec2 p = rotate(0.5) * (gl_FragCoord.xy / 64.0 - 0.5);
  gl_FragColor = vec4(swapChannels(vec3(p, asFloat(1))), 1.0);
}

A statement may not sit at global scope in GLSL: only declarations and functions can, and a global initialiser must be a constant expression. That is why the conversions above live inside functions.

The two errors that most often cost an hour:

  • dimension mismatch - a vec3 assigned to a float, or vec3(1.0) passed to a float parameter. The message is precise; read the two types it names.
  • no matching overloaded function found - the function exists but not for those argument types. min(1.0, 2) fails because there is no min(float, int).

Functions that are always there

sin cos tan asin acos atan pow exp log exp2 log2 sqrt inversesqrt abs sign floor ceil fract mod min max clamp mix step smoothstep length distance dot cross normalize reflect refract faceforward vec2 vec3 vec4 mat2 mat3 mat4 float int bool texture textureLod (ES 3.00) / texture2D (ES 1.00).

atan(y, x) - two arguments - is how you get an angle without losing the quadrant. mod(x, 1.0) repeats, but fract(x) is cheaper and identical for positive input. smoothstep(edge0, edge1, x) needs edge0 < edge1 or it is undefined: to invert a ramp, use 1.0 - smoothstep(a, b, x).

Loops and branches

In GLSL ES 1.00 the specification requires a constant loop bound:

precision highp float;
void main() {
  float sum = 0.0;
  for (int i = 0; i < 8; i++) {   // literal 8: always fine
    sum += 0.125;
  }
  gl_FragColor = vec4(vec3(sum), 1.0);
}

for (int i = 0; i < u_steps; i++) compiles on ANGLE and may fail on a mobile driver. If the count must vary, write a constant bound and break on the uniform. shader_verify warns about this (loop-bound), because the compiler here will not.

Branches are allowed but a branch that halves the work is often slower than mix(): prefer arithmetic over divergence in a fragment shader.

Derivatives need an extension in ES 1.00

fwidth, dFdx and dFdy are screen-space derivatives. In WebGL 1 they require gl.getExtension('OES_standard_derivatives') before the shader is compiled, otherwise the error is misleading:

WARNING: 0:1: 'GL_OES_standard_derivatives' : extension is not supported
ERROR: 0:108: 'fwidth' : no matching overloaded function found

It says the extension is unsupported when the real problem is that nobody asked for it. This row enables it for its own compiles; a page that embeds the shader must do the same. In ES 3.00 no extension is needed.

The uniform contract this row uses

Every wrapper dialect (shadertoy, shader-skills, module) is given:

uniformtypemeaning
u_timefloatseconds since start
u_resolutionvec2drawing buffer size in pixels
u_mousevec2pointer position in pixels
u_framefloatframe counter

Shadertoy names are provided too: iResolution (vec3), iTime, iTimeDelta, iFrameRate, iMouse (vec4) and iChannel0..3. iFrame is a float in Shadertoy and an int in the shader-skills corpus - which is why those are two dialects here. A function taking int rejects a float iFrame, and the error is no matching overloaded function found at the call site.

Parameters

Declare a tunable value on its own comment line; the tab turns it into a slider and every emitted page sets it:

// @param SPEED float 0.1..2.0 default 0.6 "Rotation speed"
precision highp float;
uniform float u_time;
uniform float u_speed;
void main() {
  float d = length(gl_FragCoord.xy / 256.0 - 0.5);
  gl_FragColor = vec4(vec3(0.5 + 0.5 * sin(d * 30.0 - u_time * u_speed)), 1.0);
}

The uniform name is u_ plus the lower-cased parameter name: SPEED -> u_speed. The source must declare it, or lint warns param-uniform.

Check yourself before you claim it works

shader_verify answers with a rung, and only these count:

  • v1-static - the rules above ran. No compiler did. Say so.
  • v2-compiled - a real compiler accepted it, on your line numbers.
  • v3-drawn - a frame was actually drawn and the pixels came back.
  • v4-measured - two different times drew differently.

A shader is not "working" at v1. If you are on a machine with no browser, say that the compile did not happen instead of implying it did.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Author an editorial HTML+SVG diagram with the Diagram Design kit - choose the visual type, read its reference, start from an example, and satisfy the safety and accessibility contract that diagram_write({kind:"html"}) enforces.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Control this machine's Docker or Podman engine through the docker_* tools - read the engine's state first, list containers and images, inspect one, tail its logs, pull an image and start it, then stop, restart or remove what you started. Covers the engine that is asleep behind Docker Desktop and the exact call for each verb, the confirm rule removals obey, and the flags the tools deliberately do not have.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Drive ffmpeg through the media_run tool as an argv array - remux instead of re-encode, map streams explicitly, trim at keyframes, scale and crop, extract audio and frames, and build GIFs, contact sheets and concatenations. Covers the flags this pack injects, reading a failure from its exit code and last log lines, and the version-dependent spellings to hedge.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Read a media file's real structure with ffprobe through media_run - the JSON invocation and how to read it, what every family of field means, how to count frames, sample without decoding everything, detect HDR and interlacing, and diagnose a missing duration, a stream with no frames or a container that lies. Covers when media_probe's own report is already enough.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Writing a fragment shader that looks like something - the full-screen triangle, uv space, signed distance fields, noise and fbm, domain warping, raymarching budgets, tone mapping and banding. Every example compiles. Read this when the task is "make it look good", not "make it compile".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Use when the user wants to design, redesign, shape, critique, audit, polish, simplify, harden, animate, or otherwise improve a frontend interface: websites, landing pages, dashboards, product UI, components, forms, settings, onboarding, empty states, and native iOS or Android screens. Handles UX review, hierarchy, layout, typography, color, motion, UX copy, accessibility, responsive behavior, edge cases, and capturing or documenting design systems (DESIGN.md, tokens). Also for making bland UI bolder, loud UI quieter, or ambitious visual effects. Not for backend-only or non-UI tasks.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

vecnode의 스킬 모두 보기

이 스킬의 문제 신고