吳哲宇 彙整 | Creative Coding TW - 互動程式創作台灣站 https://creativecoding.in/tag/吳哲宇/ 蒐集互動設計案例、教學與業界資源,幫助你一起進入互動程式創作的產業 Mon, 31 Jul 2023 07:01:47 +0000 zh-TW hourly 1 https://wordpress.org/?v=6.2.2 https://creativecoding.in/wp-content/uploads/2022/03/cropped-cct-logo-icon-2-32x32.png 吳哲宇 彙整 | Creative Coding TW - 互動程式創作台灣站 https://creativecoding.in/tag/吳哲宇/ 32 32 CC!我跟你說!S1EP4|黃新來聊聊:創作鑑賞與教學心路歷程 https://creativecoding.in/2023/07/31/podcast-s1ep4/ Mon, 31 Jul 2023 07:01:46 +0000 https://creativecoding.in/?p=3966 本集我們邀請到了——黃新一起來聊聊。黃新分享了他踏入互動藝術領域的契機,當時是如何啟發他進入這個領域的。我們深入探討了生成式藝術的獨特之處,了解這一藝術形式在當代藝術中的地位和特點。除此之外,我們還聽取了黃新分享他踏入互動藝術教學領域的原因和故事,讓我們更深入了解他對於教學的熱情和使命感。

這篇文章 CC!我跟你說!S1EP4|黃新來聊聊:創作鑑賞與教學心路歷程 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>

本集我們邀請到了——黃新一起來聊聊。黃新分享了他踏入互動藝術領域的契機,當時是如何啟發他進入這個領域的。我們深入探討了生成式藝術的獨特之處,了解這一藝術形式在當代藝術中的地位和特點。除此之外,我們還聽取了黃新分享他踏入互動藝術教學領域的原因和故事,讓我們更深入了解他對於教學的熱情和使命感。

在這一集的節目中,我們透過黃新的親身經歷和專業知識,深入探討了互動藝術和生成式藝術的精彩世界,也了解了台灣數位藝術創作者所面臨的現實挑戰!

至以下平台收聽: FirstStory / Spotify / KKBOX / Pocket Casts / Apple / Google / SoundOn

⬢ 黃新小資訊 ⬢

黃新,別名紐耶羅(newyellow),是新媒體世界的定居者,也可稱為加密世界的新移民。他在數位互動藝術領域有著超過十年的資歷,在政大就讀數位內容學程碩士時,他就對 AR/VR 等互動科技深感興趣。自 2011 年起,他開始嘗試進行數位藝術創作,作品更曾三度獲得國際黑客松 AR Spark 首獎,展現了他在此領域的卓越才華。

除了作為一位成功的數位藝術家外,黃新也是 Meta 元宇宙培訓學院的合作講師,同時也是政大區塊鏈應用課程的講師,專注於教授與分享他對數位互動藝術的知識。作為生成式藝術的創作者和收藏家,他在這個領域中扮演著重要的角色,持續為藝術世界帶來創新和驚喜。

⬢ 老闆小資訊 ⬢

老闆哲宇是互動設計師、墨雨互動設計創辦人、數位藝術家、講師、全端工程師。先前在紐約大學進修整合數位媒體碩士,在 Creative Coding 領域有相當厲害的創作專業,知名 NFT 作品包含 PochiHamily 家族等。

哲宇在教學推廣上也不遺餘力,引領超過 20,000 位學生進入互動網頁與生成藝術開發的大坑。在文化推廣上,他成立了 FAB DAO ,希望能提攜台灣數位藝術家,被世界看見,期望可以帶著更多人,在數位世界中創造驚喜的體驗與生命。

 精選片段 

Generative Art 大賣秘辛「毛毛密碼」㊙️?

⬢ 本集重點 ⬢

02:13 踏入互動藝術領域的契機

09:37 生成式藝術的獨特之處

18:59 生成式藝術都在模仿嗎?

23:44 作品大賣的神秘密碼

27:50 fxhash造就的生成式藝術作品寒武紀大爆炸

34:23 踏入互動藝術教學的原因與故事

42:42 談談Volume Dao

45:42 台灣數位藝術創作者的生存之路

如果有任何的意見回饋或建議,歡迎來信讓我們知道,各位的參與是我們進步的動力。讓我們一起朝向更好的 Podcast 節目邁進吧!

⌔ 寫信給我們:creativecoding@monoame.com

這篇文章 CC!我跟你說!S1EP4|黃新來聊聊:創作鑑賞與教學心路歷程 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
CC!我跟你說!S1EP3|數位世界的創作革命:NFT與藝術的關係 https://creativecoding.in/2023/07/13/podcast-s1ep3/ Thu, 13 Jul 2023 07:59:09 +0000 https://creativecoding.in/?p=3949 在本集的Podcast中,我們將探討 NFT 與藝術之間的關係,以及它們對藝術創作和創意產業的影響。這一集將帶領你進入 NFT 和藝術的精彩世界,並深入了解其對藝術創作和創意產業的重要影響,還有聽聽老闆在 NFT 市場的故事。

這篇文章 CC!我跟你說!S1EP3|數位世界的創作革命:NFT與藝術的關係 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>

在本集的 Podcast 中,我們將探討 NFT 與藝術之間的關係,以及它們對藝術創作和創意產業的影響。這一集將帶領你進入NFT和藝術的精彩世界,並深入了解其對藝術創作和創意產業的重要影響。還有聽聽老闆在NFT市場的故事,絕對讓你留下深刻的印象!

至以下平台收聽: FirstStory / Spotify / KKBOX / Pocket Casts / Apple / Google / SoundOn

⬢ 老闆小資訊 ⬢

老闆哲宇是互動設計師、墨雨互動設計創辦人、數位藝術家、講師、全端工程師。先前在紐約大學進修整合數位媒體碩士,在 Creative Coding 領域有相當厲害的創作專業,知名 NFT 作品包含 PochiHamily 家族等。

哲宇在教學推廣上也不遺餘力,引領超過 20,000 位學生進入互動網頁與生成藝術開發的大坑。在文化推廣上,他成立了 FAB DAO ,希望能提攜台灣數位藝術家,被世界看見,期望可以帶著更多人,在數位世界中創造驚喜的體驗與生命。

 精選片段 

程式碼也有歲月痕跡嗎?數位泛黃究竟是什麼樣的概念呢?

⬢ 本集重點 ⬢

05:01 究竟什麼是 NFT?

08:35 數位扭曲/數位失真 🌬️

11:33 NFT 市場中的精品店和假日市集?

14:19 殿堂中的經典作品

19:10 NFT 才能玩的創作技術

23:10 老闆作品被盜用的心酸故事

28:43 開源程式碼的所有權歸屬問題

31:41 進入 NFT 市場對創作初心的影響

36:43 「數位版畫」&「審美外包」的討論

如果有任何的意見回饋或建議,歡迎來信讓我們知道,各位的參與是我們進步的動力。讓我們一起朝向更好的 Podcast 節目邁進吧!

⌔ 寫信給我們:creativecoding@monoame.com

這篇文章 CC!我跟你說!S1EP3|數位世界的創作革命:NFT與藝術的關係 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
CC!我跟你說!S1EP2|深入互動設計世界:趨勢、多元應用與創業挑戰 https://creativecoding.in/2023/06/05/podcast-s1ep2/ Mon, 05 Jun 2023 07:41:19 +0000 https://creativecoding.in/?p=3923 這一集將深入探討互動設計產業目前的趨勢,也聊聊老闆創立工作室的契機和創業過程的大小故事。節目中還談到了公司在草創初期面臨的困難,以及大學時期的創業酷點子,也進一步聊到目前台灣互動設計的厲害團隊和有趣精彩的作品專案。最後,老闆還分享了他在藝術史中發現的秘辛!快來一起收聽第二集,探索互動設計的精彩世界吧!

這篇文章 CC!我跟你說!S1EP2|深入互動設計世界:趨勢、多元應用與創業挑戰 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>

這一集將深入探討互動設計產業目前的趨勢,也聊聊老闆創立工作室的契機和創業過程的大小故事。節目中還談到了公司在草創初期面臨的困難,以及大學時期的創業酷點子,也進一步聊到目前台灣互動設計的厲害團隊和有趣精彩的作品專案。最後,老闆還分享了他在藝術史中發現的秘辛!快來一起收聽第二集,探索互動設計的精彩世界吧!

至以下平台收聽: FirstStory / Spotify / KKBOX / Pocket Casts / Apple / Google / SoundOn

 老闆小檔案 

老闆哲宇是互動設計師、墨雨互動設計創辦人、數位藝術家、講師、全端工程師。先前在紐約大學進修整合數位媒體碩士,在 Creative Coding 領域有相當厲害的創作專業,知名 NFT 作品包含 Pochi 、 Hamily 家族等。

哲宇在教學推廣上也不遺餘力,引領超過 20,000 位學生進入互動網頁與生成藝術開發的大坑。在文化推廣上,他成立了 FAB DAO ,希望能提攜台灣數位藝術家,被世界看見,期望可以帶著更多人,在數位世界中創造驚喜的體驗與生命。

 精選片段 

老闆回憶大學時青澀的創業想法:做很快才不是重點!真正重要的是…

 本集重點 ⬢

02:08 互動設計產業的人才與求職趨勢

02:59 AR/VR/MR/XR小教室 👨‍🏫

05:18 老闆創立工作室的契機

07:16 公司草創初期的困難點

10:16 大學時期的創業酷點子和驚人發言

11:35 「墨雨」的由來 🌧️ 和願景

18:56 台灣の互動設計團隊 👥

25:28 互動設計的商業運用 💰

30:21 老闆在藝術史發現的秘辛… ㊙️

如果有任何的意見回饋或建議,歡迎來信讓我們知道,各位的參與是我們進步的動力。讓我們一起朝向更好的 Podcast 節目邁進吧!

⌔ 寫信給我們:creativecoding@monoame.com

這篇文章 CC!我跟你說!S1EP2|深入互動設計世界:趨勢、多元應用與創業挑戰 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
CC!我跟你說!S1EP1|理工宅的藝術創作之路:國內外程式創作、互動藝術進修資源,以及老闆的建議 https://creativecoding.in/2023/05/17/podcast-s1ep1/ Wed, 17 May 2023 08:18:14 +0000 https://creativecoding.in/?p=3767 在本集中,我們將探索 Creative Coding 的奧秘——里歐娜會和老闆一起討論什麼是 Creative Coding ,以及老闆是如何踏上這條路的,在這條路上,又遇到了什麼樣的困難和驚喜之事呢?我們還會分享一些有趣的案例,並且比較台灣與國外的程式創作資源的不同之處。如果你曾經對學習程式的門檻感到困惑,相信本集也會對你有所啟發。

這篇文章 CC!我跟你說!S1EP1|理工宅的藝術創作之路:國內外程式創作、互動藝術進修資源,以及老闆的建議 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>

在本集中,我們將探索 Creative Coding 的奧秘——里歐娜會和老闆一起討論什麼是 Creative Coding ,以及老闆是如何踏上這條路的,在這條路上,又遇到了什麼樣的困難和驚喜之事呢?我們還會分享一些有趣的案例,並且比較台灣與國外的程式創作資源的不同之處。

如果你曾經對學習程式的門檻感到困惑,相信本集也會對你有所啟發。最後,我們也會分享近期 Creative Coding 相關的活動資訊!

至以下平台收聽: FirstStory / Spotify / KKBOX / Pocket Casts / Apple / Google / SoundOn

老闆小檔案

老闆哲宇是互動設計師,也是數位藝術家、講師、全端工程師。先前在紐約大學進修整合數位媒體碩士,在 Creative Coding 領域有相當厲害的創作專業,知名 NFT 作品包含 Pochi 、 Hamily 家族等。

哲宇在教學推廣上也不遺餘力,引領超過 20,000 位學生進入互動網頁與生成藝術開發的大坑。在文化推廣上,他成立了 FAB DAO ,希望能提攜台灣數位藝術家,被世界看見,期望可以帶著更多人,在數位世界中創造驚喜的體驗與生命。

精選片段

老闆的大學回憶:在學聯會行銷部,用 Arduino 做了蝦趴聖誕樹,還在 Dcard 上爆紅?

本集重點 ⬢

02:21 究竟什麼是Creative Coding?

03:31 老闆開始接觸Creativ e Coding的契機

05:17 Creative Coding的有趣案例

08:28 藏在非典型電機人內心的創作熱血🔥

09:39 出國進修的動機💭、國外程式創作與教育環境

15:59 我們都有茫然的時期…

18:16 國外的程式創作資源、互動設計風氣和台灣有什麼不同?

21:31 面對學習程式的門檻,我該怎麼辦——身為過來人,老闆用心良苦的建議

30:44 在台灣的進修資源有哪些

32:20 學習Creative Coding有什麼出路或運用?

36:36 老闆語重心長的建議

38:09 近期Creative Coding相關活動資訊

如果有任何的意見回饋或建議,歡迎來信讓我們知道,各位的參與是我們進步的動力。讓我們一起朝向更好的 Podcast 節目邁進吧!

⌔ 寫信給我們:creativecoding@monoame.com

這篇文章 CC!我跟你說!S1EP1|理工宅的藝術創作之路:國內外程式創作、互動藝術進修資源,以及老闆的建議 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
【p5.js 程式創作】Soul Fish 數位永恆生命的靈魂魚 – 製作流程 https://creativecoding.in/2023/03/02/soul-fish-process/ Thu, 02 Mar 2023 08:59:45 +0000 https://creativecoding.in/?p=3510 此篇文章是前陣子發行的作品 - 靈魂魚 - 背後的製作流程,關於如何使用程式來創作一隻夢幻的數位生物!靈魂魚的作品是用理性的程式創造生命感的探索,也融合了互動生成音樂與視覺,是在互動型 NFT 邊界上的探索之作 。

這篇文章 【p5.js 程式創作】Soul Fish 數位永恆生命的靈魂魚 – 製作流程 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
本次內容將會以前陣子發布的作品「靈魂魚」作為主題,分為創作故事製作流程分別介紹,此篇主要是製作流程的分享。靈魂魚的作品是如何使用理性的程式創造生命感的探索,也融合了互動生成音樂與視覺,也是在互動型 NFT 邊界上的探索之作 。

靈魂魚的創作故事:p5.js 程式創作 | Soul Fish 數位永恆生命的靈魂魚 – 創作故事

