glslkit-webgl 0.1.0.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +31 -0
- data/LICENSE.txt +21 -0
- data/README.md +98 -0
- data/glslkit-webgl.gemspec +37 -0
- data/lib/glslkit/webgl/context.rb +228 -0
- data/lib/glslkit/webgl/embed.rb +158 -0
- data/lib/glslkit/webgl/errors.rb +39 -0
- data/lib/glslkit/webgl/geometry.rb +64 -0
- data/lib/glslkit/webgl/live_reload.rb +107 -0
- data/lib/glslkit/webgl/matrix.rb +77 -0
- data/lib/glslkit/webgl/program.rb +205 -0
- data/lib/glslkit/webgl/reload_result.rb +28 -0
- data/lib/glslkit/webgl/texture.rb +27 -0
- data/lib/glslkit/webgl/version.rb +7 -0
- data/lib/glslkit/webgl.rb +48 -0
- data/sample/app.rb +52 -0
- data/sample/error_panel.rb +68 -0
- data/sample/generated/cube_shaders.rb +82 -0
- data/sample/generated/neon_shaders.rb +162 -0
- data/sample/generated-broken/neon-broken_shaders.rb +162 -0
- data/sample/index.html +15 -0
- data/sample/neon-error.html +82 -0
- data/sample/neon-error.rb +119 -0
- data/sample/neon.html +22 -0
- data/sample/neon.rb +22 -0
- data/sample/shaders/common/color.glsl +5 -0
- data/sample/shaders/common/sdf.glsl +11 -0
- data/sample/shaders/cube.frag +8 -0
- data/sample/shaders/cube.vert +9 -0
- data/sample/shaders/neon.frag +79 -0
- data/sample/shaders/neon.vert +5 -0
- data/sample/shaders-broken/common/color.glsl +5 -0
- data/sample/shaders-broken/common/sdf.glsl +11 -0
- data/sample/shaders-broken/neon-broken.frag +79 -0
- data/sample/shaders-broken/neon-broken.vert +5 -0
- data/shim/glslkit-webgl.js +49 -0
- metadata +105 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#version 300 es
|
|
2
|
+
precision highp float;
|
|
3
|
+
|
|
4
|
+
uniform float u_time;
|
|
5
|
+
uniform vec2 u_resolution;
|
|
6
|
+
out vec4 frag_color;
|
|
7
|
+
|
|
8
|
+
#define PI 3.14159265359
|
|
9
|
+
|
|
10
|
+
#include "common/sdf.glsl"
|
|
11
|
+
#include "common/color.glsl"
|
|
12
|
+
|
|
13
|
+
float scene(vec3 p) {
|
|
14
|
+
p.xz *= rotate2d(u_time * 0.32);
|
|
15
|
+
p.xy *= rotate2d(sin(u_time * 0.27) * 0.55);
|
|
16
|
+
|
|
17
|
+
float angle = atan(p.z, p.x);
|
|
18
|
+
float pulse = 0.10 * sin(angle * 7.0 + u_time * 2.4);
|
|
19
|
+
float portal = sdTorus(p, vec2(1.25, 0.17 + pulse));
|
|
20
|
+
|
|
21
|
+
vec3 orb = p;
|
|
22
|
+
orb.xz *= rotate2d(-u_time * 0.7);
|
|
23
|
+
orb -= vec3(1.25, sin(u_time * 1.8) * 0.22, 0.0);
|
|
24
|
+
float satellite = length(orb) - 0.11;
|
|
25
|
+
return min(portal, satellite);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
vec3 normalAt(vec3 p) {
|
|
29
|
+
vec2 e = vec2(0.0015, 0.0);
|
|
30
|
+
float d = scene(p);
|
|
31
|
+
return normalize(vec3(
|
|
32
|
+
scene(p + e.xyy) - d,
|
|
33
|
+
scene(p + e.yxy) - d,
|
|
34
|
+
scene(p + e.yyx) - d
|
|
35
|
+
));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
float raymarch(vec3 origin, vec3 direction, out vec3 point) {
|
|
39
|
+
float distanceTravelled = 0.0;
|
|
40
|
+
for (int i = 0; i < 96; i++) {
|
|
41
|
+
point = origin + direction * distanceTravelled;
|
|
42
|
+
float distanceToScene = scene(point);
|
|
43
|
+
if (distanceToScene < 0.001 || distanceTravelled > 12.0) break;
|
|
44
|
+
distanceTravelled += distanceToScene * 0.72;
|
|
45
|
+
}
|
|
46
|
+
return distanceTravelled;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
void main() {
|
|
50
|
+
vec2 uv = (gl_FragCoord.xy * 2.0 - u_resolution) / u_resolution.y;
|
|
51
|
+
float vignette = max(0.0, 1.0 - dot(uv, uv) * 0.28);
|
|
52
|
+
|
|
53
|
+
vec3 origin = vec3(0.0, 0.0, 4.2);
|
|
54
|
+
vec3 direction = normalize(vec3(uv, -1.8));
|
|
55
|
+
vec3 point;
|
|
56
|
+
float travelled = raymarch(origin, direction, point);
|
|
57
|
+
|
|
58
|
+
vec3 color = vec3(0.006, 0.008, 0.025);
|
|
59
|
+
float rays = pow(max(0.0, 1.0 - length(uv)), 5.0);
|
|
60
|
+
color += vec3(0.12, 0.03, 0.30) * rays;
|
|
61
|
+
|
|
62
|
+
if (travelled < 12.0) {
|
|
63
|
+
vec3 normal = normalAt(point);
|
|
64
|
+
vec3 light = normalize(vec3(0.7, 1.2, 2.0));
|
|
65
|
+
float diffuse = max(dot(normal, light), 0.0);
|
|
66
|
+
float rim = pow(1.0 - max(dot(normal, -direction), 0.0), 2.4);
|
|
67
|
+
float bands = 0.5 + 0.5 * sin(atan(point.z, point.x) * 9.0 - u_time * 3.0);
|
|
68
|
+
vec3 neon = palette(bands + u_time * 0.06);
|
|
69
|
+
color += neon * (0.18 + diffuse * 0.65 + rim * 2.4);
|
|
70
|
+
color += pow(max(dot(reflect(-light, normal), -direction), 0.0), 32.0);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
float glowDistance = abs(length(uv) - 0.47 - sin(atan(uv.y, uv.x) * 7.0 + u_time) * 0.018);
|
|
74
|
+
color += palette(u_time * 0.07 + length(uv)) * 0.012 / max(glowDistance, 0.008);
|
|
75
|
+
|
|
76
|
+
color *= vignette;
|
|
77
|
+
color = pow(color, vec3(0.82));
|
|
78
|
+
frag_color = vec4(color, 1.0);
|
|
79
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#version 300 es
|
|
2
|
+
precision highp float;
|
|
3
|
+
|
|
4
|
+
uniform float u_time;
|
|
5
|
+
uniform vec2 u_resolution;
|
|
6
|
+
out vec4 frag_color;
|
|
7
|
+
|
|
8
|
+
#define PI 3.14159265359
|
|
9
|
+
|
|
10
|
+
#include "common/sdf.glsl"
|
|
11
|
+
#include "common/color.glsl"
|
|
12
|
+
|
|
13
|
+
float scene(vec3 p) {
|
|
14
|
+
p.xz *= rotate2d(u_time * 0.32);
|
|
15
|
+
p.xy *= rotate2d(sin(u_time * 0.27) * 0.55);
|
|
16
|
+
|
|
17
|
+
float angle = atan(p.z, p.x);
|
|
18
|
+
float pulse = 0.10 * sin(angle * 7.0 + u_time * 2.4);
|
|
19
|
+
float portal = sdTorus(p, vec2(1.25, 0.17 + pulse));
|
|
20
|
+
|
|
21
|
+
vec3 orb = p;
|
|
22
|
+
orb.xz *= rotate2d(-u_time * 0.7);
|
|
23
|
+
orb -= vec3(1.25, sin(u_time * 1.8) * 0.22, 0.0);
|
|
24
|
+
float satellite = length(orb) - 0.11;
|
|
25
|
+
return min(portal, satellite);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
vec3 normalAt(vec3 p) {
|
|
29
|
+
vec2 e = vec2(0.0015, 0.0);
|
|
30
|
+
float d = scene(p);
|
|
31
|
+
return normalize(vec3(
|
|
32
|
+
scene(p + e.xyy) - d,
|
|
33
|
+
scene(p + e.yxy) - d,
|
|
34
|
+
scene(p + e.yyx) - d
|
|
35
|
+
));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
float raymarch(vec3 origin, vec3 direction, out vec3 point) {
|
|
39
|
+
float distanceTravelled = 0.0;
|
|
40
|
+
for (int i = 0; i < 96; i++) {
|
|
41
|
+
point = origin + direction * distanceTravelled;
|
|
42
|
+
float distanceToScene = scene(point);
|
|
43
|
+
if (distanceToScene < 0.001 || distanceTravelled > 12.0) break;
|
|
44
|
+
distanceTravelled += distanceToScene * 0.72;
|
|
45
|
+
}
|
|
46
|
+
return distanceTravelled;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
void main() {
|
|
50
|
+
vec2 uv = (gl_FragCoord.xy * 2.0 - u_resolution) / u_resolution.y;
|
|
51
|
+
float vignette = max(0.0, 1.0 - dot(uv, uv) * 0.28);
|
|
52
|
+
|
|
53
|
+
vec3 origin = vec3(0.0, 0.0, 4.2);
|
|
54
|
+
vec3 direction = normalize(vec3(uv, -1.8));
|
|
55
|
+
vec3 point;
|
|
56
|
+
float travelled = raymarch(origin, direction, point);
|
|
57
|
+
|
|
58
|
+
vec3 color = vec3(0.006, 0.008, 0.025);
|
|
59
|
+
float rays = pow(max(0.0, 1.0 - length(uv)), 5.0);
|
|
60
|
+
color += vec3(0.12, 0.03, 0.30) * rays;
|
|
61
|
+
|
|
62
|
+
if (travelled < 12.0) {
|
|
63
|
+
vec3 normal = normalAt(point);
|
|
64
|
+
vec3 light = normalize(vec3(0.7, 1.2, 2.0));
|
|
65
|
+
float diffuse = max(dot(normal, light), 0.0);
|
|
66
|
+
float rim = pow(1.0 - max(dot(normal, -direction), 0.0), 2.4);
|
|
67
|
+
float bands = 0.5 + 0.5 * sin(atan(point.z, point.x) * 9.0 - u_time * 3.0);
|
|
68
|
+
vec3 neon = palette(bands + u_time * 0.06);
|
|
69
|
+
color += neon * (0.18 + diffuse * 0.65 + rim * 2.4);
|
|
70
|
+
color += pow(max(dot(reflect(-light, normal), -direction), 0.0), 32.0);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
float glowDistance = abs(length(uv) - 0.47 - sin(atan(uv.y, uv.x) * 7.0 + u_time) * 0.018);
|
|
74
|
+
color += palette(u_time * 0.07 + length(uv)) * 0.012 / max(glowDistance, 0.008);
|
|
75
|
+
|
|
76
|
+
color *= vignette;
|
|
77
|
+
color = pow(color, vec3(0.82));
|
|
78
|
+
frag_color = vec4(color, 1.0);
|
|
79
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const script = document.currentScript;
|
|
5
|
+
const entry = script && script.dataset.entry;
|
|
6
|
+
const rubyVersion = (script && script.dataset.rubyVersion) || "4.0";
|
|
7
|
+
const wasmWasiVersion = (script && script.dataset.wasmWasiVersion) || "2.10.1";
|
|
8
|
+
|
|
9
|
+
if (!entry) {
|
|
10
|
+
throw new Error("glslkit-webgl: data-entry must name the Ruby entry file");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const packageName = `@ruby/${rubyVersion}-wasm-wasi`;
|
|
14
|
+
const packageRoot = `https://cdn.jsdelivr.net/npm/${packageName}@${wasmWasiVersion}/dist`;
|
|
15
|
+
const wasmUrl = `${packageRoot}/ruby+stdlib.wasm`;
|
|
16
|
+
const vmUrl = `https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@${wasmWasiVersion}/dist/browser/+esm`;
|
|
17
|
+
|
|
18
|
+
async function compile(response) {
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
throw new Error(`glslkit-webgl: failed to fetch ruby.wasm (${response.status})`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
return await WebAssembly.compileStreaming(response.clone());
|
|
25
|
+
} catch (_error) {
|
|
26
|
+
return WebAssembly.compile(await response.arrayBuffer());
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function boot() {
|
|
31
|
+
const [{ DefaultRubyVM }, response] = await Promise.all([
|
|
32
|
+
import(vmUrl),
|
|
33
|
+
fetch(wasmUrl),
|
|
34
|
+
]);
|
|
35
|
+
const module = await compile(response);
|
|
36
|
+
const { vm } = await DefaultRubyVM(module);
|
|
37
|
+
const baseUrl = new URL(".", new URL(entry, document.baseURI)).href;
|
|
38
|
+
const feature = new URL(entry, document.baseURI).pathname.split("/").pop().replace(/\.rb$/, "");
|
|
39
|
+
const ruby = [
|
|
40
|
+
'require "js/require_remote/relative_shim"',
|
|
41
|
+
`JS::RequireRemote.instance.base_url = ${JSON.stringify(baseUrl)}`,
|
|
42
|
+
`JS::RequireRemote.instance.load(${JSON.stringify(feature)})`,
|
|
43
|
+
].join("\n");
|
|
44
|
+
|
|
45
|
+
await vm.evalAsync(ruby);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
window.glslkitWebGLReady = boot();
|
|
49
|
+
})();
|
metadata
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: glslkit-webgl
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0.pre
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- kyubey1228
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-08-24 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: glslkit
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.1.0.pre
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 0.2.0
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: 0.1.0.pre
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: 0.2.0
|
|
32
|
+
description: Lets you write WebGL2 rendering code entirely in Ruby, running under
|
|
33
|
+
ruby.wasm in the browser. Resolves uniform/attribute locations from a glslkit reflection
|
|
34
|
+
manifest instead of calling getActiveUniform, and surfaces shader compile errors
|
|
35
|
+
as Ruby exceptions pointing at the original file and line. REQUIRES a ruby.wasm
|
|
36
|
+
runtime (the `js` gem) to run — it installs under a normal CRuby/JRuby/TruffleRuby,
|
|
37
|
+
but raises a clear LoadError instead of working there. This gem is meant to be bundled
|
|
38
|
+
into a ruby.wasm build (see README), not required from a regular Ruby process.
|
|
39
|
+
email:
|
|
40
|
+
- kyuuka1228@gmail.com
|
|
41
|
+
executables: []
|
|
42
|
+
extensions: []
|
|
43
|
+
extra_rdoc_files: []
|
|
44
|
+
files:
|
|
45
|
+
- CHANGELOG.md
|
|
46
|
+
- LICENSE.txt
|
|
47
|
+
- README.md
|
|
48
|
+
- glslkit-webgl.gemspec
|
|
49
|
+
- lib/glslkit/webgl.rb
|
|
50
|
+
- lib/glslkit/webgl/context.rb
|
|
51
|
+
- lib/glslkit/webgl/embed.rb
|
|
52
|
+
- lib/glslkit/webgl/errors.rb
|
|
53
|
+
- lib/glslkit/webgl/geometry.rb
|
|
54
|
+
- lib/glslkit/webgl/live_reload.rb
|
|
55
|
+
- lib/glslkit/webgl/matrix.rb
|
|
56
|
+
- lib/glslkit/webgl/program.rb
|
|
57
|
+
- lib/glslkit/webgl/reload_result.rb
|
|
58
|
+
- lib/glslkit/webgl/texture.rb
|
|
59
|
+
- lib/glslkit/webgl/version.rb
|
|
60
|
+
- sample/app.rb
|
|
61
|
+
- sample/error_panel.rb
|
|
62
|
+
- sample/generated-broken/neon-broken_shaders.rb
|
|
63
|
+
- sample/generated/cube_shaders.rb
|
|
64
|
+
- sample/generated/neon_shaders.rb
|
|
65
|
+
- sample/index.html
|
|
66
|
+
- sample/neon-error.html
|
|
67
|
+
- sample/neon-error.rb
|
|
68
|
+
- sample/neon.html
|
|
69
|
+
- sample/neon.rb
|
|
70
|
+
- sample/shaders-broken/common/color.glsl
|
|
71
|
+
- sample/shaders-broken/common/sdf.glsl
|
|
72
|
+
- sample/shaders-broken/neon-broken.frag
|
|
73
|
+
- sample/shaders-broken/neon-broken.vert
|
|
74
|
+
- sample/shaders/common/color.glsl
|
|
75
|
+
- sample/shaders/common/sdf.glsl
|
|
76
|
+
- sample/shaders/cube.frag
|
|
77
|
+
- sample/shaders/cube.vert
|
|
78
|
+
- sample/shaders/neon.frag
|
|
79
|
+
- sample/shaders/neon.vert
|
|
80
|
+
- shim/glslkit-webgl.js
|
|
81
|
+
homepage: https://github.com/kyubey1228/glslkit
|
|
82
|
+
licenses:
|
|
83
|
+
- MIT
|
|
84
|
+
metadata:
|
|
85
|
+
homepage_uri: https://github.com/kyubey1228/glslkit
|
|
86
|
+
source_code_uri: https://github.com/kyubey1228/glslkit/tree/main/webgl
|
|
87
|
+
changelog_uri: https://github.com/kyubey1228/glslkit/blob/main/webgl/CHANGELOG.md
|
|
88
|
+
rdoc_options: []
|
|
89
|
+
require_paths:
|
|
90
|
+
- lib
|
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '3.1'
|
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
|
+
requirements:
|
|
98
|
+
- - ">="
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: '0'
|
|
101
|
+
requirements: []
|
|
102
|
+
rubygems_version: 3.6.2
|
|
103
|
+
specification_version: 4
|
|
104
|
+
summary: ruby.wasm WebGL2 binding that consumes glslkit reflection manifests
|
|
105
|
+
test_files: []
|