4. Procedural Texturing

Procedural Texturing #

Para este ejercicio se generó una textura que replicara la cuadricula de Hermann sobre un cubo 3D.

La textura creada puede modificarse de la siguiente manera:

  • Al oprimir la flecha izquierda, disminuirá la cantidad de cuadros negros en cada cara del cubo
  • Al oprimir la flecha derecha, aumentará la cantidad de cuadros negros en cada cara del cubo
  • Al oprimir la tecla “b” se aplicará un efecto de difuminación sobre la textura
Shaders_Procedural_Texturing.js
let pg;
let illusionShader;
let zoom = 3;
let blur = false;
function preload() {
  // shader adapted from here: https://thebookofshaders.com/09/
  illusionShader = readShader('/Template/sketches/shaders/hermann.frag', { matrices: Tree.NONE, varyings: Tree.NONE });
}

function setup() {
  createCanvas(400, 400, WEBGL);
  // create frame buffer object to render the procedural texture
  pg = createGraphics(400, 400, WEBGL);
  textureMode(NORMAL);
  noStroke();
  pg.noStroke();
  pg.textureMode(NORMAL);
  // use illusionShader to render onto pg
  pg.shader(illusionShader);
  // emitResolution, see:
  // https://github.com/VisualComputing/p5.treegl#macros
  pg.emitResolution(illusionShader);
  // https://p5js.org/reference/#/p5.Shader/setUniform
  illusionShader.setUniform('u_zoom', zoom);
  illusionShader.setUniform('u_blur', blur);
  // pg clip-space quad (i.e., both x and y vertex coordinates ∈ [-1..1])
  pg.quad(-1, -1, 1, -1, 1, 1, -1, 1);
  // set pg as texture
  texture(pg);
}

function draw() {
  background(33);
  orbitControl();
  //cylinder(100, 200);
  box(200)
  //sphere(100);
}

function keyPressed(){
  if (keyCode === LEFT_ARROW) {
    zoom -= 1;
    illusionShader.setUniform('u_zoom', zoom);
  } else if (keyCode === RIGHT_ARROW) {
    zoom += 1;
  } else if (key == 'b'){
    blur = !blur;
  }
  illusionShader.setUniform('u_zoom', zoom);
  illusionShader.setUniform('u_blur', blur);
  pg.quad(-1, -1, 1, -1, 1, 1, -1, 1);
}
hermann.frag
precision mediump float;

uniform vec2 u_resolution;
uniform float u_time;
uniform float u_zoom;
uniform bool u_blur;

vec2 tile(vec2 _st, float _zoom){
    _st *= _zoom;
    return fract(_st);
}

float box(vec2 _st, vec2 _size, float _smoothEdges){
    _size = vec2(0.5)-_size*0.5;
    vec2 aa = vec2(_smoothEdges*0.5);
    vec2 uv = smoothstep(_size,_size+aa,_st);
    uv *= smoothstep(_size,_size+aa,vec2(1.0)-_st);
    return (uv.x)*(uv.y);
}

void main(void){
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    vec3 color = vec3(0.0);

    // Amount of tiles 
    st = tile(st,u_zoom);

    // Define blur on box
    float blur_value = 0.01;

    if(u_blur){
        blur_value = 0.2;
    }else{
        blur_value = 0.01;
    }

    // Drawing box
    color = vec3(1.0 - box(st,vec2(0.85),blur_value));
    // color = vec3(st,0.0);

    gl_FragColor = vec4(color,1.0);
}