老闆在直播中分享五月份至美國紐約參加研討會的感想,研討會上有像是 6529 等創作家在研討會上做分享交流。讓老闆想到,最一開始接觸 NFT 是因為創作,從創作上也有看到像是 Pak 這樣藝術家的作品,純粹、好玩卻也附有商業性價值,因此開始接觸區塊鏈,參加像是 Consesus 這樣的區塊鏈相關活動。雖然近期不論國內與國外,對於虛擬世界的交易開始有些反感的聲浪出現,但也因此某些事項反而逆勢而起,像是在 Art Blocks 上購買生成式藝術的趨勢逐漸成長。在創作上,老闆也建議,雖然觀眾在某一期間追求的風格會相似,導致大多創作人會往同風格進行創作,但也不要忘了,走出自己的路線才最有可能被記憶紀錄。

為什麼會選靈魂魚當主題與創作概念?

在準備個展期間,有關看到一部與金魚相關影集,觀察到金魚本身的姿態,因此以此為創作靈感來源。取名自老闆的姓名,靈魂魚誕生於虛空之中,由各式各樣的情緒凝結在深海中誕生,他靜靜的在那邊帶來平靜,自己游著,有些靈魂與全身長滿了亮麗的鱗片,有些則默默地緩緩地飄動,身軀幾乎消逝於深海的光線中。

p5.js 靈魂魚實作示範

創作的初始概念,先以 Shader 呈現(下方圖示參考),使用扭曲線條模擬金魚尾巴線條的流動。 Shader 本來是以點到點之間連成的線條組成,在其後,老闆應用 Sin 波的原理,將 Shader 線條隨著波長座移動變化。

再來進到金魚的輪廓姿態,下方第一版的金魚創作其實可以看出大致上金魚的形狀,以及圖樣上模糊的效果,呈現靈魂的感覺。

將金魚的輪廓以線條構出後,發現從身體上半步到尾巴下半部的線條,呈現 Sin 波的形狀,就以多重 Sin 波線條組成第一版金魚。老闆也實際操作一次供大家參考,首先,由左到右畫出連成一條線。

function setup() {
  createCanvas(windowWidth, windowHeight);

  background(100);
}

function draw() {
  background(255);

  beginShape();

  for (x = 0; x < width; x += 20) {
    stroke(0);

    strokeWeight(5);

    vertex(x, height / 2);
  }

  endShape();
}

當線條畫出來之後,如何形成金魚的輪廓形狀呢?由左到右以及上下的的曲線變化,這時就需要加上 Sin 波,呈現出魚的一半輪廓。

function draw() {
  background(255);

  beginShape();

  for (x = 0; x < width; x += 20) {
    let ang = map(x, 0, width, 0, PI * 1.5);

    let y = height / 2 + (sin(ang) * height) / 5;

    stroke(0);

    strokeWeight(5);

    vertex(x, y);

    circle(x, y, 20);
  }

  endShape();
}

得出單一線條後,以相反方向再繪製出另一條線,將完整金魚的輪廓勾勒出來。

function draw() {
  background(255);

  translate(width / 2, height / 2);

  scale(0.8);

  translate(-width / 2, -height / 2);

  for (direction = -1; direction <= 1; direction += 1) {
    beginShape();

    stroke(0);

    noFill();

    strokeWeight(5);

    for (x = 0; x < width; x += 20) {
      let ang = map(x, 0, width, 0, PI * 1.5);

      let y = height / 2 + ((sin(ang) * height) / 5) * direction;

      vertex(x, y);

      circle(x, y, 20);
    }

    endShape();
  }
}
第一版金魚圖示

上述大略是第一版金魚的組成方式,但老闆認為於本身可以再更活潑的方式做律動,於是進行第二版的製作。第二版的示範操作,著重在呈現魚尾巴,如雨水般的流動感外,也將除了輪廓外的線條作範例,呈現擁有底色與動態的尾巴。

function draw() {
  background(255);

  translate(width / 2, height / 2);

  scale(0.8);

  translate(-width / 2, -height / 2);

  for (direction = -1; direction <= 1; direction += 0.2) {
    beginShape();

    stroke(0);

    noFill();

    strokeWeight(5);

    for (x = 0; x < width; x += 20) {
      let ang = map(x, 0, width, 0, PI * 1.5);

      let y = height / 2 + ((sin(ang) * height) / 5) * direction;

      let xx = x;

      if (ang > PI) {
        xx += (ang - PI) * 50;

        xx += sin(xx / 40 + frameCount / 50) * 50;
      } else {
        if (x % 40) {
          arc(xx, y, 100, 100, -PI / 4, PI / 4);
        }
      }

      noStroke();

      vertex(xx, y);

      fill(255, 0, 0, 90);

      arc(xx, y, 5, 5, -PI / 2, PI / 2);

      circle(x, y, 1);
    }

    endShape();
  }
}
第二版金魚圖示

反覆編輯的過程中,從第一、第二版次的基本輪廓呈現,到了第三版大面積的色彩變化(下方圖示參考),以及最後,第四版層疊了鱗片出現發光發亮的質感(下方圖示參考),再繼續堆疊後,變會呈現帶有霧霧的靈魂感覺。這樣的靈魂質感,是如何執行的呢?

第三版金魚圖示
第四版金魚圖示

在第四版金魚上,主要強調使用 blendMode,並進行疊光 screen,就能發現微發光的質感。而後建議以 shader 再去修飾外型,下方程式與圖片為示範範例。

function draw() {
  push();

  beginShape();

  background(0);

  translate(width / 2, height / 2);

  scale(0.8);

  translate(-width / 2, -height / 2);

  blendMode(SCREEN);

  for (direction = -1; direction <= 1; direction += 0.2) {
    noFill();

    strokeWeight(5);

    for (x = 0; x < width; x += 20) {
      let ang = map(x, 0, width, 0, PI * 1.5);

      let y = height / 2 + ((sin(ang) * height) / 5) * direction;

      let xx = x;

      if (ang > PI) {
        xx += (ang - PI) * 50;

        xx += sin(xx / 40 + frameCount / 50) * 50;
      } else {
        if (x % 40) {
          arc(xx, y, 150, 150, -PI / 4, PI / 4);
        }
      }

      noStroke();

      vertex(xx, y);

      fill(255, x / 2, 0, 100);

      arc(xx, y, 5, 5, -PI / 2, PI / 2);

      circle(xx, y, 5);
    }
  }

  pop();
}
第四版金魚圖示

特殊技法介紹

在完成了基本霧面質感金魚後,老闆進到 shader 技法教學。在這邊使用到 shader 的原因是想呈現發亮的螢光感,以及 shader 特有的毛邊質感。在背景中的流體顏色,也是應用 shader去達到此效果,而這樣的概念從老闆早期作品中,就陸續有不同的變化。像是如同宇宙星河般的效果,堆疊的彩色雲層。這樣雲層的概念,又是取自於老闆本身的創作,純粹使用 p5.js 繪製出的雲層效果(下方圖示)

宇宙星河作品變化

從 p5.js 單點渲染,到 shader 即時動態渲染,後面更進化到會滑動的線條,甚至在線條與線條間也出現反光感的效果,呈現細緻,類似地層沉積剖面的質感,也應用這樣的技法呈現在靈魂魚的背景中。

背景範例

老闆也提到,他認為目前應用 shader 最極致的呈現是如同金屬液態的質感創作(下方圖示)

金屬液態圖示

要呈現這樣的效果,就是將背景進行扭曲。像此圖示最初是一張漸層平面圖(下方圖示),形成原理是以多個點點構成一張圖的基底平面,每個點點會有著大小不同的漩渦,再以每個點點在圖上偏移的角度要是多少,與漩渦的方向還有角度構出。

漸層平面圖

不過老闆也說,雖然 shader 很有趣,作品彈性高,但缺點是每次遇到不同型態的需求都會需要重新造輪子,所以目前實際手寫 shader 的人不多,通常都還是以 3D 軟體執行,或是使用 Unreal、Unity 和 shader note editor 等等。以 node based shader editor 為範例,一樣也是經由不同的部分進行疊加,但不一樣的是,已經進行了模組化,讓使用上更快速簡便。

