Star

Created With

linkHardware Grayscale conversion

linkProblem Statement

Grayscale conversion: average rgb and luma.

linkBackground

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.

linkVertex Shader

The first step to rendering an image, is for geometry data to be converted from one coordinate system to another coordinate system.

linkFragment Shader

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.

linkCode en Results

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.

gray.js
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

shader.vert
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}

lumma.frag
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}

rgb.frag
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}

inverse.frag
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

gray2.js
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

shader.vert
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}

lumma.frag
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}

rgb.frag
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}

inverse.frag
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.

gray_video.js
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}

shader.vert
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}

lumma.frag
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}

rgb.frag
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}

inverse.frag
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}

linkReferences

Hardware Grayscale conversionProblem StatementBackgroundVertex ShaderFragment ShaderCode en ResultsReferences

Home

Workshopschevron_right
Imaging & Videochevron_right
Sofwarechevron_right
Hardwarechevron_right

Benchmark

Renderingchevron_right
Algovischevron_right
Computer Graphicschevron_right
HCIchevron_right
P5 Code Snippetschevron_right
Memberschevron_right