├── .gitignore ├── .gitmodules ├── 00_m.frag ├── 00_m_platform.frag ├── 01_mt.frag ├── 01_mt.vert ├── 02_bg_mt.frag ├── 03_bg_mt_pp.frag ├── 04_mt_fl_l-pbr.frag ├── 04_mt_fl_l.frag ├── 05_mt_mt.frag ├── 05_mt_mt.vert ├── 06_b_mt.frag ├── 06_b_mt.vert ├── 06_b_mt_pp.frag ├── 06_s_depth.frag ├── 06_s_normal.frag ├── 07_d_mt_pp.frag ├── 08_d_d_mt.frag ├── 08_d_d_mt.vert ├── 09_cp_mt_pp.frag ├── Makefile ├── README.md └── assets ├── .DS_Store ├── danny.png ├── default.png ├── pcl.ply ├── skull.mtl ├── skull.obj └── skull.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lygia"] 2 | path = lygia 3 | url = https://github.com/patriciogonzalezvivo/lygia.git 4 | -------------------------------------------------------------------------------- /00_m.frag: -------------------------------------------------------------------------------- 1 | 2 | #ifdef GL_ES 3 | precision mediump float; 4 | #endif 5 | 6 | uniform vec2 u_resolution; 7 | uniform vec2 u_mouse; 8 | uniform float u_time; 9 | 10 | varying vec2 v_texcoord; 11 | 12 | void main(void) { 13 | vec4 color = vec4(vec3(0.0), 1.0); 14 | vec2 pixel = 1.0/u_resolution.xy; 15 | vec2 st = gl_FragCoord.xy * pixel; 16 | vec2 uv = v_texcoord; 17 | 18 | color.rgb = vec3(st.x,st.y,abs(sin(u_time))); 19 | 20 | gl_FragColor = color; 21 | } 22 | -------------------------------------------------------------------------------- /00_m_platform.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | void main (void) { 6 | vec3 color = vec3(0.0); 7 | 8 | #if defined(PLATFORM_OSX) 9 | color = vec3(1.0, 0.0, 0.0); 10 | 11 | #elif defined(PLATFORM_LINUX) || defined(PLATFORM_RPI) 12 | color = vec3(0.0, 1.0, 0.0); 13 | 14 | #elif defined(PLATFORM_WIN) 15 | color = vec3(0.0, 0.0, 1.0); 16 | 17 | #elif defined(PLATFORM_WEBGL) 18 | color = vec3(0.0, 1.0, 1.0); 19 | #endif 20 | 21 | gl_FragColor = vec4(color, 1.0); 22 | } 23 | -------------------------------------------------------------------------------- /01_mt.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform vec3 u_camera; 6 | uniform vec3 u_light; 7 | 8 | uniform vec2 u_resolution; 9 | uniform vec2 u_mouse; 10 | uniform float u_time; 11 | 12 | varying vec4 v_position; 13 | varying vec3 v_normal; 14 | 15 | #if defined(MODEL_VERTEX_TEXCOORD) 16 | varying vec2 v_texcoord; 17 | #endif 18 | 19 | void main(void) { 20 | vec4 color = vec4(0.0, 0.0, 0.0, 1.0); 21 | vec2 pixel = 1.0/u_resolution; 22 | vec2 st = gl_FragCoord.xy * pixel; 23 | 24 | // Diffuse shading from directional light 25 | vec3 n = normalize(v_normal); 26 | vec3 l = normalize(u_light - v_position.xyz); 27 | color.rgb += dot(n, l) * 0.5 + 0.5; 28 | 29 | gl_FragColor = color; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /01_mt.vert: -------------------------------------------------------------------------------- 1 | 2 | #ifdef GL_ES 3 | precision mediump float; 4 | #endif 5 | 6 | uniform mat4 u_modelViewProjectionMatrix; 7 | uniform mat4 u_projectionMatrix; 8 | uniform mat4 u_modelMatrix; 9 | uniform mat4 u_viewMatrix; 10 | uniform mat3 u_normalMatrix; 11 | 12 | attribute vec4 a_position; 13 | varying vec4 v_position; 14 | 15 | #ifdef MODEL_VERTEX_COLOR 16 | attribute vec4 a_color; 17 | varying vec4 v_color; 18 | #endif 19 | 20 | #ifdef MODEL_VERTEX_NORMAL 21 | attribute vec3 a_normal; 22 | varying vec3 v_normal; 23 | #endif 24 | 25 | #ifdef MODEL_VERTEX_TEXCOORD 26 | attribute vec2 a_texcoord; 27 | varying vec2 v_texcoord; 28 | #endif 29 | 30 | #ifdef MODEL_VERTEX_TANGENT 31 | attribute vec4 a_tangent; 32 | varying vec4 v_tangent; 33 | varying mat3 v_tangentToWorld; 34 | #endif 35 | 36 | #ifdef LIGHT_SHADOWMAP 37 | uniform mat4 u_lightMatrix; 38 | varying vec4 v_lightCoord; 39 | #endif 40 | 41 | void main(void) { 42 | 43 | v_position = a_position; 44 | 45 | #ifdef MODEL_VERTEX_COLOR 46 | v_color = a_color; 47 | #endif 48 | 49 | #ifdef MODEL_VERTEX_NORMAL 50 | v_normal = a_normal; 51 | #endif 52 | 53 | #ifdef MODEL_VERTEX_TEXCOORD 54 | v_texcoord = a_texcoord; 55 | #endif 56 | 57 | #ifdef MODEL_VERTEX_TANGENT 58 | v_tangent = a_tangent; 59 | vec3 worldTangent = a_tangent.xyz; 60 | vec3 worldBiTangent = cross(v_normal, worldTangent);// * sign(a_tangent.w); 61 | v_tangentToWorld = mat3(normalize(worldTangent), normalize(worldBiTangent), normalize(v_normal)); 62 | #endif 63 | 64 | #ifdef LIGHT_SHADOWMAP 65 | v_lightCoord = u_lightMatrix * v_position; 66 | #endif 67 | 68 | gl_Position = u_modelViewProjectionMatrix * v_position; 69 | } 70 | -------------------------------------------------------------------------------- /02_bg_mt.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform vec3 u_camera; 6 | uniform vec3 u_light; 7 | 8 | uniform vec2 u_resolution; 9 | uniform vec2 u_mouse; 10 | uniform float u_time; 11 | 12 | varying vec4 v_position; 13 | varying vec3 v_normal; 14 | 15 | #if defined(MODEL_VERTEX_TEXCOORD) 16 | varying vec2 v_texcoord; 17 | #endif 18 | 19 | void main(void) { 20 | vec4 color = vec4(0.0, 0.0, 0.0, 1.0); 21 | vec2 pixel = 1.0/u_resolution; 22 | vec2 st = gl_FragCoord.xy * pixel; 23 | 24 | #if defined(BACKGROUND) 25 | float dist = distance(st, vec2(0.5)); 26 | color.rgb += 1.0-dist; 27 | // color.rgb += step(.5, fract( (st.x + st.y) * 10.0 + u_time)) * 0.5; 28 | 29 | #else 30 | 31 | // Diffuse shading from directional light 32 | vec3 n = normalize(v_normal); 33 | vec3 l = normalize(u_light - v_position.xyz); 34 | color.rgb += dot(n, l) * 0.5 + 0.5; 35 | #endif 36 | 37 | gl_FragColor = color; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /03_bg_mt_pp.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform sampler2D u_scene; 6 | uniform vec3 u_camera; 7 | uniform vec3 u_light; 8 | 9 | uniform vec2 u_resolution; 10 | uniform vec2 u_mouse; 11 | uniform float u_time; 12 | 13 | varying vec4 v_position; 14 | varying vec3 v_normal; 15 | 16 | #if defined(MODEL_VERTEX_TEXCOORD) 17 | varying vec2 v_texcoord; 18 | #endif 19 | 20 | #define CHROMAAB_PCT 10.5 21 | #define CHROMAAB_CENTER_BUFFER .15 22 | #define CHROMAAB_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, clamp(UV, vec2(0.001), vec2(0.999))) 23 | #include "lygia/distort/chromaAB.glsl" 24 | 25 | #define BARREL_SAMPLER_FNC(TEX, UV) chromaAB(TEX, UV); 26 | #include "lygia/distort/barrel.glsl" 27 | 28 | void main(void) { 29 | vec4 color = vec4(0.0, 0.0, 0.0, 1.0); 30 | vec2 pixel = 1.0/u_resolution; 31 | vec2 st = gl_FragCoord.xy * pixel; 32 | 33 | float dist = distance(st, vec2(0.5)); 34 | 35 | #if defined(BACKGROUND) 36 | color.rgb += 1.0-dist; 37 | // color.rgb += step(.5, fract( (st.x + st.y) * 10.0 + u_time)) * 0.5; 38 | 39 | #elif defined(POSTPROCESSING) 40 | color.rgb = barrel(u_scene, st, dist * 0.1); 41 | 42 | #else 43 | 44 | // Diffuse shading from directional light 45 | vec3 n = normalize(v_normal); 46 | vec3 l = normalize(u_light - v_position.xyz); 47 | color.rgb += dot(n, l) * 0.5 + 0.5; 48 | #endif 49 | 50 | gl_FragColor = color; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /04_mt_fl_l-pbr.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform sampler2D u_scene; 6 | 7 | uniform vec3 u_camera; 8 | uniform float u_cameraNearClip; 9 | uniform float u_cameraFarClip; 10 | 11 | uniform vec3 u_light; 12 | uniform vec3 u_lightColor; 13 | 14 | #ifdef SCENE_CUBEMAP 15 | uniform samplerCube SCENE_CUBEMAP; 16 | #endif 17 | 18 | #ifdef SCENE_SH_ARRAY 19 | uniform vec3 SCENE_SH_ARRAY[9]; 20 | #endif 21 | 22 | #ifdef LIGHT_SHADOWMAP 23 | uniform sampler2D u_lightShadowMap; 24 | varying vec4 v_lightCoord; 25 | #endif 26 | #define LIGHT_COORD v_lightCoord 27 | #define LIGHT_DIRECTION u_light 28 | 29 | uniform vec2 u_resolution; 30 | uniform vec2 u_mouse; 31 | uniform float u_time; 32 | 33 | varying vec4 v_position; 34 | varying vec4 v_color; 35 | varying vec3 v_normal; 36 | 37 | #if defined(MODEL_VERTEX_TEXCOORD) 38 | varying vec2 v_texcoord; 39 | #endif 40 | 41 | #include "lygia/color/space/linear2gamma.glsl" 42 | 43 | #include "lygia/lighting/pbrLittle.glsl" 44 | #include "lygia/lighting/material/new.glsl" 45 | 46 | void main(void) { 47 | vec4 color = vec4(1.0); 48 | vec2 pixel = 1.0/u_resolution; 49 | vec2 st = gl_FragCoord.xy * pixel; 50 | vec2 uv = v_texcoord; 51 | 52 | Material material = materialNew(); 53 | 54 | #if defined(FLOOR) 55 | // Floor 56 | vec2 uv1 = floor(fract(uv * 8.0) * 2.0); 57 | float checker = (min(1.0, uv1.x + uv1.y) - (uv1.x * uv1.y)); 58 | material.albedo.rgb = vec3(0.5) + (1.0-checker) * 0.5; 59 | material.metallic = 0.001; 60 | #else 61 | 62 | // Skull 63 | material.albedo = vec4(1.0); 64 | material.metallic = 0.1; 65 | material.roughness = 0.1; 66 | 67 | #endif 68 | 69 | color = pbrLittle(material); 70 | 71 | gl_FragColor = linear2gamma(color); 72 | } 73 | 74 | -------------------------------------------------------------------------------- /04_mt_fl_l.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform sampler2D u_buffer0; 6 | 7 | uniform sampler2D u_scene; 8 | uniform sampler2D u_sceneDepth; 9 | 10 | uniform vec3 u_camera; 11 | uniform float u_cameraNearClip; 12 | uniform float u_cameraFarClip; 13 | 14 | uniform vec3 u_light; 15 | 16 | uniform vec2 u_resolution; 17 | uniform vec2 u_mouse; 18 | uniform float u_time; 19 | 20 | varying vec4 v_position; 21 | varying vec3 v_normal; 22 | 23 | #if defined(MODEL_VERTEX_TEXCOORD) 24 | varying vec2 v_texcoord; 25 | #endif 26 | 27 | #ifdef LIGHT_SHADOWMAP 28 | uniform sampler2D u_lightShadowMap; 29 | varying vec4 v_lightCoord; 30 | uniform mat4 u_lightMatrix; 31 | #endif 32 | #include "lygia/lighting/shadow.glsl" 33 | 34 | void main(void) { 35 | vec4 color = vec4(1.0); 36 | vec2 pixel = 1.0/u_resolution; 37 | vec2 st = gl_FragCoord.xy * pixel; 38 | 39 | #if defined(FLOOR) 40 | vec2 uv = v_texcoord; 41 | color.rgb *= 0.5 + step(0.5, fract( (uv.x + uv.y) * 50.0)) * 0.5; 42 | #endif 43 | 44 | // Diffuse shading from directional light 45 | vec3 n = normalize(v_normal); 46 | vec3 l = normalize(u_light - v_position.xyz); 47 | color.rgb *= dot(n, l) * 0.5 + 0.5; 48 | color.rgb *= 0.8; 49 | 50 | color.rgb *= shadow(u_lightShadowMap, vec2(LIGHT_SHADOWMAP_SIZE), v_lightCoord.xy, v_lightCoord.z); 51 | 52 | gl_FragColor = color; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /05_mt_mt.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform vec3 u_camera; 6 | uniform vec3 u_light; 7 | 8 | uniform vec2 u_resolution; 9 | uniform vec2 u_mouse; 10 | uniform float u_time; 11 | 12 | varying vec4 v_position; 13 | varying vec3 v_normal; 14 | 15 | #ifdef MODEL_VERTEX_COLOR 16 | varying vec4 v_color; 17 | #endif 18 | 19 | #if defined(MODEL_VERTEX_TEXCOORD) 20 | varying vec2 v_texcoord; 21 | #endif 22 | 23 | void main(void) { 24 | vec4 color = vec4(0.0, 0.0, 0.0, 1.0); 25 | vec2 pixel = 1.0/u_resolution; 26 | vec2 st = gl_FragCoord.xy * pixel; 27 | 28 | #ifdef MODEL_VERTEX_COLOR 29 | color = v_color; 30 | #endif 31 | 32 | #ifdef MODEL_NAME_TOP 33 | color.rgb = vec3(1.0, 0.0, 0.0); 34 | #endif 35 | 36 | // Diffuse shading from directional light 37 | vec3 n = normalize(v_normal); 38 | vec3 l = normalize(u_light - v_position.xyz); 39 | color.rgb *= dot(n, l) * 0.5 + 0.5; 40 | 41 | gl_FragColor = color; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /05_mt_mt.vert: -------------------------------------------------------------------------------- 1 | 2 | #ifdef GL_ES 3 | precision mediump float; 4 | #endif 5 | 6 | uniform mat4 u_modelViewProjectionMatrix; 7 | uniform mat4 u_projectionMatrix; 8 | uniform mat4 u_modelMatrix; 9 | uniform mat4 u_viewMatrix; 10 | uniform mat3 u_normalMatrix; 11 | uniform float u_time; 12 | 13 | attribute vec4 a_position; 14 | varying vec4 v_position; 15 | 16 | #ifdef MODEL_VERTEX_COLOR 17 | attribute vec4 a_color; 18 | varying vec4 v_color; 19 | #endif 20 | 21 | #ifdef MODEL_VERTEX_NORMAL 22 | attribute vec3 a_normal; 23 | varying vec3 v_normal; 24 | #endif 25 | 26 | #ifdef MODEL_VERTEX_TEXCOORD 27 | attribute vec2 a_texcoord; 28 | varying vec2 v_texcoord; 29 | #endif 30 | 31 | #ifdef MODEL_VERTEX_TANGENT 32 | attribute vec4 a_tangent; 33 | varying vec4 v_tangent; 34 | varying mat3 v_tangentToWorld; 35 | #endif 36 | 37 | #ifdef LIGHT_SHADOWMAP 38 | uniform mat4 u_lightMatrix; 39 | varying vec4 v_lightCoord; 40 | #endif 41 | 42 | #include "lygia/math/const.glsl" 43 | #include "lygia/math/mirror.glsl" 44 | #include "lygia/animation/easing.glsl" 45 | #include "lygia/space/rotateX.glsl" 46 | #include "lygia/space/rotateY.glsl" 47 | 48 | void main(void) { 49 | v_position = a_position; 50 | 51 | #ifdef MODEL_VERTEX_NORMAL 52 | v_normal = a_normal; 53 | #endif 54 | 55 | #ifdef MODEL_NAME_BOTTOM 56 | float pct = mirror(u_time * 0.5); 57 | pct = elasticInOut(pct); 58 | v_position = rotateX(v_position, pct * -PI * 0.1); 59 | v_normal = rotateX(v_normal, pct * -PI * 0.1); 60 | v_position.y -= (pct) * .5; 61 | #endif 62 | 63 | v_position = rotateY(v_position, sin(u_time * 0.5)); 64 | v_normal = rotateY(v_normal, sin(u_time * 0.5)); 65 | 66 | 67 | #ifdef MODEL_VERTEX_COLOR 68 | v_color = a_color; 69 | #endif 70 | 71 | 72 | 73 | #ifdef MODEL_VERTEX_TEXCOORD 74 | v_texcoord = a_texcoord; 75 | #endif 76 | 77 | #ifdef MODEL_VERTEX_TANGENT 78 | v_tangent = a_tangent; 79 | vec3 worldTangent = a_tangent.xyz; 80 | vec3 worldBiTangent = cross(v_normal, worldTangent);// * sign(a_tangent.w); 81 | v_tangentToWorld = mat3(normalize(worldTangent), normalize(worldBiTangent), normalize(v_normal)); 82 | #endif 83 | 84 | #ifdef LIGHT_SHADOWMAP 85 | v_lightCoord = u_lightMatrix * v_position; 86 | #endif 87 | 88 | gl_Position = u_modelViewProjectionMatrix * v_position; 89 | } 90 | -------------------------------------------------------------------------------- /06_b_mt.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform sampler2D u_scene; 6 | uniform sampler2D u_buffer0; 7 | 8 | uniform vec3 u_camera; 9 | uniform float u_cameraNearClip; 10 | uniform float u_cameraFarClip; 11 | 12 | uniform vec3 u_light; 13 | 14 | uniform vec2 u_resolution; 15 | uniform vec2 u_mouse; 16 | uniform float u_time; 17 | 18 | varying vec4 v_position; 19 | varying vec4 v_color; 20 | varying vec3 v_normal; 21 | 22 | #if defined(MODEL_VERTEX_TEXCOORD) 23 | varying vec2 v_texcoord; 24 | #endif 25 | 26 | #ifdef LIGHT_SHADOWMAP 27 | uniform sampler2D u_lightShadowMap; 28 | varying vec4 v_lightCoord; 29 | uniform mat4 u_lightMatrix; 30 | #endif 31 | #include "lygia/lighting/shadow.glsl" 32 | #include "lygia/generative/worley.glsl" 33 | 34 | varying float v_pct; 35 | 36 | void main(void) { 37 | vec4 color = vec4(0.0, 0.0, 0.0, 1.0); 38 | vec2 pixel = 1.0/u_resolution; 39 | vec2 st = gl_FragCoord.xy * pixel; 40 | 41 | #if defined(BUFFER_0) 42 | color += worley( vec3(st * 10., u_time * 0.22) ); 43 | color *= worley( st * 5. + vec2(u_time * 0.5, 0.) ); 44 | 45 | #else 46 | color += v_color; 47 | 48 | #if defined(FLOOR) 49 | vec2 uv = v_texcoord; 50 | color.rgb *= 0.5 + step(0.5, fract( (uv.x + uv.y) * 50.0)) * 0.5; 51 | #endif 52 | 53 | // Diffuse shading from directional light 54 | vec3 n = normalize(v_normal); 55 | vec3 l = normalize(u_light - v_position.xyz); 56 | color.rgb *= dot(n, l) * 0.5 + 0.5; 57 | color.rgb *= 0.8; 58 | 59 | color.rgb *= mix(shadow(u_lightShadowMap, vec2(LIGHT_SHADOWMAP_SIZE), v_lightCoord.xy, v_lightCoord.z), 1.0, v_pct); 60 | #endif 61 | 62 | gl_FragColor = color; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /06_b_mt.vert: -------------------------------------------------------------------------------- 1 | 2 | #ifdef GL_ES 3 | precision mediump float; 4 | #endif 5 | 6 | uniform sampler2D u_buffer0; 7 | uniform sampler2D u_buffer1; 8 | 9 | uniform mat4 u_modelViewProjectionMatrix; 10 | uniform mat4 u_projectionMatrix; 11 | uniform mat4 u_modelMatrix; 12 | uniform mat4 u_viewMatrix; 13 | uniform mat3 u_normalMatrix; 14 | 15 | attribute vec4 a_position; 16 | varying vec4 v_position; 17 | 18 | #ifdef MODEL_VERTEX_COLOR 19 | attribute vec4 a_color; 20 | varying vec4 v_color; 21 | #endif 22 | 23 | #ifdef MODEL_VERTEX_NORMAL 24 | attribute vec3 a_normal; 25 | varying vec3 v_normal; 26 | #endif 27 | 28 | #ifdef MODEL_VERTEX_TEXCOORD 29 | attribute vec2 a_texcoord; 30 | varying vec2 v_texcoord; 31 | #endif 32 | 33 | #ifdef MODEL_VERTEX_TANGENT 34 | attribute vec4 a_tangent; 35 | varying vec4 v_tangent; 36 | varying mat3 v_tangentToWorld; 37 | #endif 38 | 39 | #ifdef LIGHT_SHADOWMAP 40 | uniform mat4 u_lightMatrix; 41 | varying vec4 v_lightCoord; 42 | #endif 43 | 44 | #include "lygia/color/palette/fire.glsl" 45 | varying float v_pct; 46 | 47 | void main(void) { 48 | v_position = a_position; 49 | 50 | #ifdef MODEL_VERTEX_COLOR 51 | v_color = a_color; 52 | #endif 53 | 54 | #ifdef MODEL_VERTEX_NORMAL 55 | v_normal = a_normal; 56 | #endif 57 | 58 | #ifdef MODEL_VERTEX_TEXCOORD 59 | v_texcoord = a_texcoord; 60 | #endif 61 | 62 | #ifdef MODEL_VERTEX_TANGENT 63 | v_tangent = a_tangent; 64 | vec3 worldTangent = a_tangent.xyz; 65 | vec3 worldBiTangent = cross(v_normal, worldTangent);// * sign(a_tangent.w); 66 | v_tangentToWorld = mat3(normalize(worldTangent), normalize(worldBiTangent), normalize(v_normal)); 67 | #endif 68 | 69 | v_pct = 0.0; 70 | #if defined(MODEL_NAME_TOP) 71 | v_pct = smoothstep(0.0, 2.0, v_position.y); 72 | float disp = texture2D(u_buffer0, v_texcoord).r ; 73 | v_position.xyz += normalize(v_position.xyz * vec3(1.0, 0.25, 1.0)) * disp * 5.0 * v_pct; 74 | v_color.rgb = mix(v_color.rgb, fire( (1.0-disp) * 2. - v_pct * 3.), v_pct); 75 | #endif 76 | 77 | #ifdef LIGHT_SHADOWMAP 78 | v_lightCoord = u_lightMatrix * v_position; 79 | #endif 80 | 81 | gl_Position = u_modelViewProjectionMatrix * v_position; 82 | } 83 | -------------------------------------------------------------------------------- /06_b_mt_pp.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform sampler2D u_buffer0; 6 | 7 | uniform sampler2D u_scene; 8 | uniform sampler2D u_sceneDepth; 9 | 10 | uniform vec3 u_camera; 11 | uniform float u_cameraNearClip; 12 | uniform float u_cameraFarClip; 13 | 14 | uniform vec3 u_light; 15 | 16 | uniform vec2 u_resolution; 17 | uniform vec2 u_mouse; 18 | uniform float u_time; 19 | 20 | varying vec4 v_position; 21 | varying vec3 v_normal; 22 | 23 | #if defined(MODEL_VERTEX_TEXCOORD) 24 | varying vec2 v_texcoord; 25 | #endif 26 | 27 | #ifdef LIGHT_SHADOWMAP 28 | uniform sampler2D u_lightShadowMap; 29 | varying vec4 v_lightCoord; 30 | uniform mat4 u_lightMatrix; 31 | #endif 32 | #include "lygia/lighting/shadow.glsl" 33 | 34 | uniform mat4 u_viewMatrix; 35 | uniform mat4 u_projectionMatrix; 36 | #include "lygia/lighting/volumetricLightScattering.glsl" 37 | 38 | #define GAUSSIANBLUR_2D 39 | #define GAUSSIANBLUR_SAMPLER_FNC(TEX, UV) texture2D(TEX, clamp(UV, 0.001, .999)) 40 | #include "lygia/filter/gaussianBlur.glsl" 41 | 42 | void main(void) { 43 | vec4 color = vec4(1.0); 44 | vec2 pixel = 1.0/u_resolution; 45 | vec2 st = gl_FragCoord.xy * pixel; 46 | 47 | #if defined(BUFFER_0) 48 | color = texture2D(u_scene, st); 49 | float brightness = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); 50 | color.rgb *= smoothstep(0.0, 1., brightness); 51 | 52 | #elif defined(POSTPROCESSING) 53 | color.rgb = texture2D(u_scene, st).rgb * 0.9; 54 | color.rgb += gaussianBlur(u_buffer0, st, pixel * 8.0, 16).rgb * 0.25; 55 | color.rgb += volumetricLightScattering(u_sceneDepth, st) * 3.0; 56 | 57 | #else 58 | 59 | #if defined(FLOOR) 60 | vec2 uv = v_texcoord; 61 | color.rgb *= 0.5 + step(0.5, fract( (uv.x + uv.y) * 50.0)) * 0.5; 62 | #endif 63 | 64 | // Diffuse shading from directional light 65 | vec3 n = normalize(v_normal); 66 | vec3 l = normalize(u_light - v_position.xyz); 67 | color.rgb *= dot(n, l) * 0.5 + 0.5; 68 | color.rgb *= 0.8; 69 | 70 | color.rgb *= shadow(u_lightShadowMap, vec2(LIGHT_SHADOWMAP_SIZE), v_lightCoord.xy, v_lightCoord.z); 71 | #endif 72 | 73 | gl_FragColor = color; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /06_s_depth.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform sampler2D u_scene; 6 | uniform sampler2D u_sceneDepth; 7 | 8 | uniform vec3 u_camera; 9 | uniform float u_cameraNearClip; 10 | uniform float u_cameraFarClip; 11 | 12 | uniform vec3 u_light; 13 | 14 | uniform vec2 u_resolution; 15 | uniform vec2 u_mouse; 16 | uniform float u_time; 17 | 18 | varying vec4 v_position; 19 | varying vec4 v_color; 20 | varying vec3 v_normal; 21 | 22 | #if defined(MODEL_VERTEX_TEXCOORD) 23 | varying vec2 v_texcoord; 24 | #endif 25 | 26 | #include "lygia/space/linearizeDepth.glsl" 27 | #include "lygia/color/palette/heatmap.glsl" 28 | 29 | void main(void) { 30 | vec4 color = vec4(0.0, 0.0, 0.0, 1.0); 31 | vec2 pixel = 1.0/u_resolution; 32 | vec2 st = gl_FragCoord.xy * pixel; 33 | 34 | #if defined(POSTPROCESSING) 35 | float depth = linearizeDepth(texture2D(u_sceneDepth, st).r, u_cameraNearClip, u_cameraFarClip) / (length(u_camera) * 2.0); 36 | color.rgb += heatmap(depth); 37 | 38 | #else 39 | color = v_color; 40 | 41 | #if defined(FLOOR) 42 | #endif 43 | 44 | #endif 45 | 46 | gl_FragColor = color; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /06_s_normal.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform sampler2D u_scene; 6 | uniform sampler2D u_sceneNormal; 7 | 8 | uniform vec2 u_resolution; 9 | uniform vec2 u_mouse; 10 | uniform float u_time; 11 | 12 | varying vec4 v_position; 13 | varying vec4 v_color; 14 | varying vec3 v_normal; 15 | 16 | #if defined(MODEL_VERTEX_TEXCOORD) 17 | varying vec2 v_texcoord; 18 | #endif 19 | 20 | void main(void) { 21 | vec4 color = vec4(0.0, 0.0, 0.0, 1.0); 22 | vec2 pixel = 1.0/u_resolution; 23 | vec2 st = gl_FragCoord.xy * pixel; 24 | 25 | #if defined(POSTPROCESSING) 26 | color = texture2D(u_sceneNormal, st); 27 | 28 | #else 29 | color = v_color; 30 | 31 | #if defined(FLOOR) 32 | #endif 33 | 34 | #endif 35 | 36 | gl_FragColor = color; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /07_d_mt_pp.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform sampler2D u_scene; 6 | uniform sampler2D u_sceneDepth; 7 | uniform sampler2D u_sceneNormal; 8 | 9 | uniform sampler2D u_doubleBuffer0; 10 | 11 | uniform vec3 u_camera; 12 | uniform float u_cameraNearClip; 13 | uniform float u_cameraFarClip; 14 | uniform vec3 u_light; 15 | 16 | uniform vec2 u_resolution; 17 | uniform vec2 u_mouse; 18 | uniform float u_time; 19 | 20 | varying vec4 v_position; 21 | varying vec3 v_normal; 22 | 23 | #if defined(MODEL_VERTEX_TEXCOORD) 24 | varying vec2 v_texcoord; 25 | #endif 26 | 27 | #include "lygia/math/decimate.glsl" 28 | #include "lygia/color/palette/hue.glsl" 29 | #include "lygia/draw/digits.glsl" 30 | #define ARROWS_STYLE_LINE 31 | #include "lygia/draw/arrows.glsl" 32 | 33 | #include "lygia/space/linearizeDepth.glsl" 34 | #include "lygia/generative/curl.glsl" 35 | #define FBM_NOISE_TYPE vec3 36 | #define FBM_NOISE3_FNC(POS_UV) curl(POS_UV) 37 | #include "lygia/generative/fbm.glsl" 38 | 39 | #ifdef LIGHT_SHADOWMAP 40 | uniform sampler2D u_lightShadowMap; 41 | uniform mat4 u_lightMatrix; 42 | varying vec4 v_lightCoord; 43 | #endif 44 | #include "lygia/lighting/shadow.glsl" 45 | 46 | uniform mat4 u_viewMatrix; 47 | uniform mat4 u_projectionMatrix; 48 | #include "lygia/lighting/volumetricLightScattering.glsl" 49 | 50 | #include "lygia/color/luma.glsl" 51 | #include "lygia/math/mirror.glsl" 52 | 53 | void main(void) { 54 | vec4 color = vec4(0.0, 0.0, 0.0, 1.0); 55 | vec2 pixel = 1.0/u_resolution; 56 | vec2 st = gl_FragCoord.xy * pixel; 57 | 58 | vec3 normal = texture2D(u_sceneNormal, st).xyz; 59 | 60 | float pct = 1.0; 61 | pct = mirror(u_time * 0.5); 62 | 63 | #if defined(DOUBLE_BUFFER_0) 64 | vec2 st1 = st - normal.xy * pixel * 2.0; 65 | st1 += pixel * vec2(0.0, -1.0) * 2.0; 66 | st1 += pixel * fbm( vec3(st1 * 5., u_time) ).xy * 2.0; 67 | 68 | color = texture2D(u_doubleBuffer0, clamp(st1, vec2(0.001), vec2(0.999)) ) * 0.99; 69 | color.r = texture2D(u_doubleBuffer0, clamp(st1 - pixel, vec2(0.001), vec2(0.999)) ).r * 0.95; 70 | color.b = texture2D(u_doubleBuffer0, clamp(st1 + pixel, vec2(0.001), vec2(0.999)) ).b * 0.96; 71 | 72 | vec4 scene = texture2D(u_scene, st); 73 | color = mix(color, scene, luma(scene)); 74 | 75 | #elif defined(POSTPROCESSING) 76 | color.xyz = texture2D(u_doubleBuffer0, st).xyz; 77 | color.rgb += volumetricLightScattering(u_sceneDepth, st) * vec3(0., 3., 1.); 78 | 79 | #else 80 | 81 | // Diffuse shading from directional light 82 | vec3 n = normalize(v_normal); 83 | vec3 l = normalize(u_light - v_position.xyz); 84 | color.rgb += dot(n, l) * 0.5 + 0.5; 85 | 86 | color.rgb *= shadow(u_lightShadowMap, vec2(LIGHT_SHADOWMAP_SIZE), v_lightCoord.xy, v_lightCoord.z); 87 | 88 | #endif 89 | 90 | gl_FragColor = color; 91 | } 92 | 93 | -------------------------------------------------------------------------------- /08_d_d_mt.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | // position 6 | uniform sampler2D u_doubleBuffer0; // 512x512 7 | 8 | // velocity 9 | uniform sampler2D u_doubleBuffer1; // 512x512 10 | 11 | uniform vec2 u_resolution; 12 | uniform float u_time; 13 | uniform float u_delta; 14 | uniform int u_frame; 15 | 16 | varying vec4 v_color; 17 | varying vec2 v_texcoord; 18 | 19 | #include "lygia/math/decimate.glsl" 20 | #include "lygia/generative/srandom.glsl" 21 | #include "lygia/generative/snoise.glsl" 22 | #include "lygia/generative/curl.glsl" 23 | 24 | void main(void) { 25 | vec4 color = vec4(0.0); 26 | vec2 pixel = 1.0/ u_resolution; 27 | vec2 st = gl_FragCoord.xy * pixel; 28 | vec2 uv = v_texcoord; 29 | 30 | vec4 buff0 = texture2D(u_doubleBuffer0, uv); 31 | vec4 buff1 = texture2D(u_doubleBuffer1, uv); 32 | vec3 pos = buff0.xyz; 33 | vec3 vel = buff1.xyz; 34 | float life = buff0.a * 100.0; 35 | 36 | pos = u_frame < 1 ? srandom3(vec3(st, 1.0)) * 0.01 : pos; 37 | vel = u_frame < 1 ? curl(vec3(st,0.5)) : vel; 38 | life = u_frame < 1 ? uv.x * 10. + uv.y * 90. : life; 39 | 40 | #if defined(DOUBLE_BUFFER_0) 41 | pos += vel; 42 | life -= 0.003; 43 | 44 | if ( length( pos ) > 1.0 || life <= 0.0) 45 | pos = srandom3(pos + u_time); 46 | 47 | if (life <= 0.0) 48 | life = 100.0; 49 | 50 | color.rgb = pos; 51 | color.a = life * 0.01; 52 | 53 | #elif defined(DOUBLE_BUFFER_1) 54 | vel *= 0.5; 55 | vel += curl( pos + u_time * 0.1) * 0.3; 56 | 57 | float dist = length( pos ); 58 | 59 | // Repulsion from the very center of the space 60 | vel += normalize(pos) * 0.5 * (1.0 - dist) * step(dist, 0.01); 61 | 62 | // Atraction to the center of the space conform the leave 63 | vel += -normalize(pos) * 0.5 * pow(dist, 2.0); 64 | 65 | color.rgb = clamp(vel * u_delta, -0.999, 0.999);// * 0.5 + 0.5; 66 | color.a = 1.0; 67 | 68 | #else 69 | color = v_color; 70 | #endif 71 | 72 | gl_FragColor = color; 73 | } 74 | -------------------------------------------------------------------------------- /08_d_d_mt.vert: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | // Position 6 | uniform sampler2D u_doubleBuffer0; // 512x512 7 | 8 | // Velocity 9 | uniform sampler2D u_doubleBuffer1; // 512x512 10 | 11 | uniform mat4 u_modelMatrix; 12 | uniform mat4 u_viewMatrix; 13 | uniform mat4 u_projectionMatrix; 14 | uniform mat4 u_modelViewProjectionMatrix; 15 | uniform vec3 u_camera; 16 | uniform vec2 u_resolution; 17 | uniform float u_time; 18 | 19 | attribute vec4 a_position; 20 | varying vec4 v_position; 21 | 22 | varying vec4 v_color; 23 | varying vec2 v_texcoord; 24 | 25 | #include "lygia/math/decimate.glsl" 26 | 27 | void main(void) { 28 | 29 | vec2 uv = a_position.xy; 30 | vec2 buffRes = vec2(512.0); 31 | vec2 buffPixel = 1.0/buffRes; 32 | uv = decimate(uv, buffRes) + 0.5 * buffPixel; 33 | v_texcoord = uv; 34 | 35 | v_position = a_position; 36 | v_position.xyz = texture2D(u_doubleBuffer0, uv).xyz; 37 | v_position.xyz *= 10.0; 38 | 39 | v_color.rgb = texture2D(u_doubleBuffer1, uv).xyz; 40 | v_color.rgb = normalize(v_color.xyz) * 0.5 + 0.5; 41 | v_color.a = 1.0; 42 | 43 | gl_Position = u_projectionMatrix * u_viewMatrix * v_position; 44 | } 45 | -------------------------------------------------------------------------------- /09_cp_mt_pp.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform sampler2D u_scene; 6 | uniform sampler2D u_pyramid0; 7 | uniform vec3 u_camera; 8 | 9 | uniform vec3 u_light; 10 | uniform vec3 u_lightColor; 11 | 12 | uniform vec2 u_resolution; 13 | uniform vec2 u_mouse; 14 | uniform float u_time; 15 | 16 | varying vec4 v_position; 17 | varying vec4 v_color; 18 | varying vec3 v_normal; 19 | 20 | #if defined(MODEL_VERTEX_TEXCOORD) 21 | varying vec2 v_texcoord; 22 | #endif 23 | 24 | #include "lygia/color/space/linear2gamma.glsl" 25 | 26 | #define CAMERA_POSITION u_camera 27 | #define POSITION v_position 28 | 29 | #include "lygia/lighting/atmosphere.glsl" 30 | #define ENVMAP_FNC(NORM, ROUGHNESS, METALLIC) atmosphere(NORM, normalize(u_light)) 31 | 32 | #include "lygia/lighting/pbrLittle.glsl" 33 | #include "lygia/lighting/material/new.glsl" 34 | 35 | 36 | void main(void) { 37 | vec4 color = vec4(1.0); 38 | vec2 pixel = 1.0/u_resolution; 39 | vec2 st = gl_FragCoord.xy * pixel; 40 | 41 | #if defined(PYRAMID_0) 42 | color = texture2D(u_scene, st); 43 | 44 | #elif defined(POSTPROCESSING) 45 | color = texture2D(u_pyramid0, st); 46 | 47 | #else 48 | vec2 uv = v_texcoord; 49 | Material material = materialNew(); 50 | material.albedo = vec4(1.0); 51 | material.metallic = 0.9; 52 | material.roughness = 0.1; 53 | color = pbrLittle(material); 54 | color = linear2gamma(color); 55 | 56 | #endif 57 | 58 | 59 | gl_FragColor = color; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 00_platform: 2 | glslViewer 00_m_platform.frag -l 3 | 4 | 00_billboard: 5 | glslViewer 00_m.frag -l 6 | 7 | 01_material: 8 | glslViewer 01_mt.frag assets/skull.obj -l 9 | 10 | 02_background: 11 | glslViewer 02_bg_mt.frag assets/skull.obj -l 12 | 13 | 03_postprocessing: 14 | glslViewer 03_bg_mt_pp.frag assets/skull.obj -l 15 | 16 | 04_floor: 17 | glslViewer 04_mt_fl_l.frag assets/skull.obj -l 18 | 19 | 04_pbr: 20 | glslViewer 04_mt_fl_l-pbr.frag assets/skull.obj -l 21 | 22 | 05_multiple_materials: 23 | glslViewer 05_mt_mt.vert 05_mt_mt.frag assets/skull.obj -l 24 | 25 | 06_buffer: 26 | glslViewer 06_b_mt.vert 06_b_mt.frag assets/skull.obj -l 27 | 28 | 06a_scene_depth: 29 | glslViewer 06_s_depth.frag assets/skull.obj -l 30 | 31 | 06a_scene_normal: 32 | glslViewer 06_s_normal.frag assets/skull.obj -l 33 | 34 | 06a_buffer_postprocessing: 35 | glslViewer 06_b_mt_pp.frag assets/skull.obj -l 36 | 37 | 07_doubleBuffer: 38 | glslViewer 07_d_mt_pp.frag assets/skull.obj -l 39 | 40 | 08_doubleDoubleBuffer: 41 | glslViewer 08_d_d_mt.vert 08_d_d_mt.frag assets/pcl.ply -l 42 | 43 | 09_convolutionPyramid: 44 | glslViewer 09_cp_mt_pp.frag assets/skull.obj -l 45 | 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## SHADER PROTOTYPING 2022 2 | 3 | 4 | ### Before the course 5 | 6 | 1. Make sure to clone this repository and their submodules recursivelly 7 | 8 | ```bash 9 | git clone --recursive https://github.com/ShaderCamp/shader_prototyping_2022.git 10 | ``` 11 | 12 | If you already clone it with out the `--recursive` flag, just do 13 | 14 | ```bash 15 | git pull 16 | git submodule init 17 | git submodule update 18 | ``` 19 | 20 | 2. Make sure you have compiled and installed GlslViewer from source following the instructions of you system of choise: 21 | 22 | * [Compile on Linux](https://github.com/patriciogonzalezvivo/glslViewer/wiki/Compile-on-linux) 23 | * [Compile on MacOS](https://github.com/patriciogonzalezvivo/glslViewer/wiki/Compile-on-MacOS) 24 | * [Compile on Windows](https://github.com/patriciogonzalezvivo/glslViewer/wiki/Compile-on-Windows) 25 | 26 | ### The course 27 | 28 | We will start by doing a fast recap of the difference between 2D and 3D shaders, to then load a simple geometry: 29 | 30 | ```bash 31 | make 01_material 32 | ``` 33 | 34 | or 35 | 36 | ```bash 37 | glslViewer 01_mt.frag assets/skull.obj -l 38 | ``` 39 | 40 | We will iterate on it adding and modifying different render passes each one with a unique notation so then it's easier to structure any pipeline: 41 | 42 | * **M** main shader (2D): when loaded only a `.frag` file or and image or video. 43 | * **Mt** material shader (3D): when loaded a `.vert` or geometry file (`.ply`/`.obj`/`.glb`/`.gltf`) 44 | * **Bg** Background shader (2D): forked using `BACKGROUND` define keyword 45 | * **Pp** Post Processing shader (2D): forked using `POSTPROCESSING` define keyword renders the entire scene into a FBO call `u_scene` and `u_sceneDepth`. 46 | * **Fl** Floor Material (3D): creates a floor plane when `FLOOR` define keyword is present and fork the shader adding that keyword as a define to it. 47 | * **L** Light's shadowMap (2D): when uniform sampler2D `u_lightShadowMap` is present create a depth pass from the perspective of the light (`vec3 u_light` and `mat4 u_lightMatrix`). 48 | * **B** Buffer (2D): when define keyword `BUFFER_` is present, forks the shader to render a 2D pass inside FBO named `u_buffer` 49 | * **D** Doubple buffer (2D): when define keyword `DOUBLE_BUFFER_` is present, forks the shader to render a 2D pass inside a double FBO named `u_doubleBuffer`. This double buffer it's also know as PingPong, where after each pass the pare is swap, allowing for feedback passing their own content in it self. 50 | * **Cp** Convolution pyramid(2D): when define keyword `CONVOLUTION_PYRAMID_` is present, forks the shader to render a 2D pass inside a FBO to be prosses according to [this paper](https://pages.cs.huji.ac.il/danix-lab/cglab/projects/convpyr/data/convpyr-small.pdf) and delivered through `u_pyramid`. 51 | * **Gn** G Buffer Normal (3D>2D): when uniform sampler2D `u_sceneNormal` is present creates a g buffer of the 3D scene normals in screenspace 52 | * **Gp** G Buffer Position (3D>2D): when uniform sampler2D `u_sceneNPosition` is present creates a g buffer of the 3D scene position in screenspace 53 | 54 | ## Examples 55 | 56 | ```bash 57 | make 00_platform 58 | 59 | make 00_billboard 60 | 61 | make 01_material 62 | 63 | make 02_background 64 | 65 | make 03_postprocessing 66 | 67 | make 04_floor 68 | 69 | make 04_pbr 70 | 71 | make 05_multiple_materials 72 | 73 | make 06_buffer 74 | 75 | make 06a_scene_depth 76 | 77 | make 06a_scene_normal 78 | 79 | make 06a_buffer_postprocessing 80 | 81 | make 07_doubleBuffer 82 | 83 | make 08_doubleDoubleBuffer 84 | 85 | make 09_convolutionPyramid 86 | ``` -------------------------------------------------------------------------------- /assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShaderCamp/shader_prototyping_2022/c40405741b32033c46f8f536dc895808368a7654/assets/.DS_Store -------------------------------------------------------------------------------- /assets/danny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShaderCamp/shader_prototyping_2022/c40405741b32033c46f8f536dc895808368a7654/assets/danny.png -------------------------------------------------------------------------------- /assets/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShaderCamp/shader_prototyping_2022/c40405741b32033c46f8f536dc895808368a7654/assets/default.png -------------------------------------------------------------------------------- /assets/skull.mtl: -------------------------------------------------------------------------------- 1 | # Blender 3.3.1 MTL File: 'None' 2 | # www.blender.org 3 | 4 | newmtl default.001 5 | Ns 10.000005 6 | Ka 1.000000 1.000000 1.000000 7 | Ks 0.200000 0.200000 0.200000 8 | Ke 0.000000 0.000000 0.000000 9 | Ni 1.500000 10 | d 1.000000 11 | illum 2 12 | map_Kd skull.png 13 | -------------------------------------------------------------------------------- /assets/skull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShaderCamp/shader_prototyping_2022/c40405741b32033c46f8f536dc895808368a7654/assets/skull.png --------------------------------------------------------------------------------