/*
Nicholas Wong
Section A
*/
var spacing = 6; //Spacing between waves
var offset; //Wave offset
function setup() {
createCanvas(600,400);
offset = 23;
}
function draw()
{
background(20,10,15)
//Star grid
for (let x = 0; x <= width; x += 15) //Cols
{
for (let y = 0; y <= height / 2; y += 15) //Rows
{
push();
noStroke();
fill(255)
circle(x+(random(0,20)),y+(random(0,20)),random(0.5,1.5)) //Offsets each star X and Y by a random amount
pop();
}
}
//Wave generation
for(let w = 0; w <= height; w += spacing) //Number of waves
{
fill(0.75*w,0.15*w,0.25*w) //Color darkens with number of loops
strokeWeight(0.25)
stroke(w)
wave(w, offset*w); //Offset of waves and wave pattern determined by number of loops
}
noLoop();
}
// Wave function
function wave(yOffset, offset)
{
beginShape();
for(let x = 0; x < width; x++)
{
let angle = offset + x *0.01;
let y = map(sin(angle), -1, 1, 100, 200);
vertex(x,y + yOffset);
}
vertex(width,height);
vertex(0,height);
endShape();
}
Month: October 2020
Looking Outwards 5: 3D Graphics and faces
3D graphics have come a long way since its inception in the late 1970s, and is prevalent everywhere today. This is most prominently seen in movie and video game industry, where new technological breakthroughs revolutionize the industry every few years. Modern hardware and software allows us to create extremely complex, photo-realistic environments through techniques such as photogrammetry and physically-based-materials. We can even somewhat accurately simulate the physics of the real world to create realistic looking fluid simulations like fire, smoke, and water.
However, despite the extreme amount of detail that can be achieved through our current technology, recreating realistic, believable CG faces remains one of the biggest challenges in the 3D graphics industry. No one can pin-point exactly what it is that makes a computer-generated face uncanny; even if every hair, every pore, every bead of sweat is generated, it will still remain in the uncanny valley.
There have been a few successes when it comes to creating fully computer-generated faces that are distinctly NOT human. The alien race from the 2012 movie Avatar is a great example of how a CG face can achieve a sense of realism and believability. More recently, Marvel’s Thanos has taken the spotlight as being one of the more successful fully-CG characters. However, these aren’t human faces, so they never come across as uncanny.
The most successful CG face that manages to cross the uncanny valley, in my opinion, is the recreation of Sean Young’s character, Rachel, in Bladerunner 2049, courtesy of the English VFX company MPC. The combination of ideal lighting conditions, high quality 3D scans, the painstaking recreation of every muscle on Sean Young’s face, and the amazing performance of body-double Loren Peta resulted in what is probably the most realistic looking CG face in movie history. And of course, a lot of credit goes to the animators that made the subtle facial expressions look absolutely flawless.
Most of MPC’s success was achieved through how the scene was filmed – camera angles, lighting trickery, and so on. The recreation of Sean Young’s character would not have looked nearly as good in any other lighting condition or environment. 3D graphics technology has yet to conquer the challenge that is the human face.
Project 5: Wallpaper
var s = 100
var x = 50
var y = 50
function setup() {
createCanvas(600, 600);
background(60, 0, 33); //mauve 4, background color
strokeWeight(0);
rectMode(CENTER);
}
function draw() {
for (let r = 0; r <=5; r += 1) {
for (let c = 0; c <= 5; c += 1) {
tile(); //tile pattern
y += 100;
//s += 100;
}
y = 50;
tile();
x += 100;
}
}
function tile() {
push();
translate(x, y);
//random dots
fill(235, 181, 211);
circle(random(-50, 0), random(-50, 0), random(2,7));
circle(random(0, 50), random(0, 50), random(2,7));
fill(193, 99, 151);
circle(random(-50, 0), random(0, 50), random(2,7));
circle(random(0, 50), random(-50, 0), random(2,7));
fill(120, 26, 78);
circle(random(-50, 0), random(-50, 0), random(2,7));
circle(random(0, 50), random(0, 50), random(2,7));
//lines
fill(120, 26, 78); // mauve 3
push();
rotate(radians(45));
rect(0, 0, s/2 + 10, s/2 + 10);
pop();
push();
fill(60, 0, 33); //mauve 4
rotate(radians(45));
rect(0, 0, s/2, s/2);
pop();
//circles
fill(120, 26, 78); // mauve 3
circle(-25, -25, 30);
circle(25, -25, 30);
circle(25, 25, 30);
circle(-25, 25, 30);
fill(60, 0, 33); //mauve 4
circle(-25, -25, 20);
circle(25, -25, 20);
circle(25, 25, 20);
circle(-25, 25, 20);
//flower
fill(193, 99, 151); //mauve 2
push();
for(let x=0; x < 8; x += 1) {
ellipse(10, 10, s/2, 10);
rotate(radians(45));
}
pop();
//inner flower
push();
fill(235, 181, 222); //mauve 1
for(let x=0; x < 8; x += 1) {
ellipse(5, 2, s/2, 10);
rotate(radians(45));
}
pop();
//flower center
fill(193, 99, 151); //mauve 2
circle(0, 0, 15);
pop();
}
I drew inspiration from my sketch. However, I decided to add more flower patterns in my code than the flower petals in my original sketch.
Looking Outwards 05
One 3D computer graphics artist I find interesting is Omar Aqil, who creates 3D abstract portraits inspired by Picasso’s work. My favorite work that he created is his “Figurative Portraits” collection, which is inspired by Picasso’s artwork. He uses different 3D textures and forms inspired by Salvador Dali’s work to emulate facial expressions. I find it really cool how he can make the shadows and forms look so realistic. For example, some objects in his pieces are shiny and can reflect other objects in the piece. The way Agil uses light in his work is really interesting because it reflects and absorbs in different textures and surfaces.
Project-05-Wallpaper
var s=10;
var col=0;
var row=0;
function setup() {
createCanvas(600, 600);
background(217,215,217);
}
function draw() {
var gap=3*s;
var xStart=gap+3;
//background grid
for(var y=0; y<=600;y+=gap){
for(var x=xStart;x<=600;x+=2*s*sqrt(3)){
fill(221,211,201);
pattern1(x,y);
col+=1;
//if(col%5==0&row%7==0){
//print(x.toString()+","+y.toString());
//}
if(col%3==0&row%9==0){
print(x.toString()+","+y.toString());
}
}
if(row%2==1){
xStart+=s*sqrt(3);
row+=1;
}
else{
xStart-=s*sqrt(3);
row+=1;
}
}
//red flower
fill(202,65,36);
pattern1(344.7691453623978,30);
pattern1(517.9742261192855,0);
pattern1(67.64101615137754,420);
pattern1(188.88457268119896,210);
pattern1(67.64101615137754,420);
pattern1(414.05117766515286,540);
pattern1(587.2562584220407,120);
pattern1(362.0896534380866,270);
//blue triangle
fill(26,25,58);
pattern2(310.1281292110203,480);
pattern2(517.9742261192855,60);
pattern2(84.96152422706632,270);
pattern2(292.80762113533154,90);
pattern2(517.9742261192855,510);
noLoop();
}
function pattern2(x,y){
push();
stroke(239,237,231);
strokeWeight(1);
translate(x,y);
var u=s*sqrt(3);
triangle(0,0,u,2*u-4,0,2*s);
triangle(0,2*s,u,2*u-4,-u,2*u-4);
triangle(0,0,0,2*s,-u,2*u-4);
pop();
}
function pattern1(x,y){
push();
stroke(239,237,231);
strokeWeight(1);
translate(x,y);
//define unit
var u=s*sqrt(3);
triangle(0,0,-2*u,0,-u,-s);
triangle(0,0,-u,-s,-u,-2*u+4);
triangle(0,0,-u,-2*u+4,0,-2*s);
triangle(0,0,0,-2*s,u,-2*u+4);
triangle(0,0,u,-2*u+4,u,-s);
triangle(0,0,u,-s,2*u,0);
triangle(0,0,2*u,0,u,s);
triangle(0,0,u,s,u,2*u-4);
triangle(0,0,u,2*u-4,0,2*s);
triangle(0,0,0,2*s,-u,2*u-4);
triangle(0,0,-u,2*u-4,-u,s);
triangle(0,0,-u,s,-2*u,0);
pop();
}
I was inspired by traditional Japanese style “和風(わふう)” patterns. Below are some screenshots of my process in illustrator:
LookingOutwards-05
The project I want to discuss is a piece of public media art, “WAVE”, created by a Korean design company called d’strict. “WAVE” is an anamorphic illusion of water surging in a giant glass jar revealed on a magnificent DOOH of COEX K-POP SQUARE, the largest & high-definition outdoor advertising screen in S.Korea at 80.1m (w) x 20.1M (h).
Needless to say, the astonishing visual effect attracts me. I admire how modern technology and art as well as the natural and artificial are perfectly integrated to maximize people’s sensual experience. Yes, besides visuals, “WAVE” also provides acoustic effect to enhance the realistic impression of the art.
I know that fluids are probably the hardest thing to simulate in 3D rendering software because its movements are complex and hard to predict. I suppose the creators simulated water flow using 3ds Max Fluids and the Motion Field space warp. The algorithm might have helped them to customize the dimension of video according to the size and geometry of the LED screen to create an anamorphic illusion.
The creators’ artistic sensibilities are manifest through the creative concept of manipulating sight to create a realiztic 3D effect on 2D media.
Looking Outwards 05 – 3D Computer Graphics
One of my favorite musical artists, Carpenter Brut, released a music video about 4 years ago for his song “Turbo Killer”. The basic premise of the video was a world where machines were living (and hence called “blood machines”) and due to their power were highly coveted and fought over. The video was directed and written by Seth Ickerman, a Paris-based CGI artist whose goal was to capture the over-the-top 80s feel of Carpenter Brut’s heavy synth music.
The video features a myriad of special effects that synergize to create this 80s atmosphere, of which 3D graphics plays a major role. Most of the video was comprised of CGI in some form, with only close-up shots of real actors shot live and superimposed onto a CGI set. Some of the CGI models used in the video are detailed to an extreme amount, leading me to believe they were not all modeled manually by hand. Generative design in certain scenes and models seem to help Ickerman model faster as well as depicting a more organic feel to these machines.
Project 05 – Wallpaper
Too much Among Us was played in the making of this wallpaper.
Cyan sus.
/*
*Eric Zhao
*ezhao2@andrew.cmu.edu
*
*Draws a wallpaper consisting of a "3D lattice"
*and Among Us sprites.
*/
var w = 50; //pillar length and height
var s = 10; //pillar width
var pillarHue = 101;
var pillarLight = 75;
var pillarDark = 25;
function setup() {
colorMode(HSB);
createCanvas(600, 600);
background(16, 34, 93);
}
function draw() {
//draws the lattice of pillars
for(let i = 0; i < 12; i++){
for(let j = 0; j < 12; j++){
if((i+j) % 2 == 0){
pillar2(i*w, j*w, s, w, pillarHue, pillarLight, pillarDark);
} else{
pillar(i*w, j*w, s, w, pillarHue, pillarLight, pillarDark);
}
}
}
//draws the Among Us sprites on rows with odd numbers of spaces
for(let i = 0; i < height; i += 2*w){
push();
translate(0, i);
for(let j = 0; j < width-w; j += 2*w){
push();
translate(j + w/2, w/2);
scale(0.45);
amongUs();
pop();
}
pop();
}
translate(w, w);
//draws the Among Us sprites on rows with even numbers of spaces
for(let i = 0; i < height-2*w; i += 2*w){
push();
translate(0, i);
for(let j = 0; j < width-2*w; j += 2*w){
push();
translate(j + w/2, w/2);
scale(0.45);
amongUs();
pop();
}
pop();
}
//shh, here's the impostor!
translate(width/3+15, height/3-2);
scale(0.2);
knife();
noLoop();
}
function pillar(x, y, s, w, hue, light, shadow){
//pillar function drawing a lattice element top left to bottom right
fill(hue, 40, shadow);
quad(x, y, x+s, y, x+w, y+w-s, w+x, w+y);
fill(hue, 40, light);
quad(x, y, w+x, w+y, w-s+x, w+y, x, s+y);
}
function pillar2(x, y, s, w, hue, light, shadow){
//pillar function drawing a lattice element bot left to top right
fill(hue, 40, shadow);
quad(x, y+w, x+w, y, x+w, y+s, x+s, y+w);
fill(hue, 40, light);
quad(x, y+w, x, y+w-s, x+w-s, y, x+w, y);
}
function amongUs(){
//creates an Among Us sprite lookalike
push();
noStroke();
fill(50);
ellipse(53, 94, 70, 15); //shadow
backpack();
body();
visor();
pop();
}
function body(){
//Among Us sprite body
//body base color
noStroke();
fill(187, 100, 76);
beginShape();
curveVertex(59, 76);
curveVertex(59, 76);
curveVertex(62, 88);
curveVertex(75, 88);
curveVertex(78, 74);
curveVertex(81, 55);
curveVertex(79, 38);
curveVertex(69, 7);
curveVertex(38, 7);
curveVertex(28, 48);
curveVertex(32, 91);
curveVertex(50, 91);
curveVertex(52, 76);
curveVertex(59, 76);
curveVertex(59, 76);
endShape();
//body highlight color
fill(172, 56, 80);
beginShape();
curveVertex(45, 62);
curveVertex(45, 62);
curveVertex(70, 63);
curveVertex(79, 38);
curveVertex(69, 7);
curveVertex(45, 4);
curveVertex(36, 32);
curveVertex(39, 54);
curveVertex(45, 62);
curveVertex(45, 62);
endShape();
//outline
stroke(0);
strokeWeight(6);
noFill();
beginShape();
curveVertex(59, 76);
curveVertex(59, 76);
curveVertex(62, 88);
curveVertex(75, 88);
curveVertex(78, 74);
curveVertex(81, 55);
curveVertex(79, 38);
curveVertex(69, 7);
curveVertex(38, 7);
curveVertex(28, 48);
curveVertex(32, 91);
curveVertex(50, 91);
curveVertex(52, 76);
curveVertex(59, 76);
curveVertex(59, 76);
endShape();
}
function backpack(){
//Among Us backpack (body colored)
noStroke();
//backpack base color
fill(187, 100, 76);
beginShape();
curveVertex(33, 27);
curveVertex(33, 27);
curveVertex(19, 31);
curveVertex(17, 69);
curveVertex(30, 72);
curveVertex(30, 72);
endShape();
//backpack highlight
fill(172, 56, 80);
beginShape();
curveVertex(33, 27);
curveVertex(33, 27);
curveVertex(19, 28);
curveVertex(18, 39);
curveVertex(33, 36);
curveVertex(33, 36);
endShape();
strokeWeight(6);
noFill();
//outline
stroke(0);
strokeWeight(6);
noFill();
beginShape();
curveVertex(33, 27);
curveVertex(33, 27);
curveVertex(19, 31);
curveVertex(17, 69);
curveVertex(30, 72);
curveVertex(30, 72);
endShape();
}
function visor(){
//Among Us visor section
strokeWeight(6);
noStroke();
fill(193, 38, 43);
ellipse(64, 28, 35, 25);
fill(196, 36, 87);
ellipse(67, 24, 25, 18);
fill(0, 0, 100);
ellipse(68, 24, 15, 5);
//outline
stroke(0);
noFill();
ellipse(64, 28, 35, 25);
}
function knife() {
//for the killer only...
strokeWeight(2);
fill(0, 0, 37);
rect(0, 0, 15, 30);
fill(11, 67, 51);
rect(-10, 30, 35, 15);
fill(0, 0, 50);
triangle(-5, 45, 7.5, 100, 20, 45);
noStroke();
fill(0, 0, 85);
triangle(7.5, 45, 7.5, 100, -5, 45);
noFill();
stroke(0);
triangle(-5, 45, 7.5, 100, 20, 45);
noLoop();
}
Project – 05 – wallpaper
var size = 60
function setup() {
createCanvas(420, 470);
background(220);
}
function draw() {
background (255, 143, 233);
for (var y = size/2 ; y < height + size/2 ; y += size *2){
for (var x = size/2; x< width + size / 2 ; x += size *2){
//stripes
noStroke();
fill(93, 146, 245, 30);
rect(x + 45, 0, width/14, height);
noStroke();
//face
fill(245, 237, 93);
circle(x, y, size);
//drips
ellipse(x, y + size/2, 10, 40);
circle(x, y + size/2 + 18, 12);
ellipse(x - size/2 + 8, y + size/2 - 8, 10, 30);
circle(x - size/2 + 8, y + size/2 + 2, 12);
ellipse(x + size/2 - 7, y + size/2 - 4, 8, 30);
circle(x + size/2 - 7, y + size/2 + 6, 10);
//eyes
stroke(0);
line(x-15, y - 15, x-5, y - 5);
line (x - 15, y - 5, x -5, y - 15);
line(x+15, y - 15, x+5, y - 5);
line (x + 15, y - 5, x + 5, y - 15);
//lightning bolt
noStroke();
fill(255, 156, 253);
quad (x + 50, y + 45, x + 75, y + 45, x + 65, y + 65,
x + 45, y + 65);
quad(x + 65, y + 65, x + 45, y + 65, x + 60, y + 80,
x + 75, y + 80);
triangle(x + 60, y + 80, x + 75, y + 80, x + 55, y + 110)
//mouth
if (x == y){
noFill();
stroke(0);
arc(x, y + 20, size/2, size/2, PI, 2*PI); // frown
fill(93, 146, 245);
noStroke();
circle(x - 15, y+3, 5);
triangle(x - 17.5, y +3, x - 12.5, y+ 3, x - 15, y - 5)
//text
textSize(15);
stroke(245, 237, 93);
fill(93, 146, 245);
text("drippy", x - 20, y + size + 10);
}else{
noFill();
stroke(0);
arc(x, y, size / 2, size /2, .1*PI, .9 * PI); // smile
}
}
}
noLoop();
}
I based this design off a doodle that i have been drawing for a while and decided to play with gradients, shapes, and texts to create a textile fabric pattern that I would love to wear.
Project 5 – Wallpaper
The famous Coca-Cola bottle and its mascot, the polar bear, were my inspiration for this wallpaper. I first digitally sketched a Coca-Cola bottle to use as a template, as shown at the bottom, and then, I added some polar bears as decoration.
/* Michelle Kim
* michell4
* Section B
*/
function setup() {
createCanvas(600, 600);
background(220);
text("p5.js vers 0.9.0 test.", 10, 15);
}
function draw() {
background(255, 244, 196);
//cola
for(var x = 75; x < width; x += 200) {
for(var y = 50; y < height; y += 220) {
push();
translate(x, y);
cola();
pop();
}
}
//polar bear
for(var a = -40; a < width; a += 200) {
for(var b = 20; b < height; b += 220) {
push();
translate(a, b);
bear();
pop();
}
}
}
function cola() {
push();
scale(0.5);
//bottle
fill(193, 252, 255);
noStroke();
rect(0, 0, 40, 70);
quad(40, 65, 0, 65, -12, 95, 52, 95);
ellipse(20, 130, 75, 125);
quad(-13, 160, 53, 160, 40, 190, 0, 190);
quad(45, 190, -5, 190, -18, 225, 58, 225);
arc(20, 280, 95, 200, radians(170), radians(10), CHORD);
noFill();
stroke(223, 248, 255);
strokeWeight(12);
arc(-7, 58, 25, 50, 0, radians(60));
arc(47, 58, 25, 50, radians(120), radians(180));
arc(-15, 185, 23, 75, radians(283), radians(80));
arc(55, 185, 23, 75, radians(100), radians(256));
arc(20, 287, 82, 15, 0, radians(180));
//soda
fill(68, 32, 10);
noStroke();
arc(20, 90, 40, 200, radians(340), radians(200), CHORD);
arc(11, 125, 40, 100, radians(80), radians(255));
arc(29, 125, 40, 100, radians(285), radians(100));
rect(0, 165, 40, 50);
arc(20, 278, 75, 178, radians(170), radians(10), CHORD);
arc(20, 284, 74, 21, 0, radians(180));
noFill();
stroke(68, 32, 10);
strokeWeight(12);
arc(-7, 183, 23, 80, radians(290), radians(80));
arc(47, 183, 23, 80, radians(100), radians(250));
//cap
fill(170, 0, 0);
noStroke();
rect(0, 0, 40, 16);
circle(1, 8, 15);
circle(39, 8, 15);
//label
rect(-15, 110, 70, 40);
noFill();
stroke(170, 0, 0);
strokeWeight(5);
arc(-11, 130, 8, 55, radians(100), radians(260));
arc(51, 130, 8, 55, radians(280), radians(80));
//bubbles
fill(200);
noStroke();
circle(23, 95, 10);
circle(33, 100, 5);
circle(37, 91, 7);
circle(10, 160, 5);
circle(25, 168, 8);
circle(12, 180, 13);
circle(27, 183, 5);
circle(0, 270, 5);
circle(-7, 280, 10);
circle(40, 260, 15);
circle(25, 270, 7);
circle(45, 275, 5);
pop();
}
function bear() {
push();
//polar bear ears
fill(255);
noStroke();
circle(5, -12, 20);
circle(45, -12, 20);
fill(220);
circle(5, -12, 10);
circle(45, -12, 10);
//polar bear body
fill(255);
rect(0, 0, 50, 70);
arc(25, 0, 50, 40, radians(180), 0);
circle(-5, 45, 15);
circle(45, 46, 50);
circle(70, 45, 15);
noFill();
stroke(255);
strokeWeight(5);
arc(60, 10, 25, 35, radians(110), radians(190));
line(3, 0, 1, 40);
fill(255);
arc(52, 45, 46, 50, radians(0), radians(120));
arc(5, 45, 30, 50, radians(60), radians(175));
ellipse(28, 65, 25, 10);
//polar bear outlines
fill(220);
noStroke();
circle(63, 47, 4);
circle(70, 47, 4);
circle(72, 53, 4);
circle(62, 58, 12);
noFill();
stroke(220);
strokeWeight(2);
arc(-7, 46, 10, 50, radians(300), radians(80));
arc(1, 65, 10, 15, radians(130), radians(190));
arc(13, 46, 10, 50, radians(300), radians(80));
arc(21, 65, 10, 15, radians(130), radians(190));
arc(38, 46, 10, 50, radians(300), radians(80));
arc(46, 65, 10, 15, radians(130), radians(190));
arc(67, 52, 30, 30,radians(205), radians(272));
//polar bear face
fill(220);
noStroke();
circle(25, 10, 18);
fill(0);
circle(13, 0, 6);
circle(37, 0, 6);
ellipse(25, 7, 7, 5);
noFill();
stroke(0);
strokeWeight(1);
arc(23, 10, 4, 8, 0, radians(130));
arc(27, 10, 4, 8, radians(50), radians(180));
pop();
}