SlideShare a Scribd company logo
1 of 71
Download to read offline
1
ENABLE YOU TO MAKE A
PARTICLE SYSTEM
SIMPLE & CUSTOMIZABLEIS
2
1. BREAK IT DOWN
2. BUILD IT UP
1. BREAK IT DOWN
3
EMITTER
PARTICLE
WORLD
4
POSITION
POSITION
OVER LIFE
POSITION
AT BIRTH
SCALE
SCALE
OVER LIFE
SCALE
AT BIRTH
ROTATION
ROTATION
OVER LIFE
ROTATION
AT BIRTH
OPACITY
OPACITY
OVER LIFE
OPACITY
AT BIRTH
ANCHOR
ANCHOR
OVER LIFE
ANCHOR
AT BIRTH
5
POSITION
POSITION
OVER LIFE
POSITION
AT BIRTH
SCALE
SCALE
OVER LIFE
SCALE
AT BIRTH
ROTATION
ROTATION
OVER LIFE
ROTATION
AT BIRTH
OPACITY
OPACITY
OVER LIFE
OPACITY
AT BIRTH
ANCHOR
ANCHOR
OVER LIFE
ANCHOR
AT BIRTHPOSITION
POSITION
OVER LIFE
POSITION
AT BIRTH
SCALE
SCALE
OVER LIFE
SCALE
AT BIRTH
ROTATION
ROTATION
OVER LIFE
ROTATION
AT BIRTH
OPACITY
OPACITY
OVER LIFE
OPACITY
AT BIRTH
ANCHOR
ANCHOR
OVER LIFE
ANCHOR
AT BIRTH
POSITION
POSITION
OVER LIFE
POSITION
AT BIRTH
SCALE
SCALE
OVER LIFE
SCALE
AT BIRTH
ROTATION
ROTATION
OVER LIFE
ROTATION
AT BIRTH
OPACITY
OPACITY
OVER LIFE
OPACITY
AT BIRTH
ANCHOR
ANCHOR
OVER LIFE
ANCHOR
AT BIRTH
POSITION
POSITION
OVER LIFE
POSITION
AT BIRTH
SCALE
SCALE
OVER LIFE
SCALE
AT BIRTH
ROTATION
ROTATION
OVER LIFE
ROTATION
AT BIRTH
OPACITY
OPACITY
OVER LIFE
OPACITY
AT BIRTH
ANCHOR
ANCHOR
OVER LIFE
ANCHOR
AT BIRTH
6
P POSITION
P POSITION
OVER LIFE
P POSITION
AT BIRTH
RANDOM
RANDOM
P SCALE
P SCALE
OVER LIFE
P SCALE
AT BIRTH
RANDOM
RANDOM
P ROTATION
P ROTATION
OVER LIFE
P ROTATION
AT BIRTH
RANDOM
RANDOM
P OPACITY
P OPACITY
OVER LIFE
P OPACITY
AT BIRTH
RANDOM
RANDOM
P ANCHOR
P ANCHOR
OVER LIFE
P ANCHOR
AT BIRTH
RANDOM
RANDOM
7
OPACITY
ROTATION
SCALE
POSITION
ANCHOR
NOISE
DISTRIBUTION
SHAPE SIZE
SHAPE
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
PARTICLE INSTANCES
35
PARTICLE INSTANCES
PARTICLE
GROUPS
36
1. BREAK IT DOWN
2. BUILD IT UP2. BUILD IT UP
37
OUTPUT
INPUT
INPUT
WIND
DRAG
GRAVITY
BOUNCE
TIME STRETCH
TIME LOOP
DENSITY
QUANTITY
SPREAD
SPEED
LIFE
ANCHOR
RANDOM SEED
POSITION
SCALE
ROTATION
LOOK
OPACITY
BIRTH
AGE
INDEX
LIFE
ANCHOR
POSITION
SCALE
ROTATION
OPACITY
START TIME
OPACITY
ROTATION
SCALE
POSITION
ANCHOR
NOISE
DISTRIBUTION
SHAPE SIZE
SHAPE
38
1. EMITTER OBJECT
contains all centralized inputs for controlling all of its child particle groups
int shape
float[3] shapeSize
int distribution
float[3] noise
float[3] anchor, position, scale, rotation
float opacity
39
2. PARTICLE GROUP OBJECT
contains all centralized inputs for controlling all of its child particle groups
Image look
int randomSeed
float startTime
float quantity
float density
float life, lifeRandom
float speed, speedRandom
boolean speedOverdriveFromEmitterMotion
40
contains all centralized inputs for controlling all of its child particle groups
float[3] spreadAngle, spreadRange, spreadRandom
boolean spreadFollowEmitterMotion
float[3] anchorOffset, anchorOffsetRandom,
anchorWiggleFrequency, anchorWiggleAmplitude
float[3] positionWiggleFrequency,
positionWiggleAmplitude
2. PARTICLE GROUP OBJECT
41
contains all centralized inputs for controlling all of its child particle groups
float[2] scale, scaleRandom,
scaleWiggleFrequency, scaleWiggleAmplitude
float[3] rotationAtBirth, rotationAtBirthRandom,
rotationSpeed, rotationSpeedRandom,
rotationWiggleFrequency,
rotationWiggleAmplitude
boolean[3] rotationInBothDirection
float opacity, opacityRandom,
opacityWiggleFrequency, opacityWiggleAmplitude
2. PARTICLE GROUP OBJECT
42
2. PARTICLE GROUP OBJECT
contains all centralized inputs for controlling all of its child particle groups
float[3] wind
float[3] gravity
boolean bounce
float bounceFloorDistance,
bounceElasticity, bounceFriction
float drag
float timeStretch
float timeLoop
43
contains generated properties to draw on screen
int index
float birth, life, age
float[3] anchor
float[3] position
float[2] scale
float[3] rotation
float opacity
3. PARTICLE INSTANCE OBJECT
44
SCALE
45
Particle Life is the longevity of the particle. It tells when the particle dies:
life = pg.life + random(-pg.lifeRandom, pg.lifeRandom);
If we have PG Life Random, Particle Life will differ from PG Life.
Particle Birth is the moment the particle gets born:
birth = pg.startTime + index/pg.density;
PG Start Time is the time this Particle Group starts showing up.
Particle Index is the order of the particle, starting from 0.
PG Density is how many particles get born in a second.
Particle Age is how old the particle is at a certain time:
age = time – birth;
Time is the global value. It keeps increasing over time.
1. PARTICLE BIRTH + LIFE + AGE
46
SCALE
47
Every particle has its anchor at the center of it. If we need PG Anchor Offset
feature, we need to implement it like this:
anchor = pg.anchorOffset +
random(-pg.anchorOffsetRandom,
pg.anchorOffsetRandom);
Anchor alters the result when rotating or scaling an object:
2. PARTICLE ANCHOR
48
SCALE
49
Particle follows Emitting Direction. When Emitting Direction changes,
Particle Direction changes,
affecting Particle Position.
3. PARTICLE POSITION
50
Step 2: Calculate Particle Direction affected by
Emitter Rotation and PG Spread:
direction =
emitter.rotation +
pg.spreadAngle +
random(-pg.spreadRandom,
pg.spreadRandom);
Step 1: Define vector Particle Velocity pointing straight up (-Y):
velocity = [0, -pg.speed, 0];
PG Speed defines how fast particles travel
when they are born.
3. PARTICLE POSITION
51
3D Rotation reference:
http://www.cs.helsinki.fi/group/goa/mallinnus/3dtransf/3drot.html
Step 3: Transform vector Particle Velocity according to Particle Direction:
v = velocity; d = direction;
β€’ X-Axis Rotation:
vNew[0] = v[0];
vNew[1] = v[1] * cos(d[0]) - v[2] * sin(d[0]);
vNew[2] = v[1] * sin(d[0]) + v[2] * cos(d[0]);
β€’ Y-Axis Rotation:
vNew[0] = v[2] * sin(d[1]) + v[0] * cos(d[1]);
vNew[1] = v[1];
vNew[2] = v[2] * cos(d[1]) - v[0] * sin(d[1]);
β€’ Z-Axis Rotation (2D Rotation):
vNew[0] = v[0] * cos(d[2]) – v[1] * sin(d[2]);
vNew[1] = v[0] * sin(d[2]) + v[1] * cos(d[2]);
vNew[2] = v[2];
3. PARTICLE POSITION
52
particlePositionAtBirth
emitterPosition
vNew * age
Step 4: We now have new vector Particle Velocity. Multiply it with
Particle Age to get its local Particle Position over time:
position = vNew * age;
Finally we get global Particle Position:
position += emitter.Position;
3. PARTICLE POSITION
53
Emitter Size
Random point picking reference
for other shapes:
http://mathworld.wolfram.
com/topics/
RandomPointPicking.html
If Emitter Shape Size is not zero. Position At Birth is
a random point within Emitter Shape. So it is
affected by Emitter Shape and Emitter Shape Size:
positionAtBirth =
random(-emitter.shapeSize/2,
emitter.shapeSize/2);
particlePositionAtBirth
emitterPosition
vNew * time
3. PARTICLE POSITION
So we have to count in Particle Position At Birth:
position += positionAtBirth;
54
SCALE
55
Particle Scale defines the size of the particle. And it is affected by PG Scale
and PG Scale Random:
scale = pg.scale +
random(-pg.scaleRandom, pg.scaleRandom);
In order to change Particle Scale Over Life we need to enable key frames for
PG Scale so its value varies from time to time, and then get its value at its
proper age, we call it PG Age:
pgAge = age * pg.life/life;
So we use this code instead of the one above:
scale = pg.scale.valueAtTime(pgAge) +
random(-pg.scaleRandom, pg.scaleRandom);
4. PARTICLE SCALE
56
SCALE
57
Particle Rotation is a little more complicated. We need to apply both
PG Particle Rotation At Birth and PG Rotation Speed:
rotation = pg.rotationAtBirth +
random(-pg.rotationAtBirthRandom,
pg.rotationAtBirthRandom) +
age *
(pg.rotationSpeed.valueAtTime(age * pg.life/life) +
random(-pg.rotationSpeedRandom,
pg.rotationSpeedRandom));
5. PARTICLE ROTATION
58
SCALE
59
Also like Particle Scale, Particle Opacity is simple, supporting Particle Opacity
Over Life:
opacity = pg.opacity.valueAtTime(pgAge) +
random(-pg.opacityRandom, pg.opacityRandom);
6. PARTICLE OPACITY
60
To achieve uniform spread, we need to add to the Particle Direction
code that we made before:
direction = emitter.rotation + pg.spreadAngle +
random(-pg.spreadRandom, pg.spreadRandom);
…with this:
direction += pg.spreadAngle – pg.spreadRange/2 +
pg.spreadRange/pg.quantity * index;
Quantity is the total number of particles of this Particle Group.
PARTICLE UNIFORM SPREAD
61
To implement Wiggle Effect for Position, Scale, Opacity and even Rotation,
we need to replicate the wiggle expression in After Effects.
Here is an example expression of Particle Scale Wiggle in After Effects:
scale = pg.scale +
wiggle(pg.scaleWiggleFrequency,
pg.scaleWiggleAmplitude);
PG Scale Wiggle Frequency is how many times a second the value changes.
PG Scale Wiggle Amplitude is how large the value changes each time.
Go to this link for reference:
http://codepen.io/jamiejefferson/pen/hHegc
WIGGLE
62
PG Wind is a vector that helps push particles at a constant speed:
position += age * pg.wind;
PG Gravity makes particles fall down or float up at an accelerated speed. We
can use this equation:
position[1] = 0.5 * pg.gravity * age * age +
vNew[1] * age;
PG Drag makes particles slow down over time to zero speed:
if (age == 0) age = 0.000001;
dragModifier = (1 – exp(-pg.drag * age)) /
(pg.drag * age);
position *= age * dragModifier;
WIND + GRAVITY + DRAG
63
PG Bounce is another story. We need to pass launch velocity, gravity, bounce
floor height, elasticity and friction to get the vertical height of the particle.
Step 1: We have velocity and gravity, we can find the max height:
𝒉 =
𝒗 𝟐
πŸπ’ˆ
=
π’ˆ 𝟐 𝒕 𝟐
πŸπ’ˆ
=
π’ˆπ’• 𝟐
𝟐
(𝒗 = π’ˆπ’•)
maxHeight = pg.bounceFloorDistance +
(vNew[1] * vNew[1]) / (2 * pg.gravity);
Step 2: Find the time the particle reaches the floor. It consists of the time the
particle travels from its position at birth to the max height and the time from
the max height to the floor. Time at bounce:
𝒕 = 𝒕 𝟏 + 𝒕 𝟐
BOUNCE
64
At max height velocity reaches zero, so we have the time from position at
birth to the max height:
𝒗 = 𝒗 𝟎 βˆ’ π’ˆπ’• 𝟏 β‡’ 𝟎 = 𝒗 𝟎 βˆ’ π’ˆπ’• 𝟏 β‡’ 𝒕 𝟏 =
𝒗 𝟎
π’ˆ
We have the max height and the gravity, we can find the time from the max
height to the floor:
𝒕 𝟐 =
πŸπ’‰
π’ˆ
(𝒉 =
π’ˆπ’• 𝟐
𝟐
𝟐
)
Finally we have:
timeAtBounce = vNew[1]/pg.gravity +
sqrt(2 * maxHeight/pg.gravity);
BOUNCE
65
Step 3: If the particle has not reached the floor (Particle Age is less than
Particle Time At Floor), it just moves under the effect of the gravity:
𝒉 = 𝒗𝒕 βˆ’
π’ˆπ’• 𝟐
𝟐
position[1] = pg.bounceFloorDistance +
vNew[1] * age –
(pg.gravity * age * age)/2;
If the particle has reached the floor (Particle Age is equal or more than
Particle Time At Floor), it’s time to calculate the bounce.
First we invert the velocity at bounce:
𝒗 = 𝒗 𝟎 βˆ’ π’ˆπ’•
v[1] = -(vNew[1] – pg.gravity * timeAtBounce);
BOUNCE
66
When the particle bounces on the floor, it will loose some velocity basing on
PG Bounce Elasticity:
v[1] *= pg.bounceElasticity;
If PG Bounce Elasticity is less than 1: the particles will lose some vertical velocity
after each bounce; is more than 1: they gain more vertical velocity.
The same for PG Bounce Friction but applied for horizontal velocity instead.
Then we add the time to the next bounce. It is twice the time to reach the
max height (if we consider there is no drag):
𝒕 = 𝟐 Γ—
𝒗
π’ˆ
timeAtBounce += 2 * v[1]/pg.gravity;
Step 4: We repreat it again and againfrom bounce to bounce until the time
between any two bounces is less than one frame duration.
Reference bounce code:
http://www.motion-graphics-exchange.com/
after-effects/Object-bouncing-on-a-floor/
473c0e7522331BOUNCE
67
Time Loop enables us to make seamless transition between the end and the
beginning of our animation, so that the animation can repeat forever.
Simple, we implement Time Loop by controlling Particle Age:
if (pg.timeLoop > 0 && age < 0)
age += pg.timeLoop;
This code will make unfinished particles at the end of the loop continue their
existence at the beginning of the loop.
TIME LOOP
68
Time Stretch defines the time and speed of the whole Particle Group.
For example if Time Stretch = 50%, the Particle Group only has half the time
to finish its animation, thus it will play faster at double speed. We can cheat
it without changing the speed by speeding up Particle Age alone:
timeStretch = abs(pg.timeStretch)/100;
age /= timeStretch;
if (pg.timeStretch < 0)
age = pg.life + pg.lifeRandom –
age – birth/timeStretch * 2;
if (pg.timeLoop > 0 && age < 0)
age += pg.timeLoop/timeStretch;
However Time Stretch also affects Particle Birth as they will get born sooner
or later:
birth = pg.startTime + timeStretch * index/pg.density;
TIME STRETCH
69
INPUT
OUTPUT
INPUT
1.
SHAPE
SHAPE SIZE
POSITION
SCALE
ROTATION
WIND
DRAG
GRAVITY
BOUNCE
TIME STRETCH
TIME LOOP
OPACITY
DENSITY
QUANTITY
SPREAD
SPEED
LIFE
ANCHOR
RANDOM SEED
POSITION
SCALE
ROTATION
LOOK
OPACITY
BIRTH
AGE
INDEX
LIFE
ANCHOR
POSITION
SCALE
ROTATION
OPACITY
DISTRIBUTION
ANCHOR
NOISE
START TIME
2. 3.
SCALE
70
For more information contact: quangnd1503@gmail.com / quangnd@vng.com.vn
71

