๐Ÿ˜‹ ์ธ์Šคํƒ€๊ทธ๋žจ ํ•„ํ„ฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”?

kimbyungchanยท2021๋…„ 3์›” 10์ผ
5
post-thumbnail

๊ฐœ์š”

์š”์ฆ˜ ์ธ์Šคํƒ€๊ทธ๋žจ์—์„œ ๋งค์šฐ ํ•ซํ•œ ํ•„ํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค.
์ธ์Šคํƒ€๊ทธ๋žจ ํ•„ํ„ฐ์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์—ฌ๊ธฐ ์ž์„ธํžˆ ์„ค๋ช… ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ˜ฌ ํ”„๋กœ๊ทธ๋žจ ์„ค์น˜๋ถ€ํ„ฐ

์—ฌ๊ธฐ๋ฅผ ๋ˆŒ๋Ÿฌ Spark AR์„ ๋‹ค์šด๋กœ๋“œ ํ•ฉ๋‹ˆ๋‹ค.
ํŽ˜์ด์Šค๋ถ ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ์„ ํ•˜๊ณ  ์ฒซ ํ™”๋ฉด์—์„œ New Project๋ฅผ ๋ˆŒ๋Ÿฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด๋ณผ๊นŒ์š”?


Blank Project๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

๐Ÿš€ ์ด์ œ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”?

์ฒซ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ํ•„ํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”?

์ผ๋‹จ ์ €์žฅ ๋จผ์ €

cmd + s ๋ฅผ ๋ˆŒ๋Ÿฌ ์ €์žฅ์„ ๋จผ์ € ํ•ด์ฃผ์„ธ์š”.

๊ทธ๋ฆฌ๊ณ  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ์‹œ๋‹ค.

FaceTracker ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

Particle System ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

Material ํ•˜๋‚˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์ƒ์„ฑํ•œ Material์„ ์„ ํƒํ•ด ShaderType์„ Flat์œผ๋กœ ๋ณ€๊ฒฝํ•ด์ค๋‹ˆ๋‹ค.

์กฐ๊ธˆ์ „์— ์ƒ์„ฑํ•œ Particle System์„ ์„ ํƒํ•ด Material์„ ํ• ๋‹นํ•ด ์ค๋‹ˆ๋‹ค.


ํ•˜์–€์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ๋œ๊ฒŒ ํ™•์ธ ๋˜์—ˆ๋‚˜์š”?

์ด๋ฏธ์ง€๋ฅผ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”


ํ•ด๋‹น ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋ฐ›์•„ Spark AR์— ๋“œ๋ž˜๊ทธํ•ด์„œ ๋„ฃ์–ด์ฃผ์„ธ์š”.

Material์— ์ด๋ฏธ์ง€๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ Camera View๋ฅผ ๋ณด๋ฉด ๊ฒ€์€์ƒ‰์ด ๊ฐ™์ด ๋‚˜์˜ค๋Š”๊ฑธ ๋ณผ์ˆ˜๊ฐ€์žˆ๋Š”๋ฐ

Blend Mode ๋ฅผ Screen์œผ๋กœ ๋ณ€๊ฒฝํ•ด์ค๋‹ˆ๋‹ค.

๋ณ€๊ฒฝํ–ˆ๋Š”๋ฐ Camera View์—์„œ ํŒŒํ‹ฐํด์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ๋„ˆ๋ฌด ์ž‘์€๊ฒƒ ๊ฐ™์•„ ๋ณด์ž…๋‹ˆ๋‹ค.

Particle System์„ ๋ˆŒ๋Ÿฌ Particle ๊ทธ๋ฃน์˜ Scale๋ฅผ ๋ณ€๊ฒฝํ•ด์ค๋‹ˆ๋‹ค. 0.01 -> 0.1

Lifespan๋„ 0.4 -> 1 ๋กœ ๋ณ€๊ฒฝ ํ•ด์ค๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ๊นŒ์ง€ ๋”ฐ๋ผ์˜ค์…จ๋‚˜์š”? 50% ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ํŒŒํ‹ฐํด์„ ๋ˆˆ ์œ„์น˜๋กœ ๋ณ€๊ฒฝํ•ด๋ด…์‹œ๋‹ค.

