Shader Variable

  • Attribute : is used to describe the position, normal, or texture coordinates of each vertex in a mesh. It is set once per mesh and does not change throughout the rendering process.
  • Uniform : is used to specify global data that is constant for all vertices or fragments in a rendering call. Examples of uniform variables include the view matrix, projection matrix, and texture samplers. Uniforms are set once per rendering call.
  • Varying : is used to pass data from the vertex shader to the fragment shader. The varying data is interpolated across the surface of the triangle to which each fragment belongs. The interpolated value is then used in the fragment shader to compute the final color of the pixel.

Each type of variable has a specific purpose in the rendering pipeline.

attribute:
attribute is a read-only variable that stores information about each individual vertex, such as vertex position, colour, normal, and uv coordinate etc. attribute cannot be used within the fragment shader.

{"title":"VertexShader","code":"\/*MY_VERTEX_SHADER*\/\n\/* #version 330 core *\/\n\n\/\/ default vertex attributes provided by BufferGeometry, No need to define explicitly. \n\/\/attribute vec3 position;\n\/\/attribute vec3 normal;\n\/\/attribute vec2 uv;\n\n\/\/ Vertex shader (conditional):\n#ifdef USE_TANGENT\n\tattribute vec4 tangent;\n#endif\n#if defined( USE_COLOR_ALPHA )\n\t\/\/ vertex color attribute with alpha\n\tattribute vec4 color;\n#elif defined( USE_COLOR )\n\t\/\/ vertex color attribute\n\tattribute vec3 color;\n#endif\n\n\n varying vec2 vUv;\n void main() {\n    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n    vUv = uv;\n}"}

uniform
As GPU manages large numbers of parallel threads, to colour pixels of the image. Also each parallel thread doesn’t know about what other threads are doing. To keep them performing properly we need to send some inputs from the CPU to all threads. And that input has to be read only, in other words, each thread receives the same data which it can read but cannot change. Those inputs are called uniforms.

Here, I am adding u_ prefix to indicate that these are the uniform variables.

{"title":"FragmentShader","code":"\/*MY_FRAGMENT_SHADER *\/\n\/* #version 330 core *\/\n\n\/\/ Predefine: No need to define\nuniform vec2 u_resolution;\nuniform vec2 u_mouse;\nuniform float u_time;\n\n\/\/ User Define: You can define this uniform from Uniforms tab\nuniform float u_frequency;\nuniform vec3 u_color;\n\nvoid main() {\n    vec3 finalColor = vec3(sin(u_time * u_frequency), u_mouse.x, u_mouse.y) * u_color;\n    gl_FragColor=vec4(finalColor, 1.0);\n}"}

Lets Understand This With Following Example:
Shader is a computer language, which is designed to program and perform mathematical calculations.

Consider the following scenario:  

  1. Suppose we have a green colour light in the world, at some position and pointing to some direction.
  2. There is a cube object in the world.
  3. And your eye or camera watches this object from some point.

Now to render the cube based on the light, shader needs information like light direction, colour and position to perform calculation in the shader. 
A uniform variable is a parameter that the cpu or in other word our application (cpp/javascript) passes to the shaders.
As the name implies, the value stored in a uniform variable will be the same for the shader programme and cannot be changed by shaders (read-only) across all GPU threads.
Uniforms can be accessed by both the vertex and the fragment shaders. 
uniforms are used to store data like, light direction, camera position in world, fog value, shadow maps etc.


varying: are parameters that the fragment shader receives from the vertex shader.
The value of each variable for each fragment will be interpolated smoothly during rasterization from the values of neighbouring vertices.varying is deprecated in the new version of OpenGL and varying is replaced with the in and out qualifiers which give clarity which variable is input to vertex shader and which is output for fragment shader. 

Eg. 1: Below example pass the colour value from the vertex shader to fragment shader. Using a variable name out_color

[]