Search code examples
shaderwebglcurtains.js

curtains.js — Unable to initialize the shader program


I'm attempting to add a fragment shader to plane created via curtains. I've used this fragment shader with other libraries before — namely, canvas-sketch — however I can't seem to get the shader to run as the console prompts me with the error: Program: Unable to initialize the shader program.

#canvas {
    /* make the canvas wrapper fits the document */
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
.plane {
    /* define the size of your plane */
    width: 80%;
    height: 80vh;
    margin: 10vh auto;
}
<div id="canvas"></div>
<div class="plane"></div>
<script type="module">
import { Curtains, Plane } from "https://cdn.jsdelivr.net/npm/[email protected]/src/index.mjs";

window.addEventListener("load", () => {
  // set up our WebGL context and append the canvas to our wrapper
  const curtains = new Curtains({
    container: "canvas",
  });

  // get our plane element
  const planeElement = document.getElementsByClassName("plane")[0];

  // set our initial parameters (basic uniforms)

  const fragmentShader = `
    precision mediump float;
    uniform float uTime;
    varying vec2 vUv;

    void main() {
        vec3 color = 0.5 + 0.5 * cos(uTime + vUv.xyx + vec3(0.0, 2.0, 4.0));
        gl_FragColor = vec4(color, 1.0);
    }
  `;
  const params = {
    fragmentShader,
    widthSegments: 20,
    heightSegments: 20,
    uniforms: {
      time: {
        name: "uTime", // uniform name that will be passed to our shaders
        type: "1f", // this means our uniform is a float
        value: 0,
      },
    },
  };

  // create our plane using our curtains object, the bound HTML element and the parameters
  const plane = new Plane(curtains, planeElement, params);

  plane.onRender(() => {
    // use the onRender method of our plane fired at each requestAnimationFrame call
    plane.uniforms.time.value++; // update our time uniform value
  });
});
</script>

I did see notes in other questions about how to enable more verbose error logging for GL but I'm not sure how to set these properties using this library.


Solution

  • curtains doesn't have a varying called vUv. It has one called vTextureCoord

    #canvas {
        /* make the canvas wrapper fits the document */
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
    }
    .plane {
        /* define the size of your plane */
        width: 80%;
        height: 80vh;
        margin: 10vh auto;
    }
    <div id="canvas"></div>
    <div class="plane"></div>
    <script type="module">
    import { Curtains, Plane } from "https://cdn.jsdelivr.net/npm/[email protected]/src/index.mjs";
    
    window.addEventListener("load", () => {
      // set up our WebGL context and append the canvas to our wrapper
      const curtains = new Curtains({
        container: "canvas",
      });
    
      // get our plane element
      const planeElement = document.getElementsByClassName("plane")[0];
    
      // set our initial parameters (basic uniforms)
    
      const fragmentShader = `
        precision mediump float;
        uniform float uTime;
        varying vec2 vTextureCoord;
    
        void main() {
            vec3 color = 0.5 + 0.5 * cos(uTime + vTextureCoord.xyx + vec3(0.0, 2.0, 4.0));
            gl_FragColor = vec4(color, 1.0);
        }
      `;
      const params = {
        fragmentShader,
        widthSegments: 20,
        heightSegments: 20,
        uniforms: {
          time: {
            name: "uTime", // uniform name that will be passed to our shaders
            type: "1f", // this means our uniform is a float
            value: 0,
          },
        },
      };
    
      // create our plane using our curtains object, the bound HTML element and the parameters
      const plane = new Plane(curtains, planeElement, params);
    
      plane.onRender(() => {
        // use the onRender method of our plane fired at each requestAnimationFrame call
        plane.uniforms.time.value++; // update our time uniform value
      });
    });
    </script>