Search code examples
c++openglexporeact-nativeshader

gl-shader: Error compiling shader: Compile failed. ERROR: 0:9: 'assign' : cannot convert from '4-component vector


I am trying to write a shader when I can pass both image saturation value like this https://gl-react-cookbook.surge.sh/saturation?menu=true and image colorscaling like this https://gl-react-cookbook.surge.sh/colorscale?menu=true in react native for that I am using opengl in react native. As from the example, I can run both the image saturation and image colorScaling separately but I don't know how to add them together. I am new to opengl i tried reading the docs but could not find any help. Please help me to figure out how to get both the functionality. Here is my Code.

Error I am getting

gl-shader: Error compiling shader:
Compile failed.
ERROR: 0:9: 'assign' :  cannot convert from '4-component vector of float' to '3-component vector of float'
ERROR: 0:12: 'constructor' : too many arguments
ERROR: 0:13: Unexpected syntax error;
ERROR: 3 compilation errors. No code generated.

Shaders

const shaders = Shaders.create({
  colorify: {
    frag: GLSL`
    precision highp float;
    varying vec2 uv;
    uniform sampler2D children, colorScale;
    uniform float contrast, saturation, brightness;
    const vec3 L = vec3(0.2125, 0.7154, 0.0721);
    float greyscale (vec3 c) { return 0.2125 * c.r + 0.7154 * c.g + 0.0721 * c.b; }
    void main() {
      vec4 c = texture2D(children, uv);
      vec3 brt = c.rgba * brightness;
      vec4 original = texture2D(children, uv);
      vec4 newcolor = texture2D(colorScale, vec2(greyscale(original.rgb), 0.5));
      gl_FragColor = vec4(mix(vec3(0.5), mix(vec3(dot(brt,L)),brt,saturation),contrast),c.a,newcolor.rgb, original.a * newcolor.a) 
    }
   `,
  },
});




export const Colorify = ({ url, colorScale, interpolation }) => (
  <Node
    shader={shaders.colorify}
    uniformsOptions={{ colorScale: { interpolation } }}
    uniforms={{
      colorScale,
      children: url,
      contrast: 0.3,
      saturation: 0.1,
      brightness: 0.2,
    }}
  />
);



const App = () => {
return (
 <Surface style={{ ...StyleSheet.absoluteFill }}>
          <Colorify
            url={route.imageUrl}
            colorScale={colorScales[color]}
            interpolation={interpolation}
          />
        </Surface>)}

Any help would be great.


Solution

  • Just read the error messages you got:

    ERROR: 0:9: 'assign' :  cannot convert from '4-component vector of float' to '3-component vector of float'
    

    So 0:9 here tells us to look into the first string (counting is 0-based here) passed to glShaderSource, line 9, which in your code is:

    vec3 brt = c.rgba * brightness;
    

    The error is cannot convert from '4-component vector of float' to '3-component vector of float. And that is a very descriptive error message. c.rgba is a vec4, vec * float yields still vec4, and you assign this to vec3 brt. You need to either:

    • store the vec4 result in a vec4 variable: vec4 brt = c.rgba * brightness;, OR
    • explicitly convert the resulting vec4 to vec3 : vec3 brt = vec3(c.rgba * brightness); or vec3 brt = (c.rgba * brightness).rgb; (or whatever components and order you want), OR
    • or, and this makes most sense here, do a vec3 calculation in the first place: vec3 brt = c.rgb * brightness;
    ERROR: 0:12: 'constructor' : too many arguments
    

    with line 12 being this gem:

    gl_FragColor = vec4(mix(vec3(0.5), mix(vec3(dot(brt,L)),brt,saturation),contrast),c.a,newcolor.rgb, original.a * newcolor.a) 
    

    A vec4 constructor obviously takes 4 argmuents, but you pass vec4(vec3, float, vec3, float). Which does make totally no sense at all. Your totally got that part of the code wrong. Just read your source materials again.

    ERROR: 0:13: Unexpected syntax error;
    

    That's because line 12 also is lacking a ; at the end, and when the compiler looked for it in the next line, it did not find it, but a } instead.