├── .gitattributes ├── .gitignore ├── Custom2DGeometry └── Custom2DGeometry.pde ├── Custom3DGeometry ├── Custom3DGeometry.pde └── Pyramid.pde ├── DynamicTextures2D ├── DynamicTextures2D.pde └── data │ └── image.jpg ├── FixedMovingTextures2D └── FixedMovingTextures2D.pde ├── GLSL_Heightmap ├── GLSL_Heightmap.pde └── data │ ├── displaceFrag.glsl │ └── displaceVert.glsl ├── GLSL_HeightmapNoise ├── GLSL_HeightmapNoise.pde └── data │ ├── displaceFrag.glsl │ └── displaceVert.glsl ├── GLSL_SphereDisplacement ├── GLSL_SphereDisplacement.pde ├── Icosahedron.pde └── data │ ├── displaceFrag.glsl │ └── displaceVert.glsl ├── GLSL_SphereDisplacementNoise ├── GLSL_SphereDisplacementNoise.pde ├── Icosahedron.pde └── data │ ├── displaceFrag.glsl │ └── displaceVert.glsl ├── GLSL_TextureMix ├── GLSL_TextureMix.pde └── data │ ├── textureMixFrag.glsl │ └── textureMixVert.glsl ├── MultiTexturedSphereGLSL ├── Icosahedron.pde ├── MultiTexturedSphereGLSL.pde └── data │ ├── earthcloudmap.jpg │ ├── earthlights1k.jpg │ ├── earthmap1k.jpg │ ├── earthspec1k.jpg │ ├── shaderFrag.glsl │ └── shaderVert.glsl ├── README.md ├── Texture2DAnimation ├── Texture2DAnimation.pde └── data │ └── animation.png ├── TexturedSphere ├── Icosahedron.pde ├── TexturedSphere.pde └── data │ └── world32k.jpg ├── TexturedSphereGLSL ├── Icosahedron.pde ├── TexturedSphereGLSL.pde └── data │ ├── shaderFrag.glsl │ ├── shaderVert.glsl │ └── world32k.jpg └── _Images ├── Attribution.txt ├── Texture01.jpg ├── Texture02.jpg └── Texture03.jpg /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /Custom2DGeometry/Custom2DGeometry.pde: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Custom 2D Geometry by Amnon Owed (May 2013) 5 | https://github.com/AmnonOwed 6 | http://vimeo.com/amnon 7 | 8 | Creating a custom 2D shape using vertices, beginShape & endShape. 9 | For more information about Shapes see: http://processing.org/reference/beginShape_.html 10 | This example also displays OpenGL's automatic color interpolation between vertices. 11 | 12 | Built with Processing 2.0b8 / 2.0b9 / 2.0 Final 13 | 14 | */ 15 | 16 | color[] colors = new color[100]; // array to store a selection of random colors 17 | PGraphics bg; // PGraphics that holds the static background (grid + names) 18 | float fc1, fc2; // global variables used by all vertices for their dynamic movement 19 | 20 | void setup() { 21 | size(1200, 800, P3D); // use the P3D OpenGL renderer 22 | createBackground(); // create the background PGraphics once, so it can be used in draw() continuously 23 | randomColors(); // generate the first set of random colors 24 | smooth(6); // set smooth level 6 (default is 2) 25 | } 26 | 27 | void draw() { 28 | image(bg, 0, 0); // draw the background PGraphics 29 | 30 | if (frameCount%240==0) { randomColors(); } // generate random colors every 240th frame 31 | 32 | translate(width/6, height/4); // uniform translate to center the Shapes in each cell 33 | 34 | // calculate fc1 and fc2 once per draw(), since they are used for the dynamic movement of each drawn vertex 35 | fc1 = frameCount*0.01; 36 | fc2 = frameCount*0.02; 37 | 38 | // draw all the Shapes using the custom drawShape() method 39 | drawShape(0, 0, LINES, 75, 150, 33); 40 | drawShape(width/3, 0, TRIANGLES, 75, 150, 20); 41 | drawShape(width/3, 0, POINTS, 75, 150, 20); 42 | drawShape(2*width/3, 0, TRIANGLE_FAN, 75, 150, 7); 43 | drawShape(0, height/2, QUAD_STRIP, 75, 150, 6); 44 | drawShape(width/3, height/2, TRIANGLE_STRIP, 75, 150, 17); 45 | drawShape(2*width/3, height/2, QUADS, 75, 150, 16); 46 | } 47 | 48 | // custom drawShape() method with input parameters for the location, shapeMode, diameters and number of segments 49 | void drawShape(int x, int y, int mode, float diam_inner, float diam_outer, int numSegments) { 50 | pushMatrix(); // use push/popMatrix so each Shape's translation does not affect other drawings 51 | translate(x, y); 52 | if (mode==POINTS || mode==LINES) { 53 | // for POINTS and LINES use a white, extra thick stroke 54 | strokeWeight(2); 55 | stroke(255); 56 | } else if (mode==QUAD_STRIP || mode==TRIANGLE_STRIP) { 57 | // for QUAD_STRIP and TRIANGLE_STRIP use a white, regular stroke 58 | strokeWeight(1); 59 | stroke(255); 60 | } else { 61 | // for all other shapeModes do not use stroke 62 | noStroke(); 63 | } 64 | beginShape(mode); // input the shapeMode in the beginShape() call 65 | if (mode==TRIANGLE_FAN) { vertex(0, 0); } // for the TRIANGLE_FAN a central point is important 66 | float step = TWO_PI/numSegments; // generate the step size based on the number of segments 67 | for (int i=0; i shapes = new ArrayList (); // arrayList to store all the shapes 23 | boolean bLights, bWhitebackground; // booleans for toggling lights and background 24 | 25 | void setup() { 26 | size(1280, 720, P3D); // use the P3D OpenGL renderer 27 | noStroke(); // turn off stroke (for the rest of the sketch) 28 | smooth(6); // set smooth level 6 (default is 2) 29 | // create all the shapes with a certain radius and height 30 | for (int i=0; i 750) { z = -5000; reset(); } // if beyond the camera, reset() and start again 33 | transparency = z<-2500?map(z, -5000, -2500, 0, 255):255; // far away slowly increase the transparency, within range is fully opaque 34 | } 35 | 36 | // displays the shape 37 | void display() { 38 | pushMatrix(); // use push/popMatrix so each Shape's translation/rotation does not affect other drawings 39 | 40 | // move and rotate the shape as a whole 41 | translate(x, y, z); // translate to the position of the shape 42 | rotateY(x + frameCount*0.01); // rotate around the Y axis based on the x position and frameCount 43 | rotateX(y + frameCount*0.02); // rotate around the X axis based on the y position and frameCount 44 | 45 | // draw the 4 side triangles of the pyramid, each connected to the top of the pyramid 46 | beginShape(TRIANGLE_FAN); // TRIANGLE_FAN is suited for this, it starts with the center point c[0] 47 | for (int i=0; i<5; i++) { 48 | fill(c[i], transparency); // use the color, but with the given z-based transparency 49 | vertex(v[i].x, v[i].y, v[i].z); // set the vertices based on the object coordinates defined in the createShape() method 50 | } 51 | // add the 'first base vertex' to close the shape 52 | fill(c[1], transparency); 53 | vertex(v[1].x, v[1].y, v[1].z); 54 | endShape(); // finalize the Shape 55 | 56 | // draw the base QUAD of the pyramid 57 | fill(c[1], transparency); // use a single color (optional: for vertex colors you can also put this in the for loop) 58 | beginShape(QUADS); // it's a QUAD so the QUADS shapeMode is the most suitable 59 | for (int i=1; i<5; i++) { 60 | vertex(v[i].x, v[i].y, v[i].z); // the 4 base points 61 | } 62 | endShape(); // finalize the Shape 63 | 64 | popMatrix(); // use push/popMatrix so each Shape's translation/rotation does not affect other drawings 65 | } 66 | 67 | // randomly sets the xy position of the shape as a whole and the colors of the shape 68 | void reset() { 69 | x = random(-2*width, 3*width); // set the x position 70 | y = random(-height, 2*height); // set the y position 71 | c[0] = color(random(150, 255), random(150, 255), random(150, 255)); // set the top color (a bit lighter) 72 | // randomly set the 4 colors in the base of the shape 73 | for (int i=1; i<5; i++) { 74 | c[i] = color(random(255), random(255), random(255)); // random RGB color 75 | } 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /DynamicTextures2D/DynamicTextures2D.pde: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Dynamic Textures 2D by Amnon Owed (May 2013) 5 | https://github.com/AmnonOwed 6 | http://vimeo.com/amnon 7 | 8 | Creating textured QUADS with dynamically generated texture coordinates. 9 | With the OpenGL renderer this can be done at interactive framerates. 10 | 11 | HORIZONTAL MOUSE MOVE = change the density of the grid 12 | 13 | Built with Processing 2.0b8 / 2.0b9 / 2.0 Final 14 | 15 | */ 16 | 17 | int DIM, NUMQUADS; // variables to hold the grid dimensions and total grid size 18 | PImage img; // the image 19 | 20 | void setup() { 21 | img = loadImage("image.jpg"); // load the image (from the /data subdirectory) 22 | size(img.width*2, img.height, P2D); // set the width of the sketch to twice the image width 23 | textureMode(NORMAL); // use normalized (0 to 1) texture coordinates 24 | noStroke(); // turn off stroke (for the rest of the sketch) 25 | smooth(6); // set smooth level 6 (default is 2) 26 | } 27 | 28 | void draw() { 29 | DIM = (int) map(mouseX, 0,width, 1, 40); // set DIM in the range from 1 to 40 according to mouseX 30 | NUMQUADS = DIM*DIM; // calculate the total number of cells in the grid 31 | beginShape(QUAD); // draw a Shape of QUADS 32 | texture(img); // use the image as a texture 33 | // draw all the QUADS in the grid... 34 | for (int i=0; i positions = new ArrayList (); // arrayList to hold positions 76 | ArrayList texCoords = new ArrayList (); // arrayList to hold texture coordinates 77 | 78 | float usegsize = 1 / (float) xsegs; // horizontal stepsize 79 | float vsegsize = 1 / (float) ysegs; // vertical stepsize 80 | 81 | for (int x=0; x= 1) { imgCopy.filter(BLUR, blurFactor); } // apply blur 131 | return imgCopy; 132 | } 133 | 134 | void keyPressed() { 135 | if (key == 'c') { currentColorMap = ++currentColorMap%colorMaps.length; resetMaps(); } // cycle through colorMaps (set variable and call resetMaps() method) 136 | if (key == 'd') { currentDisplacementMap = ++currentDisplacementMap%displacementMaps.length; resetMaps(); } // cycle through displacementMaps (set variable and call resetMaps() method) 137 | } 138 | 139 | -------------------------------------------------------------------------------- /GLSL_Heightmap/data/displaceFrag.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform sampler2D colorMap; 3 | 4 | varying vec4 vertTexCoord; 5 | 6 | void main() { 7 | gl_FragColor = texture2D(colorMap, vertTexCoord.st); 8 | } 9 | -------------------------------------------------------------------------------- /GLSL_Heightmap/data/displaceVert.glsl: -------------------------------------------------------------------------------- 1 | 2 | #define PROCESSING_TEXLIGHT_SHADER 3 | 4 | uniform mat4 modelview; 5 | uniform mat4 transform; 6 | uniform mat3 normalMatrix; 7 | uniform mat4 texMatrix; 8 | 9 | uniform int lightCount; 10 | uniform vec4 lightPosition[8]; 11 | uniform vec3 lightNormal[8]; 12 | uniform vec3 lightAmbient[8]; 13 | uniform vec3 lightDiffuse[8]; 14 | uniform vec3 lightSpecular[8]; 15 | uniform vec3 lightFalloff[8]; 16 | uniform vec2 lightSpot[8]; 17 | 18 | attribute vec4 vertex; 19 | attribute vec4 color; 20 | attribute vec3 normal; 21 | attribute vec2 texCoord; 22 | 23 | attribute vec4 ambient; 24 | attribute vec4 specular; 25 | attribute vec4 emissive; 26 | attribute float shininess; 27 | 28 | varying vec4 vertColor; 29 | varying vec4 vertTexCoord; 30 | 31 | const float zero_float = 0.0; 32 | const float one_float = 1.0; 33 | const vec3 zero_vec3 = vec3(0); 34 | 35 | uniform sampler2D displacementMap; 36 | uniform float displaceStrength; 37 | 38 | float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) { 39 | vec3 lpv = lightPos - vertPos; 40 | vec3 dist = vec3(one_float); 41 | dist.z = dot(lpv, lpv); 42 | dist.y = sqrt(dist.z); 43 | return one_float / dot(dist, coeff); 44 | } 45 | 46 | float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) { 47 | vec3 lpv = normalize(lightPos - vertPos); 48 | vec3 nln = -one_float * lightNorm; 49 | float spotCos = dot(nln, lpv); 50 | return spotCos <= minCos ? zero_float : pow(spotCos, spotExp); 51 | } 52 | 53 | float lambertFactor(vec3 lightDir, vec3 vecNormal) { 54 | return max(zero_float, dot(lightDir, vecNormal)); 55 | } 56 | 57 | float blinnPhongFactor(vec3 lightDir, vec3 vertPos, vec3 vecNormal, float shine) { 58 | vec3 np = normalize(vertPos); 59 | vec3 ldp = normalize(lightDir - np); 60 | return pow(max(zero_float, dot(ldp, vecNormal)), shine); 61 | } 62 | 63 | void main() { 64 | // Calculating texture coordinates, with r and q set both to one 65 | vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0); 66 | 67 | vec4 dv = texture2D( displacementMap, vertTexCoord.st ); // rgba color of displacement map 68 | float df = 0.30*dv.r + 0.59*dv.g + 0.11*dv.b; // brightness calculation to create displacement float from rgb values 69 | vec4 newVertexPos = vertex + vec4(normal * df * displaceStrength, 0.0); // regular vertex position + direction * displacementMap * displaceStrength 70 | 71 | // Vertex in clip coordinates 72 | gl_Position = transform * newVertexPos; 73 | 74 | // Vertex in eye coordinates 75 | vec3 ecVertex = vec3(modelview * vertex); 76 | 77 | // Normal vector in eye coordinates 78 | vec3 ecNormal = normalize(normalMatrix * normal); 79 | 80 | if (dot(-one_float * ecVertex, ecNormal) < zero_float) { 81 | // If normal is away from camera, choose its opposite. 82 | // If we add backface culling, this will be backfacing 83 | ecNormal *= -one_float; 84 | } 85 | 86 | // Light calculations 87 | vec3 totalAmbient = vec3(0, 0, 0); 88 | vec3 totalDiffuse = vec3(0, 0, 0); 89 | vec3 totalSpecular = vec3(0, 0, 0); 90 | for (int i = 0; i < 8; i++) { 91 | if (lightCount == i) break; 92 | 93 | vec3 lightPos = lightPosition[i].xyz; 94 | bool isDir = zero_float < lightPosition[i].w; 95 | float spotCos = lightSpot[i].x; 96 | float spotExp = lightSpot[i].y; 97 | 98 | vec3 lightDir; 99 | float falloff; 100 | float spotf; 101 | 102 | if (isDir) { 103 | falloff = one_float; 104 | lightDir = -one_float * lightNormal[i]; 105 | } else { 106 | falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]); 107 | lightDir = normalize(lightPos - ecVertex); 108 | } 109 | 110 | spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], 111 | spotCos, spotExp) 112 | : one_float; 113 | 114 | if (any(greaterThan(lightAmbient[i], zero_vec3))) { 115 | totalAmbient += lightAmbient[i] * falloff; 116 | } 117 | 118 | if (any(greaterThan(lightDiffuse[i], zero_vec3))) { 119 | totalDiffuse += lightDiffuse[i] * falloff * spotf * 120 | lambertFactor(lightDir, ecNormal); 121 | } 122 | 123 | if (any(greaterThan(lightSpecular[i], zero_vec3))) { 124 | totalSpecular += lightSpecular[i] * falloff * spotf * 125 | blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess); 126 | } 127 | } 128 | 129 | // Calculating final color as result of all lights (plus emissive term). 130 | // Transparency is determined exclusively by the diffuse component. 131 | vertColor = vec4(totalAmbient, 0) * ambient + 132 | vec4(totalDiffuse, 1) * color + 133 | vec4(totalSpecular, 0) * specular + 134 | vec4(emissive.rgb, 0); 135 | 136 | } 137 | -------------------------------------------------------------------------------- /GLSL_HeightmapNoise/GLSL_HeightmapNoise.pde: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Noise-Based GLSL Heightmap by Amnon Owed (May 2013) 5 | https://github.com/AmnonOwed 6 | http://vimeo.com/amnon 7 | 8 | Creating a GLSL heightmap running on shader-based procedural noise. 9 | 10 | c = cycle through the color maps 11 | 12 | Built with Processing 2.0b8 / 2.0b9 / 2.0 Final 13 | 14 | Photographs by Folkert Gorter (@folkertgorter / http://superfamous.com/) made available under a CC Attribution 3.0 license. 15 | 16 | */ 17 | 18 | int dim = 300; // the grid dimensions of the heightmap 19 | int blurFactor = 3; // the blur for the displacement map (to make it smoother) 20 | float resizeFactor = 0.25; // the resize factor for the displacement map (to make it smoother) 21 | float displaceStrength = 0.25; // the displace strength of the GLSL shader displacement effect 22 | 23 | PShape heightMap; // PShape to hold the geometry, textures, texture coordinates etc. 24 | PShader displace; // GLSL shader 25 | 26 | PImage[] images = new PImage[2]; // array to hold 2 input images 27 | int currentColorMap; // variable to keep track of the current colorMap 28 | 29 | void setup() { 30 | size(1280, 720, P3D); // use the P3D OpenGL renderer 31 | 32 | // load the images from the _Images folder (relative path from this sketch's folder) 33 | images[0] = loadImage("../_Images/Texture01.jpg"); 34 | images[1] = loadImage("../_Images/Texture02.jpg"); 35 | 36 | displace = loadShader("displaceFrag.glsl", "displaceVert.glsl"); // load the PShader with a fragment and a vertex shader 37 | displace.set("displaceStrength", displaceStrength); // set the displaceStrength 38 | displace.set("colorMap", images[currentColorMap]); // set the initial colorMap 39 | 40 | heightMap = createPlane(dim, dim); // create the heightmap PShape (see custom creation method) and put it in the global heightMap reference 41 | } 42 | 43 | void draw() { 44 | pointLight(255, 255, 255, 2*(mouseX-width/2), 2*(mouseY-height/2), 500); // required for texLight shader 45 | 46 | translate(width/2, height/2); // translate to center of the screen 47 | rotateX(radians(60)); // fixed rotation of 60 degrees over the X axis 48 | rotateZ(frameCount*0.005); // dynamic frameCount-based rotation over the Z axis 49 | 50 | background(0); // black background 51 | perspective(PI/3.0, (float) width/height, 0.1, 1000000); // perspective for close shapes 52 | scale(750); // scale by 750 (the model itself is unit length 53 | 54 | displace.set("time", millis()/5000.0); // feed time to the GLSL shader 55 | shader(displace); // use shader 56 | shape(heightMap); // display the PShape 57 | 58 | // write the fps and the current colorMap in the top-left of the window 59 | frame.setTitle(" " + int(frameRate) + " | colorMap: " + currentColorMap); 60 | } 61 | 62 | // custom method to create a PShape plane with certain xy dimensions 63 | PShape createPlane(int xsegs, int ysegs) { 64 | 65 | // STEP 1: create all the relevant data 66 | 67 | ArrayList positions = new ArrayList (); // arrayList to hold positions 68 | ArrayList texCoords = new ArrayList (); // arrayList to hold texture coordinates 69 | 70 | float usegsize = 1 / (float) xsegs; // horizontal stepsize 71 | float vsegsize = 1 / (float) ysegs; // vertical stepsize 72 | 73 | for (int x=0; x x0.y ? 1.0 : 0.0 91 | //i1.y = 1.0 - i1.x; 92 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 93 | // x0 = x0 - 0.0 + 0.0 * C.xx ; 94 | // x1 = x0 - i1 + 1.0 * C.xx ; 95 | // x2 = x0 - 1.0 + 2.0 * C.xx ; 96 | vec4 x12 = x0.xyxy + C.xxzz; 97 | x12.xy -= i1; 98 | 99 | // Permutations 100 | i = mod289(i); // Avoid truncation effects in permutation 101 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) 102 | + i.x + vec3(0.0, i1.x, 1.0 )); 103 | 104 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); 105 | m = m*m ; 106 | m = m*m ; 107 | 108 | // Gradients: 41 points uniformly over a line, mapped onto a diamond. 109 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) 110 | 111 | vec3 x = 2.0 * fract(p * C.www) - 1.0; 112 | vec3 h = abs(x) - 0.5; 113 | vec3 ox = floor(x + 0.5); 114 | vec3 a0 = x - ox; 115 | 116 | // Normalise gradients implicitly by scaling m 117 | // Approximation of: m *= inversesqrt( a0*a0 + h*h ); 118 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); 119 | 120 | // Compute final noise value at P 121 | vec3 g; 122 | g.x = a0.x * x0.x + h.x * x0.y; 123 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 124 | return 130.0 * dot(m, g); 125 | } 126 | 127 | void main() { 128 | // Calculating texture coordinates, with r and q set both to one 129 | vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0); 130 | 131 | vec2 p = texCoord; // put coordinates into vec2 p for convenience 132 | p.x += time; // add time to make the noise and the subsequent displacement move 133 | float df = snoise( p ); // create displacement float value from shader-based 2D Perlin noise 134 | vec4 newVertexPos = vertex + vec4(normal * df * displaceStrength, 0.0); // regular vertex position + direction * displacementMap * displaceStrength 135 | 136 | // Vertex in clip coordinates 137 | gl_Position = transform * newVertexPos; 138 | 139 | // Vertex in eye coordinates 140 | vec3 ecVertex = vec3(modelview * vertex); 141 | 142 | // Normal vector in eye coordinates 143 | vec3 ecNormal = normalize(normalMatrix * normal); 144 | 145 | if (dot(-one_float * ecVertex, ecNormal) < zero_float) { 146 | // If normal is away from camera, choose its opposite. 147 | // If we add backface culling, this will be backfacing 148 | ecNormal *= -one_float; 149 | } 150 | 151 | // Light calculations 152 | vec3 totalAmbient = vec3(0, 0, 0); 153 | vec3 totalDiffuse = vec3(0, 0, 0); 154 | vec3 totalSpecular = vec3(0, 0, 0); 155 | for (int i = 0; i < 8; i++) { 156 | if (lightCount == i) break; 157 | 158 | vec3 lightPos = lightPosition[i].xyz; 159 | bool isDir = zero_float < lightPosition[i].w; 160 | float spotCos = lightSpot[i].x; 161 | float spotExp = lightSpot[i].y; 162 | 163 | vec3 lightDir; 164 | float falloff; 165 | float spotf; 166 | 167 | if (isDir) { 168 | falloff = one_float; 169 | lightDir = -one_float * lightNormal[i]; 170 | } else { 171 | falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]); 172 | lightDir = normalize(lightPos - ecVertex); 173 | } 174 | 175 | spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], 176 | spotCos, spotExp) 177 | : one_float; 178 | 179 | if (any(greaterThan(lightAmbient[i], zero_vec3))) { 180 | totalAmbient += lightAmbient[i] * falloff; 181 | } 182 | 183 | if (any(greaterThan(lightDiffuse[i], zero_vec3))) { 184 | totalDiffuse += lightDiffuse[i] * falloff * spotf * 185 | lambertFactor(lightDir, ecNormal); 186 | } 187 | 188 | if (any(greaterThan(lightSpecular[i], zero_vec3))) { 189 | totalSpecular += lightSpecular[i] * falloff * spotf * 190 | blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess); 191 | } 192 | } 193 | 194 | // Calculating final color as result of all lights (plus emissive term). 195 | // Transparency is determined exclusively by the diffuse component. 196 | vertColor = vec4(totalAmbient, 0) * ambient + 197 | vec4(totalDiffuse, 1) * color + 198 | vec4(totalSpecular, 0) * specular + 199 | vec4(emissive.rgb, 0); 200 | 201 | } 202 | -------------------------------------------------------------------------------- /GLSL_SphereDisplacement/GLSL_SphereDisplacement.pde: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | GLSL Sphere Displacement by Amnon Owed (May 2013) 5 | https://github.com/AmnonOwed 6 | http://vimeo.com/amnon 7 | 8 | Creating a sphere by subdividing an icosahedron. Storing it in a PShape. 9 | Displacing it outwards with GLSL (fragment and vertex) shaders based on input textures. 10 | The input textures for both the color and the displacement can be changed in realtime. 11 | 12 | c = cycle through the color maps 13 | d = cycle through the displacement maps 14 | 15 | Built with Processing 2.0b8 / 2.0b9 / 2.0 Final 16 | 17 | Photographs by Folkert Gorter (@folkertgorter / http://superfamous.com/) made available under a CC Attribution 3.0 license. 18 | 19 | */ 20 | 21 | int subdivisionLevel = 8; // number of times the icosahedron will be subdivided 22 | int dim = 300; // the grid dimensions of the heightmap 23 | int blurFactor = 3; // the blur for the displacement map (to make it smoother) 24 | float resizeFactor = 0.2; // the resize factor for the displacement map (to make it smoother) 25 | float displaceStrength = 3.5; // the displace strength of the GLSL shader displacement effect 26 | 27 | PShape sphere; // PShape to hold the geometry, textures, texture coordinates etc. 28 | PShader displace; // GLSL shader 29 | 30 | PImage[] colorMaps = new PImage[3]; // array to hold 3 colorMaps 31 | PImage[] displacementMaps = new PImage[3]; // array to hold 3 displacementMap 32 | int currentColorMap, currentDisplacementMap = 2; // variables to keep track of the current maps (also used for setting them) 33 | 34 | void setup() { 35 | size(1280, 720, P3D); // use the P3D OpenGL renderer 36 | 37 | // load the images from the _Images folder (relative path from this sketch's folder) 38 | colorMaps[0] = loadImage("../_Images/Texture01.jpg"); 39 | colorMaps[1] = loadImage("../_Images/Texture02.jpg"); 40 | colorMaps[2] = loadImage("../_Images/Texture03.jpg"); 41 | 42 | // create the displacement maps from the images 43 | displacementMaps[0] = imageToDisplacementMap(colorMaps[0]); 44 | displacementMaps[1] = imageToDisplacementMap(colorMaps[1]); 45 | displacementMaps[2] = imageToDisplacementMap(colorMaps[2]); 46 | 47 | displace = loadShader("displaceFrag.glsl", "displaceVert.glsl"); // load the PShader with a fragment and a vertex shader 48 | displace.set("displaceStrength", displaceStrength); // set the displaceStrength 49 | resetMaps(); // set the color and displacement maps 50 | sphere = createIcosahedron(subdivisionLevel); // create the subdivided icosahedron PShape (see custom creation method) and put it in the global sphere reference 51 | } 52 | 53 | void draw() { 54 | pointLight(255, 255, 255, 2*(mouseX-width/2), 2*(mouseY-height/2), 500); // required for texLight shader 55 | 56 | translate(width/2, height/2); // translate to center of the screen 57 | rotateX(radians(60)); // fixed rotation of 60 degrees over the X axis 58 | rotateZ(frameCount*0.01); // dynamic frameCount-based rotation over the Z axis 59 | 60 | background(0); // black background 61 | perspective(PI/3.0, (float) width/height, 0.1, 1000000); // perspective for close shapes 62 | scale(100); // scale by 100 63 | 64 | shader(displace); // use shader 65 | shape(sphere); // display the PShape 66 | 67 | // write the fps, the current colorMap and the current displacementMap in the top-left of the window 68 | frame.setTitle(" " + int(frameRate) + " | colorMap: " + currentColorMap + " | displacementMap: " + currentDisplacementMap); 69 | } 70 | 71 | // a separate resetMaps() method, so the images can be change dynamically 72 | void resetMaps() { 73 | displace.set("colorMap", colorMaps[currentColorMap]); 74 | displace.set("displacementMap", displacementMaps[currentDisplacementMap]); 75 | } 76 | 77 | // convenience method to create a smooth displacementMap 78 | PImage imageToDisplacementMap(PImage img) { 79 | PImage imgCopy = img.get(); // get a copy so the original remains intact 80 | imgCopy.resize(int(imgCopy.width*resizeFactor), int(imgCopy.height*resizeFactor)); // resize 81 | if (blurFactor >= 1) { imgCopy.filter(BLUR, blurFactor); } // apply blur 82 | return imgCopy; 83 | } 84 | 85 | void keyPressed() { 86 | if (key == 'c') { currentColorMap = ++currentColorMap%colorMaps.length; resetMaps(); } // cycle through colorMaps (set variable and call resetMaps() method) 87 | if (key == 'd') { currentDisplacementMap = ++currentDisplacementMap%displacementMaps.length; resetMaps(); } // cycle through displacementMaps (set variable and call resetMaps() method) 88 | } 89 | 90 | -------------------------------------------------------------------------------- /GLSL_SphereDisplacement/Icosahedron.pde: -------------------------------------------------------------------------------- 1 | 2 | // ported to Processing 2.0b8 by Amnon Owed (10/05/2013) 3 | // from code by Gabor Papp (13/03/2010): http://git.savannah.gnu.org/cgit/fluxus.git/tree/libfluxus/src/GraphicsUtils.cpp 4 | // based on explanation by Paul Bourke (01/12/1993): http://paulbourke.net/geometry/platonic 5 | // using vertex/face list by Craig Reynolds: http://paulbourke.net/geometry/platonic/icosahedron.vf 6 | 7 | class Icosahedron { 8 | ArrayList positions = new ArrayList (); 9 | ArrayList normals = new ArrayList (); 10 | ArrayList texCoords = new ArrayList (); 11 | 12 | Icosahedron(int level) { 13 | float sqrt5 = sqrt(5); 14 | float phi = (1 + sqrt5) * 0.5; 15 | float ratio = sqrt(10 + (2 * sqrt5)) / (4 * phi); 16 | float a = (1 / ratio) * 0.5; 17 | float b = (1 / ratio) / (2 * phi); 18 | 19 | PVector[] vertices = { 20 | new PVector( 0, b, -a), 21 | new PVector( b, a, 0), 22 | new PVector(-b, a, 0), 23 | new PVector( 0, b, a), 24 | new PVector( 0, -b, a), 25 | new PVector(-a, 0, b), 26 | new PVector( 0, -b, -a), 27 | new PVector( a, 0, -b), 28 | new PVector( a, 0, b), 29 | new PVector(-a, 0, -b), 30 | new PVector( b, -a, 0), 31 | new PVector(-b, -a, 0) 32 | }; 33 | 34 | int[] indices = { 35 | 0,1,2, 3,2,1, 36 | 3,4,5, 3,8,4, 37 | 0,6,7, 0,9,6, 38 | 4,10,11, 6,11,10, 39 | 2,5,9, 11,9,5, 40 | 1,7,8, 10,8,7, 41 | 3,5,2, 3,1,8, 42 | 0,2,9, 0,7,1, 43 | 6,9,11, 6,10,7, 44 | 4,11,5, 4,8,10 45 | }; 46 | 47 | for (int i=0; i maxt)) || ((tb.x < mint) && (tc.x > maxt))) { ta.x += 0.5; } 69 | } else if ((b.x == 0) && ((b.y == 1) || (b.y == -1))) { 70 | tb.x = (ta.x + tc.x) / 2; 71 | if (((tc.x < mint) && (ta.x > maxt)) || ((ta.x < mint) && (tc.x > maxt))) { tb.x += 0.5; } 72 | } else if ((c.x == 0) && ((c.y == 1) || (c.y == -1))) { 73 | tc.x = (ta.x + tb.x) / 2; 74 | if (((ta.x < mint) && (tb.x > maxt)) || ((tb.x < mint) && (ta.x > maxt))) { tc.x += 0.5; } 75 | } 76 | 77 | // fix texture wrapping 78 | if ((ta.x < mint) && (tc.x > maxt)) { 79 | if (tb.x < mint) { tc.x -= 1; } else { ta.x += 1; } 80 | } else if ((ta.x < mint) && (tb.x > maxt)) { 81 | if (tc.x < mint) { tb.x -= 1; } else { ta.x += 1; } 82 | } else if ((tc.x < mint) && (tb.x > maxt)) { 83 | if (ta.x < mint) { tb.x -= 1; } else { tc.x += 1; } 84 | } else if ((ta.x > maxt) && (tc.x < mint)) { 85 | if (tb.x < mint) { ta.x -= 1; } else { tc.x += 1; } 86 | } else if ((ta.x > maxt) && (tb.x < mint)) { 87 | if (tc.x < mint) { ta.x -= 1; } else { tb.x += 1; } 88 | } else if ((tc.x > maxt) && (tb.x < mint)) { 89 | if (ta.x < mint) { tc.x -= 1; } else { tb.x += 1; } 90 | } 91 | 92 | addVertex(a, a, ta); 93 | addVertex(c, c, tc); 94 | addVertex(b, b, tb); 95 | 96 | } else { // level > 1 97 | 98 | PVector ab = midpointOnSphere(a, b); 99 | PVector bc = midpointOnSphere(b, c); 100 | PVector ca = midpointOnSphere(c, a); 101 | 102 | level--; 103 | makeIcosphereFace(a, ab, ca, level); 104 | makeIcosphereFace(ab, b, bc, level); 105 | makeIcosphereFace(ca, bc, c, level); 106 | makeIcosphereFace(ab, bc, ca, level); 107 | } 108 | } 109 | 110 | void addVertex(PVector p, PVector n, PVector t) { 111 | positions.add(p); 112 | normals.add(n); 113 | t.set(1.0-t.x, 1.0-t.y, t.z); 114 | texCoords.add(t); 115 | } 116 | 117 | PVector midpointOnSphere(PVector a, PVector b) { 118 | PVector midpoint = PVector.add(a, b); 119 | midpoint.mult(0.5); 120 | midpoint.normalize(); 121 | return midpoint; 122 | } 123 | } 124 | 125 | PShape createIcosahedron(int level) { 126 | // the icosahedron is created with positions, normals and texture coordinates in the above class 127 | Icosahedron ico = new Icosahedron(level); 128 | 129 | textureMode(NORMAL); // set textureMode to normalized (range 0 to 1); 130 | 131 | PShape mesh = createShape(); // create the initial PShape 132 | mesh.beginShape(TRIANGLES); // define the PShape type: TRIANGLES 133 | mesh.noStroke(); 134 | mesh.texture(colorMaps[0]); // set the texture 135 | // put all the vertices, uv texture coordinates and normals into the PShape 136 | for (int i=0; i zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], 111 | spotCos, spotExp) 112 | : one_float; 113 | 114 | if (any(greaterThan(lightAmbient[i], zero_vec3))) { 115 | totalAmbient += lightAmbient[i] * falloff; 116 | } 117 | 118 | if (any(greaterThan(lightDiffuse[i], zero_vec3))) { 119 | totalDiffuse += lightDiffuse[i] * falloff * spotf * 120 | lambertFactor(lightDir, ecNormal); 121 | } 122 | 123 | if (any(greaterThan(lightSpecular[i], zero_vec3))) { 124 | totalSpecular += lightSpecular[i] * falloff * spotf * 125 | blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess); 126 | } 127 | } 128 | 129 | // Calculating final color as result of all lights (plus emissive term). 130 | // Transparency is determined exclusively by the diffuse component. 131 | vertColor = vec4(totalAmbient, 0) * ambient + 132 | vec4(totalDiffuse, 1) * color + 133 | vec4(totalSpecular, 0) * specular + 134 | vec4(emissive.rgb, 0); 135 | 136 | } 137 | -------------------------------------------------------------------------------- /GLSL_SphereDisplacementNoise/GLSL_SphereDisplacementNoise.pde: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | GLSL Sphere Displacement by Amnon Owed (May 2013) 5 | https://github.com/AmnonOwed 6 | http://vimeo.com/amnon 7 | 8 | Creating a sphere by subdividing an icosahedron. Storing it in a PShape. 9 | Displacing it outwards through GLSL with shader-based procedural noise. 10 | 11 | c = cycle through the color maps 12 | 13 | Built with Processing 2.0b8 / 2.0b9 / 2.0 Final 14 | 15 | Photographs by Folkert Gorter (@folkertgorter / http://superfamous.com/) made available under a CC Attribution 3.0 license. 16 | 17 | */ 18 | 19 | int subdivisionLevel = 8; // number of times the icosahedron will be subdivided 20 | int dim = 300; // the grid dimensions of the heightmap 21 | int blurFactor = 3; // the blur for the displacement map (to make it smoother) 22 | float resizeFactor = 0.2; // the resize factor for the displacement map (to make it smoother) 23 | float displaceStrength = 0.75; // the displace strength of the GLSL shader displacement effect 24 | 25 | PShape sphere; // PShape to hold the geometry, textures, texture coordinates etc. 26 | PShader displace; // GLSL shader 27 | 28 | PImage[] images = new PImage[2]; // array to hold 2 input images 29 | int currentColorMap = 1; // variable to keep track of the current colorMap 30 | 31 | void setup() { 32 | size(1280, 720, P3D); // use the P3D OpenGL renderer 33 | 34 | // load the images from the _Images folder (relative path from this sketch's folder) 35 | images[0] = loadImage("../_Images/Texture01.jpg"); 36 | images[1] = loadImage("../_Images/Texture02.jpg"); 37 | 38 | displace = loadShader("displaceFrag.glsl", "displaceVert.glsl"); // load the PShader with a fragment and a vertex shader 39 | displace.set("displaceStrength", displaceStrength); // set the displaceStrength 40 | displace.set("colorMap", images[currentColorMap]); // set the initial colorMap 41 | 42 | sphere = createIcosahedron(subdivisionLevel); // create the subdivided icosahedron PShape (see custom creation method) and put it in the global sphere reference 43 | } 44 | 45 | void draw() { 46 | pointLight(255, 255, 255, 2*(mouseX-width/2), 2*(mouseY-height/2), 500); // required for texLight shader 47 | 48 | translate(width/2, height/2); // translate to center of the screen 49 | rotateX(radians(60)); // fixed rotation of 60 degrees over the X axis 50 | rotateZ(frameCount*0.005); // dynamic frameCount-based rotation over the Z axis 51 | 52 | background(0); // black background 53 | perspective(PI/3.0, (float) width/height, 0.1, 1000000); // perspective for close shapes 54 | scale(200); // scale by 200 55 | 56 | displace.set("time", millis()/5000.0); // feed time to the GLSL shader 57 | shader(displace); // use shader 58 | shape(sphere); // display the PShape 59 | 60 | // write the fps and the current colorMap in the top-left of the window 61 | frame.setTitle(" " + int(frameRate) + " | colorMap: " + currentColorMap); 62 | } 63 | 64 | void keyPressed() { 65 | if (key == 'c') { currentColorMap = ++currentColorMap%images.length; displace.set("colorMap", images[currentColorMap]); } // cycle through colorMaps (set variable and set colorMap in PShader) 66 | } 67 | 68 | -------------------------------------------------------------------------------- /GLSL_SphereDisplacementNoise/Icosahedron.pde: -------------------------------------------------------------------------------- 1 | 2 | // ported to Processing 2.0b8 by Amnon Owed (10/05/2013) 3 | // from code by Gabor Papp (13/03/2010): http://git.savannah.gnu.org/cgit/fluxus.git/tree/libfluxus/src/GraphicsUtils.cpp 4 | // based on explanation by Paul Bourke (01/12/1993): http://paulbourke.net/geometry/platonic 5 | // using vertex/face list by Craig Reynolds: http://paulbourke.net/geometry/platonic/icosahedron.vf 6 | 7 | class Icosahedron { 8 | ArrayList positions = new ArrayList (); 9 | ArrayList normals = new ArrayList (); 10 | ArrayList texCoords = new ArrayList (); 11 | 12 | Icosahedron(int level) { 13 | float sqrt5 = sqrt(5); 14 | float phi = (1 + sqrt5) * 0.5; 15 | float ratio = sqrt(10 + (2 * sqrt5)) / (4 * phi); 16 | float a = (1 / ratio) * 0.5; 17 | float b = (1 / ratio) / (2 * phi); 18 | 19 | PVector[] vertices = { 20 | new PVector( 0, b, -a), 21 | new PVector( b, a, 0), 22 | new PVector(-b, a, 0), 23 | new PVector( 0, b, a), 24 | new PVector( 0, -b, a), 25 | new PVector(-a, 0, b), 26 | new PVector( 0, -b, -a), 27 | new PVector( a, 0, -b), 28 | new PVector( a, 0, b), 29 | new PVector(-a, 0, -b), 30 | new PVector( b, -a, 0), 31 | new PVector(-b, -a, 0) 32 | }; 33 | 34 | int[] indices = { 35 | 0,1,2, 3,2,1, 36 | 3,4,5, 3,8,4, 37 | 0,6,7, 0,9,6, 38 | 4,10,11, 6,11,10, 39 | 2,5,9, 11,9,5, 40 | 1,7,8, 10,8,7, 41 | 3,5,2, 3,1,8, 42 | 0,2,9, 0,7,1, 43 | 6,9,11, 6,10,7, 44 | 4,11,5, 4,8,10 45 | }; 46 | 47 | for (int i=0; i maxt)) || ((tb.x < mint) && (tc.x > maxt))) { ta.x += 0.5; } 69 | } else if ((b.x == 0) && ((b.y == 1) || (b.y == -1))) { 70 | tb.x = (ta.x + tc.x) / 2; 71 | if (((tc.x < mint) && (ta.x > maxt)) || ((ta.x < mint) && (tc.x > maxt))) { tb.x += 0.5; } 72 | } else if ((c.x == 0) && ((c.y == 1) || (c.y == -1))) { 73 | tc.x = (ta.x + tb.x) / 2; 74 | if (((ta.x < mint) && (tb.x > maxt)) || ((tb.x < mint) && (ta.x > maxt))) { tc.x += 0.5; } 75 | } 76 | 77 | // fix texture wrapping 78 | if ((ta.x < mint) && (tc.x > maxt)) { 79 | if (tb.x < mint) { tc.x -= 1; } else { ta.x += 1; } 80 | } else if ((ta.x < mint) && (tb.x > maxt)) { 81 | if (tc.x < mint) { tb.x -= 1; } else { ta.x += 1; } 82 | } else if ((tc.x < mint) && (tb.x > maxt)) { 83 | if (ta.x < mint) { tb.x -= 1; } else { tc.x += 1; } 84 | } else if ((ta.x > maxt) && (tc.x < mint)) { 85 | if (tb.x < mint) { ta.x -= 1; } else { tc.x += 1; } 86 | } else if ((ta.x > maxt) && (tb.x < mint)) { 87 | if (tc.x < mint) { ta.x -= 1; } else { tb.x += 1; } 88 | } else if ((tc.x > maxt) && (tb.x < mint)) { 89 | if (ta.x < mint) { tc.x -= 1; } else { tb.x += 1; } 90 | } 91 | 92 | addVertex(a, a, ta); 93 | addVertex(c, c, tc); 94 | addVertex(b, b, tb); 95 | 96 | } else { // level > 1 97 | 98 | PVector ab = midpointOnSphere(a, b); 99 | PVector bc = midpointOnSphere(b, c); 100 | PVector ca = midpointOnSphere(c, a); 101 | 102 | level--; 103 | makeIcosphereFace(a, ab, ca, level); 104 | makeIcosphereFace(ab, b, bc, level); 105 | makeIcosphereFace(ca, bc, c, level); 106 | makeIcosphereFace(ab, bc, ca, level); 107 | } 108 | } 109 | 110 | void addVertex(PVector p, PVector n, PVector t) { 111 | positions.add(p); 112 | normals.add(n); 113 | t.set(1.0-t.x, 1.0-t.y, t.z); 114 | texCoords.add(t); 115 | } 116 | 117 | PVector midpointOnSphere(PVector a, PVector b) { 118 | PVector midpoint = PVector.add(a, b); 119 | midpoint.mult(0.5); 120 | midpoint.normalize(); 121 | return midpoint; 122 | } 123 | } 124 | 125 | PShape createIcosahedron(int level) { 126 | // the icosahedron is created with positions, normals and texture coordinates in the above class 127 | Icosahedron ico = new Icosahedron(level); 128 | 129 | textureMode(NORMAL); // set textureMode to normalized (range 0 to 1); 130 | 131 | PShape mesh = createShape(); // create the initial PShape 132 | mesh.beginShape(TRIANGLES); // define the PShape type: TRIANGLES 133 | mesh.noStroke(); 134 | mesh.texture(images[0]); // set the texture 135 | // put all the vertices, uv texture coordinates and normals into the PShape 136 | for (int i=0; i x0.y ? 1.0 : 0.0 91 | //i1.y = 1.0 - i1.x; 92 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 93 | // x0 = x0 - 0.0 + 0.0 * C.xx ; 94 | // x1 = x0 - i1 + 1.0 * C.xx ; 95 | // x2 = x0 - 1.0 + 2.0 * C.xx ; 96 | vec4 x12 = x0.xyxy + C.xxzz; 97 | x12.xy -= i1; 98 | 99 | // Permutations 100 | i = mod289(i); // Avoid truncation effects in permutation 101 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) 102 | + i.x + vec3(0.0, i1.x, 1.0 )); 103 | 104 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); 105 | m = m*m ; 106 | m = m*m ; 107 | 108 | // Gradients: 41 points uniformly over a line, mapped onto a diamond. 109 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) 110 | 111 | vec3 x = 2.0 * fract(p * C.www) - 1.0; 112 | vec3 h = abs(x) - 0.5; 113 | vec3 ox = floor(x + 0.5); 114 | vec3 a0 = x - ox; 115 | 116 | // Normalise gradients implicitly by scaling m 117 | // Approximation of: m *= inversesqrt( a0*a0 + h*h ); 118 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); 119 | 120 | // Compute final noise value at P 121 | vec3 g; 122 | g.x = a0.x * x0.x + h.x * x0.y; 123 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 124 | return 130.0 * dot(m, g); 125 | } 126 | 127 | void main() { 128 | // Calculating texture coordinates, with r and q set both to one 129 | vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0); 130 | 131 | vec2 p = texCoord; // put coordinates into vec2 p for convenience 132 | p.x += time; // add time to make the noise and the subsequent displacement move 133 | float df = snoise( p ); // create displacement float value from shader-based 2D Perlin noise 134 | vec4 newVertexPos = vertex + vec4(normal * df * displaceStrength, 0.0); // regular vertex position + direction * displacementMap * displaceStrength 135 | 136 | // Vertex in clip coordinates 137 | gl_Position = transform * newVertexPos; 138 | 139 | // Vertex in eye coordinates 140 | vec3 ecVertex = vec3(modelview * vertex); 141 | 142 | // Normal vector in eye coordinates 143 | vec3 ecNormal = normalize(normalMatrix * normal); 144 | 145 | if (dot(-one_float * ecVertex, ecNormal) < zero_float) { 146 | // If normal is away from camera, choose its opposite. 147 | // If we add backface culling, this will be backfacing 148 | ecNormal *= -one_float; 149 | } 150 | 151 | // Light calculations 152 | vec3 totalAmbient = vec3(0, 0, 0); 153 | vec3 totalDiffuse = vec3(0, 0, 0); 154 | vec3 totalSpecular = vec3(0, 0, 0); 155 | for (int i = 0; i < 8; i++) { 156 | if (lightCount == i) break; 157 | 158 | vec3 lightPos = lightPosition[i].xyz; 159 | bool isDir = zero_float < lightPosition[i].w; 160 | float spotCos = lightSpot[i].x; 161 | float spotExp = lightSpot[i].y; 162 | 163 | vec3 lightDir; 164 | float falloff; 165 | float spotf; 166 | 167 | if (isDir) { 168 | falloff = one_float; 169 | lightDir = -one_float * lightNormal[i]; 170 | } else { 171 | falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]); 172 | lightDir = normalize(lightPos - ecVertex); 173 | } 174 | 175 | spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], 176 | spotCos, spotExp) 177 | : one_float; 178 | 179 | if (any(greaterThan(lightAmbient[i], zero_vec3))) { 180 | totalAmbient += lightAmbient[i] * falloff; 181 | } 182 | 183 | if (any(greaterThan(lightDiffuse[i], zero_vec3))) { 184 | totalDiffuse += lightDiffuse[i] * falloff * spotf * 185 | lambertFactor(lightDir, ecNormal); 186 | } 187 | 188 | if (any(greaterThan(lightSpecular[i], zero_vec3))) { 189 | totalSpecular += lightSpecular[i] * falloff * spotf * 190 | blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess); 191 | } 192 | } 193 | 194 | // Calculating final color as result of all lights (plus emissive term). 195 | // Transparency is determined exclusively by the diffuse component. 196 | vertColor = vec4(totalAmbient, 0) * ambient + 197 | vec4(totalDiffuse, 1) * color + 198 | vec4(totalSpecular, 0) * specular + 199 | vec4(emissive.rgb, 0); 200 | 201 | } 202 | -------------------------------------------------------------------------------- /GLSL_TextureMix/GLSL_TextureMix.pde: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | GLSL Texture Mix by Amnon Owed (May 2013) 5 | https://github.com/AmnonOwed 6 | http://vimeo.com/amnon 7 | 8 | Creating a smooth mix between multiple textures in the fragment shader. 9 | 10 | MOUSE PRESS = toggle between three mix types (Subtle, Regular, Obvious) 11 | 12 | Built with Processing 2.0b8 / 2.0b9 / 2.0 Final 13 | 14 | Photographs by Folkert Gorter (@folkertgorter / http://superfamous.com/) made available under a CC Attribution 3.0 license. 15 | 16 | */ 17 | 18 | PShader textureMix; // PShader that - given it's content - can be applied to textured geometry 19 | PImage[] images = new PImage[3]; // array to hold 3 images 20 | int mixType; // variable to set the current mixType 21 | int maxTypes = 3; // variable used to keep the sketch within the maximum number of types (defined in the shader) 22 | 23 | void setup() { 24 | size(1150, 850, P2D); // use the P2D OpenGL renderer 25 | 26 | // load the images from the _Images folder (relative path from this sketch's folder) into the GLTexture array 27 | images[0] = loadImage("../_Images/Texture01.jpg"); 28 | images[1] = loadImage("../_Images/Texture02.jpg"); 29 | images[2] = loadImage("../_Images/Texture03.jpg"); 30 | 31 | // load the PShader with a fragment and a vertex shader 32 | textureMix = loadShader("textureMixFrag.glsl", "textureMixVert.glsl"); 33 | 34 | // set the images as respective textures for the fragment shader 35 | textureMix.set("tex0", images[0]); 36 | textureMix.set("tex1", images[1]); 37 | textureMix.set("tex2", images[2]); 38 | } 39 | 40 | void draw() { 41 | background(0); // black background 42 | 43 | textureMix.set("mixType", mixType); // set the mixType 44 | textureMix.set("time", millis()/5000.0); // feed time to the PShader 45 | shader(textureMix); // apply the shader to subsequent textured geometry 46 | image(images[0], 0, 0, 850, 850); // display any image as a 'textured geometry canvas' for the PShader 47 | resetShader(); // reset to the default shader for subsequent geometry 48 | 49 | // display the 3 original images on the right 50 | for (int i=0; i positions = new ArrayList (); 9 | ArrayList normals = new ArrayList (); 10 | ArrayList texCoords = new ArrayList (); 11 | 12 | Icosahedron(int level) { 13 | float sqrt5 = sqrt(5); 14 | float phi = (1 + sqrt5) * 0.5; 15 | float ratio = sqrt(10 + (2 * sqrt5)) / (4 * phi); 16 | float a = (1 / ratio) * 0.5; 17 | float b = (1 / ratio) / (2 * phi); 18 | 19 | PVector[] vertices = { 20 | new PVector( 0, b, -a), 21 | new PVector( b, a, 0), 22 | new PVector(-b, a, 0), 23 | new PVector( 0, b, a), 24 | new PVector( 0, -b, a), 25 | new PVector(-a, 0, b), 26 | new PVector( 0, -b, -a), 27 | new PVector( a, 0, -b), 28 | new PVector( a, 0, b), 29 | new PVector(-a, 0, -b), 30 | new PVector( b, -a, 0), 31 | new PVector(-b, -a, 0) 32 | }; 33 | 34 | int[] indices = { 35 | 0,1,2, 3,2,1, 36 | 3,4,5, 3,8,4, 37 | 0,6,7, 0,9,6, 38 | 4,10,11, 6,11,10, 39 | 2,5,9, 11,9,5, 40 | 1,7,8, 10,8,7, 41 | 3,5,2, 3,1,8, 42 | 0,2,9, 0,7,1, 43 | 6,9,11, 6,10,7, 44 | 4,11,5, 4,8,10 45 | }; 46 | 47 | for (int i=0; i maxt)) || ((tb.x < mint) && (tc.x > maxt))) { ta.x += 0.5; } 69 | } else if ((b.x == 0) && ((b.y == 1) || (b.y == -1))) { 70 | tb.x = (ta.x + tc.x) / 2; 71 | if (((tc.x < mint) && (ta.x > maxt)) || ((ta.x < mint) && (tc.x > maxt))) { tb.x += 0.5; } 72 | } else if ((c.x == 0) && ((c.y == 1) || (c.y == -1))) { 73 | tc.x = (ta.x + tb.x) / 2; 74 | if (((ta.x < mint) && (tb.x > maxt)) || ((tb.x < mint) && (ta.x > maxt))) { tc.x += 0.5; } 75 | } 76 | 77 | // fix texture wrapping 78 | if ((ta.x < mint) && (tc.x > maxt)) { 79 | if (tb.x < mint) { tc.x -= 1; } else { ta.x += 1; } 80 | } else if ((ta.x < mint) && (tb.x > maxt)) { 81 | if (tc.x < mint) { tb.x -= 1; } else { ta.x += 1; } 82 | } else if ((tc.x < mint) && (tb.x > maxt)) { 83 | if (ta.x < mint) { tb.x -= 1; } else { tc.x += 1; } 84 | } else if ((ta.x > maxt) && (tc.x < mint)) { 85 | if (tb.x < mint) { ta.x -= 1; } else { tc.x += 1; } 86 | } else if ((ta.x > maxt) && (tb.x < mint)) { 87 | if (tc.x < mint) { ta.x -= 1; } else { tb.x += 1; } 88 | } else if ((tc.x > maxt) && (tb.x < mint)) { 89 | if (ta.x < mint) { tc.x -= 1; } else { tb.x += 1; } 90 | } 91 | 92 | addVertex(a, a, ta); 93 | addVertex(c, c, tc); 94 | addVertex(b, b, tb); 95 | 96 | } else { // level > 1 97 | 98 | PVector ab = midpointOnSphere(a, b); 99 | PVector bc = midpointOnSphere(b, c); 100 | PVector ca = midpointOnSphere(c, a); 101 | 102 | level--; 103 | makeIcosphereFace(a, ab, ca, level); 104 | makeIcosphereFace(ab, b, bc, level); 105 | makeIcosphereFace(ca, bc, c, level); 106 | makeIcosphereFace(ab, bc, ca, level); 107 | } 108 | } 109 | 110 | void addVertex(PVector p, PVector n, PVector t) { 111 | positions.add(p); 112 | normals.add(n); 113 | t.set(1.0-t.x, 1.0-t.y, t.z); 114 | texCoords.add(t); 115 | } 116 | 117 | PVector midpointOnSphere(PVector a, PVector b) { 118 | PVector midpoint = PVector.add(a, b); 119 | midpoint.mult(0.5); 120 | midpoint.normalize(); 121 | return midpoint; 122 | } 123 | } 124 | 125 | PShape createIcosahedron(int level) { 126 | // the icosahedron is created with positions, normals and texture coordinates in the above class 127 | Icosahedron ico = new Icosahedron(level); 128 | 129 | textureMode(NORMAL); // set textureMode to normalized (range 0 to 1); 130 | PImage tex = loadImage("earthmap1k.jpg"); // load a texture to make it a textured PShape 131 | 132 | PShape mesh = createShape(); // create the initial PShape 133 | mesh.beginShape(TRIANGLES); // define the PShape type: TRIANGLES 134 | mesh.noStroke(); 135 | mesh.texture(tex); // set the texture 136 | // put all the vertices, uv texture coordinates and normals into the PShape 137 | for (int i=0; i zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], 105 | spotCos, spotExp) 106 | : one_float; 107 | 108 | if (any(greaterThan(lightAmbient[i], zero_vec3))) { 109 | totalAmbient += lightAmbient[i] * falloff; 110 | } 111 | 112 | if (any(greaterThan(lightDiffuse[i], zero_vec3))) { 113 | totalDiffuse += lightDiffuse[i] * falloff * spotf * 114 | lambertFactor(lightDir, ecNormal); 115 | } 116 | 117 | if (any(greaterThan(lightSpecular[i], zero_vec3))) { 118 | totalSpecular += lightSpecular[i] * falloff * spotf * 119 | blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess); 120 | } 121 | } 122 | 123 | // Calculating final color as result of all lights (plus emissive term). 124 | // Transparency is determined exclusively by the diffuse component. 125 | vertColor = vec4(totalAmbient, 0) * ambient + 126 | vec4(totalDiffuse, 1) * color + 127 | vec4(totalSpecular, 0) * specular + 128 | vec4(emissive.rgb, 0); 129 | 130 | // Calculating texture coordinates, with r and q set both to one 131 | vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0); 132 | 133 | vec3 ecPosition = vec3(transform * vertex); 134 | vec3 tnorm = normalize(normalMatrix * normal); 135 | vec3 lightVec = normalize(lightPosition[0].xyz - ecPosition); 136 | vec3 reflectVec = reflect(-lightVec, tnorm); 137 | vec3 viewVec = normalize(-ecPosition); 138 | 139 | float spec = clamp(dot(reflectVec, viewVec), 0.0, 1.0); 140 | spec = pow(spec, 8.0); 141 | Specular = vec3(spec) * vec3(1.0, 0.941, 0.898) * 0.3; 142 | Diffuse = max(dot(lightVec, tnorm), 0.0); 143 | } 144 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Geometry, Textures & Shaders Tutorial for CAN 2 | =================================== 3 | 4 | Fully commented code examples for the Geometry, Textures & Shaders tutorial I've written for [CreativeApplications.net](http://www.creativeapplications.net/). 5 | You can find and read the complete tutorial [here](http://www.creativeapplications.net/processing/geometry-textures-shaders-processing-tutorial/). 6 | Code tested & working under Windows (7 x64 and XP SP3 x32) for both NVIDIA (GTX 570M) and Radeon (HD 4800). 7 | Since Processing 2.0 was still in development at the time of writing, the examples were initially made available for Processing 1.5.1 (with the GLGraphics library). 8 | As a service during 2.0 development and since Processing 2.0 Final has been released now, the examples are also made available for Processing 2.0b8/2.0b9/2.0 Final. 9 | 10 | * Code examples for [Processing 1.5.1.](http://processing.org/download/) and in most cases [GLGraphics 1.0.0](http://glgraphics.sourceforge.net/) are in [this repo](https://github.com/AmnonOwed/P5_CanTut_GeometryTexturesShaders). 11 | * Code examples for [Processing 2.0b8/2.0b9/2.0Final](http://processing.org/download/) are in [this repo](https://github.com/AmnonOwed/P5_CanTut_GeometryTexturesShaders2B8). 12 | 13 | Note: To save some space, many of these sketches share one central **_Images** folder! 14 | 15 | ####Custom2DGeometry 16 | Creating a custom 2D shape with interpolated colors using beginShape-vertex-endShape. 17 | 18 | ####Custom3DGeometry 19 | Creating a custom 3D shape with interpolated colors using beginShape-vertex-endShape. 20 | 21 | ####DynamicTextures2D 22 | Creating textured QUADS with dynamically generated texture coordinates. 23 | 24 | ####FixedMovingTextures2D 25 | Creating MOVING custom 2D shapes with either FIXED or MOVING textures. See the difference. 26 | 27 | ####GLSL_Heightmap 28 | Creating a heightmap through GLSL with separate color and displacement maps that can be changed in realtime. 29 | 30 | ####GLSL_HeightmapNoise 31 | Creating a GLSL heightmap running on shader-based procedural noise instead of a displacement map texture. 32 | 33 | ####GLSL_SphereDisplacement 34 | Displacing a sphere outwards through GLSL with separate color and displacement maps that can be changed in realtime. 35 | 36 | ####GLSL_SphereDisplacementNoise 37 | Displacing a sphere outwards through GLSL with shader-based procedural noise instead of a displacement map texture. 38 | 39 | ####GLSL_TextureMix 40 | Creating a smooth mix between multiple textures in the fragment shader. 41 | 42 | ####MultiTexturedSphereGLSL 43 | Applying a GLSL shader with multiple input textures to the TexturedSphere example. 44 | 45 | ####Texture2DAnimation 46 | Creating an animation by using texture coordinates to read from a spritesheet. 47 | 48 | ####TexturedSphere 49 | Creating a correctly textured sphere by subdividing an icosahedron. 50 | 51 | ####TexturedSphereGLSL 52 | Adding a basic GLSL shader for dynamic lighting to the TexturedSphere example. 53 | -------------------------------------------------------------------------------- /Texture2DAnimation/Texture2DAnimation.pde: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Texture 2D Animation by Amnon Owed (May 2013) 5 | https://github.com/AmnonOwed 6 | http://vimeo.com/amnon 7 | 8 | Creating an animation by using texture coordinates to read from a spritesheet. 9 | An individual offset can be used to differentiate the current frame for each instance. 10 | 11 | MOUSE MOVE = change the scale of individual instances based on the distance from the mouse 12 | (note that a negative scale is possible, this will scale AND invert the shape!) 13 | 14 | Built with Processing 2.0b8 / 2.0b9 / 2.0 Final 15 | 16 | Spritesheet created by Amnon Owed using Illustrator's blend mode... not recommended! ;-) 17 | 18 | If you make something awesome, based on this sketch, please let me know via twitter @AmnonOwed 19 | 20 | */ 21 | 22 | PImage spritesheet; // the image that holds the spritesheet animation 23 | int DIM = 6; // the horizontal and vertical dimensions of the spritesheet grid (important! get this wrong and it'll all fall down to pieces) 24 | int NUMSHAPES = 300; // the number of shapes to draw on the canvas 25 | float W = 1.0/DIM; // calculate the normalized width of one cell in the spritesheet grid 26 | float H = 1.0/DIM; // calculate the normalized height of one cell in the spritesheet grid 27 | 28 | void setup() { 29 | size(1280, 720, P2D); // use the P2D OpenGL renderer 30 | spritesheet = loadImage("animation.png"); // load the image (from the /data subdirectory) 31 | textureMode(NORMAL); // use normalized (0 to 1) texture coordinates 32 | noStroke(); // turn off stroke (for the rest of the sketch) 33 | smooth(6); // set smooth level 6 (default is 2) 34 | } 35 | 36 | void draw() { 37 | // some calculations for the color gradient below 38 | int dmod = frameCount%510; 39 | int col = dmod<255?dmod:510-dmod; 40 | 41 | // create a continuous smooth dynamic color gradient covering the whole sketch window 42 | beginShape(); // default shapeMode 43 | // top color and vertices 44 | fill(255, col, 0); 45 | vertex(0, 0); 46 | vertex(width, 0); 47 | // bottom color and vertices 48 | fill(0, 255, 255-col); 49 | vertex(width, height); 50 | vertex(0, height); 51 | endShape(); // finalize the Shape 52 | 53 | // set a randomSeed() so the shapes are 'randomly' placed in the same place 54 | randomSeed(0); 55 | for (int i=0; i positions = new ArrayList (); 9 | ArrayList normals = new ArrayList (); 10 | ArrayList texCoords = new ArrayList (); 11 | 12 | Icosahedron(int level) { 13 | float sqrt5 = sqrt(5); 14 | float phi = (1 + sqrt5) * 0.5; 15 | float ratio = sqrt(10 + (2 * sqrt5)) / (4 * phi); 16 | float a = (1 / ratio) * 0.5; 17 | float b = (1 / ratio) / (2 * phi); 18 | 19 | PVector[] vertices = { 20 | new PVector( 0, b, -a), 21 | new PVector( b, a, 0), 22 | new PVector(-b, a, 0), 23 | new PVector( 0, b, a), 24 | new PVector( 0, -b, a), 25 | new PVector(-a, 0, b), 26 | new PVector( 0, -b, -a), 27 | new PVector( a, 0, -b), 28 | new PVector( a, 0, b), 29 | new PVector(-a, 0, -b), 30 | new PVector( b, -a, 0), 31 | new PVector(-b, -a, 0) 32 | }; 33 | 34 | int[] indices = { 35 | 0,1,2, 3,2,1, 36 | 3,4,5, 3,8,4, 37 | 0,6,7, 0,9,6, 38 | 4,10,11, 6,11,10, 39 | 2,5,9, 11,9,5, 40 | 1,7,8, 10,8,7, 41 | 3,5,2, 3,1,8, 42 | 0,2,9, 0,7,1, 43 | 6,9,11, 6,10,7, 44 | 4,11,5, 4,8,10 45 | }; 46 | 47 | for (int i=0; i maxt)) || ((tb.x < mint) && (tc.x > maxt))) { ta.x += 0.5; } 69 | } else if ((b.x == 0) && ((b.y == 1) || (b.y == -1))) { 70 | tb.x = (ta.x + tc.x) / 2; 71 | if (((tc.x < mint) && (ta.x > maxt)) || ((ta.x < mint) && (tc.x > maxt))) { tb.x += 0.5; } 72 | } else if ((c.x == 0) && ((c.y == 1) || (c.y == -1))) { 73 | tc.x = (ta.x + tb.x) / 2; 74 | if (((ta.x < mint) && (tb.x > maxt)) || ((tb.x < mint) && (ta.x > maxt))) { tc.x += 0.5; } 75 | } 76 | 77 | // fix texture wrapping 78 | if ((ta.x < mint) && (tc.x > maxt)) { 79 | if (tb.x < mint) { tc.x -= 1; } else { ta.x += 1; } 80 | } else if ((ta.x < mint) && (tb.x > maxt)) { 81 | if (tc.x < mint) { tb.x -= 1; } else { ta.x += 1; } 82 | } else if ((tc.x < mint) && (tb.x > maxt)) { 83 | if (ta.x < mint) { tb.x -= 1; } else { tc.x += 1; } 84 | } else if ((ta.x > maxt) && (tc.x < mint)) { 85 | if (tb.x < mint) { ta.x -= 1; } else { tc.x += 1; } 86 | } else if ((ta.x > maxt) && (tb.x < mint)) { 87 | if (tc.x < mint) { ta.x -= 1; } else { tb.x += 1; } 88 | } else if ((tc.x > maxt) && (tb.x < mint)) { 89 | if (ta.x < mint) { tc.x -= 1; } else { tb.x += 1; } 90 | } 91 | 92 | addVertex(a, a, ta); 93 | addVertex(c, c, tc); 94 | addVertex(b, b, tb); 95 | 96 | } else { // level > 1 97 | 98 | PVector ab = midpointOnSphere(a, b); 99 | PVector bc = midpointOnSphere(b, c); 100 | PVector ca = midpointOnSphere(c, a); 101 | 102 | level--; 103 | makeIcosphereFace(a, ab, ca, level); 104 | makeIcosphereFace(ab, b, bc, level); 105 | makeIcosphereFace(ca, bc, c, level); 106 | makeIcosphereFace(ab, bc, ca, level); 107 | } 108 | } 109 | 110 | void addVertex(PVector p, PVector n, PVector t) { 111 | positions.add(p); 112 | normals.add(n); 113 | t.set(1.0-t.x, 1.0-t.y, t.z); 114 | texCoords.add(t); 115 | } 116 | 117 | PVector midpointOnSphere(PVector a, PVector b) { 118 | PVector midpoint = PVector.add(a, b); 119 | midpoint.mult(0.5); 120 | midpoint.normalize(); 121 | return midpoint; 122 | } 123 | } 124 | 125 | PShape createIcosahedron(int level) { 126 | // the icosahedron is created with positions, normals and texture coordinates in the above class 127 | Icosahedron ico = new Icosahedron(level); 128 | 129 | textureMode(NORMAL); // set textureMode to normalized (range 0 to 1); 130 | PImage tex = loadImage("world32k.jpg"); // load the texture 131 | 132 | PShape mesh = createShape(); // create the initial PShape 133 | mesh.beginShape(TRIANGLES); // define the PShape type: TRIANGLES 134 | mesh.noStroke(); 135 | mesh.texture(tex); // set the texture 136 | // put all the vertices, uv texture coordinates and normals into the PShape 137 | for (int i=0; i zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], 101 | spotCos, spotExp) 102 | : one_float; 103 | 104 | if (any(greaterThan(lightAmbient[i], zero_vec3))) { 105 | totalAmbient += lightAmbient[i] * falloff; 106 | } 107 | 108 | if (any(greaterThan(lightDiffuse[i], zero_vec3))) { 109 | totalDiffuse += lightDiffuse[i] * falloff * spotf * 110 | lambertFactor(lightDir, ecNormal); 111 | } 112 | 113 | if (any(greaterThan(lightSpecular[i], zero_vec3))) { 114 | totalSpecular += lightSpecular[i] * falloff * spotf * 115 | blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess); 116 | } 117 | } 118 | 119 | // Calculating final color as result of all lights (plus emissive term). 120 | // Transparency is determined exclusively by the diffuse component. 121 | vertColor = vec4(totalAmbient, 0) * ambient + 122 | vec4(totalDiffuse, 1) * color + 123 | vec4(totalSpecular, 0) * specular + 124 | vec4(emissive.rgb, 0); 125 | 126 | // Calculating texture coordinates, with r and q set both to one 127 | vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0); 128 | } 129 | -------------------------------------------------------------------------------- /TexturedSphereGLSL/data/world32k.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmnonOwed/P5_CanTut_GeometryTexturesShaders2B8/930f15dfe51a3fd41f152461eafb4e3d5f450cda/TexturedSphereGLSL/data/world32k.jpg -------------------------------------------------------------------------------- /_Images/Attribution.txt: -------------------------------------------------------------------------------- 1 | 2 | Photographs by Folkert Gorter (@folkertgorter / http://superfamous.com/) made available under a CC Attribution 3.0 license. 3 | -------------------------------------------------------------------------------- /_Images/Texture01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmnonOwed/P5_CanTut_GeometryTexturesShaders2B8/930f15dfe51a3fd41f152461eafb4e3d5f450cda/_Images/Texture01.jpg -------------------------------------------------------------------------------- /_Images/Texture02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmnonOwed/P5_CanTut_GeometryTexturesShaders2B8/930f15dfe51a3fd41f152461eafb4e3d5f450cda/_Images/Texture02.jpg -------------------------------------------------------------------------------- /_Images/Texture03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmnonOwed/P5_CanTut_GeometryTexturesShaders2B8/930f15dfe51a3fd41f152461eafb4e3d5f450cda/_Images/Texture03.jpg --------------------------------------------------------------------------------