More Related Content

Similar to OGDC 2014_Build your own Particle System_Mr. Nguyen Dang Quang

Projectile-Motion_Process_Final.pdf
Projectile-Motion_Process_Final.pdfProjectile-Motion_Process_Final.pdf
Projectile-Motion_Process_Final.pdfPragyaPrakash29
Β 
Game Programming 11 - Game Physics
Game Programming 11 - Game PhysicsGame Programming 11 - Game Physics
Game Programming 11 - Game PhysicsNick Pruehs
Β 
relativity
 relativity relativity
relativityEhab Hegazy
Β 
PPT-Rectilinear Motion.pptx
PPT-Rectilinear Motion.pptxPPT-Rectilinear Motion.pptx
PPT-Rectilinear Motion.pptxKenneth Arlando
Β 
Nada kamel
Nada kamelNada kamel
Nada kamelnadakamel19
Β 
physics1_q1_mod4_motionintwoandthreedimension_v1.pdf
physics1_q1_mod4_motionintwoandthreedimension_v1.pdfphysics1_q1_mod4_motionintwoandthreedimension_v1.pdf
physics1_q1_mod4_motionintwoandthreedimension_v1.pdfAbigaelSantos2
Β 
PHY300 Chapter 5 physics 5e
PHY300 Chapter 5 physics 5ePHY300 Chapter 5 physics 5e
PHY300 Chapter 5 physics 5eBealCollegeOnline
Β 
Physics relativity
Physics relativityPhysics relativity
Physics relativityDinesh Dinesh
Β 

