patriciogonzalezvivo / glslcanvas Goto Github PK
View Code? Open in Web Editor NEWSimple tool to load GLSL shaders on HTML Canvas using WebGL
Home Page: http://patriciogonzalezvivo.github.io/glslCanvas/
License: MIT License
Simple tool to load GLSL shaders on HTML Canvas using WebGL
Home Page: http://patriciogonzalezvivo.github.io/glslCanvas/
License: MIT License
Under the section The easy way, it appearstrought a url using the attribute
should be through a url using the attribute
Here is a minimal reproducible example of the issue. I should get just a gray canvas but it looks like u_gray uniform is always zero. Am I doing something wrong?
index.js
var canvas = document.getElementById('glslCanvas');
var sandbox = new GlslCanvas(canvas);
sandbox.setUniform("u_gray", 0.5);
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js"></script>
</head>
<body>
<canvas id="glslCanvas" class='glslCanvas' data-fragment-url="shader.frag" width="512" height="512"></canvas>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
shader.frag
precision mediump float;
uniform float u_gray;
void main() {
gl_FragColor = vec4(vec3(u_gray), 1.0);
}
I'm wondering if there is any potential for #include support
The .setMouse()
function returns faulty values. Please excuse if I am using the function incorrectly.
For example, when passing sandbox.useMouse({ x: 0, y: 0 })
and logging sandbox.uniforms
, u_mouse
returns as follows:
{
"name": "u_mouse",
"type": "vec2",
"value": [
1.785604900459418,
149.35220838052095
],
"method": "uniform2f",
"location": {}
}
In case the function maps the coordinates to the canvas element, here is my react implementation:
const Canvas = () => {
const canvasRef = useRef();
const { current } = canvasRef;
useEffect(() => {
if (current) {
const sandbox = new GlslCanvas(current);
sandbox.load(program.frag);
sandbox.setUniform('u_texture', testImg);
console.log(sandbox);
sandbox.setMouse({ x: 0, y: 0 });
}
}, [current, mouse]);
return <canvas ref={canvasRef} />;
};
what would be best way to show shader's fps?
Hi this is my code for animating the reaction-diffusion simulation, I want to use mouse click to add species B to the screen, I run it in glslEditor, it reports no error but only shows a black background.
Hope you help me check what's wrong with my code
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform sampler2D u_buffer0;
const vec4 params = vec4(0.16, 0.08, 0.06, 0.062);
const vec4 color1 = vec4(0.0, 0.0, 0.0, 0.3137);
const vec4 color2 = vec4(1.0, 0.1843, 0.5333, 0.3765);
const vec4 color3 = vec4(0.8549, 1.0, 0.5333, 0.3882);
const vec4 color4 = vec4(0.3765, 1.0, 0.4784, 0.3922);
const vec4 color5 = vec4(1.0);
void main()
{
vec2 uv_texcoord = gl_FragCoord.xy / u_resolution.xy;
#if defined( BUFFER0 )
if(u_mouse.x < -5.0)
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
return;
}
vec2 pixelSize = 1.0 / u_resolution.xy;
vec2 cen = texture2D(u_buffer0, uv_texcoord).xy;
vec2 rig = texture2D(u_buffer0, uv_texcoord + vec2( pixelSize.x, 0.0)).xy;
vec2 top = texture2D(u_buffer0, uv_texcoord + vec2( 0.0, pixelSize.y)).xy;
vec2 lef = texture2D(u_buffer0, uv_texcoord + vec2(-pixelSize.x, 0.0)).xy;
vec2 bot = texture2D(u_buffer0, uv_texcoord + vec2( 0.0, -pixelSize.y)).xy;
float Du = params.x;
float Dv = params.y;
float feed = params.z;
float kill = params.w;
vec2 lapl = rig + top + lef + bot - 4.0 * cen;
float du = Du * lapl.x - cen.x * cen.y * cen.y + feed * (1.0 - cen.x);
float dv = Dv * lapl.y + cen.x * cen.y * cen.y - (feed + kill) * cen.y;
vec2 newValue = cen + 0.6 * vec2(du, dv);
if(u_mouse.x > 0.0)
{
vec2 diff = (gl_FragCoord.xy - u_mouse.xy);
float dist = dot(diff, diff);
if(dist < 1.0)
newValue.y = 0.9;
}
gl_FragCoord = vec4(newValue, 0.0, 1.0);
#else
float value = texture2D(u_buffer0, uv_texcoord).y;
float a;
vec3 col;
if (value <= color1.w)
{
col = color1.xyz;
}
else if (value > color1.w && value <= color2.w)
{
a = (value - color1.w) / (color2.w - color1.w);
col = mix(color1.xyz, color2.xyz, a);
}
else if (value > color2.w && value <= color3.w)
{
a = (value - color2.w) / (color3.w - color2.w);
col = mix(color2.xyz, color3.xyz, a);
}
else if (value > color3.w && value <= color4.w)
{
a = (value - color3.w) / (color4.w - color3.w);
col = mix(color3.xyz, color4.xyz, a);
}
else if (value > color4.w && value <= color5.w)
{
a = (value - color4.w) / (color5.w - color4.w);
col = mix(color4.xyz, color5.xyz, a);
}
gl_FragColor = vec4(col.xyz, 1.0);
#endif
}
Hello,
is it possible to load a shader in a external file? any example on how to do that?
thanks,
J
Hello,
Yesterday I wanted to try this nice tool. Following the documentation gave me a white canvas.
Here the example
Sixclones
I notice the mousemove
event listener (that is attached to document
) is not released in the destroy()
method, causing a leak.
/Fredrik Blomqvist
Hi,
the following code in https://beta.observablehq.com/ returns "Error: invalid module":
glslCanvas = require('glslCanvas')
It worked until few days ago.
Adding the release it works as expected:
glslCanvas = require('[email protected]')
Hi everyone,
I was trying to setup the lib for one of my project.
but while trying to use the librairy à constently get the folling message on my webpage :
"It does not appear your computer can support WebGL...."
I tried with chromium and firefox, on linux and android and got the same error.
while reading "the book of shaders" every samples and examples seem to work fine on the same browser I got the error.
It works even with the following test :
https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/By_example/Detect_WebGL
First, I'm wondering what I'm doing wrong ? Second It seems the error message is not very useful and do not provide a lot of information.
I'm using the lib with these lines :
<canvas id="my-sketch" data-fragment-url="./resources/frag/sketch.frag" width="300" height="300"></canvas> //same issue with no data-fragment
<script src="glslCanvas/GlslCanvas.min.js"></script> // same issue when pointing to github hosted file.
const buffer = document.getElementById('my-sketch');
const sandbox = new GlslCanvas(buffer);
Any guess ?
Hello Patricio, I am using glslCanvas (self hosted) to show some shaders fullscreen.
I receive this warning message:
"Error: WebGL warning: texImage2D: Alpha-premult and y-flip are deprecated for non-DOM-Element uploads."
The result is totally different from what I obtain using glslViewer.
Do you know if it is something related to glslCanvas? I have prepared a test page containing the error here:
https://davideprati.com/artworks/pattern2-argusianus-argus/1.html
The weird thing is that in another page I am also using textures https://davideprati.com/artworks/pattern1-appunti-su-piuma/1.html but it works correctly.
I tried to clone the whole repo and tried to serve the html file with a simple server. After visiting that html file in the browser all I see is black color. What am I doing wrong?
I am wondering if this project is still maintained? I am willing to add my support/contribution if required.
John
Hello, thank you for this helpful library.
I noticed some WebGL warnings when running it in Firefox (version 117.0.1, Linux 64 bits), but not on Chromium (version 116.0.5845.187, Linux 64 bits). Here's the list:
WebGL warning: texImage: Alpha-premult and y-flip are deprecated for non-DOM-Element uploads.
WebGL warning: drawArraysInstanced: Drawing without vertex attrib 0 array enabled forces the browser to do expensive emulation work when running on desktop OpenGL platforms, for example on Mac. It is preferable to always draw with vertex attrib 0 array enabled, by using bindAttribLocation to bind some always-used attribute to location 0.
WebGL warning: enableVertexAttribArray: -1 is not a validindex
. This value probably comes from a getAttribLocation() call, where this return value -1 means that the passed name didn't correspond to an active attribute in the specified program.
WebGL warning: vertexAttribI?Pointer:index
(4294967295) must be < MAX_VERTEX_ATTRIBS.
WebGL warning: texImage: Alpha-premult and y-flip are deprecated for non-DOM-Element uploads.
I can see the same warnings on the example page: http://patriciogonzalezvivo.github.io/glslCanvas/
Should this be solved in the library or in each project? Is it a big issue at all?
Many thanks!
Code: (same as default code, but with a 0.25 value for alpha channel)
// Author:
// Title:
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
vec3 color = vec3(0.);
color = vec3(st.x,st.y,abs(sin(u_time)));
gl_FragColor = vec4(color,0.25);
}
Browsers in screenshot below, left to right:
I cannot understand why this is happening, but it seems to be that alpha is output as 1.0 for gl_FragColor values greater than approximately 0.002197265508584
, and as 0.0 for values below. (e.g. 0.0001 is interpreted as 0.0).
I'm using glslCanvas
within a react app and am failing to cleanly destroy
the instance.
It appears the render loop does not get aborted so causes an error after the destruction?
My hook looks like this:
// Spawn the glsl canvas
useEffect(() => {
if (!webGlSupported && GlslCanvas) return;
sandbox.current = new GlslCanvas(canvas.current);
return () => {
sandbox.current.pause();
sandbox.current.destroy();
};
}, [webGlSupported]);
This causes an error:
Uncaught TypeError: Cannot read property 'canvas' of null
at GlslCanvas.resize (GlslCanvas.es.js:1394)
at RenderLoop (GlslCanvas.es.js:1084)
Related: #8
I tested very simple html page(below) as local file, and it shows nothing.
<html>
<head>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js"></script>
</head>
<body>
<canvas class="glslCanvas" data-fragment="
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}
" width="500" height="500"></canvas>
</body>
</html>
It seems an instant render overwritten or ignored if render timing is too fast.
Adding a line that postpones rendering render once more at the next frame, It works fine.
// glslCanvas.js: 179L
setTimeout(() => { this.forceRender = true; }, 1);
Thanks.
hi patricio!
i tried loading this shader from shadertoy into glslCanvas but get the following error:
GlslCanvas.js:692 *** Error compiling shader [object WebGLShader]:ERROR: 0:28: 'iChannel0' : undeclared identifier
ERROR: 0:28: 'textureLod' : no matching overloaded function found
ERROR: 0:28: 'yx' : field selection requires structure or vector on left hand side
ERROR: 0:28: '=' : dimension mismatch
ERROR: 0:28: '=' : cannot convert from 'const mediump float' to 'mediump 2-component vector of float'
which I gather is because shadertoy is written for WebGL 3.0+ and glslCanvas is written for WebGL 2.0., is that correct? is there any way currently for glslCanvas to support 3.0? or what would be the best way of embedding a shader like that into a separate page?
I noticed that every time you update a uniform value the code calls this:
this.gl.getUniformLocation(this.program, name);
It's my understanding that this is (or can be) a pretty slow call. An easy fix would be to lazy initialize the value.
see for example: http://nical.github.io/onGameStart2013/ (slide 7)
If you like I supply a patch.
Hello Patricio
Thanks for this library!
How to debug the shader? I have one that works on GlslViewer on SublimeText, but it appears black on glslCanvas.
Even declaring u_time, it appears with the flag animated: false
Thanks!
Hello, glslCanvas is very usefull and the shaders works great.
But I don't know why I necessrary need to write the shader after data-fragment,if i use data-fragment-url with the localisation of the frag file I get a black screen.
For the texture it's a little the same, after I properly set the data-texture, the sampler2D u_tex0 give me a black result.
I don't know if I do something wrong but even when I download the glslCanvas and I launch the exemple defaut index.html file I can't see the textures en the screen is all black(the shader is still working, i can add color at the gl_FragColor it seems to be just that the textures are black).
I read many times the read me and I can't figure it out, it's for that I finaly write here.
First of all, glslCanvas is great. By far the easiest way I've found so far to get working shaders onto a webpage. Thanks for your work on it, and Book of Shaders.
I'm tearing my hair out trying to resolve an issue I'm having loading a texture from an Amazon S3 bucket in Chrome and Safari. Firefox works just fine.
I'm specifying the texture path as a data-texture
attribute like so:
<canvas data-textures="http://s3-us-west-1.amazonaws.com/my-bucket/image.jpg" width="900" height="380" data-fragment=""></canvas>
When glslCanvas attempts to load the texture, I get an error:
Access to Image at 'http://s3-us-west-1.amazonaws.com/my-bucket/image.jpg' from origin 'http://foo.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://foo.com' is therefore not allowed access.
When the image does load (which I've accomplished by testing with a local texture source) the shader works great. Occasionally, but not often, the textures will successfully load without me doing anything different, which makes troubleshooting this very difficult. Every time I think "Oh! It magically works now!" turns out it was a fluke and I'm back to the beginning.
I have the CORS on my s3 bucket set up appropriately, as well as in my sites .htaccess
. I'm using other tools which are also using javascript to load images from the same s3 bucket, so it would seem that it may be unique to something glslCanvas is doing.
Anybody else have any experience with this?
hiya - looking at the source I'm guessing it's not currently possible to use the webcam as a texture.
I can see it would be fairly easy to hack in e.g. by a ".webcam" extension, but I'm wondering if this was the best way?
Additionally, I would like to get access to the texture elements that are created - is this possible. (e.g so I can change the various parameters including CSS).
Hi, Patricio, thank you for all your astonishing and amazing work.
I'm afraid, I ran into a problem with playing video as a texture. Video doesn't play in Chrome (67) (Mac and Win) and Safari (11.1.1) browsers. It freezes on the first frame. However, in Firefox (Mac, Win), Opera (Mac, Win), Edge (Win) everything is playing just fine.
Safari 9.1.3 (old one) gives me an error:
"ReferenceError: Can't find variable: performance. GlslCanvas.js:1417"
There is one more strange detail about it. If you reload the page in Chrome and immediately (very quickly, really) click somewhere in the browser window — video starts to play. Or if you reload the page with the inspector previously opened — video starts to play also.
It would be great if there were some way to handle this.
Thanks!
Moving issue patriciogonzalezvivo/thebookofshaders#59 here for more consistency!
How can I access a texture from a shader?
Or set a uniform?
My html looks like this:
<html>
<head>
<title>Loading Shader</title>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js"></script>
<style>
body {
margin:0px;
}
</style>
</head>
<body>
<canvas class="glslCanvas" data-fragment-url="shader.frag" data-textures="pic.png" width="500" height="500"></canvas>
</body>
</html>
The uniforms I set don't seem to be available in my shader
Example:
https://codepen.io/giannif/pen/vevZWj?editors=1111
var sandbox = new GlslCanvas(canvas);
// this doesn't work! why?
sandbox.setUniform("u_brightness",.5);
console.log(sandbox.uniforms) // it's here with a value of [[0.5]]
var frag = `
precision mediump float;
uniform float u_brightness;
void main() {
// u_brightness is not equal to 0.5
gl_FragColor = vec4(1.0,0.0,1.0,u_brightness);
}
`
sandbox.load(frag)
I'm new to this stuff, any help would be appreciated
is there a simple demo of how this could be accomplished with the current buffer setup?
Many thanks
hello Patricio, the README contains a url that returns a 404
https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js
the correct one is
https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.js
Hello,
Is it possible to use a kind of uniform sampler2D backbuffer
to get the pixels color of previous screen frame?
Thank you in advance,
Let me start by complimenting on an awesome repository! It's what I was looking for, because I'm pretty sure I would have been trying to work out how to even get WebGL working in the first place.
When trying to prepend 'webgl2' to names[] in function create3DContext()
, I kept getting the error "It does not appear your computer can support WebGL...". But I knew WebGL works in my browser, so after some trial and error I found that there was an itty-bitty bug in the code. It turns out that currently the 'experimental-webgl' is always selected, even if 'webgl' would return a valid context because the catch (e)
is never reached to break out of the for loop.
Here's what I made of it:
function create3DContext(canvas, optAttribs)
{
var names = ['webgl2'
, 'webgl', 'experimental-webgl'];
var context = null;
for (var i = 0; i < names.length; ++i)
{
try
{
context = canvas.getContext(names[i], optAttribs);
if (context) break;
}
catch (e)
{
if (context) break; /// Can probably just leave this out all together.
}
}
return context;
}
Hope this helps.
Cheers.
PS: Wow, the code formatting (Insert code) realy made it unreadable 🤮. Have seen better on other sites.
first off, this library is fantastic.
Second, is texture repeating wrapping possible to set?
thanks
I tried #version 300 es this but didn't work
http://www.shaderific.com/blog/2014/3/13/tutorial-how-to-update-a-shader-for-opengl-es-30
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform float u_time;
void main(){
vec2 st = gl_FragCoord.xy/u_resolution.xy;
gl_FragColor = vec4( 1 & 2);
}
Hi,
Is it possible to draw vertices? For instance, with this [vertex shader]](https://github.com/hrbigelow/wij-wemnan/blob/master/shaders/scatter-v.cc), I eventually call it with:
write_to_gl: function() {
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.glbuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.jsbuf, this.gl.STATIC_DRAW);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
}
But I don't see any part of glslCanvas API that allows sending vertex data to it, is there?
Thanks!
Hello Patricio
Cool thing you did with glslCanvas. Going to use it for React components and the specifics there is that components can be mounted / unmounted often. So destroying component properly without memory leak is crucial.
SInce I do not see any explicit methods for destroying glslCanvas I want to ask: What is the proper way to do this?
Is there any possibility to use WebGL 2.0?
Rawgit, used to load glslCanvas has been shut down.
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js"></script>
Bit of a webgl noob here, please excuse if the answer is obvious.
How would I go about creating multiple shader passes? I cannot find any documentation on this, other the native buffer access added in 0.1.1
(which to my understanding gives access to the previous pass).
Can this be achieved by creating multiple sandbox instances and passing them to each other as a texture similar to this?
const pass1 = new GlslCanvas(canvas);
const pass2 = new GlslCanvas(canvas);
const pass1 = sandbox.load(myFrag);
const pass2 = sandbox.load(myFrag2);
pass2.setUniform("u_texture”, pass1);
Hello I am trying to convert the canvas back to a media stream so that I can send it over webrtc. I am calling .captureStream() on the canvas which I passed into new GlslCanvas(canvas).
However every frame is black. Any idea why? Do I need to perform some intermediary step?
Hi,
I'm kinda surprised that having an idle animation with glslCanvas causes a non-negligible amount of CPU usage. When my animation is idle, it uses 6-7% of my CPU, and when I mouse over it, it uses ~15% of my CPU. I figure it would be less resource intensive if I force it to refresh at 30 frames per second instead of 60. Is there a simple way of doing that?
Hey everyone, I have the following shader:
https://glslsandbox.com/e#81208.1
It responds to mouse movement smoothly.
However, the same shader using glslsandbox:
https://shaders-threejs.glitch.me
Moving around the cursor causes the screen to flash blue, a markedly different effect from the expected behavior. Any ideas how I can fix this, asides from removing the u_mouse variable completely?
I'm unable to import the dependency directly via es6 modules.
A possible workaround is importing the following but this feels fragile & is suboptimal in terms of package size.
import Canvas from 'glsl-canvas-js/dist/cjs/canvas/canvas'
"glsl-canvas-js": "~0.2.9"
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 22.3.0: Mon Jan 30 20:42:11 PST 2023; root:xnu-8792.81.3~2/RELEASE_X86_64
Binaries:
Node: 18.11.0
npm: 8.19.2
Yarn: 1.22.19
pnpm: N/A
Relevant packages:
next: 13.1.6
eslint-config-next: 13.1.6
react: 18.2.0
react-dom: 18.2.0
If canvas size is set to fit the container, resizing the window makes the frame rate drop a lot, from ~60 to about 5 fps.
Hi,
I want to use glslCanvas in a Svelte component but got syntax error on the basic example of this repo. Syntax error is thrown on the both vertex and fragment strings. The code is very simple and easy to understand :
<script>
import GlslCanvas from 'glslCanvas'
import { onMount } from 'svelte';
let gl, canvas
const vert = "attribute vec4 a_position;\n main(){\n\tgl_Position = a_position;\n};\n\n";
const frag = "main(){\n\tgl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n};\n\n";
onMount( () => {
console.log(vert, frag)
gl = new GlslCanvas( canvas )
gl.load(frag, vert )
});
</script>
<canvas bind:this={canvas}
class="glslCanvas"
width="200"
height="200"/>
And here are the error from the console :
GlslCanvas.es.js:318 *** Error compiling shader [object WebGLShader]:ERROR: 0:2: 'main' : syntax error
GlslCanvas.es.js:318 *** Error compiling shader [object WebGLShader]:ERROR: 0:1: 'main' : syntax error
GlslCanvas.es.js:346 Uncaught TypeError: Failed to execute 'attachShader' on 'WebGLRenderingContext': parameter 2 is not of type 'WebGLShader'.
I have the same exact code that gives me two different results on glslCanvas and glslViewer.
vec2 origSt = (2.0 * gl_FragCoord.xy - u_resolution.xy)/ u_resolution.y;
vec4 texZoom = vec4(texture2D(u_tex0, origSt + vec2(0.5)));
gl_FragColor = texZoom;
This is the result using glslViewer:
And this is the result on glslCanvas:
Can it be that gl.REPEAT is different between the two?
I have the following shader, which is ported from this shadertoy:
https://www.shadertoy.com/view/Mfy3Wt
in shader toy the normal seem to update properly when rotating the cube, however not in the GSLS canvas version. Anyone has an idea on what could be happening ?
I am new to shader and 3d computer graphic so I might be missing something obvious.
#version 300 es
precision lowp float;
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
out vec4 fragColor;
#define MAX_STEPS 200
#define MAX_DIST 100.
#define SURF_DIST .001
mat2 Rot(float a) {
float s = sin(a);
float c = cos(a);
return mat2(c, -s, s, c);
}
float smin( float a, float b, float k ) {
float h = clamp( 0.5+0.5*(b-a)/k, 0., 1. );
return mix( b, a, h ) - k*h*(1.0-h);
}
float sdCapsule(vec3 p, vec3 a, vec3 b, float r) {
vec3 ab = b-a;
vec3 ap = p-a;
float t = dot(ab, ap) / dot(ab, ab);
t = clamp(t, 0., 1.);
vec3 c = a + t*ab;
return length(p-c)-r;
}
float sdCylinder(vec3 p, vec3 a, vec3 b, float r) {
vec3 ab = b-a;
vec3 ap = p-a;
float t = dot(ab, ap) / dot(ab, ab);
t = clamp(t, 0., 1.);
vec3 c = a + t*ab;
float x = length(p-c)-r;
float y = (abs(t-.5)-.5)*length(ab);
float e = length(max(vec2(x, y), 0.));
float i = min(max(x, y), 0.);
return e+i;
}
float sdTorus(vec3 p, vec2 r) {
float x = length(p.xz)-r.x;
return length(vec2(x, p.y))-r.y;
}
float sdBox(vec3 p, vec3 s) {
p = abs(p)-s;
return length(max(p, 0.))+min(max(p.x, max(p.y, p.z)), 0.);
}
float GetDist(vec3 p) {
float plane = p.y;
float box = sdBox(p-vec3(0,1,0), vec3(1));
float d = min(plane, box);
return d;
}
float RayMarch(vec3 ro, vec3 rd) {
float dO=0.;
for(int i=0; i<MAX_STEPS; i++) {
vec3 p = ro + rd*dO;
float dS = GetDist(p);
dO += dS;
if(dO>MAX_DIST || dS<SURF_DIST) break;
}
return dO;
}
vec3 GetNormal(vec3 p) {
float d = GetDist(p);
vec2 e = vec2(.001, 0);
vec3 n = d - vec3(
GetDist(p-e.xyy),
GetDist(p-e.yxy),
GetDist(p-e.yyx));
return normalize(n);
}
vec3 R(vec2 uv, vec3 p, vec3 l, float z) {
vec3 f = normalize(l-p),
r = normalize(cross(vec3(0,1,0), f)),
u = cross(f,r),
c = p+f*z,
i = c + uv.x*r + uv.y*u,
d = normalize(i-p);
return d;
}
void main( )
{
vec2 uv = (gl_FragCoord.xy * 2. - u_resolution.xy) / u_resolution.y;
vec2 m = (u_mouse.xy * 2. - u_resolution.xy) / u_resolution.y;
vec3 col = vec3(0);
vec3 ro = vec3(0, 4, -5);
ro.yz *= Rot(-m.y*3.14+1.);
ro.xz *= Rot(-m.x*6.2831);
vec3 rd = R(uv, ro, vec3(0,1,0), 1.);
float d = RayMarch(ro, rd);
if(d<MAX_DIST) {
vec3 p = ro + rd * d;
vec3 norm = GetNormal(p);
col = norm;
}
fragColor = vec4(col,1.0);
}
Hi,
I've found an issue when you want to dynamicly access to an index of an array.
vec2 p[9];
int i = 0;
for (float y = -1.0; y <= 1.0; y++) {
p[i++] = y; // The error says : Index expression must be constant
}
I test this code with glslViewer and that work well.
In the readme file, it says to include https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js
. When trying to use this to draw a test image, it did not draw. However, when looking at the example usage at https://patriciogonzalezvivo.github.io/glslCanvas
, it included https://patriciogonzalezvivo.github.io/glslCanvas/build/GlslCanvas.js
. When I included this file instead, it fixed the problem.
I am using 64-bit Chrome 66.0.3359.117 on Ubuntu 16.04.4 if it makes a difference.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.