cmd + option + p ๋ฅผ ๋ˆŒ๋Ÿฌ Patch Editor ๋ฅผ ์ผœ์ค๋‹ˆ๋‹ค.

faceTracker0์„ ๋“œ๋ž˜๊ทธํ•˜์—ฌ Patch Editor ์˜์—ญ ์œ„์— ๋†“์•„์ค์‹œ๋‹ค.

faceTracker0 ๋…ธ๋“œ์˜ ์ฒซ๋ฒˆ์งธ Property๋ฅผ ๋“œ๋ž˜๊ทธํ•˜์—ฌ ๋‹ค์‹œ ๋†“์•„ ์ค๋‹ˆ๋‹ค.

๋‹ค๋ฅธ Patch๋ฅผ ๊ฒ€์ƒ‰ํ• ์ˆ˜์žˆ๋Š” ์ฐฝ์ด ๋œจ๋Š”๋ฐ Eyelid๋ฅผ ์„ ํƒํ•ด์ค๋‹ˆ๋‹ค.

Particle System์„ ์„ ํƒํ•˜์—ฌ Transformations ๊ทธ๋ฃน์˜ Position ์™ผ์ชฝ์˜ ํ™”์‚ดํ‘œ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

Eyelid์˜ ์ฒซ๋ฒˆ์งธ Property๋ฅผ ๋…ธ๋ž€์ƒ‰ ํ™”์‚ดํ‘œ๊นŒ์ง€ ๋“œ๋ž˜๊ทธํ•˜์—ฌ ๋†“์•„์ค๋‹ˆ๋‹ค.

์™ผ์ชฝ ๋ˆˆ์— ๋ถ™์–ด์žˆ๋Š”๊ฒƒ์„ ํ™•์ธํ–ˆ๋‚˜์š”?

์ง€๊ธˆ Camera View๋ฅผ ๋ณด๋ฉด Particle์ด ๊ฐ‘์ž๊ธฐ ์‚ฌ๋ผ์ง€๋Š”๊ฒŒ ๊ฑฐ์Šฌ๋ฆฝ๋‹ˆ๋‹ค. ๐Ÿค”

์ด์ œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

์ฒ˜์Œ์— ๋งŒ๋“  script.tsํŒŒ์ผ์„ ์ผœ์ค๋‹ˆ๋‹ค.

/**
 * (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
 */

//==============================================================================
// Welcome to scripting in Spark AR Studio! Helpful links:
//
// Scripting Basics - https://fb.me/spark-scripting-basics
// Reactive Programming - https://fb.me/spark-reactive-programming
// Scripting Object Reference - https://fb.me/spark-scripting-reference
// Changelogs - https://fb.me/spark-changelog
//
// For projects created with v87 onwards, JavaScript is always executed in strict mode.
//==============================================================================

// How to load in modules
import Scene from 'Scene';
import Diagnostics from 'Diagnostics';

// To use variables and functions across files, use export/import keyword
// export const animationDuration = 10;

// Use import keyword to import a symbol from another file
// import { animationDuration } from './script.js'

(async function () {  // Enables async/await in JS [part 1]

    // To access scene objects
    // const [directionalLight] = await Promise.all([
    //   Scene.root.findFirst('directionalLight0')
    // ]);

    // To access class properties
    // const directionalLightIntensity = directionalLight.intensity;

    // To log messages to the console
    // Diagnostics.log('Console message logged from the script.');

})(); // Enables async/await in JS [part 2]

์ด๋ ‡๊ฒŒ ์ž‘์„ฑ ๋˜์–ด์žˆ์„ํ…๋ฐ ๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ณ 

์•„๊นŒ ์ƒ์„ฑํ•œ Particle System์„ ๊ฐ€์ ธ์™€๋ด…์‹œ๋‹ค.

import Scene from 'Scene';