Similar to OGDC 2014_Build your own Particle System_Mr. Nguyen Dang Quang (9)

Projectile-Motion_Process_Final.pdf
Projectile-Motion_Process_Final.pdfProjectile-Motion_Process_Final.pdf
Projectile-Motion_Process_Final.pdf
Β 
Moment inertia
Moment inertiaMoment inertia
Moment inertia
Β 
Game Programming 11 - Game Physics
Game Programming 11 - Game PhysicsGame Programming 11 - Game Physics
Game Programming 11 - Game Physics
Β 
relativity
 relativity relativity
relativity
Β 
PPT-Rectilinear Motion.pptx
PPT-Rectilinear Motion.pptxPPT-Rectilinear Motion.pptx
PPT-Rectilinear Motion.pptx
Β 
Nada kamel
Nada kamelNada kamel
Nada kamel
Β 
physics1_q1_mod4_motionintwoandthreedimension_v1.pdf
physics1_q1_mod4_motionintwoandthreedimension_v1.pdfphysics1_q1_mod4_motionintwoandthreedimension_v1.pdf
physics1_q1_mod4_motionintwoandthreedimension_v1.pdf
Β 
PHY300 Chapter 5 physics 5e
PHY300 Chapter 5 physics 5ePHY300 Chapter 5 physics 5e
PHY300 Chapter 5 physics 5e
Β 
Physics relativity
Physics relativityPhysics relativity
Physics relativity
Β 

