Grayscale conversion: average rgb and luma.
Traditional shaders calculate rendering effects on graphics hardware with a high degree of flexibility. Most shaders are coded for (and run on) a graphics processing unit (GPU), though this is not a strict requirement. Shading languages are used to program the GPU's rendering pipeline, which has mostly superseded the fixed-function pipeline of the past that only allowed for common geometry transforming and pixel-shading functions; with shaders, customized effects can be used. The position and color (hue, saturation, brightness, and contrast) of all pixels, vertices, and/or textures used to construct a final rendered image can be altered using algorithms defined in a shader, and can be modified by external variables or textures introduced by the computer program calling the shader.
The first step to rendering an image, is for geometry data to be converted from one coordinate system to another coordinate system.
A Fragment Shader is the Shader stage that will process a Fragment generated by the Rasterization into a set of colors and a single depth value.
In the exercise shaders are used to apply effects on the images, using Luma, rgb average and inverse on an image, which can be found in the fragment shader. In all cases the same vertex shader is used.
In the first case, the shaders are applied to an image, obtaining the same variations around the color that were obtained in the same exercise by software. No difference is evident.
1link
2linklet grayShader;
3linklet lumaShader;
4linklet theShader;
5linklet img;
6link
7linkfunction preload() {
8link img = loadImage('/vc/docs/sketches/lenna.png');
9link grayShader = loadShader('/vc/docs/sketches/workshop2/exercice1/shader.vert', '/vc/docs/sketches/workshop2/> >exercice1/rgb.frag');
10link lumaShader = loadShader('/vc/docs/sketches/workshop2/exercice1/shader.vert', '/vc/docs/sketches/workshop2/> >exercice1/luma.frag');
11link inverseShader = loadShader('/vc/docs/sketches/workshop2/exercice1/shader.vert','/vc/docs/sketches/workshop2/> >exercice1/inverse.frag')
12link}
13link
14linkfunction setup() {
15link createCanvas(768, 256, WEBGL);
16link noStroke();
17link
18link theShader = createGraphics(256, 256, WEBGL);
19link theShader.noStroke();
20link
21link angleMode(DEGREES);
22link}
23link
24linkfunction draw() {
25link
26link theShader.shader(grayShader);
27link grayShader.setUniform('tex', img);
28link texture(theShader);
29link theShader.rect(0,0,256,256);
30link rect(-124,-256/2.0,256,256)
31link
32link theShader.shader(inverseShader);
33link inverseShader.setUniform('tex', img);
34link texture(theShader);
35link theShader.rect(0,0,256,256);
36link rect(140,-256/2.0,256,256);
37link
38link
39link theShader.shader(lumaShader);
40link rotateY(180);
41link lumaShader.setUniform('tex0', img);
42link texture(theShader);
43link theShader.rect(0,0,256,256);
44link rect(132,-256/2.0,256,256);
45link
46link}
47link
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkattribute vec3 aPosition;
6linkattribute vec2 aTexCoord;
7link
8linkvarying vec2 vTexCoord;
9link
10linkvoid main() {
11link vTexCoord = aTexCoord;
12link
13link vec4 positionVec4 = vec4(aPosition, 1.0);
14link positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
15link
16link gl_Position = positionVec4;
17link}
1linkprecision mediump float;
2link
3linkvarying vec2 vTexCoord;
4link
5linkuniform sampler2D tex0;
6link
7link
8linkfloat luma(vec3 color) {
9link return dot(color, vec3(0.299, 0.587, 0.114));
10link}
11link
12link
13linkvoid main() {
14link
15link vec2 uv = vTexCoord;
16link uv = 1.0 - uv;
17link
18link vec4 tex = texture2D(tex0, uv);
19link
20link float gray = luma(tex.rgb);
21link
22link gl_FragColor = vec4(gray, gray, gray, 1.0);
23link}
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkvarying vec2 vTexCoord;
6link
7linkuniform sampler2D tex;
8link
9linkfloat rgb(vec3 color) {
10link return dot(color, vec3(1.0/3.0, 1.0/3.0, 1.0/3.0));
11link}
12link
13linkvoid main() {
14link vec2 uv = vTexCoord;
15link uv.y = 1.0 - uv.y;
16link
17link vec4 tex_f = texture2D(tex, uv);
18link
19link float gray = rgb(tex_f.rgb);
20link
21link gl_FragColor = vec4(gray,gray,gray,1.0);
22link}
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkvarying vec2 vTexCoord;
6link
7linkuniform sampler2D tex;
8link
9link
10linkvoid main() {
11link vec2 uv = vTexCoord;
12link uv.y = 1.0 - uv.y;
13link
14link vec4 tex_f = texture2D(tex, uv);
15link
16link tex_f.rgb = 1.0 - tex_f.rgb;
17link
18link gl_FragColor = tex_f;
19link}
Using another image, differences are not evident with respect to the exercise in software
1link
2linklet grayShader;
3linklet lumaShader;
4linklet space;
5linklet shaderTexture;
6linklet inverseShader;
7link
8link
9linkfunction preload() {
10link img = loadImage('/vc/docs/sketches/adv.jpg');
11link grayShader = loadShader('/vc/docs/sketches/workshop2/exercice1/shader.vert', '/vc/docs/sketches/workshop2/> >exercice1/rgb.frag');
12link lumaShader = loadShader('/vc/docs/sketches/workshop2/exercice1/shader.vert', '/vc/docs/sketches/workshop2/> >exercice1/luma.frag');
13link inverseShader = loadShader('/vc/docs/sketches/workshop2/exercice1/shader.vert','/vc/docs/sketches/workshop2/> >exercice1/inverse.frag')
14link}
15link
16linkfunction setup() {
17link createCanvas(768, 256, WEBGL);
18link noStroke();
19link
20link theShader = createGraphics(256, 256, WEBGL);
21link theShader.noStroke();
22link
23link angleMode(DEGREES);
24link}
25link
26linkfunction draw() {
27link
28link theShader.shader(grayShader);
29link grayShader.setUniform('tex', img);
30link texture(theShader);
31link theShader.rect(0,0,256,256);
32link rect(-124,-256/2.0,256,256)
33link
34link theShader.shader(inverseShader);
35link inverseShader.setUniform('tex', img);
36link texture(theShader);
37link theShader.rect(0,0,256,256);
38link rect(140,-256/2.0,256,256);
39link
40link
41link theShader.shader(lumaShader);
42link rotateY(180);
43link lumaShader.setUniform('tex0', img);
44link texture(theShader);
45link theShader.rect(0,0,256,256);
46link rect(132,-256/2.0,256,256);
47link
48link
49link}
50link
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkattribute vec3 aPosition;
6linkattribute vec2 aTexCoord;
7link
8linkvarying vec2 vTexCoord;
9link
10linkvoid main() {
11link vTexCoord = aTexCoord;
12link
13link vec4 positionVec4 = vec4(aPosition, 1.0);
14link positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
15link
16link gl_Position = positionVec4;
17link}
1linkprecision mediump float;
2link
3linkvarying vec2 vTexCoord;
4link
5linkuniform sampler2D tex0;
6link
7link
8linkfloat luma(vec3 color) {
9link return dot(color, vec3(0.299, 0.587, 0.114));
10link}
11link
12link
13linkvoid main() {
14link
15link vec2 uv = vTexCoord;
16link uv = 1.0 - uv;
17link
18link vec4 tex = texture2D(tex0, uv);
19link
20link float gray = luma(tex.rgb);
21link
22link gl_FragColor = vec4(gray, gray, gray, 1.0);
23link}
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkvarying vec2 vTexCoord;
6link
7linkuniform sampler2D tex;
8link
9linkfloat rgb(vec3 color) {
10link return dot(color, vec3(1.0/3.0, 1.0/3.0, 1.0/3.0));
11link}
12link
13linkvoid main() {
14link vec2 uv = vTexCoord;
15link uv.y = 1.0 - uv.y;
16link
17link vec4 tex_f = texture2D(tex, uv);
18link
19link float gray = rgb(tex_f.rgb);
20link
21link gl_FragColor = vec4(gray,gray,gray,1.0);
22link}
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkvarying vec2 vTexCoord;
6link
7linkuniform sampler2D tex;
8link
9link
10linkvoid main() {
11link vec2 uv = vTexCoord;
12link uv.y = 1.0 - uv.y;
13link
14link vec4 tex_f = texture2D(tex, uv);
15link
16link tex_f.rgb = 1.0 - tex_f.rgb;
17link
18link gl_FragColor = tex_f;
19link}
However, it is possible to identify a significant difference in the result obtained by hardware, the performance.
Regarding the exercise by software, it is evident that the videos are reproduced fluently, revealing the difference in processing capacity of the CPU versus the GPU, because a CPU has a few cores optimized for sequential serial processing, while a GPU has a huge parallel architecture consisting of thousands of smaller, more efficient cores, designed to handle multiple tasks at the same time.
1linklet grayShader;
2linklet lumaShader;
3linklet space;
4linklet shaderTexture;
5linklet inverseShader;
6link
7link
8linkfunction preload() {
9link video = createVideo(['/vc/docs/sketches/fingers.mov', '/vc/docs/sketches/fingers.webm']);
10link grayShader = loadShader('/vc/docs/sketches/workshop2/exercice1/shader.vert', '/vc/docs/sketches/workshop2/> >exercice1/rgb.frag');
11link lumaShader = loadShader('/vc/docs/sketches/workshop2/exercice1/shader.vert', '/vc/docs/sketches/workshop2/> >exercice1/luma.frag');
12link inverseShader = loadShader('/vc/docs/sketches/workshop2/exercice1/shader.vert','/vc/docs/sketches/workshop2/> >exercice1/inverse.frag')
13link video.hide();
14link}
15link
16linkfunction setup() {
17link createCanvas(768, 256, WEBGL);
18link noStroke();
19link
20link theShader = createGraphics(256, 256, WEBGL);
21link theShader.noStroke();
22link
23link video.loop();
24link angleMode(DEGREES);
25link}
26link
27linkfunction draw() {
28link
29link theShader.shader(grayShader);
30link grayShader.setUniform('tex', video);
31link texture(theShader);
32link theShader.rect(0,0,256,256);
33link rect(-124,-256/2.0,256,256)
34link
35link theShader.shader(inverseShader);
36link inverseShader.setUniform('tex', video);
37link texture(theShader);
38link theShader.rect(0,0,256,256);
39link rect(140,-256/2.0,256,256);
40link
41link theShader.shader(lumaShader);
42link rotateY(180);
43link lumaShader.setUniform('tex0', video);
44link texture(theShader);
45link theShader.rect(0,0,256,256);
46link rect(132,-256/2.0,256,256)
47link}
48link
49linkfunction mousePressed() {
50link video.loop();
51link}
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkattribute vec3 aPosition;
6linkattribute vec2 aTexCoord;
7link
8linkvarying vec2 vTexCoord;
9link
10linkvoid main() {
11link vTexCoord = aTexCoord;
12link
13link vec4 positionVec4 = vec4(aPosition, 1.0);
14link positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
15link
16link gl_Position = positionVec4;
17link}
1linkprecision mediump float;
2link
3linkvarying vec2 vTexCoord;
4link
5linkuniform sampler2D tex0;
6link
7link
8linkfloat luma(vec3 color) {
9link return dot(color, vec3(0.299, 0.587, 0.114));
10link}
11link
12link
13linkvoid main() {
14link
15link vec2 uv = vTexCoord;
16link uv = 1.0 - uv;
17link
18link vec4 tex = texture2D(tex0, uv);
19link
20link float gray = luma(tex.rgb);
21link
22link gl_FragColor = vec4(gray, gray, gray, 1.0);
23link}
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkvarying vec2 vTexCoord;
6link
7linkuniform sampler2D tex;
8link
9linkfloat rgb(vec3 color) {
10link return dot(color, vec3(1.0/3.0, 1.0/3.0, 1.0/3.0));
11link}
12link
13linkvoid main() {
14link vec2 uv = vTexCoord;
15link uv.y = 1.0 - uv.y;
16link
17link vec4 tex_f = texture2D(tex, uv);
18link
19link float gray = rgb(tex_f.rgb);
20link
21link gl_FragColor = vec4(gray,gray,gray,1.0);
22link}
1link#ifdef GL_ES
2linkprecision mediump float;
3link#endif
4link
5linkvarying vec2 vTexCoord;
6link
7linkuniform sampler2D tex;
8link
9link
10linkvoid main() {
11link vec2 uv = vTexCoord;
12link uv.y = 1.0 - uv.y;
13link
14link vec4 tex_f = texture2D(tex, uv);
15link
16link tex_f.rgb = 1.0 - tex_f.rgb;
17link
18link gl_FragColor = tex_f;
19link}