(async function () {
  const particleSystem = await Scene.root.findFirst('emitter0'); // emitter0 ์ด๋ผ๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•จ.
})();

Scene.root.findFirst ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด Scene์— ์กด์žฌํ•˜๋Š” ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ฌ์ˆ˜์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ํˆฌ๋ช…๋„์™€ ์‚ฌ์ด์ฆˆ๋ฅผ ์กฐ์ ˆ ํ•ด๋ด…์‹œ๋‹ค.

import Scene from 'Scene';
import Animation from "Animation";

(async function () {
  const emitter0 = await Scene.root.findFirst('emitter0');

  emitter0.sizeModifier = Animation.samplers.easeInOutSine(0.0, -0.1);
  emitter0.hsvaColorModulationModifier = Animation.samplers.HSVA([
    Animation.samplers.constant(1),
    Animation.samplers.constant(1),
    Animation.samplers.constant(1),
    Animation.samplers.easeInOutSine(1, 0),
  ]);
})();

ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  Camera View๋ฅผ ๋ณด๋ฉด ์•„๊นŒ๋ณด๋‹ค ๋” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์‚ฌ๋ผ์ง€๋Š”๊ฑธ ๋ณผ์ˆ˜๊ฐ€์žˆ์ฃ ?

์ด์ œ ์‹ค์ œ ๊ธฐ๊ธฐ์—์„œ ์‹คํ–‰ํ•ด๋ด…์‹œ๋‹ค.

์ธ์Šคํƒ€๊ทธ๋žจ์œผ๋กœ ์ „์†กํ•ด๋ด…์‹œ๋‹ค.

์•„๋งˆ ๋กœ๊ทธ์ธ์ด ๋˜์–ด์žˆ์œผ๋ฉด ์ด๋ ‡๊ฒŒ ๋…ธํ‹ฐ๊ฐ€ ์˜ฌํ…๋ฐ ๋“ค์–ด๊ฐ€์„œ ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์‹œ๋ฉด๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ๋ฅผ ๋ˆŒ๋Ÿฌ ํ•„ํ„ฐ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณผ์ˆ˜์žˆ์Šต๋‹ˆ๋‹ค. ~~(์ตœ๋Œ€ 200๋ฒˆ ๋ณผ์ˆ˜์žˆ์–ด์„œ.. ๋งํฌ๊ฐ€ ๋งŒ๋ฃŒ๋ ์ˆ˜์žˆ์Šต๋‹ˆ๋‹ค.)~~

ํ”„๋กœ์ ํŠธ ํŒŒ์ผ์€ ์—ฌ๊ธฐ์— ์˜ฌ๋ ค๋‘์—ˆ์Šต๋‹ˆ๋‹ค


๊ฐ„๋‹จํ•˜๊ฒŒ ์ธ์Šคํƒ€๊ทธ๋žจ ํ•„ํ„ฐ ๋งŒ๋“ค์–ด๋ณด๊ธฐ์˜€์Šต๋‹ˆ๋‹ค. ๐Ÿ˜€

๋‹ค์Œ ๊ธ€์—์„œ Shader๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•˜์—ฌ ๊ธฐ์ˆ  ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋˜ ํ˜„์žฌ WE-AR์—์„œ ์ธ์Šคํƒ€๊ทธ๋žจ ํ•„ํ„ฐ ๊ฐœ๋ฐœ์ž๋ฅผ ๋ชจ์ง‘ํ•˜๊ณ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์ฑ„์šฉ ๊ณต๊ณ ๊ฐ€ ์žˆ์œผ๋‹ˆ ๋งŽ์€ ์ง€์› ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

profile
์‹œ๊ฐ์ ์ธ ์š”์†Œ๋ฅผ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋Š” ๊ฐœ๋ฐœ์ž ์ž…๋‹ˆ๋‹ค.

๊ด€์‹ฌ ์žˆ์„ ๋งŒํ•œ ํฌ์ŠคํŠธ

0๊ฐœ์˜ ๋Œ“๊ธ€