More from ogdc

OGDC 2014_Entity system in mobile game development_Mr. Cody nguyen
OGDC 2014_Entity system in mobile game development_Mr. Cody nguyenOGDC 2014_Entity system in mobile game development_Mr. Cody nguyen
OGDC 2014_Entity system in mobile game development_Mr. Cody nguyenogdc
Β 
OGDC 2014_Sky Garden Mobile conceptualization: From PC to Mobile_Mr. Luc Hoan...
OGDC 2014_Sky Garden Mobile conceptualization: From PC to Mobile_Mr. Luc Hoan...OGDC 2014_Sky Garden Mobile conceptualization: From PC to Mobile_Mr. Luc Hoan...
OGDC 2014_Sky Garden Mobile conceptualization: From PC to Mobile_Mr. Luc Hoan...ogdc
Β 
OGDC 2014_Creativity in Game Design - Case Study: Famous Vietnamese mobile ga...
OGDC 2014_Creativity in Game Design - Case Study: Famous Vietnamese mobile ga...OGDC 2014_Creativity in Game Design - Case Study: Famous Vietnamese mobile ga...
OGDC 2014_Creativity in Game Design - Case Study: Famous Vietnamese mobile ga...ogdc
Β 
OGDC 2014_Vietnam Mobile Internet 2014: A focus in smartphone game and compar...
OGDC 2014_Vietnam Mobile Internet 2014: A focus in smartphone game and compar...OGDC 2014_Vietnam Mobile Internet 2014: A focus in smartphone game and compar...
OGDC 2014_Vietnam Mobile Internet 2014: A focus in smartphone game and compar...ogdc
Β 
OGDC 2014_Vietnam Smartphone game market 2013 overview. From vision to action...
OGDC 2014_Vietnam Smartphone game market 2013 overview. From vision to action...OGDC 2014_Vietnam Smartphone game market 2013 overview. From vision to action...
OGDC 2014_Vietnam Smartphone game market 2013 overview. From vision to action...ogdc
Β 
OGDC 2014_User segmentation and Monetization_Mr. Phat hoang
OGDC 2014_User segmentation and Monetization_Mr. Phat hoangOGDC 2014_User segmentation and Monetization_Mr. Phat hoang
OGDC 2014_User segmentation and Monetization_Mr. Phat hoangogdc
Β 
OGDC 2014_Animation workflow with Spine in Tiny Busters_Mr. Huynh Dong Hai
OGDC 2014_Animation workflow with Spine in Tiny Busters_Mr. Huynh Dong HaiOGDC 2014_Animation workflow with Spine in Tiny Busters_Mr. Huynh Dong Hai
OGDC 2014_Animation workflow with Spine in Tiny Busters_Mr. Huynh Dong Haiogdc
Β 
OGDC 2014_Speed Up and make quality 3D game models_Mr. Pham Duc Duy
OGDC 2014_Speed Up and make quality 3D game models_Mr. Pham Duc DuyOGDC 2014_Speed Up and make quality 3D game models_Mr. Pham Duc Duy
OGDC 2014_Speed Up and make quality 3D game models_Mr. Pham Duc Duyogdc
Β 
OGDC 2014_Architecting Games in Unity_Mr. Rustum Scammell
OGDC 2014_Architecting Games in Unity_Mr. Rustum ScammellOGDC 2014_Architecting Games in Unity_Mr. Rustum Scammell
OGDC 2014_Architecting Games in Unity_Mr. Rustum Scammellogdc
Β 
OGDC 2014_One-Man Studio: How to make a game prototype_Mr. Le Vo Tien Giang
OGDC 2014_One-Man Studio: How to make a game prototype_Mr. Le Vo Tien GiangOGDC 2014_One-Man Studio: How to make a game prototype_Mr. Le Vo Tien Giang
OGDC 2014_One-Man Studio: How to make a game prototype_Mr. Le Vo Tien Giangogdc
Β 
OGDC 2014_Hands on experience with Cocos2dx in cross-platform with Farmery_Mr...
OGDC 2014_Hands on experience with Cocos2dx in cross-platform with Farmery_Mr...OGDC 2014_Hands on experience with Cocos2dx in cross-platform with Farmery_Mr...
OGDC 2014_Hands on experience with Cocos2dx in cross-platform with Farmery_Mr...ogdc
Β 
OGDC 2014_Optimize or Die: Key disciplines to optimize your mobile game_Mr. P...
OGDC 2014_Optimize or Die: Key disciplines to optimize your mobile game_Mr. P...OGDC 2014_Optimize or Die: Key disciplines to optimize your mobile game_Mr. P...
OGDC 2014_Optimize or Die: Key disciplines to optimize your mobile game_Mr. P...ogdc
Β 
OGDC 2014_Why choosing 2D animation for Mobile Game?_Mr. Joe Tran
OGDC 2014_Why choosing 2D animation for Mobile Game?_Mr. Joe TranOGDC 2014_Why choosing 2D animation for Mobile Game?_Mr. Joe Tran
OGDC 2014_Why choosing 2D animation for Mobile Game?_Mr. Joe Tranogdc
Β 
OGDC 2014_ An artist's story_Mr. Vu Cam Cong Danh
OGDC 2014_ An artist's story_Mr. Vu Cam Cong DanhOGDC 2014_ An artist's story_Mr. Vu Cam Cong Danh
OGDC 2014_ An artist's story_Mr. Vu Cam Cong Danhogdc
Β 
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...ogdc
Β 
OGDC 2014_Cross platform mobile game application development_Mr. Makku J.Kero
OGDC 2014_Cross platform mobile game application development_Mr. Makku J.KeroOGDC 2014_Cross platform mobile game application development_Mr. Makku J.Kero
OGDC 2014_Cross platform mobile game application development_Mr. Makku J.Keroogdc
Β 
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...ogdc
Β 
OGDC 2014_Business design is game design: 10 bits of business/design wisdom_M...
OGDC 2014_Business design is game design: 10 bits of business/design wisdom_M...OGDC 2014_Business design is game design: 10 bits of business/design wisdom_M...
OGDC 2014_Business design is game design: 10 bits of business/design wisdom_M...ogdc
Β 
OGDC 2014_ Game Design: 5 years of painful lessons_Mr. Do Van Thanh
OGDC 2014_ Game Design: 5 years of painful lessons_Mr. Do Van ThanhOGDC 2014_ Game Design: 5 years of painful lessons_Mr. Do Van Thanh
OGDC 2014_ Game Design: 5 years of painful lessons_Mr. Do Van Thanhogdc
Β 
OGDC 2014_3D Graphic on mobile_Mr. Hoang Minh Truong
OGDC 2014_3D Graphic on mobile_Mr. Hoang Minh TruongOGDC 2014_3D Graphic on mobile_Mr. Hoang Minh Truong
OGDC 2014_3D Graphic on mobile_Mr. Hoang Minh Truongogdc
Β 

