actarian / vscode-glsl-canvas

Live WebGL preview of GLSL shaders
MIT License
335 stars 25 forks source link

Vertex and fragment shader in one file doesn't work? #67

Closed bencresty closed 2 years ago

bencresty commented 2 years ago

Hi,

According to the documentation of glsl-canvas (https://github.com/actarian/glsl-canvas) we should be able to use both vertex and fragment shader code in one glsl file:

#if defined(VERTEX)

attribute vec4 a_position;
attribute vec4 a_normal;
attribute vec2 a_texcoord;
attribute vec4 a_color;

void main(void) {
    v_position = a_position;
    v_position = u_projectionMatrix * u_modelViewMatrix * v_position;
    v_normal = u_normalMatrix * a_normal;
    v_texcoord = a_texcoord;
    v_color = a_color;
    gl_Position = v_position;
}

// fragment shader
#else

void main() {
  ...
}
#endif

Buf when doing this with the glsl-canvas vs code extension this isn't working.

When doing this:

#version 300 es // webgl2

#ifdef GL_ES
precision highp float;
#endif

#if defined(VERTEX)
// ----------------------- VERTEX SHADER ----------------------------------

in vec4 a_position;
in vec4 a_normal;
in vec2 a_texcoord;
in vec4 a_color;

void main(void) {
    v_position = a_position;
    v_normal = a_normal;
    v_color = a_color;
    gl_Position = v_position;
}

#else
// ----------------------- FRAGMENT SHADER ----------------------------------

out vec4 outColor;

void main() {
    vec3 color = vec3(1.0, 0.0, 0.0);
    outColor = vec4(color, 1.0);
}

#endif

The canvas shows a list of errors: image

Apart from the vertex shader code the fragment shader code works just fine, so it's not accepting the fact that there's also vertex shader code in there now.

Already the first error in the list 'doesn't make sense'; it tells us that a #version directive must occur before everything else. But when looking at the code it DOES occur before everything else.

So my guess is that internally this extension adds its own vertex shader code before this, causing this #version to not be first anymore and the rest of the code to fail.

If that's the case: How could we enter custom vertex shader code? If that's not the case it looks like there's some issue somewhere in the extension preventing us from executing vertex shader code within the same file OR the documentation of the glsl-canvas has an error perhaps.

actarian commented 2 years ago

@bencresty Issue has been resolved on latest version 0.2.15. Thank you for your submission!

#version 300 es

#ifdef GL_ES
precision mediump float;
#endif

uniform mat4 u_projectionMatrix;
uniform mat4 u_modelViewMatrix;
uniform mat4 u_normalMatrix;
uniform vec2 u_resolution;

uniform vec2 u_textureResolution;
uniform float u_time;
uniform vec2 u_mouse;
uniform vec2 u_pos;
uniform sampler2D u_buffer0;

#if defined(VERTEX)

in vec4 a_position; // glsl-canvas/data/duck-toy.obj
// in vec4 a_position;
in vec4 a_normal;
in vec2 a_texcoord;
in vec4 a_color;

out vec4 v_position;
out vec4 v_normal;
out vec2 v_texcoord;
out vec4 v_color;

mat4 rotationAxis(float angle, vec3 axis) {
    axis = normalize(axis);
    float s = sin(angle);
    float c = cos(angle);
    float oc = 1.0 - c;
    return mat4(oc * axis.x * axis.x + c,           oc * axis.x * axis.y - axis.z * s,  oc * axis.z * axis.x + axis.y * s,  0.0,
                oc * axis.x * axis.y + axis.z * s,  oc * axis.y * axis.y + c,           oc * axis.y * axis.z - axis.x * s,  0.0,
                oc * axis.z * axis.x - axis.y * s,  oc * axis.y * axis.z + axis.x * s,  oc * axis.z * axis.z + c,           0.0,
                0.0,                                0.0,                                0.0,                                1.0);
}

vec3 rotateZ(vec3 p, float angle) {
    mat4 rmy = rotationAxis(angle, vec3(0.0, 0.0, 1.0));
    return (vec4(p, 1.0) * rmy).xyz;
}

float easeQuintInOut(float t) {
    if ((t / 2.0) < 1.0) return 0.5 * t * t * t * t * t;
    return 0.5 * ((t -= 2.0) * t * t * t * t + 2.0);
}

void main(void) {
    v_position = a_position;
    // v_position.y += sin(v_position.x * 0.1) * 10.0;
    // float d = (5.0 + cos(u_time) * 2.5);
    float a = sin((u_time * 4.0) + a_position.y) * 0.1;
    float b = cos(((u_time + 1.5) * 10.0) + a_position.y * 2.0) * 0.05;
    float c = sin((u_time * 4.0) + a_position.y) * 0.3;
    v_position.z += a - b;
    v_position.xyz = rotateZ(v_position.xyz, cos(u_time + a_position.x) * (2.0 * a));
    // v_position.x -= a + c;
    // v_position.xyz += a_normal.xyz * 0.025 + (cos(u_time * 5.0)) * a_normal.xyz * 0.025;
    v_position = u_projectionMatrix * u_modelViewMatrix * v_position;
    v_normal = u_normalMatrix * a_normal;
    v_texcoord = a_texcoord;
    v_color = a_color;
    gl_Position = v_position;
}

#elif defined(BUFFER_0)

vec2 coord(in vec2 p) {
    p = p / u_resolution.xy;
    // correct aspect ratio
    /*
    if (u_resolution.x > u_resolution.y) {
        p.x *= u_resolution.x / u_resolution.y;
        p.x += (u_resolution.y - u_resolution.x) / u_resolution.y / 2.0;
    } else {
        p.y *= u_resolution.y / u_resolution.x;
        p.y += (u_resolution.x - u_resolution.y) / u_resolution.x / 2.0;
    }
    */
    // centering
    p -= 0.5;
    p *= vec2(-1.0, 1.0);
    return p;
}

#define rx 1.0 / min(u_resolution.x, u_resolution.y)
#define uv gl_FragCoord.xy / u_resolution.xy
#define st coord(gl_FragCoord.xy)

float fill(in float d) {
    float s = 0.2;
    return 1.0 - smoothstep(0.0 - s, rx * 2.0 + s, d);
}

float sCircle(in vec2 p, in float w) {
    return length(p) * 2.0 - w;
}
float circle(in vec2 p, in float w) {
    float d = sCircle(p, w);
    return fill(d);
}

in vec4 v_position;
in vec4 v_normal;
in vec2 v_texcoord;
in vec4 v_color;

out vec4 outColor;

void main() {
    vec3 color = vec3(1.0);
    vec3 bufferColor = texture(u_buffer0, uv).rgb;
    // bufferColor *= 0.99;
    bufferColor *= 0.6;
    vec2 p = vec2(
        st.x + cos(u_time * 5.0) * 0.4,
        st.y + sin(u_time * 2.25) * 0.4
    );
    float c = circle(p, 0.05);
    bufferColor = mix(bufferColor, color, c);
    bufferColor += pow(bufferColor.r, 2.0);
    bufferColor = min(vec3(1.0), bufferColor);
    outColor = vec4(bufferColor, 1.0);
}

#else

in vec4 v_position;
in vec4 v_normal;
in vec2 v_texcoord;
in vec4 v_color;

out vec4 outColor;

void main() {
    vec4 buffer = texture(u_buffer0, v_texcoord);
    vec3 color = vec3(0.0);
    color = vec3(
        abs(cos(u_time * 0.1)) * v_texcoord.y,
        abs(cos(u_time * 0.2)) * v_texcoord.y,
        abs(sin(u_time)) * v_texcoord.y
    );
    /*
    // uv.x = fract(uv.x + u_time * 0.5);
    vec4 buffer = texture(u_buffer0, uv);
    */
    float fresnel = dot(v_normal.xyz, vec3(0.0, 0.0, 1.0));
    fresnel = 1.0 - pow(fresnel, 1.0);

    // light
    float incidence = max(dot(v_normal.xyz, vec3(0.0, 1.0, 0.0)), 0.0);
    vec3 light = vec3(0.2) + (vec3(1.0) * incidence);
    outColor = vec4((color.rgb * light) * light, 0.1 + (fresnel + buffer.r) * 2.0);

    // outColor = vec4(fresnel + color.rgb, fresnel + buffer.r);
    // outColor = vec4(vec3(fresnel), 1.0);
    // outColor = vec4(v_color.rgb * color.rgb * buffer.rgb * buffer.rgb * light, buffer.r);
    // outColor = buffer;
    // outColor = vec4(v_color.rgb * light, 1.0);
}

#endif
bencresty commented 2 years ago

@actarian Thanks a lot for this! Very much appreciated! It's great to be able to do this within vs code!

bencresty commented 2 years ago

Hi @actarian , I just tried the version you mention having the fix (0.2.15) with your exact same glsl code, but it's not working here. I'm getting the following error (in VS Code 1.64.2):

image

Which is odd, because #version is the very first thing in the file on the first row. I also checked all glsl-canvas-related settings in VS Code, but can't find anything that looks related to the change.

Is there anything I should do, know or change to make this work?

actarian commented 2 years ago

@bencresty , please try reinstall the extension by removing and deleting the extension folder, seems there's a problem in vscode in updating the extension dependancies, after a clear install it should work.

bencresty commented 2 years ago

@bencresty , please try reinstall the extension by removing and deleting the extension folder, seems there's a problem in vscode in updating the extension dependancies, after a clear install it should work.

Thanks for your response. Just removed the complete extension folder for this extension from inside {user}/.vscode/extensions` and reinstalled the module from within vs code. That didn't help. The exact same glsl code you posted here keeps throwing the same error message as shown in my previous post.

After that I upgraded VS Code because there was a new update. That also didn't help.

Than I went to the extension folder and did an pnpm install, which couldn't complete because of an error: image [edit] When installing with npm instead of pnpm it does work. There are quite some deprecation messages tho. Not sure why pnpm is not working in this case, never seen that before and using it for years. Cannot run the compile script to test a new compilation without installing things other than in the private repo, so leave it with that.