(截圖自 node based shader editor

讓我們重新回到作品靈魂魚的技法上吧!

在創作金魚本體時,我們有使用到一個叫做 blendmode 的融合選項,在 blendmode 中其實有兩種不同的方式能呈現疊色。第一個就是上述有提及的 blendmode(SCREEN),這一項變化就是讓疊色時出現螢光的效果,再來第二個就是 blendmode(MULTIPLY),而這線就是將疊色效果呈現墨水的質感。以下使用範例是以多線條的方式,進行 blendmode(MULTIPLY),所呈現出的細緻金魚。

疊色技法金魚(截圖自影片

以魚鰭來舉例,下方圖示可以看到老闆簡單的說明

金魚魚鰭說明(截圖自影片

魚鰭是依據金魚身體上半部的輪廓點延伸,設定在特定距離上做不同點,再依這些點連成一條又一條組合成魚鰭的線。不過,也因為以線條作為主要組成金魚的來源,所以效能上並不是非常理想。在最終完成品上,可以觀察到,除了金魚本身與線條外,內部也有像是生命線般,會在魚擺動時跟著起舞,這個部分是老闆使用物理模擬操作。在 p5.js 中, Example 中有一個系列叫做 Simulation 物理模擬,在這系列裡,像是 chain,此功能就是將特定點與點之間連成線外,也能進行動態移動,除了作品上,老闆也將其運用在官網上面,將視覺衝擊更加優化。

官網應用(截圖自墨雨設計官網

作品在電腦上完成後,老闆也有將靈魂魚藉由台北藝術中心舉辦的活動,大範圍的投影在藝術中心外,最顯眼的位置做展示。

台北藝術中心展示(截圖自老闆推特

生成式音樂

在圖樣不斷變化的過程中,老闆也在本次創作中增加入生成式音樂做襯托,讓音樂配合游動的靈魂魚產生不同音調。不過生程式藝術結合音樂輔助呈現這個部分,目前是 fxhash 才提供可上架的服務,因為生成式音樂本身檔案較大,像是 artblocks 目前無法接收過大的夾帶檔案。靈魂魚的生成式音樂是將每一節的音樂 sample 檔案與空白格做不同的排列組合,使用 tone.sampler 做完整拼接,拼接完再套用 bpm 讓整段旋律有休止或是不同的音樂變化,最後,再以 reverb 營造具有回音的空間感,讓我們在觀看、收聽時,能夠聽到一段又一段的美妙旋律。

生成式音樂撰寫(截圖自影片

如何將作品上架 fxhash

接下來,我們進入統整上 fxhash 的流程,老闆習慣當作品在 openprocessing 修整到一定程度後,就回到 VsCode 上,使用 fxhash 的模板進行整合。 fxhash 的模板會提供一個固定的亂數,引導你如何使用這套亂數,讓導出的結果都是一樣的(參考連結),而 fxrand 就是提供的亂數名稱,只要給它特定的 hash,就會產生特定的 random。在 VsCode 編輯上,老闆就會針對例如說 features 的這個選項進行編輯。為何是 features 呢?在將生成式藝術上架到 fxhash 時,都會需要標記每一個作品產出的相關特徵,而老闆通常會使用 renderfeatureas() 的方式,將特徵全都渲染出來,但也有時候會因為抓取的值與原本創作呈現的值其實是不同的狀況,這時候就會需要再根據一定的規則算出,我們最終要顯示的是什麼。這樣,在告訴收藏家時,也能以較通俗的說明讓藏家了解作品本身,除了意象外的特徵內容。

fxhash 模板介面(截圖自影片
fxhash 模板 feature 介面(截圖自影片

為了應對較複雜的上架流程,老闆製作了一個名為「previewer」的專案,這個專案可以印出所有生成式藝術作品中的渲染結果。當今天一個作品渲染出了一千張圖片後,這個功能會將這一千張圖片綜合在一個小型網頁上,然後可以在此網頁上進行不同種類的過濾,以進行每一張渲染圖片的檢查。在上架方面,老闆分享了他在fxhash上架時遇到的問題,包括價格、數量和最初設定的販售名單和策略之間的差異,因此他建議同學們在這方面要多加注意。此外,他還提到了作品呈現方面的要求,希望之後製作的每一件作品都能具有足夠的精采度。在前置作業完成後,老闆帶領我們稍微講解了白名單處理流程。在NFT世界中,每當我們購買一件項目,都需要鑄造並購買NFT,但通常NFT在販售時會有數量限制,並非所有人都能鑄造,這就是「白名單」的概念。白名單主要是指只有在名單內的購買方才能鑄造項目,因為他們已經預先保留在名單中了。因此,賣方需要在fxhash上設定白名單流程,首先,要去「mint generation token」瀏覽要上傳的解壓縮檔案,然後按照每個步驟的要求進行上傳或選項勾選,最後,確定上架後就完成了。老闆還建議上架最好一次上完,並且數量控制在256到500之間,這樣對於購買單項作品的買家再繼續購入,帶來的後續效益會更大。老闆也順勢舉例近期執行的「FabDAO 百岳山脈計畫 」,此計畫除了老闆外也與多位藝術家合作,執行公益的 NFT 計畫。在計畫中,老闆的作品便是以 Shader 執行,也示範有無 Shader 的差異。作品內容都十分精彩,有興趣的同學都歡迎至官網做更進一步的了解。

新作品介紹

新作品呈現如同粒子搬形成的圖畫,經由 Shader 再去製造出邊緣不規則的狀態。

最初作品構想(參考連結

作品經反覆編輯製作後,以2D 生成3D 的方向勾勒出虛擬世界感。而此項目將會與老闆致英國作展出。展出的地方名為 Outernet London,主要就是在進行生成式藝術展示的展館,那到時至英國後,老闆也會與共同展出的藝術家們合作交流,後續有任何更新也都會開直播影片與大家分享心得。

預計展出的圖片參考(截圖自影片

總結

在最後也觀眾提出有關近期蔚為風潮,MidJourney – AI 生成藝術的相關問題,老闆也對於這個興起的議題提出了一些看法。其實,不論是生成式藝術與 AI 生成藝術都是經由更快速與便利,與傳統手繪不同的數位化方法進行藝術創作,個人特色或是創意能不能持續表現,才是更值得被記錄的,也希望大家都能勇於嘗試不同的方法做各式各樣的藝術創作探索。

如果想要更深入的了解,目前有與李婷婷講師合開針對 Web3的相關課程,也歡迎直接訂閱老闆的 Youtube 頻道,時不時會有直播 live coding或是近期有持續更新像是 Web3相關影片等等,都歡迎加入並進行踴躍發問喔!

以上就是本次影片和文章的介紹啦!別忘了加入互動藝術程式創作入門課程開始學習吧!還有不要忘了追蹤老闆 Twitter 和訂閱老闆,來點寇汀吧。Boss, CODING please. Youtube 頻道隨時補充新媒體藝術的養份,讓我們一起探索這多元的世界吧!下次見~

此篇直播筆記由幫手熊柑協助整理

這篇文章 【p5.js 程式創作】Soul Fish 數位永恆生命的靈魂魚 – 製作流程 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
【p5.js 程式創作】Soul Fish 數位永恆生命的靈魂魚 – 創作故事 https://creativecoding.in/2023/01/30/soul-fish-story/ Mon, 30 Jan 2023 10:42:09 +0000 https://creativecoding.in/?p=3475 在這篇文章中,哲宇想跟大家介紹為什麼會製作靈魂魚,如何透過多重感官觀賞作品,他的完整故事與設計,以及在視覺跟聽覺和互動上的巧思,曾展出的空間形式和未來期待繼續發展的方向!

這篇文章 【p5.js 程式創作】Soul Fish 數位永恆生命的靈魂魚 – 創作故事 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
本次內容將會以前陣子發布的作品「靈魂魚」作為主題,分為創作故事製作流程分別介紹,此篇主要是製作流程的分享。靈魂魚的作品是如何使用理性的程式創造生命感的探索,也融合了互動生成音樂與視覺,也是在互動型 NFT 邊界上的探索之作 。

靈魂魚的製作過程:【p5.js 程式創作】Soul Fish 數位永恆生命的靈魂魚 – 製作過程

SoulFish #183

大家好,我是生成式藝術家吳哲宇,四五年前我開始製作動態的數位藝術,像是互動網站、平面設計等開始對踏入互動設計的領域,後來研究所到了紐約 NYU 互動媒體學系讀書,因此認識了 Creative Coding 這個領域而深深著迷,發現程式也有很多的可能性,不僅是為了設計或是達成目標而存在,而是寫程式的本身即是藝術

在這篇文章中,我想跟大家介紹為什麼會製作靈魂魚,如何透過多重感官觀賞作品,他的完整故事與設計,以及在視覺跟聽覺和互動上的巧思,曾展出的空間形式和未來期待繼續發展的方向!

Soul Fish Fxhash 作品專案連結 ( https://www.fxhash.xyz/generative/slug/soulfish )

我曾製作了很多互動型態的作品,像是 CryptoPochi 或是 Seahams,也曾在 Foundation 平台上嘗試傳統繪畫手法探索美術館質感的作品,我發現我最喜歡的是能夠製造有機的狀態,意味著作品的本身的隨機性除了表現在初始屬性之外,也隨著動態生長讓作品在執行的過程中有一定的隨機度,例如粒子的軌跡是由每個時刻的亂數累積決定的,最後繪製成一個完整的作品,得益於亂數原理與現在的區塊鏈技術,我們能夠確保在同一個數位作品中,完美而精準的重現隨機過程,這是我覺得最迷人的部分。

永恆的生命是什麼樣子?

剛開始想到製作靈魂魚的時候,我的靈感來自於深海生物,他們的形體透明的浮游在水中,通常會有一些自己的發光器官來照亮周圍的環境,我覺得這樣的有機感很迷人,也很喜歡一些像是光暈、觸鬚般物理上的物理模擬動態,因此想來以深海魚作為主題來創作一個作品,我想要創造出深海中精細結構帶有透明狀態的魚的感覺,這些魚像是靈魂似的漂浮在幽暗的水域中,因此取名為「靈魂魚」,這些魚能夠永恆的存在與游動,不跟著時間的進行而逝去。

靈魂魚其實也同時取名自我自己的名字 – 吳哲宇最後一個字,他們靈魂魚誕生於虛空之中,在各式各樣的情緒凝結,在深海中誕生,他靜靜的在那邊帶來平靜,自己游著,有些靈魂與全身長滿了亮麗的鱗片,有些則默默地緩緩地飄動,身軀幾乎消逝於深海的光線中。

如何去繪製魚柔軟有機的形體呢?

在製作初期,我仔細的觀察後發現,魚的形狀類似於一個波(sin/cos)的前半部所有狀態疊加的形狀,所以如果我把一條波的線條擷取出來,上下透過不同的比例複製重複,就能夠繪製出外觀。

Sin / Cos 波構成魚的線條

過程中除了計算一個一個點的精確位置之外,也確保不會死板的加入了不同頻率,也就是不同大小的波來建構形體,如果加上了時間函數讓他們慢慢的交錯移動,就能夠形成魚的動態質感。每一個點都有額外再經過噪聲跟波形處理,來創造靈魂般不穩定的形體跟質感,最後再加上從身體到尾部的波狀動態,產生出空間中尾巴來回擺動的效果。

使用波狀函數、自然噪聲以及物理模擬

我製作的第一個版本看起來像實心的卡通魚,接下來逐漸改的透明、加上shader背景,讓所有的線條跟筆觸在繪製時,能夠帶有透明度的重疊,也逐漸加入細節 像是魚骨頭、鬍鬚、魚鰭、尾巴等設計,為了創造出有機感,我混合了材質、形狀跟很多的結構設計,包括中心的魚骨頭一節一節的可以動、生命線的鬍鬚是由20幾個點透過鎖鏈物理模擬的形式來控制,與尾巴跟魚鰭的薄膜每一條線條,都透過精密的計算擺動隨機性的設計,每一隻魚都會有不同的線條數量、大小跟身體結構。

顏色設計上,我讓魚可以橫跨所有的光譜,並且在每一隻魚中,都會有類似泡泡表面的色偏質感,也讓他們的顏色更為有機,隨機性的產生了所有的顏色數值之後,我讓他們再對應到相對的顏色的名字。顏色上會有兩個主要的顏色過渡來建構一隻魚的形體,來確保能夠產生和諧漂亮的漸層,我想要作品呈現出類似極光般的質感以及擁有漂亮的光暈,因此用不同的顏色模式重疊了幾次混合,模擬用光線作為筆觸來去繪製靈魂般的小生物

光線色偏的效果 Soul Fish #123

另外也有一些魚是白色背景的,小時候的我很喜歡生物科學,不同於黑色背景螢光的效果,白色的背景更像是顏料暈染,也很像小時候在做標本時,會將植物的組織切片染色,在顯微鏡底下看到的狀態。

Soul Fish #302
SoulFish #3

背景中有什麼樣的巧思?

在靈魂魚的系列中,有三款主要的背景 – 虛空、波動跟深海,大部分的魚都是虛空背景,能夠讓你在投影或黑暗的空間感受時,能最直觀的感受到作品的神聖感,會將焦點全部都放在魚的身上。波動的背景來自於以前的另一個作品 – 星雲 (220413 Nebula Drift),是由 GPU計算所有的星星之後,動態的扭曲來創造流動的銀河。最後一種背景深海,是模擬由上照下的一束光線穿進深海的質感,在者三款背景中,都有額外加入一些灰塵跟懸浮物,會緩緩地在水中漂動,並會跟著音樂閃爍。

220413 Nebula Drift

如何搭配視覺產生有機的聲音系統設計?

在靈魂魚的作品中,聲音是很重要的部分,在前幾個作品如 Sliderverse 或是 Soul sea 中,我都有嘗試使用 Web audio api 的方式來合成聲響,而在 Soul Fish 這個作品中,我使用了一組鋼琴的 Sample,並在作品開始執行的時候,確定這個作品的和弦進行和旋律線,因為是動態生成的音樂,每一隻魚的旋律線都是獨一無二的,會搭配較高的弦律線與較低的伴奏聲音來構築曲子,每一隻魚都是旋律自動機,能夠合成屬於他的曲調。

SoulFish #59

就像是 生成式視覺一樣,生成式音樂的概念鮮為人知,是打散一首歌的長度跟制式編曲,不是根據既有的譜面來演奏,而是透過規則來去建構音符和和弦的進行,因此可以產生永不停止可以持續生成而有機的聲音編制,在 開啟基因 (B) 的模式中,你能夠看到每隻魚都有自己對應的和弦,是自己的旋律不斷的重複的自動機,另外泡泡破掉時,也可以聽到他觸發高音的鋼琴音符,這也對應到我當初對於作品的期望,是能夠創造視覺與聽覺的詩意同步,當這些所有的感官整合起來觀賞作品時能夠有最完整的體驗。

在互動設計中有哪些可以玩的元素?

在製作作品的最後,我加入了游動與泡泡的設計讓藏家能夠去控制魚的游動時快時慢,以及使用鍵盤往特定的方向移動,我搜尋了一些真實的魚的影片,發現他們其實魚鰭跟尾巴在高速游動時都比我預期的快跟靈活,因此加上了游動的機制之後變的很生動,更像自然中魚類運動的樣子。

除了魚的互動之外,泡泡會不斷的從下方冒上來,你能夠使用滑鼠戳破泡泡,或泡泡碰到魚的時候,會同時觸發高音的鋼琴聲,跟背景的音樂呼應。

發售的狀況與後續調整

在 2023/1/16 順利鑄造完售!

我在 2022 五月時發行了靈魂魚的作品,原本計畫是500版次,原本預期會有很多 Hamily 來 mint 所以調整成 1000 版,近期調整回 400 版確保作品的獨特性,雖然在過去的一年中沒有馬上 mint out,隨著時間過去,終於在 2023 Jan 16, 02:53:29 PM 鑄造完畢,達成了里程碑!

此外,我也曾受邀在台北表演藝術中心的大圓球建築物上投影靈魂魚,在大街上看到魚在圓球上游泳很像實體世界的巨型魚缸。我於台北101的個展 – 「混沌實驗室」中有展出,投影在沈浸式的空間中,沐浴在像是極光般的靈魂魚質感時很浪漫。

2022/5 月在台北 101 的個展 「Chaos Laboratory

除了單件作品的展示之外,我也很喜歡讓靈魂魚以群體的方式呈現,因此後續希望能夠在線上做一個虛擬的水族箱,一個發光的海底世界,並且結合場域投影讓魚有機會再實體空間持續存在與游動,如果能夠結合實體場域,製作一個全互動式的虛擬投影空間,讓人可以彷彿置於深海的體驗黑暗中的光輝,一定會非常感動。

如果你對更多的創作過程有興趣,可以看之前的靈魂魚製作分享直播!

這篇文章 【p5.js 程式創作】Soul Fish 數位永恆生命的靈魂魚 – 創作故事 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
【老闆週六來聊聊】吳哲宇 Artblocks Project – Electriz 製作分享 https://creativecoding.in/2022/06/09/artblocks-electriz/ Thu, 09 Jun 2022 02:40:00 +0000 https://creativecoding.in/?p=2865 老闆不藏私!抓住NFT生成式藝術浪潮,分享在製作 Artblocks Project - Electriz 背後的理念與故事,以及介紹如何在生成式藝術平台上架p5.js演算法的技術細節。

這篇文章 【老闆週六來聊聊】吳哲宇 Artblocks Project – Electriz 製作分享 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
在這波沸沸揚揚的NFT風潮中,不知道大家有沒有跟上呢?在之前的文章中,我們稍微介紹了NFT的基礎概念,但相信有些人對於從生成式藝術到上架成為NFT的方法、規範是什麼感到好奇,這次直播就要來跟大家分享老闆在製作 Artblocks Project – Electriz 背後的理念與故事,以及介紹如何在生成式藝術平台上架p5.js演算法的技術細節!

Electriz ©Che Yu Wu
Electriz ©Che Yu Wu

Project Electriz

概念來自於模擬粒子在不同空間中的各種行為模式,並記錄電子移動所留下的軌跡。早期物理學家在偵測最小粒子時,會利用加速器撞擊兩顆不同的原子,試著擊破看看裡面還有無更小粒子的存在。在實驗進行的過程中為了看見這些迷你的粒子,科學家會利用一種叫雲室(Cloud Chamber)的儀器,當粒子經過雲霧時會凝結霧滴變成軌跡。

首張觀測到正電子存在的雲室照片 By Carl D. Anderson (1905–1991) - Anderson, Carl D. (1933). "The Positive Electron". Physical Review 43 (6): 491–494. DOI:10.1103/PhysRev.43.491., Public Domain, https://commons.wikimedia.org/w/index.php?curid=93111759
首張觀測到正電子存在的雲室照片 By Carl D. Anderson (1905–1991) – Anderson, Carl D. (1933). “The Positive Electron”. Physical Review 43 (6): 491–494. DOI:10.1103/PhysRev.43.491., Public Domain, https://commons.wikimedia.org/w/index.php?curid=93111759

作品的主要架構可以分為兩個部分—空間的切割與粒子的移動和軌跡保存。空間分佈可以分為兩種—長型與圓形,當粒子經過每個不同帶電的空間(正電或負電)或者干擾力場,便會出現左右或旋轉偏移等不同行為模式。

粒子偏移的不同方式:力場拖拉與正負電場
粒子偏移的不同方式:力場拖拉與正負電場

上架&測試作品

Artblocks 分為 staging environment 跟 official environment,staging 為測試的網站,藝術家可以先把作品上架到這裡看看渲染後的效果。跟一般上架的概念類似,在 Artblocks 的後台有很多的欄位需要填寫(作品名稱、介紹描述等),值得注意的是每更改一個欄位都需要付相對應的手續費,所以下好離手、想清楚再寫唷。

在後台有一個區域稱為「Script」,在這裡需要引用 Artblocks 認證過的函式庫,並上傳自己的程式碼到區塊鏈。程式碼會依照長度切分成不同的 chunck 來上傳,一個 chunck 差不多是1個 ETH,這樣的好處是比起只有靜態的圖片,包含程式碼的做法會讓作品的附加價值更高。

帶大家一窺Artblocks後台的廬山真面目,Script為上傳程式碼的地方
帶大家一窺Artblocks後台的廬山真面目,Script為上傳程式碼的地方

以上為介面介紹,而就程式面來說要從 p5.js 走到 Artblocks chuncks 最重要的就是—亂數的固定化。假設我們今天創作完了一個作品,想藉由這個架構產生 100 個 NFT,這時候很常用到 random 這個語法來亂數生成,但又希望確保每一次的 random 所得到的東西會是相同的。這邊提供由多個藝術家共同開發的演算法(參考 code RandomHash 的分頁),主要概念為透過 keccak 這個 function 取得hash,再複寫掉原先的 random,你就會得到全部的亂數都是固定數的作品囉,同時也可以確保作品和預覽圖的一致性與獨一性。

Template HashRandomLib
Template HashRandomLib

以前在測試作品時都要手動一個一個貼上 hash,這邊介紹一個簡單又好用的工具 Token Art Tools,他可以透過左邊的 scale 調整 hash 的組成並自動餵給 script,這樣就可以快速地看到作品在不同 hash 時的不同樣貌囉。Token Art Tools 有一個功能是回到上一動,這也就代表在隨機的過程中有機會記錄到偏好的作品的亂數,對於生程式藝術來說過往可能在挑選作品時是幾百張圖片挑一張、重製的可能性不高,透過這樣的方法我們有機會保留自己最喜歡的樣貌,至於「隨機」的原則與否,這點便見仁見智了。

Token Art Tools網站截圖
Token Art Tools網站截圖

NFT之於創作者

正如同所有快速爆紅的東西,NFT 勢必也會面對泡沫化的可能性,而在茫茫的 NFT 海中,藝術家們又該何去何從?或許這是所有類型的創作者都會面臨到的窘境,不論是實體或是數位,這些都是傳達理念的一種「手法」。特別是在手法多元化爆炸的時代,如何好好掌握「品牌」和「理念」就是一件很重要的事。老闆這邊分享了自己除了在 NFT 平台(如:Artblocks、Opensea)上的經營外,同時也有經營個人的 Discord Channel,不定時推播新作品上線等相關資訊,也針對支持新作品的老朋友,給予相對應的回饋,進而增加社群的黏著度。

這邊介紹一個藝術家 Tyler Hobbs @ Feral File,除了線上的作品以外,藝術家也會將自己的作品實體展出,近一步結合虛擬和實體的概念。類似的還有先前在 Oursong 平台推出自家 NFT 的師園鹹酥雞,透過購買香菇、四季豆等 NFT,可以在店面兌換相對應的實體物品。近期老闆也在策劃關於台灣藝術家的育成合作(Artist Incubator),主要會輔導藝術家進行作品的上架、協助媒合合適的NPO,有興趣的讀者歡迎關注粉專以獲取最新的第一手消息唷! (相關閱讀:首家 NFT 炸雞店!師園鹹酥雞 NFT 上架 OurSong 一天內漲幅超過 100 倍

Feral File – Exhibiting, Curating, and Collecting Digital Media

在直播中老闆也分享說其實在NFT的領域成名與否和作品的品質不見得有正相關,很多時候是需要一個被看到的機運,衍伸而來後續的曝光。雖然有一些運氣的成份存在,但身為創作者可以盡量完整自己在平台、網站上的作品,以建立「個人品牌」的方向去努力,等待成熟發酵的那一天。

以上是這次老闆週六來聊聊的內容,希望大家看完後也可以對於航行在NFT這塊汪洋藝術之海可以更有方向,直播影片請往這裡走,我們下次再見啦!👉🏻 https://www.youtube.com/watch?v=9kUJirQsS7M

歡迎加入互動藝術程式創作入門(Creative Coding)線上課程,課程中你可以認識程式與互動藝術產業應用,開啟對工程跟設計的想像,學會使用 p5.js 開發互動介面,整合繪圖、音訊、視訊、文字、3D、互動與機器創作完整的作品,並將創作輸出應用在個人品牌或網站、主視覺或海報,甚至互動裝置、遊戲與教材製作等場景,讓你對進修的資源與路線更有方向。

有興趣的朋友歡迎加入我們的臉書社團,第一時間接收活動報名消息,希望不久的將來,就能看到你跟大家分享你的生成式藝術創作囉!

此篇直播筆記由幫手 Jeudi Kuo 協助整理

墨雨設計banner

這篇文章 【老闆週六來聊聊】吳哲宇 Artblocks Project – Electriz 製作分享 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
初次見面請多指教!Creative Coding第一次社群聚(下)黃豆泥:沒有市場的靈魂綁定NFT https://creativecoding.in/2022/05/08/creative-coding-meetup-202204-mashbean/ Sun, 08 May 2022 01:28:00 +0000 https://creativecoding.in/?p=2651 FAB DAO 的黃豆泥以收藏家的角度,帶大家了解靈魂綁定的NFT究竟有沒有市場,以及第三位創作者 Mizok 帶來他的<宇宙>共創作品分享。

這篇文章 初次見面請多指教!Creative Coding第一次社群聚(下)黃豆泥:沒有市場的靈魂綁定NFT 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
上篇 初次見面請多指教!Creative Coding第一次社群聚(上)吳哲宇的生成式藝術宇宙 我們聊了Creative Coding,還有藝術家吳哲宇從 p5.js 到 Shader 的生成式藝術(Generative art)創作之路。

中篇 初次見面請多指教!Creative Coding第一次社群聚(中)Hoba與叁式的演算視覺邁進之路 則是由叁式互動新媒體的技術美術Hoba帶來演算視覺的應用,不藏私揭露叁式近年來精彩的作品幕後祕辛,以及另一位與會的創作者張文瀚帶來作品 <Wormhole>分享。

下篇則是由 FAB DAO 的黃豆泥讓大家一窺<沒有市場的靈魂綁定NFT>又是怎麼一回事(影片從這裡開始看),以及第三位創作者 Mizok 帶來他的<Universe-alpha>及<Universe-beta>(作者展示)。

我的PFP是一隻雞,我叫黃豆泥

豆泥是江湖藝名而非本名,元宇宙裡大家都喜歡用 PFP (Profile Picture) NFT 當個人頁的大頭照,我是一隻雞,我叫黃豆泥。

去年還在當醫師時,就買了哲宇的 Hahow 互動藝術程式創作入門的課程,到現在只聽了四堂課,大家都知道,一個班級裡有成績很好也有成績很差的同學,黃豆泥完全可以被歸類在沒聽課、成績超爛的壞學生之中。後來離開了醫界,想要開始認真學習 p5.js,上了王連晟老師的課程,號稱上完四個星期的課程後就可以在 fxhash 發行作品了,但我到現在都還沒有。

既然自己沒有辦法成為一個合格的創作者,那就成為一個瘋狂的收藏者吧!在這半年間,我買了超多跟生成式藝術相關的 NFT 大約六百多件。我在過去幾個月,一直在看生成式藝術的市場,從幾十幾百塊台幣就可以入手,但便宜的也可能價值翻倍、一開始貴的也可能身價下跌。

今天我要分享什麼是生成藝術的 NFT,有甚麼樣的形式,但今天我特別想講的,是那些不會紅的生成式藝術,也就是所謂的靈魂綁定 NFT。

話說從頭 – FAB DAO

在這之前,要先吹捧一下哲宇,身為生成式藝術家,賣了很多 NFT,但生成式藝術家是否能為台灣做一些事情呢?可以,我和哲宇一起創立的 FAB DAO,中文名稱福爾摩沙藝術銀行, FAB DAO 想做的事情是藉由區塊鏈或是 NFT 等新技術,幫助非營利組織,特別是公益團體及文化團體發行 NFT,一方面做文化保存,另一方面開拓新的募款管道。台灣目前還沒有人做這個事情,但我們有一群人在這裡努力研究開拓。組織是由哲宇去年在 Art Blocks 上賣的系列作品 Electriz 所賺進的十顆乙太幣資金成立,萬一你們之後發達了、想為台灣做一些好事,歡迎來找 FAB DAO。

生成式藝術NFT?

哲宇的作品 SoulSea
哲宇的作品 SoulSea

現在來用哲宇的作品 SoulSea 簡單介紹甚麼是生成藝術的 NFT,這一張是我收藏的第 251 號 SoulSea .每一件生成藝術作品在 fxhash 平台上,一個生成藝術就有一個種子碼,一個種子碼就是一個獨一無二的 NFT。這件作品就是一個蠻常見、經典的生成式藝術作品形式。

fxhash 從 beta 版要升成為正式版的過渡期,big burn 把目前未鑄造完成或是未賣出的作品全部燒光光
fxhash 從 beta 版要升成為正式版的過渡期,big burn 把目前未鑄造完成或是未賣出的作品全部燒光光

大家可能會好奇這個網頁下面為什麼會有火焰,現在(註:活動日期為 2022 年 4 月 14 日)是 fxhash 從 beta 版要升成為正式版的過渡期,big burn 就是指他們把目前 beta 上未鑄造完成或是未賣出的作品全部燒光光。fxhash 正式版已經於四月中上線,全世界的知名生成式藝術家都磨刀霍霍,準備上新作品了,平台的功能也會與 Art Blocks 大相逕庭,哲宇接下來又會有甚麼新作呢?敬請期待。

fxhash又是什麼

簡單介紹 fxhash ,這個平台有點類似 Art Blocks.完成上線的程式碼會成為一件生成式藝術作品,去鑄造(mint)的時候會隨機獲得一個種子碼,產生一個新的 NFT。這些 NFT 可能會有一些特色(features)、屬性,也可能沒有。

 California Hills in Late Sun #38
California Hills in Late Sun #38

我收藏的另外一件作品 California Hills in Late Sun #38 ,我非常喜歡她山坡紋理的呈現,也因為經由獨特種子碼產生,作品也是獨一無二、可以拿去販售的。

 Anaverse - forbidden city
Anaverse – forbidden city

再舉一個很ㄎ一ㄤ的案例,作品名稱為 Anaverse – forbidden city ,每個人會鑄造到屬於自己的城市或說是宮廷,相異的特色包括大小、作品名稱、建築和水池的數量等等。這個宮廷特別的地方在於,是可以進入到這個空間裡互動的,點擊官網、確認已連結到你的錢包之後,你就可以在你的宮廷裡走來走去,把這件生成式藝術作品直接變成虛擬展場空間,擁有者甚至可以掛所收藏的其他 NFT 等。

同時作為生成式藝術作品也是虛擬展間,最有名的虛擬展間是Oncyber,可以買下一個他人已做好的 3D 空間,掛上自己的收藏,這個展場本身就是藝術品,在藝術品中又能放進更多藝術品而成為一件新的策展作品,不斷堆疊出新的概念,繼續成為新的生成式藝術 NFT。

黃豆泥收藏的川貝母作品
黃豆泥收藏的川貝母作品
黃豆泥收藏的川貝母作品
黃豆泥收藏的川貝母作品

大家在坊間最常見的 NFT 作品形式是 PFP ,看起來不怎麼樣但背後也是大有學問。這個頁面是我所收藏台灣插畫家川貝母發行的 NFT,每個物件雖然是預先畫好的圖像,藉由程式的隨機性做堆疊,成為了不同排列組合的頭像圖片。一般常見的 PFP 也都是相同的概念,廣義而言算是生成式藝術,狹義而言只是從一個資料庫裡抓取元素生成。

靈魂綁定的NFT就沒有市場?

終於進到本次分享的重點:有沒有 NFT 是真正靈魂綁定且無法交易所以沒有市場的?我認為有,且也有許多人在做這些實驗。先前分享的作品案例都是屬於下圖左邊的這一類型,也就是說作者寫了一段程式碼,在購買程式碼的過程會生成 NFT ,透過種子碼讓作品成為買家專有的。可以留著或坐交易,在賣掉的過程中,種子碼會跟著 NFT 一起轉交給下一位買家,所以不管是在稀有度、視覺體驗上,每個人都可以去複製。也正因為這樣的設計,從去年到現在非常的火紅,是因為可以做交易。

圖說兩種不同類型的NFT
圖說兩種不同類型的NFT

那有沒有反交易的 NFT 呢?其實是有的,就是上圖右邊這一類型。今天有一串由創作者寫好的程式碼,鑄造成一個版次很大的 NFT (十版或上百版),買家是買到同一個 NFT 可是每個人在買 NFT 的時候,因為每個人的錢包地址都不同,這個代表錢包地址的一串亂碼在加密貨幣及區塊鏈的世界也就是代表某一個人(的錢包),把地址當成種子碼置入 NFT ,也就是說, NFT 會跟著你的錢包地址而變動,生成獨一無二的作品。

當我們買到一個 NFT ,只有我看得到我所看到的圖像,當下一個買家買走一件作品,重新綁定他的錢包地址,他看到的作品跟當初我所擁有時的樣貌不會一樣。我們無法交易這個經驗,除非截圖,但截圖儲存和分享,就失去了交易這一個環節。

這就是我們所謂的靈魂綁定,他跟你的人生經驗是綁在一起的,除非你再去開另一個錢包,把 NFT 傳過去,這時候才會有另外一個經驗的產生,但屬於你的經驗仍舊屬於你,直到你將錢包的帳密移轉給他人為止。

黃豆泥擁有的Evil Bean
黃豆泥擁有的Evil Bean

南藝大的林經堯教授發行的 Evil Bean 正是一個例子,黃豆泥剛好鑄造到一個醜到賣不出去的 NFT ,看起來很稀有卻是賣不掉的。回到林經堯教授的頁面上看其他的作品,一開始發布時的預覽圖是十六顆彩色邪惡豆豆以及一串地址,也可以看到其他被鑄造的 NFT 樣貌,有一些是由他自己手動鑄造出來的。

Evil Bean 發行的首圖
Evil Bean 發行的首圖
其他Evil Bean
其他Evil Bean

另外一件案例是藝術家黃新跟台灣當代藝術館當期的展覽《蓋婭:基因、演算、智能設計與自動機_幻我;它境》所做的合作,這個案例能夠真正詮釋我所謂的靈魂綁定 NFT 。沈伯丞為策展人,討論科技、生物及未來的技術,只要新台幣五十元就可以看到國內外數十位藝術家的作品。

NFT 作為展覽展品目前仍為少數,而黃新為此次展覽「蓋婭:基因、演算、智能設計與自動機_幻我;它境」做了新的一個 NFT 藝術品:展覽門票,他的賦能是只要花一百元買這張 NFT 門票,就可以無限次進場看展。這個東西有意思的地方在於,門票的「材質」呈現會因人而異,每個人因錢包位址不同,所鑄造出來的都會不一樣,像豆泥自己的看起來很像竹影飄搖的感覺。因為同一個 NFT 換人擁有就會大大改變他的樣貌,於是所有擁有這個 NFT 不同版次的人,都會將自己的 NFT 截圖後上傳至台灣當代藝術館粉絲專頁上,創造大量的留言。

黃豆泥擁有的台北當代藝術館「蓋婭:基因、演算、智能設計與自動機_幻我;它境」NFT
黃豆泥擁有的台北當代藝術館「蓋婭:基因、演算、智能設計與自動機_幻我;它境」NFT

經驗無法複製,很像當代藝術在討論的議題「靈光 Aura 」,由藝術家班雅明在攝影機剛發明的時代,討論藝術是否因為機械複製,而導致靈光消失?創作的靈光是否因為大量的複製,是否亦會消失?回過頭來看 Creative Coding、生成式藝術, NFT 的出現,讓創作透過種子碼製造的隨機性、自動性產生新型態的互動,還沒有大量的被當代藝術的世界中討論,但會是未來的趨勢。

其實生成式藝術並非完全是大家看到的樣子,還是有一些反市場的、非主流、實驗性的東西,FAB DAO 這個組織也在做非常多的嘗試,也希望有更多志同道合的人一齊加入。


Lightning talk 3 – Mizok

每一次的 Creative Coding Taiwan 聚會都會事先提供一個主題,邀請大家趁著這個機會創作出一件互動藝術作品並與大家分享。在一次又一次的共創過程中,激盪出更多更有趣的火花。

<Universe Alpha>

Mizok <UniverseAlpha>
Universe Alpha

<Universe Beta>

Mizok <Universe Beta>
Universe Beta

作品連結:https://mizok.github.io/generative-art-playground/#universe-alpha

創作主要是在表達自己心裡的意象,可能是淺顯或埋較深的,<宇宙>這個主題會讓我立即聯想到星空、星雲,於是便用程式將他做出來。主要的技術為 ejs & typescript & scss,首先利用柏林噪聲、簡單的粒子系統以及 p5.js 裡的 random() 達到完成星雲,再使用預渲染及分層選染的方式算出圖樣,類金屬的光澤和質感由漸層加上 Blend mode 實現,On frame draw 再逐針疊上亂數生成的星星。


若你還沒有讀過前面的精彩內容,現在還來得及收看:
初次見面請多指教!Creative Coding第一次社群聚(上)吳哲宇的生成式藝術宇宙
初次見面請多指教!Creative Coding第一次社群聚(中)Hoba與叁式的演算視覺邁進之路

歡迎加入互動藝術程式創作入門(Creative Coding)線上課程,課程中你可以認識程式與互動藝術產業應用,開啟對工程跟設計的想像,學會使用 p5.js 開發互動介面,整合繪圖、音訊、視訊、文字、3D、互動與機器創作完整的作品,並將創作輸出應用在個人品牌或網站、主視覺或海報,甚至互動裝置、遊戲與教材製作等場景,讓你對進修的資源與路線更有方向。

四月的 Creative Coding Taiwan 社群聚會在這邊告一個段落,不知道大家有沒有跟 Chia 編一樣收穫滿滿呀?五月的社群預計在5/12(四)舉辦,有興趣的朋友歡迎加入我們的臉書社團,第一時間接收活動報名消息,希望不久的將來,就能看到你跟大家分享你的生成式藝術創作囉!

整理編輯:Chia 編

墨雨設計banner

訂閱 Creative Coding Taiwan 電子報:

這篇文章 初次見面請多指教!Creative Coding第一次社群聚(下)黃豆泥:沒有市場的靈魂綁定NFT 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
初次見面請多指教!Creative Coding第一次社群聚(上)吳哲宇的生成式藝術宇宙 https://creativecoding.in/2022/05/06/creative-coding-meetup-202204-cheyu-wu/ Fri, 06 May 2022 02:59:00 +0000 https://creativecoding.in/?p=2639 第一次的社群聚,召集人吳哲宇破題開講 Creative Coding 以及 Shader 在生成式藝術領域的相關應用,分享他經典的NFT作品,最後也帶來他為這次的共創主題<宇宙>的新作

這篇文章 初次見面請多指教!Creative Coding第一次社群聚(上)吳哲宇的生成式藝術宇宙 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
2022年4月14日這個重要的日子必須紀念一下,因為喜愛生成式藝術的 Creative Coding Taiwan 社群,大家終於在臺北實體見面啦!

Creative Coding Taiwan 社群大合照
Creative Coding Taiwan 社群大合照

Creative Coding Taiwan 是由墨雨互動設計所發起與支持的社群,旨在台灣推廣互動程式設計以及任何由程式創作衍生出來的藝術作品及行為。之前一直都是在線上直播、線上課程,接下來我們希望藉由每個月的固定聚會,舉辦各種不同類型的活動,讓喜歡寇汀的大家互相交流,分享自己的創作與想法,技術上有任何不懂的,現場說不定也會有很多大神出沒可以討教哦!

什麼是 Creative Coding?

Creative Coding 顧名思義是結合程式加創意,狹義上是用程式寫一些看起來很有藝術感的圖形,廣義上是可以用程式,將世界上的各種事物賦予互動跟連結起來,創造出新的現象、關聯與有趣的呈現。用程式偵測走在路上的人群,轉換成五線譜之後播放成音樂,或是比較商業的演唱會背景,擷取歌手的影像做後製,結合動態設計,變成即時的互動背景,跟著聲音的大小、人的位置、時間等做變化,這些都是程式創作能應用的範疇。近期由於 NFT 生成藝術平台 Art Blocks 的興起,也讓更多人注意到了生成藝術與 Creative Coding 的魅力與各種可能性!

因為篇幅關係,此次的內容將這次將近兩小時的直播影片拆成上、中、下三篇,首先由吳哲宇破題開講 Creative Coding 以及生成式藝術的相關應用,最後也帶來他為這次的共創主題<宇宙>的新作(影片同時服用);中篇由叁式互動新媒體的技術美術Hoba帶來演算視覺的應用,不藏私揭露叁式近年來精彩的作品幕後祕辛(影片從這裡開始看),以及另一位與會的創作者張文瀚帶來作品 <Wormhole>分享(看看作者的詮釋及解析);下篇則是由 FAB DAO 的黃豆泥讓大家一窺<沒有市場的靈魂綁定NFT>又是怎麼一回事(影片從這裡開始看),以及第三位創作者 Mizok 帶來他的<Universe-alpha>及<Universe-beta>(作者展示)。

延伸閱讀:
初次見面請多指教!Creative Coding第一次社群聚(中)Hoba與叁式的演算視覺邁進之路
初次見面請多指教!Creative Coding第一次社群聚(下)黃豆泥:沒有市場的靈魂綁定NFT

墨雨設計創辦人 吳哲宇 <Creative Coding 是甚麼?Shader與Generative Art 應用>

對藝術家吳哲宇,也是我們口中的老闆來說, Creative Coding 程式創作是結合設計、工程、數學、動態、程式邏輯甚至是硬體的一種藝術創作形式,把程式當作畫筆,搜尋喜歡的主題,利用一行行的程式碼將世界上的各種事物連結起來、賦予互動,以邏輯思維創造出新的現象、關聯,編織成有趣互動的成果呈現。例如下方這一個神祕的生物,僅僅是用不到二十行的程式碼寫成。

哲宇用簡單算式程式碼完成的神祕生物
哲宇用簡單算式程式碼完成的神祕生物

很多人都會說你視覺要看起來有藝術感才能算是藝術。但哲宇覺得, Creative Coding 本身程式的運作以及邏輯概念是藝術的展現,Creative Coding 的魅力也正在此。

進入程式創作的世界,常使用的軟體包括 Unreal 以及 Unity 兩套3D遊戲開發軟體及引擎,MaxMSP 是一款圖形化編程語言的軟體工具,還有主流創作的 Open Frameworks 和 Touch Designer,有興趣的都可以玩玩看。

想必有許多人都是透過 p5.js 生成式藝術創作認識哲宇以及 Creative Coding 的,2020年因為疫情,哲宇而開啟了一天一 p5.js 創作的計畫,最初的起點其實都很簡單,利用三角形、圓形、線條、色彩等不同的主題,從生活中取材,隨意實驗,慢慢發展出有趣的圖像以及互動小品。包括用物理模擬做成軟軟的生物、魚鉤釣魚,或是童趣的蝸牛、用 shader 寫 DNA 等。

常使用的平台是 Open Processing 這個線上編輯器,修改程式碼能即時看到成果。 p5.js 是個入門好上手的程式語言,只要花個一週左右的時間就可以做出有趣的作品,尤其是即時視覺回饋的有趣,足以沖淡一些學習或是撰寫程式的痛苦。

p5.js 生成式藝術創作的過程其實跟一般藝術創作的過程相似,從最初始的動機,也許是個視覺想法(波浪?)或是某個靈感開始,想像不同的可能性(大小、顏色、樣態、互動等等)將草圖逐步建置成形,中途來回不停修改,像調配藥水一樣嘗試各種排列組合、疊加變形,甚至有時會有一些意料之外的驚喜,最後完成作品。

生成式藝術的核心

常看哲宇直播的人,或是 Creative Coding 台灣站的忠實讀者大概可以發現,其實生成式藝術,或說用程式創作藝術,重要的概念可大致分為以下:

  • 規則:大自然中有法則,透過探索、模仿,建立規則而非框架。
  • 限制:有限制才能激發更多的創意以及自由。
  • 核心概念及故事:也是創作的動機,賦予作品更多意義。
  • 視覺呈現:加上材質、小動態,用心雕琢細節是畫龍點睛的關鍵。
  • 變化:一成不變讓人無趣,無論是透過時間、
  • 隨機性:加入一點 random 一點 noise,讓人摸不透規則更好奇。
  • 輸入/輸出:輸入包含了影像、音像,滑鼠點擊或移動,其他外部資料或是時間;輸出則是以視覺、聲音及動態(也可能是硬體)為三個主要的方向。

像是哲宇之前利用骰子骰出來的數字控制檯燈的作品;或是將 Unreal 結合動態捕捉系統,即時接收舞者(也就是哲宇本人)的動作並顯示在四周的投影牆上,再加上物理引擎模擬,碰撞、擾動虛擬世界中的圖像,所完成的現場即時表演,這些都算是互動藝術。無論是在 p5.js 或是 Unreal 等平台,程式創作和互動的邏輯都是可以互通的。

NFT作品分享:SoulSea 以及 CryptoPochi

如果對於哲宇在 NFT 的心路歷程有興趣,歡迎右轉閱讀【老闆週六來聊聊】我開始賣NFT作品啦!生成式藝術在NFT的價值,這邊就不再多述,僅挑出兩件特別喜歡的作品跟大家分享。

哲宇在fxhash上發行的SoulSea系列作品
哲宇在fxhash上發行的SoulSea系列作品

第一件是發布在 fxhash 的 SoulSea 系列作品,其實是在做商業案子的時候,哲宇發現太漂亮到捨不得給別人,所以就自己上架。作品使用 p5.js 製作出噪聲和波形,模擬海洋的質感,從一條波浪,在多個地方疊加上 noise 產生連續且自然的波紋,加上材質等小元素,其中牽涉到了對數學、形狀的掌握度,製造出接近生活體驗、有機體的東西。

哲宇在OpenSea上發布的互動型NFT <CryptoPochi>
哲宇在OpenSea上發布的互動型NFT <CryptoPochi>

第二件是發布在 OpenSea 的 CryptoPochi ,也是一個互動型的 NFT,結合區塊鏈以及網頁的技術,以網頁的形式呈現,並使用物理模擬引擎與 Artblocks 製作互動,隨時都可以透過滑鼠去玩他,甚至製作了 On Chain Event 觸發同步事件,可以讓不同作品內的 Pochi 互相互動。

如果你是工程師,鼓勵你多看一些作品,會有一些想法和創意開始踏出利用程式碼創作的第一步;如果你是設計師,便可以從熟悉 p5.js 語法開始,慢慢地往生成式藝術的方向邁進。

在這裡也要推薦一下在HaHow好學校的〈互動藝術程式創作入門〉課程。大約兩年前開這堂線上課程時,還沒有很多人知道 Creative Coding 這個領域,如今隨著元宇宙、NFT成為夯字,也越來越多人投入。

哲宇不藏私,分享他在創作的同時,也持續思考作品商業的潛力,除了持續創作、賣 NFT 之外,另外跟很多品牌合作,從品牌的角度出發,例如跟漢堡店合作,將漢堡層層拆分,以程式藝術手法詮釋。未來硬體也會越來越強大、跑得動複雜的程式碼,之後許多公司品牌可能都會開始發展動態或是 3D 的視覺以及衍伸行銷,大家也可以想想看新媒體藝術有哪些商業應用。哲宇也趁機苦口婆心地以過來人身分勸大家不要賣自己作品的授權,因為哲宇之前曾遇過,授權給對方使用他的畫作,對方還反寄律師函回來告的情形。

Shader 與 Generative Art 的應用

哲宇用Shader創作出來的生成式藝術
哲宇用Shader創作出來的生成式藝術

Shader 就是執行在GPU上的電腦程式,控制著GPU渲染管線,處理開發者給他的各種繪圖相關的資料,即使是畫一個點、一個顏色、一個向量,也要透過 Shader 渲染。 Shader 就像是 Creative Coding 的進階版,將原本在 3D 軟體內才能看到的材質,運用 Shader 做出來。

GLSL(OpenGL Shading Language) 全稱 OpenGL 著色語言,是一個以C語言為基礎的高階著色語言,用來在OpenGL 中著色編程,這個語言的好處是因在 shader 裡面全部的東西以像素為單位做運算,若你的 GPU 越強,就能渲染出越精細漂亮的畫面,而且效能也很好。如果有興趣的話,也可以參考一些哲宇之前使用相關語言做的作品:

哲宇的作品 The Soul
哲宇的作品 The Soul

舉一件自己的作品當例子,看起來像瞳孔的這幅作品 The Soul,程式碼就非常單純,計算離中心的角度,算出像是類似山脈的偏移效果,再把顏色畫出來,從內到外,紅色是離中心距離的兩倍、綠色是離中心距離的三倍,就可以呈現這種類似極光、光譜分散的效果。

大家有興趣都可以去 fork 哲宇的 shader template (連結這裡走,不可商用、需標記來源),裡面已經準備好 shader 裡基礎的東西,從這個環境開始,可以快速完成你自己的 shader 作品.或是你可以從改一些範本中的不同參數,看會製造出甚麼樣的效果開始。

另外也想跟大家介紹一個很酷的學/寫程式的好用工具 VSCode,你可以去申請 Copilot 的功能,他可以解釋程式碼在做些甚麼,假設我這邊有一串 shader 或是任何其他語言的程式碼,選取後點選 Ask Copilot 就會出現解釋,他甚至會去猜你的變數在幹嘛,譬如說這個 p 可能是位置等。在撰寫程式碼的時候也會有一個自動輸入功能,你只要起頭,他就會幫忙填完 function 和 name 甚至是後面的程式碼,也可以把寫好的程式碼轉換成各式各樣的語言。

若想了解更多有關 shader 的知識,可以參考 TheBook of Shaders https://thebookofshaders.com/,一步步帶你了解如何使用 Fragment Shaders 開始做幾何圖形,從像素開始建構圖像、 3D 等。

Q:整包 HTML 如何上傳變成 NFT?

A:可以用 fxhash 這個平台,將你的程式碼打包成一個 zip 檔案丟上去就可以了,需要注意的是要使用官方提供的 fxhash-snippet 把每個 NFT 獨立的序號生成一個 random object(fxrand),這個 random 就能夠自行產生你在作品中所需要用到的亂數,只要作品序號相同,亂數就是一樣的。把這個部分丟進去、順利跟 fxrand 對接之後,就可以產生很多獨一無二的 NFT 了。

參考:Guide to mint a token

截圖自Guide to mint a token

Lightning talk 2 – 吳哲宇

社群聚當天,最後的一個小環節是 Lightning Talk,每一次的 Creative Coding Taiwan 聚會都會事先提供一個主題,邀請大家趁著這個機會創作出一件互動藝術作品並與大家分享。在一次又一次的共創過程中,激盪出更多更有趣的火花。

哲宇為這次的共創主題<宇宙>所作的創作 <Nebula Shift>
哲宇為這次的共創主題<宇宙>所作的創作 <Nebula Shift>

作品連結:https://openprocessing.org/sketch/1543928

用 Shader 寫的作品,移動鼠標不只有星雲飄動,還有星星閃爍。將粒子的資料輸入進 Shader 裡使用,透過 p5.js 使用多層 perlin noise 與一般的 noise 兩種不同的躁聲做扭曲,呈現出線條流動之感,另外也須計算點跟星星的距離,完成不同明暗程度的閃爍以及穿透霧氣的感覺,將 RGB 分層處理,因為光譜頻率偏差,便會有如色散的效果呈現。

由哲宇創辦的墨雨設計也持續地經營 Creative Coding Taiwan 互動程式藝術創作台灣站,無論是 p5.js 的實作教學,或是你該怎麼入門、去哪裡找資源,都可以從這邊看起。歡迎各方好手加入,一齊充實內容!


最後小小工商時間,我們第一次的社群聚會現場也請到了 AWS Activate Taiwan 的 Alex Cheng 帶著最正宗的韓式炸雞來到現場,以及分享給新創公司的好康,無論你是剛起步的小團隊,或是已經加入育成中心、新創加速器的新創公司,使用 AWS 升級服務可以獲得 US$1,000 的免費積分!有興趣的人歡迎掃瞄下方 QR Code 了解更多。

這次 Creative Coding Taiwan 四月社群聚,每位講者都帶著滿滿的知識和熱忱分享,若是你對哲宇的生成式藝術感到意猶未盡,那你一定要繼續看下去:
初次見面請多指教!Creative Coding第一次社群聚(中)Hoba與叁式的演算視覺邁進之路
初次見面請多指教!Creative Coding第一次社群聚(下)黃豆泥:沒有市場的靈魂綁定NFT

五月的社群已經開放報名囉,有興趣的朋友歡迎加入我們的臉書社團,第一時間接收活動報名消息,希望不久的將來,就能看到你跟大家分享你的生成式藝術創作囉!

整理編輯:Chia 編

墨雨設計banner

訂閱 Creative Coding Taiwan 電子報:

這篇文章 初次見面請多指教!Creative Coding第一次社群聚(上)吳哲宇的生成式藝術宇宙 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
【p5.js創作教學】Sweet Trap 甜蜜陷阱 https://creativecoding.in/2022/04/25/p5-js-sweet-trap/ Mon, 25 Apr 2022 05:52:00 +0000 https://creativecoding.in/?p=2568 生成式藝術迷人的地方就在於它的程式邏輯、它的數學藝術呈現,有秩序卻又充滿了隨機。吳哲宇的<甜蜜陷阱>便是這樣有機的創作作品。此文帶大家一步步從 sin 波慢慢建構出目眩神迷的 p5.js 創作。

這篇文章 【p5.js創作教學】Sweet Trap 甜蜜陷阱 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
色彩繽紛的幾何形狀不斷輻合旋轉,細細的線條卻像是毒刺一樣。動態改變形狀一下密密麻麻一下稀疏鬆散,多變的風貌讓人甜蜜陶醉卻又像是陷阱般危險的感覺!

<甜蜜陷阱>成品圖
<甜蜜陷阱>成品圖

本文是【p5.js 程式創作直播】210731 Sweet Trap 甜蜜陷阱 的直播影片筆記,大家如果想要和老闆一起 chill 度過寫程式的時光,可以打開影片開啟這趟心流之旅,或者…繼續往下看!

這次直播是用 openprocessing 網頁平台來撰寫,打開網頁就可以開始 coding 創作了!成品在這裡。

直播時老闆聊到了設計的作品被剽竊的故事,但也因為這樣被 Art Blocks 平台看見。現在正是NFT藝術品百花齊放的時候,大家在這支影片中可以了解到生成式藝術迷人的地方,甚至開始創作自己的 NFT 。來吧,這次的作品運用到不少關於角度的概念,讓我們一起建立一個秩序又隨機的世界!

這次直播筆記會帶大家學會

  • 將三角函數的概念運用在極座標,透過計算角度來畫出花瓣狀的軌跡
  • 旋轉與移動座標系,簡單定位軌跡中的每個點
  • 利用存取滑鼠的座標,自由變化圖形的樣貌
  • 計算角度簡單繪製出三角形狀
  • 存下自己喜歡的色票並隨機呈現顏色,每一次播放都會產生不同顏色組合
  • 運用noise()製造出有規律的隨機

會使用到的 API

這次作品會使用以下的 API,大家可以先感受一下每個 API 的功能,還沒完全理解的話也沒關係,後續透過一步步實作會漸漸學會運用的。

  • createCanvas(width, height): 創建畫布,參數中分別傳入寬跟高。
  • background(colorCode): 加上背景色,可依照文件傳入色碼參數。
  • noStroke(): 取消繪製圖形的邊框。
  • colorMode(): 定義顏色的方式,預設為 RGB 顏色,HSB 模式依序要填入的值則為(色相, 飽和度, 明度)。
  • fill(): 選擇填入的顏色,依照 colorMode 選擇的填色模式填入對應的參數。
  • ellipse(posX, posY, width, height): 在 (posX, posY) 上繪製一個寬高(width, height)的橢圓形。
  • rect(x, y, width, height): 以 (x, y) 的位置為左上角的點,畫一個寬度 width 高度 height 的方形(如果要畫正方形的話,即寬度=高度)。
  • triangle(x1, y1, x2, y2, x3, y3):以三個頂點座標繪製出三角形。
  • text(str, x, y):在(x,y)座標呈現出文字str
  • rotate(angle): 將座標系依照該角度旋轉
  • translate(x, y): 將座標系移到(x,y) 上
  • push(): 儲存目前畫筆設定的狀態
  • pop(): 恢復畫筆在push()時儲存的狀態,與push()合併使用
  • random(): 沒有傳參數時,會返回一個0~1之間的隨機浮點數。
  • noise(x,[y],[z]): 產生0~1之間的浮點數。傳入的x,y,z代表座標,會在一、二、三維的Perlin noise噪聲空間取出對應該座標在0~1之間的值。這個方法會使得相近的座標取到的值也相近,比較有連續性,不會像random()每次取值都是完全隨機的。有興趣的同學也可以延伸閱讀相關資訊:2D Noise – Perlin Noise and p5.js Tutorial
  • map(value, start1, stop1, start2, stop2, [withinBounds]):會回傳某個位於start1~stop1範圍的值如果對應到start2~stop2範圍中是多少。最後一個參數的意義可以參考文件描述。
  • pow(n,e):計算n的e次方
  • blendMode(mode):讓圖形相互以不同的方式疊加色彩,有各種模式可以選擇,例如:DARKEST、LIGHTEST、DIFFERENCE等。
  • image(img, x, y, [width], [height]):以img材質在x,y座標畫出圖片。
  • pixelDensity(val):增加像素的密度,預設像素的密度是與螢幕相同。

跟著老闆開始動手做

1. 簡單的起手式

在 openprocessing 網頁右上角可以Create a Sketch,會來到一個已有預設程式碼的新頁面。從這裡開始我們來認識setup()、draw()與mouseX()、mouseY()。

  • setup(): 可以視為程式環境的初始化,在每次按下撥放鍵開始執行時,會呼叫 setup() 裡的程式碼一次。
    • createCanvas(width, height):創建畫布,參數中分別設定寬跟高(單位是px)。也可以直接寫(windowWidth, windowHeight),會自動判斷螢幕的寬高變為滿版畫布。
    • background(colorCode):設定背景顏色,依照 p5.js 文件說明傳入不同的色碼參數表示方式,這邊寫的 100 是代表 0(黑)~255(白) 之間的灰色值 100。
  • draw(): 在不按停止播放的狀況下,會不斷重複執行在 draw() 裡面的程式碼,要繪製的內容主要會寫在這裡。
    • ellipse(posX, posY, width, height):在 (posX, posY) 上繪製寬高 (width, height) 的橢圓形,如果 (posX, posY) 帶入 (mouseX,mouseY) ,表示取滑鼠的座標當作繪製圓圈的位置。
function setup() {
  createCanvas(windowWidth, windowHeight);
  background(100);
}
function draw() {
  ellipse(mouseX, mouseY, 20, 20);
}

2. 繪製sin波形

這次老闆從自己日常紀錄的創作靈感筆記中,選擇創作類似花的圖案,可以用 sin 波來實踐-想想 sin 波的形狀是不是很像一片片的花瓣?正式的說法是,我們將在極座標(0~360度)上畫出 sin波 ,下圖的 θ 是從 0~360 度,可以看到不同的算式真的會讓 sin 波變成花瓣呢!

變成花瓣的 sin 波
變成花瓣的 sin 波

我們就先從畫出一個正常的 sin 波開始吧!老闆喜歡在畫布上再畫一個黑色矩形當作背景,這個可以寫在setup()中畫一次就好。接著在 draw() 裡透過 for 迴圈,讓 x 由左到右,每隔 20 就畫一個白色的圓點來描繪 sin 波波形。以下是 API 的相關參數意義。

  • fill(colorCode):設定接下來要填入形狀的顏色,色碼0為黑色,色碼255為白色。
  • rect(0,0,width,height):width,height是兩個可以方便取用的變數,儲存曾在createCanvas(w,h)中設定的寬高值。矩形的繪製會以(0,0)為左上角頂點,往右為寬、往下為高畫出與畫布一樣大的矩形。
  • noStroke():設定接下來畫出的圖形沒有邊框。
  • translate(0,height/2):座標系是從整個畫布的左上角為原點(0,0),往右方x越大,往下方y越大,我們運用translate()把座標系的原點改到(0,height/2),接下來座標的計算都可以重新依這個新原點為準。
  • frameCount:從程式開始執行畫面不斷更新的次數,其實也就是draw()反覆執行的次數,所以frameCount是以固定的速度增加其數值。
  • ellipse(x,y, 50):在(x,y)畫出寬高皆為50的圓形。

y = sin(x) 可以繪製出 sin 波形,如果我們想要調整波形的樣貌,可以進一步運用不同的參數來調整!在這裡如果把它表達成 y=sin(x/a+b)*c 來思考,會發現 a 越大波長越長;而 b 如果是個變動的數字,程式反覆執行時,就會讓波上的點開始垂直動起來(不然會是靜止的)。老闆即運用 frameCount/100 來當作垂直運動的速度,大家可以試試看如果將 frameCount 除以10、50 會有什麼不同?另外由於 sin() 只會給出 -1~1 之間的值,因此可以乘以一個倍數 c 來控制 y 的高度,在這裡用的是 height/5。大家可以在 y=sin(x/a+b)*c 中試驗不同 的a、b、c 參數來創作你喜歡的 sin 波模樣喔!

function setup() {
  createCanvas(1000, 1000);
  background(100);
  fill(0)
  rect(0,0,width,height)
}
 
function draw() {   
  fill(255)
  noStroke()
  translate(0,height/2)
  for(var x=0;x<width;x+=20){
    let y=sin(x/10+frameCount/100)*height/5
    ellipse(x,y, 50)
  }
}
動態的 sin 波
動態的 sin 波

如果我們想要綜觀不同的參數設定會讓 sin 波長得如何不同,這時候可以好好運用滑鼠座標 mouseX、 mouseY 啦!老闆這邊想要觀察的是圓點取樣的多寡還有波的長短,因此利用 mouseX 由小到大的值對應為圓點取樣的間隔, mouseY 的大小則對應著波長的長短,並分別由變數 span、freq 把對應的值儲存下來。大家可以試驗滑鼠在不同的位置是如何影響波的樣貌?你也會發現很有趣的是當取樣的點(由 mouseX 決定)由多至少時,本身波長很短也會變得像波長很長的波,甚至看似多條 sin 波複合。

  • map(mouseX,0,width,0,100,true):將原先 mouseX 的值本來從 0~width 大小,對應到 1~100 之間,最後的 true 是當 mouseX 的值超出 0~width,也嚴格限制值落在 1~100 之間。
function setup() {  
  createCanvas(1000, 1000);
  background(100);
  fill(0)
  rect(0,0,width,height)
}

function draw() {
  fill(0)
  rect(0,0,width,height)
   
  fill(255)
  noStroke()
  translate(0,height/2)
  let span = map(mouseX,0,width,1,100,true)
  let freq = map(mouseY,0,height,5,100,true)
  for(var x=0;x<width;x+=span){
    let y=sin(x/freq+frameCount/100)*height/5
    ellipse(x,y, 5)
  }
}
偵測滑鼠位置控制 sin 波疏密
偵測滑鼠位置控制 sin 波疏密

3. 把 sin 波轉到極座標上

為了要讓 sin 波變成花狀,我們要運用極座標,把 x 當成 0~360 度,sin(x) 的值當成長度。首先,先把座標系的原點改移到畫布中央 (width/2,height/2) 。接著很有趣的是,老闆不直接算出圓點的位置,而是再度移動座標系:讓座標系旋轉 x 度數再移動整個座標系讓原點移至 (sin(x),0) ,因此每一個圓形只要繪製在原點 (0,0) 上就好了!

座標系移動過後都要讓它回到原位再做下一次的移動,所以移動前都先用 push() 儲存目前的設定。每次旋轉+移動完座標系後,再透過 pop() 恢復原廠設定,下一次就又會從原先設定的狀態也就是座標系原點畫布中央開始!

  • push()、pop():前者存下當前的畫筆設定、後者恢復 push() 時儲存的設定。通常我們會把想要大動特動的畫筆設定寫在 push() 與 pop() 之間,執行完想繪製的東西後就能夠恢復成原本冷靜的狀態。
  • rotate(x/width*2*PI):座標系的旋轉。根據設定的 angleMode,可以填入弧度或是角度,為了避免搞混,我們使用在裡面填入弧度 PI。當 x 在 0~width 之間,x/width*2*PI 就是從 0~360 度的範圍。
function setup() {
  createCanvas(1000, 1000);
  background(100);
  fill(0)
  rect(0,0,width,height)
  ellipse(0,10, 15)
}

function draw() {
  //畫背景
  fill(0)
  rect(0,0,width,height)
  
  //畫圓圈 
  fill(255)
  noStroke()
  translate(width/2,height/2) //將原點設定到畫面中央
  rect(0,0,50,50) //畫個矩形確認座標系原點是否移到畫布中央

  let span = map(mouseX,0,width,1,100,true)
  let freq = map(mouseY,0,height,5,100,true)
  for(var x=0;x<width;x+=span){
    push()
      rotate(x/width*2*PI) //把座標系旋轉到0-360度之間
      let y=sin(x/freq+frameCount/100)*height/2 //藉由height/2讓波幅是畫面的一半高
      translate(y,0) //把旋轉過座標系在X軸上移動y個距離
      ellipse(0,0,10)
    pop()
  }
}

4. 來幫圖形上色吧

上色時老闆喜歡運用 coolors 這個網站挑選喜歡的配色,可以用空白鍵隨選5個顏色的搭配,也可以鎖住喜歡的顏色、繼續點空白鍵直到找到五個最喜歡的顏色搭配為止。每個顏色條裡也有一些提供調整的選擇。小撇步是當你決定好時,可以複製上方的代表顏色的字碼回到程式世界喔!

老闆想嘗試看看不同的視覺效果,將原先的圓形改為方形。接著指定一個變數 colors 來儲存這串字碼,並用程式將一個個色碼分開後,將每個色碼前面加上「#」成為完整的表示,例如:#1be7ff,#6eeb83。

為了讓每個方形輪流上不同的顏色,採用取餘數的方式:colors[int(x%colors.length)],可以讓餘數落在 0~colors.length-1,對應到 colors 陣列裡的各個色碼,在這裡外面包了一層 int() 是因為有時候j avascript 餘數運算出來是浮點數,因此要讓它強制取整。

//指定一個色票陣列
var colors = "1be7ff-6eeb83-e4ff1a-ffb800-ff5714-DB4D6D".split("-").map(a=>"#"+a)

function setup() {
  createCanvas(1000, 1000);
  background(100);
  fill(0)
  rect(0,0,width,height)
}

function draw() {
  //畫背景
  fill(0)
  rect(0,0,width,height)
  
  //畫圈圈 
  fill(255)
  noStroke()
  translate(width/2,height/2) 
  rect(0,0,50,50) 
  
  let span = map(mouseX,0,width,1,100,true)
  let freq = map(mouseY,0,height,5,100,true)
  for(var x=0;x<width;x+=span){
    push()
      fill(colors[int(x%colors.length)]) //選取色票陣列裡的特定顏色
      rotate(x/width*2*PI) 
      let y=sin(x/freq+frameCount/100)*height/2
      translate(y,0)
      rect(0,0,50)
    pop()
  }
}
<甜蜜陷阱>步驟四:加入顏色
<甜蜜陷阱>步驟四:加入顏色

記得中途若是做到喜歡的圖樣,可以自訂範圍截圖存取(mac:command+shift+4、window:win+shift+s),如果要將程式碼階段性保存起來,在 openprocessing 右上角有樹枝狀的按鈕 fork,就可以再複製一個出來繼續往下做喔!

5. 用圓形、方形、三角形來豐富

x 是我們畫每個點的依據,現在如果要讓每個位置可以分別呈現圓形、方形、三角形可以怎麼做呢?老闆是運用 x 除以3(代表 3 種形狀的餘數)與 if 條件式來實現,藉由餘數 0、1、2 分別對應到繪製不同的形狀。但在這裡還有一個關於繪製正三角形的挑戰:如果直接去計算 triangle(x1, y1, x2, y2, x3, y3) 的每一點座標是有些困難的,於是我們用三角函數的方式來計算。看著下圖我們可以看到透過角度 0、120、240 度,可以取得頂點的 x、y 座標 (r*cos(θ),r*sin(θ))。

var colors = "1be7ff-6eeb83-e4ff1a-ffb800-ff5714-DB4D6D".split("-").map(a=>"#"+a)
function setup() {
  createCanvas(1000, 1000);
  background(100);
  fill(0)
  rect(0,0,width,height)
}
 
//將製作三角形定義成一支function可以隨時在draw()裡呼叫取用
function myTriangle(x,y,r){      //function可以設定想定義的參數
  push()
    translate(x,y)
    let points=[] //存放三角形的頂點座標
    for(var i=0;i<3;i++){   
      let rr =r
      let angle=i*120
      let xx = rr*cos(angle/360*2*PI) //將角度數值轉換為角度
      let yy = rr*sin(angle/360*2*PI)
      points.push(xx,yy)	//將各頂點座標依序放入points陣列
    }
    triangle(...points) //用ES6語法...展開points從一陣列變成個別的6個值
  pop()
}

function draw() {
  //畫背景
  fill(0)
  rect(0,0,width,height)
  
  //畫圈圈 
  fill(255)
  noStroke()
  translate(width/2,height/2)
  rect(0,0,50,50) 
 
  let span = map(mouseX,0,width,1,100,true)
  let freq = map(mouseY,0,height,5,100,true)
  for(var x=0;x<width;x+=span){
    push()
      fill(colors[int(x%colors.length)])
      rotate(x/width*2*PI) //把座標系旋轉到0-360度之間
      let y=sin(x/freq+frameCount/100)*height/3
      translate(y,0) //把旋轉過座標系在X軸上移動y個距離
      
      let shapeId = int(x)%3
      if(shapeId == 0){
        rect(0,0,50)
      }
      if(shapeId == 1){
        ellipse(0,0,50)
      }
      if(shapeId == 2){
        myTriangle(0,0,50)
      }
    pop()
  }
}
<甜蜜陷阱>步驟五:用不同的幾何圖形豐富圖面
<甜蜜陷阱>步驟五:用不同的幾何圖形豐富圖面

6. 妝點-陰影、材質

 再來老闆使出自己愛用的方法,給予圖樣更豐富的變化。一開始嘗試陰影效果,有兩種陰影製作的方式可以選擇,除了陰影的顏色要設定外,分別結合陰影模糊程度的設定、陰影偏離物體多少。

  • drawingContext:HTML5 Canvas的功能可以用這個API取得。
    • drawingContext.shadowBlur:設定陰影模糊的程度
    • drawingContext.shadowColor:設定陰影的顏色
    • drawingContext.shadowOffsetX:設定陰影偏離物體多少x距離
    • drawingContext.shadowOffsetY:設定陰影偏離物體多少y距離
var colors = "1be7ff-6eeb83-e4ff1a-ffb800-ff5714-DB4D6D".split("-").map(a=>"#"+a)
function setup() {
  createCanvas(1000, 1000);
  background(100);
  fill(0)
  rect(0,0,width,height)
  ellipse(0,10, 15)

  //選擇一
  drawingContext.shadowBlur=5 
  drawingContext.shadowColor = color(0,100)//透明度0-255

  //選擇二,drawingContext.shadowBlur很當時可以使用
  drawingContext.shadowColor = color(0,100)//透明度0-255
  drawingContext.shadowOffsetX = 10
  drawingContext.shadowOffsetY = 10
}
<甜蜜陷阱>步驟六:加上陰影
<甜蜜陷阱>步驟六:加上陰影

如果想要加入材質感,可以學習製作一塊材質圖樣,再把材質圖樣疊加到畫布中。在這裡老闆設計的是噪點感的材質,噪點由許多深淺不一的灰階值組成。在 p5.js 裡可以透過指定一個變數製作出空白圖樣範圍,把圖樣像素化後可以用 for 迴圈指定每一個像素要畫什麼顏色。在這裡顏色的設定利用了 noise() 產生較有規律的 0~1 數值、random([a,b,c]) 決定 noise() 值放大的倍率來設定顏色的透明度。大家也可以試試在 noise() 傳入不同的參數、random() 陣列裡設定不同的倍率來製作不同的噪點感。製作好材質後可以選擇特定的疊加方法繪製出圖片。

  • createGraphics(width,height):設定一塊圖樣,傳入想要的寬高大小。
  • loadPixels():將圖樣的像素傳到 pixels[] 陣列,後續才可以讀取或者寫入想要的圖樣。
  • updatePixels():在設定完每一個像素的顏色後,可以用這個 api 更新成為新圖樣。
  • color(gray, [alpha]):第一個參數代表 0~255 的灰階值,第二個參數代表透明度。
  • noise(x,[y],[z]): 根據傳入的座標產生 0~1 之間浮點數,傳入的座標值越相近,產生出的浮點數會較有規律,不會變動很大。
  • random([array]):如果沒有特別傳入參數,random() 會返回0~1之間的浮點數,如果有寫明一個陣列,則每次會隨機在陣列裡挑選一個元素返回。
  • image(img, x, y, [width], [height]):在特定座標繪製出圖片。
var colors = "1be7ff-6eeb83-e4ff1a-ffb800-ff5714-DB4D6D".split("-").map(a=>"#"+a)
let overallTexture
function setup() {
  createCanvas(1000, 1000);
  background(100);
  fill(0)
  rect(0,0,width,height)
  
  //選擇二,drawingContext.shadowBlur很當時可以使用
  drawingContext.shadowColor = color(0,100)//透明度0-255
  drawingContext.shadowOffsetX = 10
  drawingContext.shadowOffsetY = 10
  
  //製作噪點材質
  overAllTexture=createGraphics(width,height)
  overAllTexture.loadPixels()
 
  // noStroke()
  for(var i=0;i<width+50;i++){
    for(var o=0;o<height+50;o++){
      overAllTexture.set(i,o,color(150,noise(i/10,i*o/300)*random([50,100,200])))  
      //每一個像素指定特定的顏色
      //如果將random的值改小材質就不會太黑太明顯
    }
  }  
  overAllTexture.updatePixels()
}
 
function draw() {
  //畫背景
  fill(0)
  rect(0,0,width,height)
  
  push()
    //畫圈圈 
    fill(255)
    noStroke()
    translate(width/2,height/2)
    rect(0,0,50,50) 
 
    //製作三角形的函式
    function myTriangle(x,y,r){
      let points=[] 
      for(var i=0;i<3;i++){   
        let rr =r
        let angle=i*120
        let xx = rr*cos(angle/360*2*PI) 
        let yy = rr*sin(angle/360*2*PI)
        points.push(xx,yy)
      }
      triangle(...points) 
    }

    let span = map(mouseX,0,width,1,100,true)
    let freq = map(mouseY,0,height,5,100,true)
    for(var x=0;x<width;x+=span){
      push()
        fill(colors[int(x%colors.length)])
        rotate(x/width*2*PI) 
        let y=sin(x/freq+frameCount/100)*height/2
        anslate(y,0)

        let shapeId = int(x)%3
        if(shapeId == 0){
          rect(0,0,50)
        }
        if(shapeId == 1){
          ellipse(0,0,50)
        }
        if(shapeId == 2){
          myTriangle(0,0,50)
        }
      pop()
    }
  pop()

  //將噪點材質疊加到畫布上
  push()
    blendMode(MULTIPLY)
    image(overAllTexture,0,0) //
  pop()
}
<甜蜜陷阱>步驟六:加上材質

7. 讓圖形大小變化與自轉、長出刺與小圓點

為了讓整個互動的畫面更豐富有變化,老闆運用sin() 來設定形狀的大小。此外,形狀們除了不斷輻合到畫面中央外,也用rotate() 讓它開始自轉,並且形狀上、周圍加上一些裝飾:看起來像是刺的長短不一的線條、修改利用前面製作三角形的函式讓每個形狀的周圍環繞三個小圓形。

for(var x=0;x<width;x+=span){
  push()
    fill(colors[int(x%colors.length)])
    rotate(x/width*2*PI) 
    let y=sin(x/freq+frameCount/100)*height/3
    translate(y,0) 
    let shapeId = int(x)%3
	
    let rr= sin(x)*80 //讓每個圖形大小變化
    rotate(frameCount/50) //讓每個圖形自轉 


    if(shapeId == 0){
      rect(0,0,rr)
    }
    if(shapeId == 1){
      ellipse(0,0,rr)
    }
    if(shapeId == 2){
      myTriangle(0,0,rr)
    }

    //畫上刺
    strokeWeight(3)
    stroke(255)
    line(0,0,-rr,-rr) //線條與圖形用的是同一個座標系設定

    //畫環繞的圓形
    for(var i=0;i<3;i++){   
      noStroke()
      let rr =50
      let angle=i*120
      let xx = rr*cos(angle/360*2*PI) 
      let yy = rr*sin(angle/360*2*PI)
      ellipse(xx,yy,5)
    }
  pop()
}
<甜蜜陷阱>步驟七:讓圖形大小變化與自轉、長出刺與小圓點
<甜蜜陷阱>步驟七:讓圖形大小變化與自轉、長出刺與小圓點

8. 製作網格背景

再來我們要來製作現代感的網格背景,因此在座標系設定到畫面中央後,我們新增一段程式碼,設定線條的顏色並分別畫上水平線條與垂直線條。這裡老闆運用了取餘數,讓線條每 5 條就增強它的粗度與變得更明顯(調整透明度),這邊也用到了一些 javascript 的數學與邏輯表示方式。

  • abs():取絕對值
  • boolean?a:b:如果前面的變數 boolean 值是 true,就返回 a 值;是 false,就返回 b 值
translate(width/2,height/2) //將原點設定到畫面中央
			
 //畫網格線
stroke(255,100)
for(let xx=-width/2;xx<width/2;xx+=40){
let isSpan = (abs(xx/20)%5==0)
  strokeWeight(isSpan?3:1)
  stroke(255,20+isSpan?200:0)
  line(xx,-height/2,xx,height/2)
  }
		
for(let yy=-height/2;yy<height/2;yy+=40){
  let isSpan = (abs(yy/20)%5==0)
  strokeWeight(isSpan?3:1)
  stroke(255,20+isSpan?200:0)
  line(-width/2,yy,width/2,yy)
}
noStroke()
<甜蜜陷阱>步驟八:製作網格背景
<甜蜜陷阱>步驟八:製作網格背景

9. 隨機選取顏色子集合、印出文字

為了讓圖樣在程式每次開始執行時都可以選取不同的顏色來繪製,老闆運用隨機的概念,讓每個在顏色陣列裡的色碼,會透過機率的方式決定會不會被選到。為了避免所有顏色都未能被選入,也預先儲存一些絕對會畫上去的顏色。

var colors = "1be7ff-6eeb83-e4ff1a-ffb800-ff5714-DB4D6D".split("-").map(a=>"#"+a)
var useColors = ['#000','#fff'] //真正用於著色的陣列,可以預先填入一些顏色
let overallTexture
function setup() {
  createCanvas(1000, 1000);
  background(100);
  fill(0)
  rect(0,0,width,height)
  ellipse(0,10, 15)           
         
  //繪製陰影
  drawingContext.shadowColor = color(0,100)//透明度0-255
  drawingContext.shadowOffsetX = 10
  drawingContext.shadowOffsetY = 10

  //製作噪點材質
  overAllTexture=createGraphics(width,height)
  overAllTexture.loadPixels()
 
  // noStroke()
  for(var i=0;i<width+50;i++){
    for(var o=0;o<height+50;o++){
      overAllTexture.set(i,o,color(150,noise(i/10,i*o/300)*random([50,100,200])))  
      //每一個像素指定特定的顏色
      //如果將random的值改小材質就不會太黑太明顯
    }
  }
  overAllTexture.updatePixels()

  //顏色子集合
  colors = colors.concat(colors) //隨機條件若很嚴格可以藉由讓顏色陣列複製自己,增加顏色被選到的機率
  randomSeed(Date.now()) //讓隨機依據變動的數字(如用當下的時間)會更隨機
  colors.forEach(clr=>{ //對於顏色陣列裡的每個顏色(設定變數clr)會逐一的執行{}裡的指令
    if(random()<0.25){ //當random()的值小於某數時才會執行
      useColors.push(clr)  //執行將某色存入useColors陣列
    }
  })
}

別忘了要將填色的部分改選用useColors陣列喔!

function draw(){
  ...
  for(var x=0;x<width;x+=span){
    push()
      fill(useColors[int(x%useColors.length)]) 
      rotate(x/width*2*PI) 
      let y=sin(x/freq+frameCount/100)*height/3 				
      translate(y,0) 
      let shapeId = int(x)%3
    pop()
  }
}

再來可以在畫面上以文字呈現一些參數是如何變化,讓作品看起來很有科幻系統的感覺。為了讓形狀都會有陰影但文字不會,將原本在 setup() 關於陰影的設定搬到 draw(),但在要繪製文字之前將陰影設定取消。這邊很有趣的是,老闆還繪製出了填色矩形記錄每次圖樣是由哪幾個顏色構成。

  • text(str, x, y):在 (x,y) 座標呈現出文字
function draw() {	
  drawingContext.shadowColor = color(0,200)//透明度0-255
  drawingContext.shadowOffsetX = 10
  drawingContext.shadowOffsetY = 10

  //畫背景
  fill(0)
  rect(0,0,width,height)
    
  push()         
    // blendMode(SCREEN)
    //畫圈圈 
    fill(255)
    noStroke()
    translate(width/2,height/2) //將原點設定到畫面中央
			
    //畫網格線
    stroke(255,100)
    for(let xx=-width/2;xx<width/2;xx+=40){ //
      let isSpan = (abs(xx/20)%5==0)
      strokeWeight(isSpan?3:1)
      stroke(255,20+isSpan?200:0)
      line(xx,-height/2,xx,height/2)
    }
		
    for(let yy=-height/2;yy<height/2;yy+=40){ //
      let isSpan = (abs(yy/20)%5==0)
      strokeWeight(isSpan?3:1)
      stroke(255,20+isSpan?200:0)
      line(-width/2,yy,width/2,yy)
    }
    noStroke()
		
			
    //畫形狀
    let span = map(mouseX,0,width,1,100,true)
    let freq = map(mouseY,0,height,1,100,true)
    let curveFactor = noise(frameCount/1000)*3+5 
    for(var x=0;x<width;x+=span){
      push()
        fill(useColors[int(x%useColors.length)])
        rotate(x/width*2*PI) 
        let y=sin(x/freq+frameCount/100)*height/2 
        translate(y,0) //把旋轉過的X軸上移y個距離
        let shapeId = int(x)%3
				
        let rr=(pow(noise(x),2)+pow(sin(x),1.2))*100 //製作大小不一的形狀
        rotate(frameCount/50)//自轉 
				
        if(shapeId == 0){
          rect(0,0,rr)
        }
        if(shapeId == 1){
          ellipse(0,0,rr)
        }
        if(shapeId == 2){
          myTriangle(0,0,rr)
        }
        strokeWeight(3)
        stroke(255)
        line(0,0,-rr,-rr)
				
        //環繞的小圓形
        for(var i=0;i<3;i++){  
          noStroke()
          let rr =50
          // let cirR =10 *sin(x)
          let cirR =10
          let angle=i*120+frameCount/100+x*curveFactor//?
          let xx = rr*cos(angle/360*2*PI) //將角度數值轉換為角度
          let yy = rr*sin(angle/360*2*PI)
          ellipse(xx,yy,cirR)
        }			
      pop()
    }
  pop()     
		
    //為了寫文字取消陰影
    drawingContext.shadowColor = color(0,200)//透明度0-255
    drawingContext.shadowOffsetX = 0
    drawingContext.shadowOffsetY = 0
		
  push()
    
    for(var colorId = 0;colorId<useColors.length;colorId++){
      fill(useColors[colorId])
      strokeWeight(2)
      rect(colorId*40+40,height-210,30,30) //注意這裡的座標系原點是以左上
                                        //角(0,0)計算,每個方形間隔40,寬高30
    }
    fill(255) //字體設定白色
    textSize(24)
    textStyle(BOLD)
    text("TIME: "+frameCount+"fp",50,height-130)
    text("SPAN: "+span.toFixed(2)+"\"",50,height-90) //這裡值得注意為了要顯示”
                                                     //需要在前面加一條\方便程式辨識喔
    text("FREQ: "+span.toFixed(2)+"Hz",50,height-50)
  pop()
		
  push()
    blendMode(MULTIPLY)
    image(overAllTexture,0,0)
  pop()
}
<甜蜜陷阱>步驟九:隨機選取顏色組合,並在圖的左下角新增文字
<甜蜜陷阱>步驟九:隨機選取顏色組合,並在圖的左下角新增文字

10. 最後一點小調整!

為了讓很多東西不要只隨著 sin 變化,減少單調以及增加更多的韻律,例如小圓形原本只會跟著大圓形、方形、三角形一起同週期旋轉,為了讓它有自己的旋轉,加上了 frameCount/100,再透過加上 x*a(a 代表一個設定的倍數),讓每個位置上的三個小圓形都有不同的偏轉角度,看起來就像是扭轉纏繞的模樣。另外,利用 noise() 讓本來只會隨著 sin(x) 值規律變大變小的形狀可以增加一點隨機的變化,合併使用 pow() 次方的相乘讓值更極端。

我們可以在 setup() 設定一開始滑鼠的位置來規範一開始執行程式時就出現想要的圖樣,最後方便儲存圖片可使用 mousePressed() 偵測滑鼠點按事件的發生並以 save() 存下圖片。

  • pow(n,e):n的e次方。
  • save():存取當前畫面。
var colors = "1be7ff-6eeb83-e4ff1a-ffb800-ff5714-DB4D6D".split("-").map(a=>"#"+a)
var useColors =["#000","#fff"]
let overAllTexture

function mousePressed(){ //偵測滑鼠點按
  save()   //儲存畫面
}

function setup() {
  colors = colors.concat(colors)
	
  createCanvas(1000,1000);
  background(100);
  fill(0)
  rect(0,0,width,height)
  pixelDensity(2)     //增加像素密度
  // drawingContext.shadowBlur=5
	
  randomSeed(Date.now())
  mouseX = random(1,width/10) //設定一開始的滑鼠座標
  mouseY = random(1,height/2) //設定一開始的滑鼠座標
	
  colors.forEach(clr=>{
    if (random()<0.25){
      useColors.push(clr)
    }
  })
	
  overAllTexture=createGraphics(width,height)
  overAllTexture.loadPixels()
  // noprotect
  // noStroke()
  for(var i=0;i<width+50;i++){
    for(var o=0;o<height+50;o++){
      overAllTexture.set(i,o,color(150,noise(i/10,i*o/300)*random([0,0,0,80,200]))) 
      //可以透過在陣列裡複製多一點某個值讓它被隨選到的機率增加
    }
  }
  overAllTexture.updatePixels()
}

function myTriangle(x,y,r){
  push()
    translate(x,y)
    let points = []
    for(var i=0;i<3;i++){
      let rr = r
      let angle =i*120
      let xx = rr* cos(angle/360*2*PI)
      let yy = rr* sin(angle/360*2*PI)
      points.push(xx,yy)
    }
    triangle(...points)
  pop()
}

function draw() {
  drawingContext.shadowColor=color(0,200)
  drawingContext.shadowOffsetX=10
  drawingContext.shadowOffsetY=10

  // print(mouseX,mouseY)
  //畫背景
  fill("#000")
  rect(0,0,width,height)
  // push()
  //  fill(0,0.1)
  //  rect(0,0,width,height)
  // pop()

  push()
    // blendMode(SCREEN)
    //畫圈圈
    fill(255)
    noStroke()

    //translate to center
    translate(width/2,height/2)

    stroke(255,100)
    for(let xx=-width/2;xx<width/2;xx+=40){
      let isSpan = (abs(xx/20)%5==0?150:0) 
      strokeWeight(isSpan?2:1)
      stroke(255,20+ isSpan?100:0)
      line(xx,-height/2,xx,height/2)
    }

    for(let yy=-height/2;yy<height/2;yy+=40){
      let isSpan = (abs(yy/20)%5==0?150:0) 
      strokeWeight(isSpan?2:1)
      stroke(255,20+ isSpan?100:0)
      line(-width/2,yy,width/2,yy)
    }
    noStroke()

    // rect(0,0,50,50)
    let span = map(mouseX,0,width,1,10,true)
    // print(span)
    let freq = map(mouseY,0,height,1,100,true)
    let curveFactor = noise(frameCount/1000)*3+5 //小圓形扭轉的程度
    for(var x=0;x<width;x+=span){
      push()
        fill(useColors[int(x%useColors.length)])
        rotate(x/width*2*PI)
        let y = sin(x/freq+frameCount/100)*height/2
        translate(y,0)
        let shapeId = int(x)%3
        let rr = ( pow(noise(x),2)+ pow(sin(x),1.2))*80 //讓形狀大小變化度更大
        rotate(frameCount/50)
        if (shapeId==0){
          rect(0,0,rr)
        }
        if (shapeId==1){
          ellipse(0,0,rr)
        }
        if (shapeId==2){
          myTriangle(0,0,rr)
        }
        strokeWeight(3)
        stroke(255)
        line(0,0,-rr,-rr)

        for(var i=0;i<3;i++){
          noStroke()
          let rr = 50
          let cirR = 10
          let angle =i*120+frameCount/100 + x*curveFactor //製造三個小圓形第二層旋轉、不同位置的三個小圓形偏轉不同角度
          let xx = rr* cos(angle/360*2*PI)
          let yy = rr* sin(angle/360*2*PI)
          ellipse(xx,yy,cirR)
        }
        // ellipse(0,0,50)
      pop()
    }
  pop()

  //把陰影取消掉
  drawingContext.shadowColor=color(0,200)
  drawingContext.shadowOffsetX=0
  drawingContext.shadowOffsetY=0

  push()
    textSize(24)
    textStyle(BOLD);
    for(var colorId =0;colorId<useColors.length;colorId++){
      fill(useColors[colorId])
      strokeWeight(2)
      rect(colorId*40+40,height-210,30,30)
    }
    fill(255)
    text("TIME: "+frameCount+ "fp", 50,height-130)
    text("SPAN: "+span.toFixed(2) + "\"", 50,height-90)
    text("FREQ: "+freq.toFixed(2) + "Hz", 50,height-50)
  pop()
  push()
    blendMode(MULTIPLY)
    image(overAllTexture,0,0)
  pop()
}
<甜蜜陷阱>成品圖
<甜蜜陷阱>成品圖

老闆來結語

再次附上這次範例的成品<甜蜜陷阱>讓大家在開發時參考。這次的創作是從一個點子開始慢慢精修,一邊做一邊調整,讓我們快速回顧一下甜蜜陷阱的創作過程:

  • 了解 openprocessing 創作的起手式 – setup() 與 draw()
  • 運用滑鼠座標來動態改變sin波的樣貌
  • 運用旋轉與移動座標系來繪製花狀波形
  • 上色與變化形狀
  • 加入陰影、噪點材質
  • 調整形狀大小
  • 自轉、毒刺與環繞的小圓形
  • 加上網格背景與文字
  • 最後的調整修飾

這部影片結合了許多好用的數學概念與 API,讓我們可以邏輯化的選取或製作特定效果。在寫程式時也可以善用註解,比較好區塊化地理解與管理每一段程式影響了畫面哪些部分。大家會發現老闆在過程中會不斷微調參數值或是回頭修改使用的 API 試驗不同的效果,這也是創作磨人卻有趣的地方,大家一起探索與試驗吧!

如果你喜歡老闆的教學,《互動藝術程式創作入門》課程中也有手把手的實作引導。寫程式製作生成藝術世紀是一趟需要精準又沿路充滿驚喜的旅程,需要腦瓜裡有彈性的空間-細心規劃,但也放膽試驗、歡迎意外!

此篇直播筆記由幫手 C 協助整理

墨雨設計banner

訂閱 Creative Coding Taiwan 電子報:

這篇文章 【p5.js創作教學】Sweet Trap 甜蜜陷阱 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>