More from ogdc (20)

OGDC 2014_Entity system in mobile game development_Mr. Cody nguyen
OGDC 2014_Entity system in mobile game development_Mr. Cody nguyenOGDC 2014_Entity system in mobile game development_Mr. Cody nguyen
OGDC 2014_Entity system in mobile game development_Mr. Cody nguyen
Β 
OGDC 2014_Sky Garden Mobile conceptualization: From PC to Mobile_Mr. Luc Hoan...
OGDC 2014_Sky Garden Mobile conceptualization: From PC to Mobile_Mr. Luc Hoan...OGDC 2014_Sky Garden Mobile conceptualization: From PC to Mobile_Mr. Luc Hoan...
OGDC 2014_Sky Garden Mobile conceptualization: From PC to Mobile_Mr. Luc Hoan...
Β 
OGDC 2014_Creativity in Game Design - Case Study: Famous Vietnamese mobile ga...
OGDC 2014_Creativity in Game Design - Case Study: Famous Vietnamese mobile ga...OGDC 2014_Creativity in Game Design - Case Study: Famous Vietnamese mobile ga...
OGDC 2014_Creativity in Game Design - Case Study: Famous Vietnamese mobile ga...
Β 
OGDC 2014_Vietnam Mobile Internet 2014: A focus in smartphone game and compar...
OGDC 2014_Vietnam Mobile Internet 2014: A focus in smartphone game and compar...OGDC 2014_Vietnam Mobile Internet 2014: A focus in smartphone game and compar...
OGDC 2014_Vietnam Mobile Internet 2014: A focus in smartphone game and compar...
Β 
OGDC 2014_Vietnam Smartphone game market 2013 overview. From vision to action...
OGDC 2014_Vietnam Smartphone game market 2013 overview. From vision to action...OGDC 2014_Vietnam Smartphone game market 2013 overview. From vision to action...
OGDC 2014_Vietnam Smartphone game market 2013 overview. From vision to action...
Β 
OGDC 2014_User segmentation and Monetization_Mr. Phat hoang
OGDC 2014_User segmentation and Monetization_Mr. Phat hoangOGDC 2014_User segmentation and Monetization_Mr. Phat hoang
OGDC 2014_User segmentation and Monetization_Mr. Phat hoang
Β 
OGDC 2014_Animation workflow with Spine in Tiny Busters_Mr. Huynh Dong Hai
OGDC 2014_Animation workflow with Spine in Tiny Busters_Mr. Huynh Dong HaiOGDC 2014_Animation workflow with Spine in Tiny Busters_Mr. Huynh Dong Hai
OGDC 2014_Animation workflow with Spine in Tiny Busters_Mr. Huynh Dong Hai
Β 
OGDC 2014_Speed Up and make quality 3D game models_Mr. Pham Duc Duy
OGDC 2014_Speed Up and make quality 3D game models_Mr. Pham Duc DuyOGDC 2014_Speed Up and make quality 3D game models_Mr. Pham Duc Duy
OGDC 2014_Speed Up and make quality 3D game models_Mr. Pham Duc Duy
Β 
OGDC 2014_Architecting Games in Unity_Mr. Rustum Scammell
OGDC 2014_Architecting Games in Unity_Mr. Rustum ScammellOGDC 2014_Architecting Games in Unity_Mr. Rustum Scammell
OGDC 2014_Architecting Games in Unity_Mr. Rustum Scammell
Β 
OGDC 2014_One-Man Studio: How to make a game prototype_Mr. Le Vo Tien Giang
OGDC 2014_One-Man Studio: How to make a game prototype_Mr. Le Vo Tien GiangOGDC 2014_One-Man Studio: How to make a game prototype_Mr. Le Vo Tien Giang
OGDC 2014_One-Man Studio: How to make a game prototype_Mr. Le Vo Tien Giang
Β 
OGDC 2014_Hands on experience with Cocos2dx in cross-platform with Farmery_Mr...
OGDC 2014_Hands on experience with Cocos2dx in cross-platform with Farmery_Mr...OGDC 2014_Hands on experience with Cocos2dx in cross-platform with Farmery_Mr...
OGDC 2014_Hands on experience with Cocos2dx in cross-platform with Farmery_Mr...
Β 
OGDC 2014_Optimize or Die: Key disciplines to optimize your mobile game_Mr. P...
OGDC 2014_Optimize or Die: Key disciplines to optimize your mobile game_Mr. P...OGDC 2014_Optimize or Die: Key disciplines to optimize your mobile game_Mr. P...
OGDC 2014_Optimize or Die: Key disciplines to optimize your mobile game_Mr. P...
Β 
OGDC 2014_Why choosing 2D animation for Mobile Game?_Mr. Joe Tran
OGDC 2014_Why choosing 2D animation for Mobile Game?_Mr. Joe TranOGDC 2014_Why choosing 2D animation for Mobile Game?_Mr. Joe Tran
OGDC 2014_Why choosing 2D animation for Mobile Game?_Mr. Joe Tran
Β 
OGDC 2014_ An artist's story_Mr. Vu Cam Cong Danh
OGDC 2014_ An artist's story_Mr. Vu Cam Cong DanhOGDC 2014_ An artist's story_Mr. Vu Cam Cong Danh
OGDC 2014_ An artist's story_Mr. Vu Cam Cong Danh
Β 
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
Β 
OGDC 2014_Cross platform mobile game application development_Mr. Makku J.Kero
OGDC 2014_Cross platform mobile game application development_Mr. Makku J.KeroOGDC 2014_Cross platform mobile game application development_Mr. Makku J.Kero
OGDC 2014_Cross platform mobile game application development_Mr. Makku J.Kero
Β 
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
OGDC 2014_Tips and Tricks for seasonal events and community building in Drago...
Β 
OGDC 2014_Business design is game design: 10 bits of business/design wisdom_M...
OGDC 2014_Business design is game design: 10 bits of business/design wisdom_M...OGDC 2014_Business design is game design: 10 bits of business/design wisdom_M...
OGDC 2014_Business design is game design: 10 bits of business/design wisdom_M...
Β 
OGDC 2014_ Game Design: 5 years of painful lessons_Mr. Do Van Thanh
OGDC 2014_ Game Design: 5 years of painful lessons_Mr. Do Van ThanhOGDC 2014_ Game Design: 5 years of painful lessons_Mr. Do Van Thanh
OGDC 2014_ Game Design: 5 years of painful lessons_Mr. Do Van Thanh
Β 
OGDC 2014_3D Graphic on mobile_Mr. Hoang Minh Truong
OGDC 2014_3D Graphic on mobile_Mr. Hoang Minh TruongOGDC 2014_3D Graphic on mobile_Mr. Hoang Minh Truong
OGDC 2014_3D Graphic on mobile_Mr. Hoang Minh Truong
Β 

OGDC 2014_Build your own Particle System_Mr. Nguyen Dang Quang

  • 1. 1
  • 2. ENABLE YOU TO MAKE A PARTICLE SYSTEM SIMPLE & CUSTOMIZABLEIS 2
  • 3. 1. BREAK IT DOWN 2. BUILD IT UP 1. BREAK IT DOWN 3
  • 5. POSITION POSITION OVER LIFE POSITION AT BIRTH SCALE SCALE OVER LIFE SCALE AT BIRTH ROTATION ROTATION OVER LIFE ROTATION AT BIRTH OPACITY OPACITY OVER LIFE OPACITY AT BIRTH ANCHOR ANCHOR OVER LIFE ANCHOR AT BIRTH 5
  • 6. POSITION POSITION OVER LIFE POSITION AT BIRTH SCALE SCALE OVER LIFE SCALE AT BIRTH ROTATION ROTATION OVER LIFE ROTATION AT BIRTH OPACITY OPACITY OVER LIFE OPACITY AT BIRTH ANCHOR ANCHOR OVER LIFE ANCHOR AT BIRTHPOSITION POSITION OVER LIFE POSITION AT BIRTH SCALE SCALE OVER LIFE SCALE AT BIRTH ROTATION ROTATION OVER LIFE ROTATION AT BIRTH OPACITY OPACITY OVER LIFE OPACITY AT BIRTH ANCHOR ANCHOR OVER LIFE ANCHOR AT BIRTH POSITION POSITION OVER LIFE POSITION AT BIRTH SCALE SCALE OVER LIFE SCALE AT BIRTH ROTATION ROTATION OVER LIFE ROTATION AT BIRTH OPACITY OPACITY OVER LIFE OPACITY AT BIRTH ANCHOR ANCHOR OVER LIFE ANCHOR AT BIRTH POSITION POSITION OVER LIFE POSITION AT BIRTH SCALE SCALE OVER LIFE SCALE AT BIRTH ROTATION ROTATION OVER LIFE ROTATION AT BIRTH OPACITY OPACITY OVER LIFE OPACITY AT BIRTH ANCHOR ANCHOR OVER LIFE ANCHOR AT BIRTH 6
  • 7. P POSITION P POSITION OVER LIFE P POSITION AT BIRTH RANDOM RANDOM P SCALE P SCALE OVER LIFE P SCALE AT BIRTH RANDOM RANDOM P ROTATION P ROTATION OVER LIFE P ROTATION AT BIRTH RANDOM RANDOM P OPACITY P OPACITY OVER LIFE P OPACITY AT BIRTH RANDOM RANDOM P ANCHOR P ANCHOR OVER LIFE P ANCHOR AT BIRTH RANDOM RANDOM 7
  • 9. 9
  • 10. 10
  • 11. 11
  • 12. 12
  • 13. 13
  • 14. 14
  • 15. 15
  • 16. 16
  • 17. 17
  • 18. 18
  • 19. 19
  • 20. 20
  • 21. 21
  • 22. 22
  • 23. 23
  • 24. 24
  • 25. 25
  • 26. 26
  • 27. 27
  • 28. 28
  • 29. 29
  • 30. 30
  • 31. 31
  • 32. 32
  • 33. 33
  • 34. 34
  • 37. 1. BREAK IT DOWN 2. BUILD IT UP2. BUILD IT UP 37
  • 38. OUTPUT INPUT INPUT WIND DRAG GRAVITY BOUNCE TIME STRETCH TIME LOOP DENSITY QUANTITY SPREAD SPEED LIFE ANCHOR RANDOM SEED POSITION SCALE ROTATION LOOK OPACITY BIRTH AGE INDEX LIFE ANCHOR POSITION SCALE ROTATION OPACITY START TIME OPACITY ROTATION SCALE POSITION ANCHOR NOISE DISTRIBUTION SHAPE SIZE SHAPE 38
  • 39. 1. EMITTER OBJECT contains all centralized inputs for controlling all of its child particle groups int shape float[3] shapeSize int distribution float[3] noise float[3] anchor, position, scale, rotation float opacity 39
  • 40. 2. PARTICLE GROUP OBJECT contains all centralized inputs for controlling all of its child particle groups Image look int randomSeed float startTime float quantity float density float life, lifeRandom float speed, speedRandom boolean speedOverdriveFromEmitterMotion 40
  • 41. contains all centralized inputs for controlling all of its child particle groups float[3] spreadAngle, spreadRange, spreadRandom boolean spreadFollowEmitterMotion float[3] anchorOffset, anchorOffsetRandom, anchorWiggleFrequency, anchorWiggleAmplitude float[3] positionWiggleFrequency, positionWiggleAmplitude 2. PARTICLE GROUP OBJECT 41
  • 42. contains all centralized inputs for controlling all of its child particle groups float[2] scale, scaleRandom, scaleWiggleFrequency, scaleWiggleAmplitude float[3] rotationAtBirth, rotationAtBirthRandom, rotationSpeed, rotationSpeedRandom, rotationWiggleFrequency, rotationWiggleAmplitude boolean[3] rotationInBothDirection float opacity, opacityRandom, opacityWiggleFrequency, opacityWiggleAmplitude 2. PARTICLE GROUP OBJECT 42
  • 43. 2. PARTICLE GROUP OBJECT contains all centralized inputs for controlling all of its child particle groups float[3] wind float[3] gravity boolean bounce float bounceFloorDistance, bounceElasticity, bounceFriction float drag float timeStretch float timeLoop 43
  • 44. contains generated properties to draw on screen int index float birth, life, age float[3] anchor float[3] position float[2] scale float[3] rotation float opacity 3. PARTICLE INSTANCE OBJECT 44
  • 46. Particle Life is the longevity of the particle. It tells when the particle dies: life = pg.life + random(-pg.lifeRandom, pg.lifeRandom); If we have PG Life Random, Particle Life will differ from PG Life. Particle Birth is the moment the particle gets born: birth = pg.startTime + index/pg.density; PG Start Time is the time this Particle Group starts showing up. Particle Index is the order of the particle, starting from 0. PG Density is how many particles get born in a second. Particle Age is how old the particle is at a certain time: age = time – birth; Time is the global value. It keeps increasing over time. 1. PARTICLE BIRTH + LIFE + AGE 46
  • 48. Every particle has its anchor at the center of it. If we need PG Anchor Offset feature, we need to implement it like this: anchor = pg.anchorOffset + random(-pg.anchorOffsetRandom, pg.anchorOffsetRandom); Anchor alters the result when rotating or scaling an object: 2. PARTICLE ANCHOR 48
  • 50. Particle follows Emitting Direction. When Emitting Direction changes, Particle Direction changes, affecting Particle Position. 3. PARTICLE POSITION 50
  • 51. Step 2: Calculate Particle Direction affected by Emitter Rotation and PG Spread: direction = emitter.rotation + pg.spreadAngle + random(-pg.spreadRandom, pg.spreadRandom); Step 1: Define vector Particle Velocity pointing straight up (-Y): velocity = [0, -pg.speed, 0]; PG Speed defines how fast particles travel when they are born. 3. PARTICLE POSITION 51
  • 52. 3D Rotation reference: http://www.cs.helsinki.fi/group/goa/mallinnus/3dtransf/3drot.html Step 3: Transform vector Particle Velocity according to Particle Direction: v = velocity; d = direction; β€’ X-Axis Rotation: vNew[0] = v[0]; vNew[1] = v[1] * cos(d[0]) - v[2] * sin(d[0]); vNew[2] = v[1] * sin(d[0]) + v[2] * cos(d[0]); β€’ Y-Axis Rotation: vNew[0] = v[2] * sin(d[1]) + v[0] * cos(d[1]); vNew[1] = v[1]; vNew[2] = v[2] * cos(d[1]) - v[0] * sin(d[1]); β€’ Z-Axis Rotation (2D Rotation): vNew[0] = v[0] * cos(d[2]) – v[1] * sin(d[2]); vNew[1] = v[0] * sin(d[2]) + v[1] * cos(d[2]); vNew[2] = v[2]; 3. PARTICLE POSITION 52
  • 53. particlePositionAtBirth emitterPosition vNew * age Step 4: We now have new vector Particle Velocity. Multiply it with Particle Age to get its local Particle Position over time: position = vNew * age; Finally we get global Particle Position: position += emitter.Position; 3. PARTICLE POSITION 53
  • 54. Emitter Size Random point picking reference for other shapes: http://mathworld.wolfram. com/topics/ RandomPointPicking.html If Emitter Shape Size is not zero. Position At Birth is a random point within Emitter Shape. So it is affected by Emitter Shape and Emitter Shape Size: positionAtBirth = random(-emitter.shapeSize/2, emitter.shapeSize/2); particlePositionAtBirth emitterPosition vNew * time 3. PARTICLE POSITION So we have to count in Particle Position At Birth: position += positionAtBirth; 54
  • 56. Particle Scale defines the size of the particle. And it is affected by PG Scale and PG Scale Random: scale = pg.scale + random(-pg.scaleRandom, pg.scaleRandom); In order to change Particle Scale Over Life we need to enable key frames for PG Scale so its value varies from time to time, and then get its value at its proper age, we call it PG Age: pgAge = age * pg.life/life; So we use this code instead of the one above: scale = pg.scale.valueAtTime(pgAge) + random(-pg.scaleRandom, pg.scaleRandom); 4. PARTICLE SCALE 56
  • 58. Particle Rotation is a little more complicated. We need to apply both PG Particle Rotation At Birth and PG Rotation Speed: rotation = pg.rotationAtBirth + random(-pg.rotationAtBirthRandom, pg.rotationAtBirthRandom) + age * (pg.rotationSpeed.valueAtTime(age * pg.life/life) + random(-pg.rotationSpeedRandom, pg.rotationSpeedRandom)); 5. PARTICLE ROTATION 58
  • 60. Also like Particle Scale, Particle Opacity is simple, supporting Particle Opacity Over Life: opacity = pg.opacity.valueAtTime(pgAge) + random(-pg.opacityRandom, pg.opacityRandom); 6. PARTICLE OPACITY 60
  • 61. To achieve uniform spread, we need to add to the Particle Direction code that we made before: direction = emitter.rotation + pg.spreadAngle + random(-pg.spreadRandom, pg.spreadRandom); …with this: direction += pg.spreadAngle – pg.spreadRange/2 + pg.spreadRange/pg.quantity * index; Quantity is the total number of particles of this Particle Group. PARTICLE UNIFORM SPREAD 61
  • 62. To implement Wiggle Effect for Position, Scale, Opacity and even Rotation, we need to replicate the wiggle expression in After Effects. Here is an example expression of Particle Scale Wiggle in After Effects: scale = pg.scale + wiggle(pg.scaleWiggleFrequency, pg.scaleWiggleAmplitude); PG Scale Wiggle Frequency is how many times a second the value changes. PG Scale Wiggle Amplitude is how large the value changes each time. Go to this link for reference: http://codepen.io/jamiejefferson/pen/hHegc WIGGLE 62
  • 63. PG Wind is a vector that helps push particles at a constant speed: position += age * pg.wind; PG Gravity makes particles fall down or float up at an accelerated speed. We can use this equation: position[1] = 0.5 * pg.gravity * age * age + vNew[1] * age; PG Drag makes particles slow down over time to zero speed: if (age == 0) age = 0.000001; dragModifier = (1 – exp(-pg.drag * age)) / (pg.drag * age); position *= age * dragModifier; WIND + GRAVITY + DRAG 63
  • 64. PG Bounce is another story. We need to pass launch velocity, gravity, bounce floor height, elasticity and friction to get the vertical height of the particle. Step 1: We have velocity and gravity, we can find the max height: 𝒉 = 𝒗 𝟐 πŸπ’ˆ = π’ˆ 𝟐 𝒕 𝟐 πŸπ’ˆ = π’ˆπ’• 𝟐 𝟐 (𝒗 = π’ˆπ’•) maxHeight = pg.bounceFloorDistance + (vNew[1] * vNew[1]) / (2 * pg.gravity); Step 2: Find the time the particle reaches the floor. It consists of the time the particle travels from its position at birth to the max height and the time from the max height to the floor. Time at bounce: 𝒕 = 𝒕 𝟏 + 𝒕 𝟐 BOUNCE 64
  • 65. At max height velocity reaches zero, so we have the time from position at birth to the max height: 𝒗 = 𝒗 𝟎 βˆ’ π’ˆπ’• 𝟏 β‡’ 𝟎 = 𝒗 𝟎 βˆ’ π’ˆπ’• 𝟏 β‡’ 𝒕 𝟏 = 𝒗 𝟎 π’ˆ We have the max height and the gravity, we can find the time from the max height to the floor: 𝒕 𝟐 = πŸπ’‰ π’ˆ (𝒉 = π’ˆπ’• 𝟐 𝟐 𝟐 ) Finally we have: timeAtBounce = vNew[1]/pg.gravity + sqrt(2 * maxHeight/pg.gravity); BOUNCE 65
  • 66. Step 3: If the particle has not reached the floor (Particle Age is less than Particle Time At Floor), it just moves under the effect of the gravity: 𝒉 = 𝒗𝒕 βˆ’ π’ˆπ’• 𝟐 𝟐 position[1] = pg.bounceFloorDistance + vNew[1] * age – (pg.gravity * age * age)/2; If the particle has reached the floor (Particle Age is equal or more than Particle Time At Floor), it’s time to calculate the bounce. First we invert the velocity at bounce: 𝒗 = 𝒗 𝟎 βˆ’ π’ˆπ’• v[1] = -(vNew[1] – pg.gravity * timeAtBounce); BOUNCE 66
  • 67. When the particle bounces on the floor, it will loose some velocity basing on PG Bounce Elasticity: v[1] *= pg.bounceElasticity; If PG Bounce Elasticity is less than 1: the particles will lose some vertical velocity after each bounce; is more than 1: they gain more vertical velocity. The same for PG Bounce Friction but applied for horizontal velocity instead. Then we add the time to the next bounce. It is twice the time to reach the max height (if we consider there is no drag): 𝒕 = 𝟐 Γ— 𝒗 π’ˆ timeAtBounce += 2 * v[1]/pg.gravity; Step 4: We repreat it again and againfrom bounce to bounce until the time between any two bounces is less than one frame duration. Reference bounce code: http://www.motion-graphics-exchange.com/ after-effects/Object-bouncing-on-a-floor/ 473c0e7522331BOUNCE 67
  • 68. Time Loop enables us to make seamless transition between the end and the beginning of our animation, so that the animation can repeat forever. Simple, we implement Time Loop by controlling Particle Age: if (pg.timeLoop > 0 && age < 0) age += pg.timeLoop; This code will make unfinished particles at the end of the loop continue their existence at the beginning of the loop. TIME LOOP 68
  • 69. Time Stretch defines the time and speed of the whole Particle Group. For example if Time Stretch = 50%, the Particle Group only has half the time to finish its animation, thus it will play faster at double speed. We can cheat it without changing the speed by speeding up Particle Age alone: timeStretch = abs(pg.timeStretch)/100; age /= timeStretch; if (pg.timeStretch < 0) age = pg.life + pg.lifeRandom – age – birth/timeStretch * 2; if (pg.timeLoop > 0 && age < 0) age += pg.timeLoop/timeStretch; However Time Stretch also affects Particle Birth as they will get born sooner or later: birth = pg.startTime + timeStretch * index/pg.density; TIME STRETCH 69
  • 70. INPUT OUTPUT INPUT 1. SHAPE SHAPE SIZE POSITION SCALE ROTATION WIND DRAG GRAVITY BOUNCE TIME STRETCH TIME LOOP OPACITY DENSITY QUANTITY SPREAD SPEED LIFE ANCHOR RANDOM SEED POSITION SCALE ROTATION LOOK OPACITY BIRTH AGE INDEX LIFE ANCHOR POSITION SCALE ROTATION OPACITY DISTRIBUTION ANCHOR NOISE START TIME 2. 3. SCALE 70
  • 71. For more information contact: quangnd1503@gmail.com / quangnd@vng.com.vn 71