rwtexture3d in Unity Graphics
rwtexture3d in Unity Graphics
vol.3
IndieVisualLab
2018-10-08 IndieVisualLab
1
Unity Unity
tips
github
[Link]
Processing openFrameworks
3DCG Unity
3DCG
IndieVisualLab (& )
Unity
Unity
Unity
github issue
2
Web [Link]
1FAIpQLSdxeansJvQGTWfZTBN_2RTuCK_kRqhA6QHTZKVXHCijQnC8zw/viewform
[Link]@[Link]
3
2
3 ScreenSpaceFluidRendering 49
3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.2 Screen Space Fluid Rendering . . . . . . . . . . . . . . . . . 49
3.3 Deferred Rendering , 50
4
3.4 G-Buffer . . . . . . . . . . . . . . . . . . . 52
3.5 CommandBuffer . . . . . . . . . . . . . . . . . . . . . . . 53
3.6 . . . . . . . . . . . . . . . . . . . . . . . 53
3.7 . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5
7.6 . . . . . . . . . . . . . . . . . . . . . . . . . 145
7.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
7.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
8 150
8.1 . . . . . . . . . . . . . . . . . . . . . . . 151
8.2 . . . . . . . . . . . . . . . . . . . . . . . . . 151
8.3 . . . . . . . . . . . . . . . . . . . . . . . . . 153
8.4 . . . . . . . . . . . . . . . . . . . . . . . . . . 156
8.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
158
6
1
1.1
1.1
Unity Animator
SkinnedMeshRenderer
7
1 Baking Skinned Animation to Texture
Animator SkinnedMeshRenderer
GPU
SkinnedMeshRenderer
1
Twitter @sugi_cho
(._.)
1.2 SkinedMeshRenderer
5000
5000
1890
3D
8
1.2 SkinedMeshRenderer 5000
1.2
FPS 8.8
1.3
9
1 Baking Skinned Animation to Texture
1.3 5000
Unity
Window Profiler : Ctr+7
Add Profiler GPU GPU Usage
GPU Usage
GPU Usage
10
1.2 SkinedMeshRenderer 5000
11
1 Baking Skinned Animation to Texture
1.3 SkinnedMeshRenderer
SkinnedMeshRenderer
[Link](Mesh)
1: Animator animator;
2: SkinnedMeshRenderer skinedMesh;
3: List<Mesh> meshList;
4:
5: void Start(){
6: animator = GetComponent<Animator>();
7: skinnedMesh = GetComponentInChildren<SkinnedMeshRenderer>();
8: meshList = new List<Mesh>();
9: [Link]("Run");
10: }
11:
12: void Update(){
13: var mesh = new Mesh();
14: [Link](mesh);
15: //mesh
16: [Link](mesh);
17: }
12
1.4
1.4
Mesh
[Link], [Link]
1.4.1 Vector3
Vector3
1.2
1: Mesh objMesh;
2: List<Vector3>[] vertecesLists;
3: List<Vector3>[] normalsLists;
4: //
5: //[Link](List<Vector3>)
6:
7: void Start(){
8: objMesh = GetComponent<MeshFilter>().mesh;
9: [Link]();
10: }
11:
12: void Update(){
13: var frame = xx;
14: //
15:
16: [Link](vertecesLists[frame]);
17: [Link](normalsLists[frame]);
18: }
CPU
VertexTextureFetch
CPU
13
1 Baking Skinned Animation to Texture
1.4.2
1.2 Color
r float
g float
b float
a float
1.3
1.3
14
1.4
Mesh
15
1 Baking Skinned Animation to Texture
Index
1.5
Unity [Link](Color[]) ColorForm
at.RGBA32,ARGB32,RGB24,Alpha8
Fixed
RGBAHalf, RGBAFloat
1 Clamp
Color RGB
1/256
1.4.3 [Link]()
[Link]
(gameObject, time); GameObject
16
1.5
AnimationClip Animation
Animator Animation Animator
AnimationClip
1.5
• [Link]
• [Link]
• [Link]
17
1 Baking Skinned Animation to Texture
18
AnimationClipTextureBaker
ComputeShader Sh
ader AnimationClip Clips
1.6
1.7
ContextMenuAttribute Unity
bake
texture Bake 1.6
1.4 [Link]
1: using [Link];
2: using [Link];
3: using UnityEngine;
4:
5: #if UNITY_EDITOR
6: using UnityEditor;
19
1 Baking Skinned Animation to Texture
7: using [Link];
8: #endif
9:
10: public class AnimationClipTextureBaker : MonoBehaviour
11: {
12:
13: public ComputeShader infoTexGen;
14: public Shader playShader;
15: public AnimationClip[] clips;
16:
17: //
18: public struct VertInfo
19: {
20: public Vector3 position;
21: public Vector3 normal;
22: }
23:
24: //Reset() GameObject
25: private void Reset()
26: {
27: var animation = GetComponent<Animation>();
28: var animator = GetComponent<Animator>();
29:
30: if (animation != null)
31: {
32: clips = new AnimationClip[[Link]()];
33: var i = 0;
34: foreach (AnimationState state in animation)
35: clips[i++] = [Link];
36: }
37: else if (animator != null)
38: clips = [Link];
39: //Animation Animator AnimationClip
40: }
41:
42: [ContextMenu("bake texture")]
43: void Bake()
44: {
45: var skin = GetComponentInChildren<SkinnedMeshRenderer>();
46: var vCount = [Link];
47: var texWidth = [Link](vCount);
48: var mesh = new Mesh();
49:
50: foreach (var clip in clips)
51: {
52: var frames = [Link]((int)([Link] / 0.05f));
53: var dt = [Link] / frames;
54: var infoList = new List<VertInfo>();
55:
56: var pRt = new RenderTexture(texWidth, frames,
57: 0, [Link]);
58: [Link] = [Link]("{0}.{1}.posTex", name, [Link]);
59: var nRt = new RenderTexture(texWidth, frames,
60: 0, [Link]);
61: [Link] = [Link]("{0}.{1}.normTex", name, [Link]);
62: foreach (var rt in new[] { pRt, nRt })
63: {
20
1.5
21
1 Baking Skinned Animation to Texture
1.4 119,120
ComputeShader
GPU
22
1.5
1.5
1.5 [Link]
1.8
1.8
x
y
uv.y
[Link] = Bilinear
23
1 Baking Skinned Animation to Texture
Shader
Run W
rapMode = Repeat
WrapMode = Clamp
Shader
1.6
1.6 [Link]
1: Shader "Unlit/TextureAnimPlayer"
2: {
3: Properties
4: {
5: _MainTex ("Texture", 2D) = "white" {}
6: _PosTex("position texture", 2D) = "black"{}
7: _NmlTex("normal texture", 2D) = "white"{}
8: _DT ("delta time", float) = 0e
9:
10: _Length ("animation length", Float) = 1
11: [Toggle(ANIM_LOOP)] _Loop("loop", Float) = 0
12: }
13: SubShader
14: {
15: Tags { "RenderType"="Opaque" }
16: LOD 100 Cull Off
17:
18: Pass
19: {
20: CGPROGRAM
21: #pragma vertex vert
22: #pragma fragment frag
23: #pragma multi_compile ___ ANIM_LOOP
24: //
25:
26: #include "[Link]"
27:
28: #define ts _PosTex_TexelSize
29:
30: struct appdata
31: {
32: float2 uv : TEXCOORD0;
33: };
34:
35: struct v2f
36: {
37: float2 uv : TEXCOORD0;
38: float3 normal : TEXCOORD1;
24
1.5
25
1 Baking Skinned Animation to Texture
ID SV_Ve
rtexID
appdata uv appdata P
OSITION,NORMAL
UV uv.y
0 1.0
uv.x vid uv.x = (vid + 0.5) * _TexelSize.
x 0.5
Bilinear (n + 0.5) /
ID
0.5
{TextureName}_TexelSize float4
1.7 (Unity )
x 1.0/width
y 1.0/height
z width
w height
26
1.6 5000
1.6 5000
1.9 5000
SkinnedMeshRenderer Renderer
FPS
8 56.4 1.9
PC GPU GeForce MX150 NVIDIA Pascal GPU
27
1 Baking Skinned Animation to Texture
SkinnedMeshRenderer GPU
Shader
Grap
[Link]() 4000
Shader GitHub
1.7
Shader AnimatorController
4K 8K 16K
1
VertexShader
[Link] C
[Link]
AnimatorController Unity
28
1.8
1.8
•
•
•
• GPU GPU
29
2
Gravitational N-Body
Simulation
2.1
2.1 Result
[Link]
30
2.2 N-Body
Assets/NBodySimulation
2.2 N-Body
N N-Body
N-Body
N-Body
N-Body
•
•
•
2.3
Mm
f =G (2.1)
r2
f G M, m 2
r 2 ( )
Unity 3
2 ( i, j )
m i mj r ij
f ij = G · (2.2)
∥r ij ∥2 ∥r ij ∥
f ij i j mi , m j 2
rij j i
31
2 Gravitational N-Body Simulation
2 1 (i)
Fi
! ! mj r ij
Fi = f ij = Gmi · (2.3)
∥r ij ∥3
j∈N j∈N
Softening ε
! mj r ij
F i ≃ Gmi · 3 (2.4)
j∈N (∥r ij ∥2 + ε) 2
( 0 )
ma = f
Fi
mi ai = F i =⇒ ai = (2.5)
mi
! mj r ij
ai ≃ G · 3 (2.6)
j∈N (∥r ij ∥2 + ε) 2
32
2.4
2.4
(2.6)
2.2
2.4.1
f (t)
df f (t + ∆t) − f (t)
= lim (2.7)
dt ∆t→0 ∆t
33
2 Gravitational N-Body Simulation
f(t)
傾き = 微分値
fn
fn
∆t
t
tn tn
2.3
tn
∆t
(2.7)
2.4.2
∆t
df f (t + ∆t) − f (t)
≃ (2.8)
dt ∆t
∆t
∆t
2.2
34
2.5
dx dx
x(t) dt
v(t) dt
a(t)
2.4 ( )
(2.8) 2.4
t ∆t
( )
∆t (
) 1 (60fps 1/60 )
2.5
SimpleNBodySimula-
[Link]
2.5.1 CPU
(2.7) 1
[Link]
35
2 Gravitational N-Body Simulation
Byte [Link]
[Link](Type t)
[Link]
void InitBuffer()
{
// (Read/Write )
bodyBuffers = new ComputeBuffer[2];
// Body
bodyBuffers[READ] = new ComputeBuffer(numBodies,
[Link](typeof(Body)));
0
*1
[Link]
void DistributeBodies()
{
[Link](seed);
//
*1
36
2.5
//
Body[] bodies = new Body[numBodies];
int i = 0;
while (i < numBodies)
{
//
Vector3 pos = [Link];
//
bodies[i].position = pos * scale;
bodies[i].velocity = [Link];
bodies[i].mass = [Link](0.1f, 1.0f);
i++;
}
//
bodyBuffers[READ].SetData(bodies);
bodyBuffers[WRITE].SetData(bodies);
ComputeShader ∆t
Unity [Link] GPU
[Link]
void Update()
{
//
// t
[Link]("_DeltaTime", [Link]);
//
[Link]("_Damping", damping);
// Softening
[Link]("_SofteningSquared", softeningSquared);
//
[Link]("_NumBodies", numBodies);
37
2 Gravitational N-Body Simulation
//
[Link]("_ThreadDim",
new Vector4(SIMULATION_BLOCK_SIZE, 1, 1, 0));
//
[Link]("_GroupDim",
new Vector4([Link](numBodies / SIMULATION_BLOCK_SIZE), 1, 1, 0));
//
[Link](0, "_BodiesBufferRead", bodyBuffers[READ]);
[Link](0, "_BodiesBufferWrite", bodyBuffers[WRITE]);
//
[Link](0,
[Link](numBodies / SIMULATION_BLOCK_SIZE), 1, 1);
// Read/Write ( )
Swap(bodyBuffers);
}
[Link]
void OnRenderObject()
{
[Link](0);
[Link]("_Particles"", bodyBuffers[READ]);
[Link]([Link], numBodies);
}
2.5.2 GPU
N-Body
O(n2 )
UnityGraphicsProgramming Vol1 3
SharedMemory( )
38
2.5
I/O
2.5
(DispatchThreadID)
1
( /
) 256 (SIMULA-
39
2 Gravitational N-Body Simulation
TION_BLOCK_SIZE) 5x5
256x256
Sync (Sync
) Sync
CPU ComputeShader
Body
[Link] cginc
[Link]
#include "[Link]"
//
cbuffer cb {
float _SofteningSquared, _DeltaTime, _Damping;
uint _NumBodies;
float4 _GroupDim, _ThreadDim;
};
//
StructuredBuffer<Body> _BodiesBufferRead;
RWStructuredBuffer<Body> _BodiesBufferWrite;
// ( )
groupshared Body sharedBody[SIMULATION_BLOCK_SIZE];
[Link]
uint start = 0; //
uint finish = _NumBodies;
40
2.5
int currentTile = 0;
// ( )
for (uint i = start; i < finish; i += SIMULATION_BLOCK_SIZE)
{
//
// sharedBody[ ID]
// = _BodiesBufferRead[ ID * + ID]
sharedBody[threadID.x]
= _BodiesBufferRead[wrap(groupID.x + currentTile, _GroupDim.x)
* SIMULATION_BLOCK_SIZE + threadID.x];
//
GroupMemoryBarrierWithGroupSync();
//
acc = gravitation(body, acc, threadID);
GroupMemoryBarrierWithGroupSync();
currentTile++; //
}
return acc;
for
2.6 ID for
41
2 Gravitational N-Body Simulation
for
[Link]
//
//
for (uint i = 0; i < SIMULATION_BLOCK_SIZE;)
{
accel = bodyBodyInteraction(accel, sharedBody[i], body);
i++;
}
return accel;
}
return
(2.2)
[Link]
//
float3 bodyBodyInteraction(float3 acc, Body b_i, Body b_j)
{
float3 r = b_i.position - b_j.position;
// invDistCube = 1/distSqr^(3/2)
float distSixth = distSqr * distSqr * distSqr;
float invDistCube = 1.0f / sqrt(distSixth);
// s = m_j * invDistCube
float s = b_j.mass * invDistCube;
return acc;
}
42
2.6
[Link]
[numthreads(SIMULATION_BLOCK_SIZE,1,1)]
void CSMain (
uint3 groupID : SV_GroupID, // ID
uint3 threadID : SV_GroupThreadID, // ID
uint3 DTid : SV_DispatchThreadID // ID
) {
//
uint index = DTid.x;
//
Body body = _BodiesBufferRead[index];
//
[Link] += [Link] * _DeltaTime;
_BodiesBufferWrite[index] = body;
2.6
*2 GPU
2.6.1
43
2 Gravitational N-Body Simulation
( 2.8 )
Quad
1 xy Quad
*3
Quad *4
Quad
*3 UnityGraphicsProgramming Vol.1
*4
44
2.6
x
x y y
x
x
y
2.8
[Link]
45
2 Gravitational N-Body Simulation
[maxvertexcount(4)]
void geom(point v2g input[1], inout TriangleStream<g2f> outStream) {
g2f o;
//
billboardMatrix._m03 = billboardMatrix._m13 =
billboardMatrix._m23 = billboardMatrix._m33 = 0;
[Link] = pos
+ mul(transpose(billboardMatrix), float4((uv * 2 - float2(1, 1))
* _Scale, 0, 1));
[Link] = input[0].id;
[Link](o);
}
}
[Link]();
}
2.7
46
2.8
2.9 ( ...)
2.8
[Link] 1
[Link]
2.1
47
2 Gravitational N-Body Simulation
2.9
Gravitational N-Body Simulation GPU
N-Body
Unity
2.10
• GPU Gems 3 - Chapter 31. Fast N-Body Simulation with CUDA
• N -
[Link]
proceeding/galaxy_fujii.pdf
• - [Link] [Link]
html
48
3
ScreenSpaceFluidRendering
3.1
Deferred Shading
Screen Space Fluid Rendering
49
3 ScreenSpaceFluidRendering
3.1
Deferred Rendering
2
Forward Rendering
3.2 Forward Rendering Deferred Rendering
50
3.3 Deferred Rendering ,
Forward Rendering 1
Deferred Rendering
2 G-Buffer
2
•
•
•
• G Buffer PostEffect SSAO
•
• MSAA
•
• Orthographic
• Unity Pro
• MRT
• 3.0
• two-sided
51
3 ScreenSpaceFluidRendering
3.4 G-Buffer
2 G-Buffer Unity
G-Buffer
G-Buffer
G-Buffer
Assets/ScreenSpaceFluidRendering/Scenes/ShowG-
BufferTest G-Buffer
52
3.5 CommandBuffer
3.3 G-Buffer
3.5 CommandBuffer
CommandBuffer Unity API
CPU
GPU
GPU
Unity [Link](),
[Link]()
Unity API CommandBuffer Unity
Unity
CommandBuffer
[Link]
3.6
3DCG
53
3 ScreenSpaceFluidRendering
Homogeneous Coordinates
3 (x,y,z) (x,y,z,w) 4
Homogeneous Coordinates
4 4x4 Matrix
4x4 Matrix
4
(x/w, y/w, z/w, 1) =
(x, y, z, w)
Object Space ( , , )
World Space ,
World Space
World Space
Modeling Transform Object Space
Eye(View) Space ,
Eye Space
Clip Space ,
Clip Space View Matrix
field of view(FOV) near clip far clip Projection
Matrix View Space
Projection Transform
54
3.7
Screen(Window) Space
Normalized Device Coordinates
Direct3D
Deferred Rendering
3.3 3DCG
3.4
3.7
Assets/ScreenSpaceFluidRendering/Scenes/ScreenSpaceFluidRendering
55
3 ScreenSpaceFluidRendering
3.7.1
Screen Space Fluid Rendering
1.
2.
3.
4.
3.7.2
[Link]
[Link]
[Link]
[Link]
RenderGBuff[Link] G-Buffer
3.7.3 CommandBuffer
[Link] OnWillRenderObject
CommandBuffer Com-
mandBuffer
[Link]
// (MeshRenderer)
void OnWillRenderObject()
{
//
var act = [Link] && enabled;
if (!act)
{
CleanUp();
return;
}
//
var cam = [Link];
if (!cam)
{
return;
56
3.7
//
// CommandBuffer
if (!_cameras.ContainsKey(cam))
{
// CommandBuffer
var buf = new CmdBufferInfo();
[Link] = [Link];
[Link] = new CommandBuffer();
[Link] = "Screen Space Fluid Renderer";
// G-Buffer
// CommandBuffer
[Link]([Link], [Link]);
// CommandBuffer
_cameras.Add(cam, buf);
}
Disable RemoveCommandBuffer
Cleanup
CommandBuffer
CommandBuff[Link]
3.7.4
[Link]
// --------------------------------------------------------------------
// 1.
// --------------------------------------------------------------------
// ID
int depthBufferId = [Link]("_DepthBuffer");
// RenderTexture
57
3 ScreenSpaceFluidRendering
//
[Link]
(
new RenderTargetIdentifier(depthBufferId), //
new RenderTargetIdentifier(depthBufferId) //
);
//
[Link](true, true, [Link]);
//
_renderParticleDepthMaterial.SetFloat ("_ParticleSize", _particleSize);
// ComputeBuffer
_renderParticleDepthMaterial.SetBuffer("_ParticleDataBuffer",
_particleControllerScript.GetParticleDataBuffer());
//
[Link]
(
[Link],
_renderParticleDepthMaterial,
0,
[Link],
_particleControllerScript.GetMaxParticleNum()
);
[Link]
// --------------------------------------------------------------------
// Vertex Shader
// --------------------------------------------------------------------
v2g vert(uint id : SV_VertexID)
{
v2g o = (v2g)0;
FluidParticle fp = _ParticleDataBuffer[id];
[Link] = float4([Link], 1.0);
return o;
}
// --------------------------------------------------------------------
// Geometry Shader
// --------------------------------------------------------------------
//
static const float3 g_positions[4] =
{
float3(-1, 1, 0),
float3( 1, 1, 0),
float3(-1,-1, 0),
float3( 1,-1, 0),
};
// UV
static const float2 g_texcoords[4] =
{
float2(0, 1),
58
3.7
float2(1, 1),
float2(0, 0),
float2(1, 0),
};
[maxvertexcount(4)]
void geom(point v2g In[1], inout TriangleStream<g2f> SpriteStream)
{
g2f o = (g2f)0;
//
float3 vertpos = In[0].[Link];
// 4
[unroll]
for (int i = 0; i < 4; i++)
{
//
float3 pos = g_positions[i] * _ParticleSize;
pos = mul(unity_CameraToWorld, pos) + vertpos;
[Link] = UnityObjectToClipPos(float4(pos, 1.0));
// UV
[Link] = g_texcoords[i];
//
[Link] = UnityObjectToViewPos(float4(pos, 1.0)).xyz * float3(1, 1, 1);
//
[Link] = _ParticleSize;
[Link](o);
}
[Link]();
}
// --------------------------------------------------------------------
// Fragment Shader
// --------------------------------------------------------------------
struct fragmentOut
{
float depthBuffer : SV_Target0;
float depthStencil : SV_Depth;
};
fragmentOut frag(g2f i)
{
//
float3 N = (float3)0;
[Link] = [Link] * 2.0 - 1.0;
float radius_sq = dot([Link], [Link]);
if (radius_sq > 1.0) discard;
N.z = sqrt(1.0 - radius_sq);
//
float4 pixelPos = float4([Link] + N * [Link], 1.0);
float4 clipSpacePos = mul(UNITY_MATRIX_P, pixelPos);
//
float depth = clipSpacePos.z / clipSpacePos.w; //
fragmentOut o = (fragmentOut)0;
[Link] = depth;
[Link] = depth;
59
3 ScreenSpaceFluidRendering
return o;
}
C#
RenderTexture Command-
Buff[Link] RenderTexture
GetTemporaryRT
ID
ID Unity
int ID [Link]
ID
GetTemporaryRT 2,3 -1
Camera pixel
width, height
4 _DepthBuffer
+ 0
RenderTexture CommandBuff[Link]
ClearRenderTarget
CommandBuff[Link]
3.5
60
3.7
Vertex Geometry
Fragment
UV
3.6
3.7.5
61
3 ScreenSpaceFluidRendering
3.7
3.7.6
X Y
3.8
[Link]
62
3.7
// --------------------------------------------------------------------
// Fragment Shader
// --------------------------------------------------------------------
// UV
float3 uvToEye(float2 uv, float z)
{
float2 xyPos = uv * 2.0 - 1.0;
//
float4 clipPos = float4([Link], z, 1.0);
//
float4 viewPos = mul(unity_CameraInvProjection, clipPos);
//
[Link] = [Link] / viewPos.w;
return [Link];
}
//
float sampleDepth(float2 uv)
{
#if UNITY_REVERSED_Z
return 1.0 - tex2D(_DepthBuffer, uv).r;
#else
return tex2D(_DepthBuffer, uv).r;
#endif
}
//
float3 getEyePos(float2 uv)
{
return uvToEye(uv, sampleDepth(uv));
}
//
#if UNITY_REVERSED_Z
if (Linear01Depth(depth) > 1.0 - 1e-3)
discard;
#else
if (Linear01Depth(depth) < 1e-3)
discard;
#endif
//
float2 ts = _DepthBuffer_TexelSize.xy;
// uv
float3 posEye = getEyePos(uv);
// x
float3 ddx = getEyePos(uv + float2(ts.x, 0.0)) - posEye;
float3 ddx2 = posEye - getEyePos(uv - float2(ts.x, 0.0));
ddx = abs(ddx.z) > abs(ddx2.z) ? ddx2 : ddx;
63
3 ScreenSpaceFluidRendering
// y
float3 ddy = getEyePos(uv + float2(0.0, ts.y)) - posEye;
float3 ddy2 = posEye - getEyePos(uv - float2(0.0, ts.y));
ddy = abs(ddy.z) > abs(ddy2.z) ? ddy2 : ddy;
//
float3 N = normalize(cross(ddx, ddy));
//
float4x4 vm = _ViewMatrix;
N = normalize(mul(vm, float4(N, 0.0)));
return col;
}
3.9
3.7.7
G-Buffer
G-Buffer
64
3.7
[Link]
// --------------------------------------------------------------------
// 4. G-Buffer
// --------------------------------------------------------------------
[Link]("_NormalBuffer", normalBufferId); //
[Link]("_DepthBuffer", depthBufferId); //
//
_renderGBufferMaterial.SetColor("_Diffuse", _diffuse );
_renderGBufferMaterial.SetColor("_Specular",
new Vector4(_specular.r, _specular.g, _specular.b, 1.0f - _roughness));
_renderGBufferMaterial.SetColor("_Emission", _emission);
// G-Buffer
[Link]
(
new RenderTargetIdentifier[4]
{
BuiltinRenderTextureType.GBuffer0, // Diffuse
BuiltinRenderTextureType.GBuffer1, // Specular + Roughness
BuiltinRenderTextureType.GBuffer2, // World Normal
BuiltinRenderTextureType.GBuffer3 // Emission
},
[Link] // Depth
);
// G-Buffer
[Link](quad, [Link], _renderGBufferMaterial);
[Link]
// GBuffer
struct gbufferOut
{
half4 diffuse : SV_Target0; //
half4 specular : SV_Target1; //
half4 normal : SV_Target2; //
half4 emission : SV_Target3; //
float depth : SV_Depth; //
};
sampler2D _DepthBuffer; //
sampler2D _NormalBuffer;//
fixed4 _Diffuse; //
fixed4 _Specular; //
float4 _Emission; //
65
3 ScreenSpaceFluidRendering
#if UNITY_REVERSED_Z
if (Linear01Depth(d) > 1.0 - 1e-3)
discard;
#else
if (Linear01Depth(d) < 1e-3)
discard;
#endif
[Link] = _Diffuse;
[Link] = _Specular;
[Link] = float4([Link] , 1.0);
[Link] = _Emission;
#ifndef UNITY_HDR_ON
[Link] = exp2(-[Link]);
#endif
[Link] = d;
}
SetRenderTarget G-Buffer
1 BuiltinRender-
TextureType GBuffer0 GBuffer1 GBuffer2 GBuffer3
RenderTargetIdentifier 2
CameraTarget G-Buffer
DrawMesh
3.7.8 RenderTexture
GetTemporaryRT RenderTexture Re-
leaseTemporaryRT
66
3.8
3.7.9
3.10
3.8
Deferred Shading
3DCG
Unity Deferred Rendering
CG
Forward
Rendering CG
67
3 ScreenSpaceFluidRendering
3.9
• GDC Screen Space Fluid Rendering for Games, Simon Green, NVIDIA
[Link]
• , Satoshi Kodaira
[Link]
68
4
4.1
Processing*1
iGeo*2 Cell Division and Growth Algorithm
1 *3 GPU
[Link]
CellularGrowth
GPU
• Append/ConsumeStructuredBuffer GPU
• GPU
• Atomic
*1 [Link]
*2 [Link]
*3 [Link]
69
4 GPU-Based Cellular Growth Simulation
4.1 [Link]
Particle Edge
4.2
Particle Edge
2
1 Particle 1
• Growth( ):
• Repulsion( ): Particle
• Division( ): 2 Particle
70
4.3
4.2
4.3
71
4 GPU-Based Cellular Growth Simulation
[StructLayout([Link])]
public struct Particle_t {
public Vector2 position; //
public Vector2 velocity; //
float radius; //
float threshold; //
int links; // Edge ( scene )
uint alive; //
}
Particle
Append/ConsumeStructuredBuffer GPU
Append/ConsumeStructuredBuffer
Append/ConsumeStructuredBuffer*4 *5 Direct3D11
GPU LIFO(Last In First Out : )
AppendStructuredBuffer ConsumeStructuredBuffer
GPU
Particle
[Link]
*4 [Link]
appendstructuredbuffer
*5 [Link]
consumestructuredbuffer
72
4.3
//
poolBuffer = new ComputeBuffer(
count,
[Link](typeof(int)),
[Link]
);
[Link](0);
countBuffer = new ComputeBuffer(
4,
[Link](typeof(int)),
[Link]
);
[Link](countArgs);
//
dividablePoolBuffer = new ComputeBuffer(
count,
[Link](typeof(int)),
[Link]
);
[Link](0);
// Particle ( )
InitParticlesKernel();
...
}
particleBuffer PingPongBuffer
2 Particle
poolBuffer
int Particle index
( 4.4)
73
4 GPU-Based Cellular Growth Simulation
countBuffer int
// AppendStructuredBuffer
[Link](kernel, "_ParticlePoolAppend", poolBuffer);
Dispatch1D(kernel, count);
}
[Link]
74
4.3
THREAD
void InitParticles(uint3 id : SV_DispatchThreadID)
{
uint idx = id.x;
// Particle
Particle p = create();
[Link] = false; // Particle
_Particles[idx] = p;
// Particle index
_ParticlePoolAppend.Append(idx);
}
particleBuffer Particle
poolBuffer Particle index
Particle
Particle Particle CellularGrowthPar-
[Link] Particle
[Link]
EmitParticlesKernel Particle
[Link]
emitCount = [Link](
0,
[Link](emitCount, CopyPoolSize(poolBuffer))
75
4 GPU-Based Cellular Growth Simulation
);
if (emitCount <= 0) return;
// ConsumeStructuredBuffer
[Link](kernel, "_ParticlePoolConsume", poolBuffer);
[Link]("_Point", point);
[Link]("_EmitCount", emitCount);
Dispatch1D(kernel, emitCount);
}
GPU (AppendStructured-
Buffer) (ConsumeStructuredBuffer)
CPU GPU
EmitParticlesKernel emitCount GetPoolSize
index
index (GPU
_ParticlePoolConsume.Consume )
[Link]
THREAD
void EmitParticles(uint3 id : SV_DispatchThreadID)
{
// _EmitCount Particle
if (id.x >= (uint) _EmitCount)
return;
// Particle index
uint idx = _ParticlePoolConsume.Consume();
Particle c = create();
// Particle
float2 offset = random_point_on_circle([Link] + float2(0, _Time));
[Link] = _Point.xy + offset;
[Link] = nrand([Link] + float2(_Time, 0));
// Particle index
_Particles[idx] = c;
76
4.3
Particle
Particle Particle
4.2
• Growth : Particle
• Repulsion : Particle
• Division : Particle
Growth Repulsion
Growth Repulsion Update
[Link]
//
[Link](kernel, "_ParticlesRead", [Link]);
//
[Link](kernel, "_Particles", [Link]);
[Link]("_Drag", drag); //
[Link]("_Limit", limit); //
[Link]("_Repulsion", repulsion); //
[Link]("_Grow", grow); //
Dispatch1D(kernel, count);
// (Ping Pong)
[Link]();
77
4 GPU-Based Cellular Growth Simulation
UpdateParticles
[Link]
THREAD
void UpdateParticles(uint3 id : SV_DispatchThreadID)
{
uint idx = id.x;
Particle p = _ParticlesRead[idx];
// Particle
if ([Link])
{
// Grow : Particle
[Link] = min([Link], [Link] + _DT * _Grow);
// Repulsion : Particle
for (uint i = 0; i < count; i++)
{
Particle other = _ParticlesRead[i];
if(i == idx || ![Link]) continue;
// Particle
float2 dir = [Link] - [Link];
float l = length(dir);
// Particle *_Repulsion
//
float r = ([Link] + [Link]) * _Repulsion;
if (l < r)
{
[Link] += normalize(dir) * (r - l);
}
}
// _Drag velocity
[Link] =
normalize([Link]) *
min(
78
4.3
length([Link]) * _Drag,
_Limit
);
}
else
{
[Link] = float2(0, 0);
}
}
_Particles[idx] = p;
}
UpdateParticles Particle
(_ParticlesRead) (_Particles)
GPU
Particle
Particle
( )
UpdateParticles
(
Ping Pong )
Division
Particle
Particle
[Link]
...
79
4 GPU-Based Cellular Growth Simulation
...
// Particle dividablePoolBuffer
protected void GetDividableParticlesKernel()
{
// dividablePoolBuffer
[Link](0);
Dispatch1D(kernel, count);
}
// (maxDivideCount)
// Particle (poolBuffer )
maxDivideCount = [Link](CopyPoolSize(poolBuffer), maxDivideCount);
Dispatch1D(kernel, count);
}
80
4.3
DivideParticlesKernel
• maxDivideCount
• dividablePoolBuffer Particle
• poolBuffer Particle
[Link]
// Particle
//
bool dividable_particle(Particle p, uint idx)
{
//
float rate = ([Link] / [Link]);
return rate >= 0.95;
//
// return nrand(float2(idx, _Time)) < 0.1;
}
// Particle
uint divide_particle(uint idx, float2 offset)
{
Particle parent = _Particles[idx];
Particle child = create();
//
float rh = [Link] * 0.5;
rh = max(rh, 0.1);
[Link] = [Link] = rh;
//
float2 center = [Link];
[Link] = center - offset;
[Link] = center + offset;
//
float x = nrand(float2(_Time, idx));
[Link] = rh * lerp(1.25, 2.0, x);
// index Particle
uint cidx = _ParticlePoolConsume.Consume();
_Particles[cidx] = child;
// Particle
_Particles[idx] = parent;
return cidx;
}
81
4 GPU-Based Cellular Growth Simulation
{
Particle parent = _Particles[idx];
//
float2 offset =
random_point_on_circle(float2(idx, _Time)) *
[Link] * 0.25;
...
THREAD
void GetDividableParticles(uint3 id : SV_DispatchThreadID)
{
uint idx = id.x;
uint count, strides;
_Particles.GetDimensions(count, strides);
if (idx >= count)
return;
Particle p = _Particles[idx];
if ([Link] && dividable_particle(p, idx))
{
_DividablePoolAppend.Append(idx);
}
}
THREAD
void DivideParticles(uint3 id : SV_DispatchThreadID)
{
if (id.x >= _DivideCount)
return;
82
4.3
4.5 [Link]
4.3.2 ([Link])
Particle Edge
[Link]
Edge Particle Particle
Edge
[Link]
[StructLayout([Link])]
public struct Edge_t
{
public int a, b; // Edge 2 Particle index
public Vector2 force; // 2 Particle
uint alive; //
}
83
4 GPU-Based Cellular Growth Simulation
Division
1. Edge dividablePoolBuffer
2. Edge Edges 0 Particle(links 0
Particle) 2 Particle Edge
3. Edge dividablePoolBuffer Edge
Particle
Edge [Link]
[Link]
// ( ) Edge
switch(pattern)
84
4.3
{
case [Link]:
//
DivideEdgesClosedKernel(
dividableEdgesCount,
maxDivideCount
);
break;
case [Link]:
//
DivideEdgesBranchKernel(
dividableEdgesCount,
maxDivideCount
);
break;
}
}
}
...
// Particle
[Link]("_MaxLink", maxLink);
Dispatch1D(kernel, count);
}
...
Dispatch1D(kernel, count);
}
85
4 GPU-Based Cellular Growth Simulation
Edge (GetDividableEdges)
[Link]
//
bool dividable_edge(Edge e, uint idx)
{
Particle pa = _Particles[e.a];
Particle pb = _Particles[e.b];
// Particle (_MaxLink)
// dividable_particle
return
!([Link] >= _MaxLink && [Link] >= _MaxLink) &&
(dividable_particle(pa, e.a) && dividable_particle(pb, e.b));
}
...
// Edge
THREAD
void GetDividableEdges(uint3 id : SV_DispatchThreadID)
{
uint idx = id.x;
uint count, strides;
_Edges.GetDimensions(count, strides);
if (idx >= count)
return;
Edge e = _Edges[idx];
if ([Link] && dividable_edge(e, idx))
{
_DividablePoolAppend.Append(idx);
}
}
// Atomic ( )
// Particle
InterlockedAdd(_Particles[a].links, 1);
InterlockedAdd(_Particles[b].links, 1);
Edge e;
e.a = a;
e.b = b;
[Link] = float2(0, 0);
86
4.3
[Link] = true;
_Edges[eidx] = e;
}
...
// Edge Particle
THREAD
void DivideUnconnectedParticles(uint3 id : SV_DispatchThreadID)
{
uint count, stride;
_Particles.GetDimensions(count, stride);
if (id.x >= count)
return;
// Particle Particle
uint cidx = divide_particle(idx);
87
4 GPU-Based Cellular Growth Simulation
Atomic (InterlockedAdd )
(
( )
)
Atomic ( )
GPU
a
HLSL Interlocked prefix
InterlockedAdd
InterlockedAdd
_Particles[index].links 1
a [Link]
advanced-stages-cs-atomic-functions
([Link])
([Link])
88
4.3
4.6 ([Link])
[Link]
//
protected void DivideEdgesKernel(
int kernel,
int dividableEdgesCount,
int maxDivideCount
)
{
// Consume
// maxDivideCount
maxDivideCount = [Link](dividableEdgesCount, maxDivideCount);
maxDivideCount = [Link]([Link](), maxDivideCount);
maxDivideCount = [Link]([Link](), maxDivideCount);
if (maxDivideCount <= 0) return;
89
4 GPU-Based Cellular Growth Simulation
[Link](
kernel, "_Particles",
[Link]
);
[Link](
kernel, "_ParticlePoolConsume",
[Link]
);
[Link](kernel, "_Edges", [Link]);
[Link](kernel, "_EdgePoolConsume", [Link]);
Dispatch1D(kernel, maxDivideCount);
}
GPU (DivideEdgesClosed)
divide_edge_closed Particle Edge
Particle 1 Particle 3
Particle 3 Edge ( 4.7)
Particle 2 Particle
Edge Particle Edge
( 4.8)
90
4.3
[Link]
//
void divide_edge_closed(uint idx)
{
Edge e = _Edges[idx];
Particle pa = _Particles[e.a];
Particle pb = _Particles[e.b];
// Particle Particle
connect(e.a, cidx);
// 2 Particle Edge
// Particle Edge
InterlockedAdd(_Particles[e.a].links, -1);
InterlockedAdd(_Particles[cidx].links, 1);
e.a = cidx;
}
_Edges[idx] = e;
}
...
91
4 GPU-Based Cellular Growth Simulation
//
THREAD
void DivideEdgesClosed(uint3 id : SV_DispatchThreadID)
{
if (id.x >= _DivideCount)
return;
// Edge index
uint idx = _DividablePoolConsume.Consume();
divide_edge_closed(idx);
}
Edge
Edge 2 Particle
1. Edge 2 Particle
2. Particle Edge
[Link]
...
Dispatch1D(kernel, count);
}
92
4.3
[Link]
);
[Link](kernel, "_Edges", [Link]);
Dispatch1D(kernel, count);
}
[Link]
THREAD
void UpdateEdges(uint3 id : SV_DispatchThreadID)
{
uint idx = id.x;
uint count, strides;
_Edges.GetDimensions(count, strides);
if (idx >= count)
return;
Edge e = _Edges[idx];
//
[Link] = float2(0, 0);
if (![Link])
{
_Edges[idx] = e;
return;
}
Particle pa = _Particles[e.a];
Particle pb = _Particles[e.b];
if (![Link] || ![Link])
{
_Edges[idx] = e;
return;
}
// 2 Particle
//
float2 dir = [Link] - [Link];
float r = [Link] + [Link];
float len = length(dir);
if (abs(len - r) > 0)
{
// ( )
float l = ((len - r) / r);
float2 f = normalize(dir) * l * _Spring;
[Link] = f;
}
_Edges[idx] = e;
}
THREAD
void SpringEdges(uint3 id : SV_DispatchThreadID)
93
4 GPU-Based Cellular Growth Simulation
{
uint idx = id.x;
uint count, strides;
_Particles.GetDimensions(count, strides);
if (idx >= count)
return;
Particle p = _Particles[idx];
if (![Link] || [Link] <= 0)
return;
//
float dif = 1.0 / [Link];
_Edges.GetDimensions(count, strides);
// Edge Particle
for (uint i = 0; i < count; i++)
{
Edge e = _Edges[i];
if (![Link])
continue;
// Edge
if (e.a == iidx)
{
[Link] -= [Link] * dif;
}
else if (e.b == iidx)
{
[Link] += [Link] * dif;
}
}
_Particles[idx] = p;
}
4.3.3
Edge (dividable_edge )
[Link] enum
([Link])
4.9
94
4.3
Particle Particle
4.9
[Link]
[Link]
//
void divide_edge_branch(uint idx)
{
Edge e = _Edges[idx];
Particle pa = _Particles[e.a];
Particle pb = _Particles[e.b];
// Particleindex
uint i = lerp(e.b, e.a, step([Link], [Link]));
...
//
THREAD
95
4 GPU-Based Cellular Growth Simulation
// Edge index
uint idx = _DividablePoolConsume.Consume();
divide_edge_branch(idx);
}
Edge
dividable_edge Particle
(_MaxLink)
96
4.3
97
4 GPU-Based Cellular Growth Simulation
4.12 _MaxLink 3 2
([Link])
4.4
GPU
CG Andy Lomas*6
Morphogenetic Creations [Link]*7
Computational Biology
(
Houdini )
*6 [Link]
*7 [Link]
*8 [Link]
*9 [Link]
98
4.5
2 iGeo
*10 3
3 3
3
[Link]
4.5
• [Link]
• [Link]
*10 [Link]
99
5
Reaction Diffusion
5.1
Unity ComputeShader
[Link]
ReactionDiffusion
Reaction Diffusion
Gray-Scott
Gray-Scott 1983 [Link] [Link]
U V 2
100
5.2 Reaction Diffusion
1. U Feed
2. V U Reaction V
3. V V Kill
5.2 U V
U V
U V
∂u
= Du∆u − uv 2 + f(1−u)
∂t
∂v
= Dv∆v + uv 2 − (f + k)
∂t
101
5 Reaction Diffusion
U u V v
Du∆u Dv∆v Du Dv u v
∆u ∆v U V
Diffusion
uv 2 U V Reaction U
V
+f(1−u) U Feed
−(f + k)
V Kill
U V U V
U V U +f(1−u)
V −(f + k)
U V Du∆u Dv∆v
5.3 Unity
Unity
ReactionDiffusion2D_1
5.3.1
U V
ComputeShader ComputeBuffer
[Link]
5.3.2
[Link]
/// <summary>
///
/// </summary>
void Initialize()
102
5.3 Unity
{
...
//
bufData = new RDData[wh];
bufData2 = new RDData[wh];
//
ResetBuffer();
// Seed
inputData = new Vector2[inputMax];
inputIndex = 0;
inputBuffer = new ComputeBuffer(
inputMax, [Link](typeof(Vector2))
);
}
ComputeBuffer buffers
ComputeShader
5.3.3
[Link]
//
void UpdateBuffer()
{
[Link]("_TexWidth", texWidth);
[Link]("_TexHeight", texHeight);
[Link]("_DU", du);
[Link]("_DV", dv);
[Link]("_Feed", feed);
[Link]("_K", kill);
103
5 Reaction Diffusion
SwapBuffer();
}
C# ComputeShader
ComputeShader
[Link]
//
[numthreads(THREAD_NUM_X, THREAD_NUM_X, 1)]
void Update(uint3 id : SV_DispatchThreadID)
{
f = _Feed;
k = _K;
_BufferWrite[idx].u = saturate(
u + (_DU * LaplaceU(id.x, id.y) - uvv + f * (1.0 - u))
);
_BufferWrite[idx].v = saturate(
v + (_DV * LaplaceV(id.x, id.y) + uvv - (k + f) * v)
);
}
GetIndex()
ComputeBuffer
[Link]
//
int GetIndex(int x, int y) {
x = (x < 0) ? x + _TexWidth : x;
x = (x >= _TexWidth) ? x - _TexWidth : x;
y = (y < 0) ? y + _TexHeight : y;
y = (y >= _TexHeight) ? y - _TexHeight : y;
return y * _TexWidth + x;
}
104
5.3 Unity
_BufferRead u v
LaplaceU LaplaceV U V
[Link]
// U
float LaplaceU(int x, int y) {
float sumU = 0;
return sumU;
}
// V
float LaplaceV(int x, int y) {
float sumV = 0;
return sumV;
}
u v _BufferWrite saturate 0 1
5.3.4
A C U V
A SeedNum
Seed C
[Link]
/// <summary>
/// Seed
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
void AddSeed(int x, int y)
{
105
5 Reaction Diffusion
inputData
[Link]
/// <summary>
/// Seed ComputeShader
/// </summary>
void AddSeedBuffer()
{
if (inputIndex > 0)
{
[Link](inputData);
[Link]("_InputNum", inputIndex);
[Link]("_TexWidth", texWidth);
[Link]("_TexHeight", texHeight);
[Link]("_SeedSize", seedSize);
[Link](kernelAddSeed, "_InputBufferRead", inputBuffer);
[Link](kernelAddSeed, "_BufferWrite", buffers[0]); // update
0
[Link](kernelAddSeed,
[Link]((float)inputIndex / (float)THREAD_NUM_X),
1,
1);
inputIndex = 0;
}
}
inputBuffer inputeData
ComputeShader
[Link]
//
[numthreads(THREAD_NUM_X, 1, 1)]
void AddSeed(uint id : SV_DispatchThreadID)
{
if (_InputNum <= id) return;
int w = _SeedSize;
int h = _SeedSize;
float radius = _SeedSize * 0.5;
106
5.3 Unity
{
for (int y = 0; y < h; y++)
{
float dis = distance(
float2(centerX, centerY),
float2(startX + x, startY + y)
);
if (dis <= radius) {
_BufferWrite[GetIndex((centerX + x), (centerY + y))].v = 1;
}
}
}
}
C# inputBuffer v 1
5.3.5 RenderTexture
RenderTexture
RenderTexture u v
RenderTexture 1
RenderTextureFormat RFloat RenderTextureFor-
[Link] 1 float RenderTexture
[Link]
/// <summary>
/// RenderTexture
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns></returns>
RenderTexture CreateRenderTexture(int width, int height)
{
RenderTexture tex = new RenderTexture(width, height, 0,
[Link],
[Link]);
[Link] = true;
[Link] = [Link];
[Link] = [Link];
[Link]();
return tex;
}
ComputeShader RenderTexture C#
[Link]
107
5 Reaction Diffusion
/// <summary>
/// ReactionDiffusion
/// </summary>
void DrawTexture()
{
[Link]("_TexWidth", texWidth);
[Link]("_TexHeight", texHeight);
[Link](kernelDraw, "_BufferRead", buffers[0]);
[Link](kernelDraw, "_HeightMap", resultTexture);
[Link](kernelDraw,
[Link]((float)texWidth / THREAD_NUM_X),
[Link]((float)texHeight / THREAD_NUM_X),
1);
}
ComputeShader u v
[Link]
//
float GetValue(int x, int y) {
int idx = GetIndex(x, y);
float u = _BufferRead[idx].u;
float v = _BufferRead[idx].v;
return 1 - clamp(u - v, 0, 1);
}
...
//
[numthreads(THREAD_NUM_X, THREAD_NUM_X, 1)]
void Draw(uint3 id : SV_DispatchThreadID)
{
float c = GetValue(id.x, id.y);
// height map
_HeightMap[[Link]] = c;
5.3.6
Unlit Shader
[Link]
/// <summary>
///
/// </summary>
void UpdateMaterial()
108
5.4
{
[Link]("_MainTex", resultTexture);
[Link]("_Color0", bottomColor);
[Link]("_Color1", topColor);
}
[Link]
5.3
5.4
Feed Kill
109
5 Reaction Diffusion
5.4.1
Feed:0.037 / Kill:0.06
5.4
5.4.2
Feed:0.03 / Kill:0.062
5.5
110
5.4
5.4.3
Feed:0.0263 / Kill:0.06
5.6
5.4.4
Feed:0.077 / Kill:0.0615
5.7
111
5 Reaction Diffusion
5.4.5
Feed:0.039 / Kill:0.058
5.8
5.4.6
Feed:0.026 / Kill:0.051
5.9
112
5.5 Surface Shader
5.4.7
Feed:0.014 / Kill:0.0477
5.10
5.5.1
ReactionDiffusion
[Link] XYZ
[Link]
[Link]
void Initialize()
{
...
heightMapTexture = CreateRenderTexture(texWidth, texHeight,
[Link]); //
normalMapTexture = CreateRenderTexture(texWidth, texHeight,
113
5 Reaction Diffusion
[Link]); //
...
}
/// <summary>
/// RenderTexture
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="texFormat"></param>
/// <returns></returns>
RenderTexture CreateRenderTexture(
int width,
int height,
RenderTextureFormat texFormat)
{
RenderTexture tex = new RenderTexture(width, height, 0,
texFormat, [Link]);
[Link] = true;
[Link] = [Link];
[Link] = [Link];
[Link]();
return tex;
}
...
void DrawTexture()
{
...
[Link](kernelDraw, "_HeightMap", heightMapTexture);
[Link](kernelDraw, "_NormalMap", normalMapTexture); //
[Link](kernelDraw,
[Link]((float)texWidth / THREAD_NUM_X),
[Link]((float)texHeight / THREAD_NUM_X),
1);
}
ComputeShader
[Link]
...
114
5.5 Surface Shader
//
[numthreads(THREAD_NUM_X, THREAD_NUM_X, 1)]
void Draw(uint3 id : SV_DispatchThreadID)
{
float c = GetValue(id.x, id.y);
// height map
_HeightMap[[Link]] = c;
// normal map
_NormalMap[[Link]] = float4(GetNormal(id.x, id.y), 1);
}
SurfaceOutputStandard
struct SurfaceOutputStandard
{
fixed3 Albedo; // ( )
fixed3 Normal; //
half3 Emission; //
half Metallic; // 0= , 1=
half Smoothness; // 0= , 1=
half Occlusion; // ( 1)
fixed Alpha; //
};
[Link]
float2 uv = IN.uv_MainTex;
//
half v0 = tex2D(_MainTex, uv).x;
//
float3 norm = UnpackNormal(tex2D(_NormalTex, uv));
// A B
half p = smoothstep(_Threshold, _Threshold + _Fading, v0);
115
5 Reaction Diffusion
Unity unpackNormal
SurfaceOutputStandard
5.11 SurfaceShader
RGB
116
5.6
5.6
Reaction Diffusion
RenderTexture ComputeBuffer
ReactionDiffusion3D
5.6.1
RenderTexture
[Link]
return tex;
}
[Link] [Link]
[Link].Tex3D
RenderTexture
RenderTexture
Reaction Diffusion ComputeBuffer
[Link]
void Initialize()
{
...
int whd = texWidth * texHeight * texDepth;
buffers = new ComputeBuffer[2];
...
for (int i = 0; i < [Link]; i++)
{
117
5 Reaction Diffusion
5.6.2
ComputeShader RenderTex-
ture ComputeShader RWTex-
ture2D<float> RWTexture3D<float>
[Link]
RWTexture3D<float> _HeightMap; //
laplacePower
[Link]
//
static const int3 laplaceIndex[27] = {
int3(-1,-1,-1), int3(0,-1,-1), int3( 1,-1,-1),
int3(-1, 0,-1), int3(0, 0,-1), int3(1, 0,-1),
int3(-1, 1,-1), int3(0, 1,-1), int3(1, 1,-1),
//
static const float laplacePower[27] = {
0.02, 0.02, 0.02,
0.02, 0.1, 0.02,
0.02, 0.02, 0.02,
118
5.6
//
int GetIndex(int x, int y, int z) {
x = (x < 0) ? x + _TexWidth : x;
x = (x >= _TexWidth) ? x - _TexWidth : x;
y = (y < 0) ? y + _TexHeight : y;
y = (y >= _TexHeight) ? y - _TexHeight : y;
z = (z < 0) ? z + _TexDepth : z;
z = (z >= _TexDepth) ? z - _TexDepth : z;
// U
float LaplaceU(int x, int y, int z) {
float sumU = 0;
// V
float LaplaceV(int x, int y, int z) {
float sumV = 0;
5.6.3
RenderTexture
Unlit Shader Surface Shader
119
5 Reaction Diffusion
*1
5.7
Gray-Scott Feed
Kill
5.8
• Reaction-Diffusion Tutorial [Link]
• Reaction diffusion system Gray-Scott model
[Link]
*1 Tips [Link]
*2 DIFFUSION [Link]
*3 Reaction-Diffusion [Link]
120
6
Strange Attractor
6.1
Strange Attractor
Unity GPU
[Link]
StrangeAttractors
6.1.1
• ComputeShader 5.0
• Unity2018.2.9f1
Attractor
Strange Attractor
*1 Lorenz Attractor *2 Thomas’ Cyclically
Symmetric Attractor
121
6 Strange Attractor
*3 [Link]
122
6.3 Lorenz Attractor
6.3.1 Lorenz
Lorenz
dx
= −px + py
dt
dy
= −xz + rx − y
dt
dz
= xy − bz
dt
123
6 Strange Attractor
[Link]
Strange Attractor
[Link]
ComputeBuffer
[Link]
124
6.3 Lorenz Attractor
[Link] InitializeCompute-
Buffer [Link]
Unity
gradient emitterSize particleSize
Params ComputeBuffer cBuffer SetData
id
id
Strange Attractor
LorenzAttrator p r b
[Link]
[Link]
125
6 Strange Attractor
struct Params
{
float3 emitPos;
float3 position;
float3 velocity; //xyz = velocity
float life;
float2 size; // x = current size, y = target size.
float4 color;
};
RWStructuredBuffer<Params> buf;
Emit [Link]
id
id
[Link] 0
[Link]
#define DT 0.022
//Lorenz
float3 LorenzAttractor(float3 pos)
{
126
6.4 Thomas’ Cyclically Symmetric Attractor
LorenzAttractor Lorenz
x,y,z
Unity
Unity [Link]
Strange Attractor
2 DT
127
6 Strange Attractor
dx
= sin y − bx
dt
dy
= sin z − by
dt
dz
= sin x − bz
dt
b b ≃ 0.208186
Strange Attractor b≃0
128
6.4 Thomas’ Cyclically Symmetric Attractor
Lorenz Attractor
CPU
[Link]
[Link]
129
6 Strange Attractor
Emit LorenzAttrator
6.5
Strange Attractor GPU
Strange Attractor
*4 UedaAttractor 2 *5 AizawaAttractor
6.6
• [Link]
*4 [Link]
*5 [Link]
130
6.6
• [Link]
• Lorenz, E. N. Deterministic Nonperiodic Flow, Journal of Atmospheric
Sciences, Vol.20, pp.130-141, 1963.
• Thomas, Ren 1999 . "Deterministic chaos seen in terms of feedback
circuits: Analysis, synthesis, ’labyrinth chaos’". Int. J. Bifurcation and
Chaos. 9 10 : 1889 1905.
131
7
Portal Unity
7.1
Portal*1 2007 Valve
Unity
[Link]
PortalGateSystem
7.2
•
•
•
Unity
Adam*2
E
*1 [Link]
*2 [Link]
adam-guard-lu-74842
132
7.3
• WASD
•
•
• E
•
Portal-
Gate
7.2.1
Unity Standard Assets *3 FirstPerson-
Character ThirdPersonChracter
Player Player
CullingMask
7.2.2
unity3d-jp playGROWnd*4
Portal
StageColl
7.3
XY
Z+
*3 [Link]
*4 [Link]
133
7 Portal Unity
7.1
Portal
[Link]
[Link] = [Link];
134
7.3
[Link]();
}
}
StageColl [Link]
[Link]
Z
[Link]() normal.y
[Link]
PortalGate Y
Portal
7.2
135
7 Portal Unity
7.3
7.4 VirtualCamera
7.4.1
(VirtualCamera) RenderTexture
PortalGate
VirtualCamera
136
7.4 VirtualCamera
7.4 VirtualCamera
[Link]()
VirtualCamera
[Link]
VirtualCamera pairVC;
if ()
{
if ((vc == null) || [Link] < maxGeneration)
{
pairVC = pairVCTable[cam] = CreateVirtualCamera(cam, vc);
return;
}
}
137
7 Portal Unity
7.5
1. VirtualCamera
2. VirtualCamera VirtualCamera
3. VirtualCamera VirtualCamera
4.
VirtualCamera
[Link]
[Link]
var go = Instantiate(virtualCameraPrefab);
[Link] = [Link] + "_virtual" + generation;
[Link](transform);
var vc = [Link]<VirtualCamera>();
[Link] = rootCam;
[Link] = parentCam;
138
7.4 VirtualCamera
[Link] = this;
[Link] = generation;
[Link]();
return vc;
}
[Link] VirtualCamera
[Link]
camera_.targetTexture = tex0;
currentTex0 = true;
}
[Link]() Vir-
tualCamera CullingMask Player
[Link]
h - 1
[Link]() CommandBuffer
PostProcessingStack*5
7.4.2
VirtualCamera [Link]
[Link]
*5 [Link]
139
7 Portal Unity
Destroy(gameObject);
return;
}
camera_.enabled = [Link](parentCamera);
if (camera_.enabled)
{
var parentCamTrans = [Link];
var parentGateTrans = [Link];
[Link](
transform,
[Link],
[Link]
);
UpdateCamera();
}
}
VirtualCamera
[Link]
return ret;
}
1.
Z+
2. Unity
140
7.4 VirtualCamera
[Link]()
transform
[Link]
[Link](pos, rot);
}
1.
2. gateRot
3.
4.
gateRot
Y 180 Z
141
7 Portal Unity
[Link]
void UpdateCamera()
{
var pair = [Link];
var pairTrans = [Link];
var mesh = [Link]<MeshFilter>().sharedMesh;
var vtxList = [Link]
.Select(vtx => [Link](vtx)).ToList();
[Link](camera_, vtxList);
// Oblique
// pairGate = nearClipPlane pairGate
var pairGateTrans = [Link];
var clipPlane = CalcPlane(camera_,
[Link],
-[Link]);
camera_.projectionMatrix = camera_.CalculateObliqueMatrix(clipPlane);
}
VirtualCamera
VirtualCamera
[Link]()
[Link]
VirtualCamera
[Link]
bliqueMatrix()
xyz w
Vector4
142
7.5
7.5
•
•
• 7.6
• VirtualCamera
• [Link] VirtualCamera
PortalGate
7.6
[Link]
GrabPass
{
"_BackgroundTexture"
}
GrabPass*6
7.5.1
[Link]
*6 [Link]
143
7 Portal Unity
[Link] = clipPos;
[Link] = [Link];
[Link] = ComputeScreenPos(clipPosOnMain);
[Link] = ComputeGrabScreenPos([Link]);
return o;
}
2
clipPos clipPosOnMain
VirtualCamera
RenderTexture GrabPass
7.5.2
[Link]
float2 uv = [Link];
uv = (uv - 0.5) * 2; // map 0~1 to -1~1
float insideRate = (1 - length(uv)) * _OpenRate;
insideRate 1 0
_OpenRate Portal-
[Link]()
[Link]
// background
float4 grabUV = [Link];
float2 grabOffset = float2(
snoise(float3(uv, _Time.y )),
snoise(float3(uv, _Time.y + 10))
);
[Link] += grabOffset * 0.3 * insideRate;
float4 bgColor = tex2Dproj(_BackgroundTexture, grabUV);
144
7.6
[Link]
_MainTex VirutualCamera
UV
[Link]
// color
float4 col = lerp(bgColor, sideColor, _ConnectRate);
bgColor sideColor _
ConnectRate 0 1 1
[Link]
// frame
float frame = smoothstep(0, 0.1, insideRate);
float frameColorRate = 1 - abs(frame - 0.5) * 2;
float mixRate = saturate(grabOffset.x + grabOffset.y);
float3 frameColor = lerp(_FrameColor0, _FrameColor1, mixRate);
[Link] = lerp([Link], frameColor, frameColorRate);
col.a = frame;
insideRate _FrameColor0,_FrameCol
or1
7.6
PortalObj
GameObject
7.6.1
PortalObj
145
7 Portal Unity
7.7
[Link]
OnTriggerEnder() OnTriggerStay()
Enter
tougingGates PortalGa
[Link] [Link]
llision()
OnTriggerExit()
[Link] PortalGate
OnTriggerStay()
146
7.6
7.6.2
[Link]
if (passedGate != null)
{
PassGate(passedGate);
}
center Transform
PortalObj GameObject
[Link] z > 0f
touchingGates
PassGate()
PortalObj
[Link]
if (rigidbody_ != null)
{
rigidbody_.velocity = [Link](rigidbody_.velocity);
rigidbody_.useGravity = false;
ignoreGravityStartTime = [Link];
147
7 Portal Unity
if (fpController != null)
{
fpController.m_MoveDir = [Link](fpController.m_MoveDir);
[Link]();
}
}
VirtualCamera
[Link]() Transform
RigidBody fpController
7.6.3
PortalObj
OnTriggerEn
ter(),OnCollisionEnter() [Link]()
On~Enter()
[Link]()
Enter
PortalObj
Unity
148
7.7
7.7
Portal Unity
CG
7.8
• Portal [Link]
• Adam Character Pack [Link]
com/packages/essentials/tutorial-projects/
adam-character-pack-adam-guard-lu-74842
• playGROWnd [Link]
• PostProcessingStack [Link]
PostProcessing
149
8
8.1
[Link]
OverReaction
150
8.1
8.1
OverReaction
Inspector
PhysicsScene
8.2
3
1.
2.
3.
moveEnergy
kinetic energy
move energy
Updat
e FixedUpdate
[Link]
UpdateMoveEnergy();
UpdateDeformEnergy();
DeformMesh();
[Link] = [Link];
[Link] = [Link];
}
FixedUpdate 2
3 ~ Update
151
8
UpdateMoveEnergy
[Link]
y = UpdateMoveEnergy
([Link].y, [Link].y, [Link].y),
z = UpdateMoveEnergy
([Link].z, [Link].z, [Link].z),
};
}
X, Y, Z U
pdateMoveEnergy
[Link]
if (crntMoveSign == 0)
{
return moveEnergy * [Link];
}
152
8.3
[Link]
if (crntMoveSign != prevMoveSign)
{
return moveEnergy - crntMove;
}
[Link]
if (crntMoveSign != moveEnergySign)
{
return moveEnergy + crntMove;
}
[Link]
if (crntMoveSign < 0)
{
return [Link](crntMove * [Link],
moveEnergy * [Link]);
}
else
{
return [Link](crntMove * [Link],
moveEnergy * [Link]);
}
8.3
deformEnergy
UpdateDeformEnergy
153
8
1
0
[Link]
+0.8 -0.8
1 - 0.8 = 0.2
* 0.8 1 * 1.8
[Link]
float deformEnergyHorizontalRatio
= deformEnergyVertical / [Link];
float deformEnergyHorizontal
= 1 - deformEnergyHorizontalRatio;
deformEnergyVertical = 1 + deformEnergyVertical;
}
154
8.3
deformEnergyHorizontal 1
deformEnergyVertical deformEnergyHorizontal
1
[Link]
float deformEnergyHorizontalRatio
= deformEnergyVertical / [Link];
float deformEnergyHorizontal
= 1 - deformEnergyHorizontalRatio;
if (deformEnergyVertical < 0)
{
deformEnergyVertical = deformEnergyHorizontalRatio;
}
deformEnergyVertical = 1 + deformEnergyVertical;
[Link]
deformEnergyVertical = [Link](deformEnergyVertical,
[Link],
[Link]);
deformEnergyHorizontal = [Link](deformEnergyHorizontal,
[Link],
[Link]);
155
8
8.4
DeformMesh
GPU
deformEnergy moveEnergy
moveEnergy
[Link]
Quaternion moveEnergyRotation
= [Link]([Link], [Link]);
Quaternion moveEnergyRotationI = [Link](moveEnergyRotation);
1.
2.
3. deformEnergy
4.
5.
deformEnergy
[Link]
156
8.5
deformedVertices[i].z * [Link].z);
deformedVertices[i] = moveEnergyRotation * deformedVertices[i];
deformedVertices[i] = crntRotationI * deformedVertices[i];
}
[Link] = deformedVertices;
8.5
157
1 Baking Skinned Animation to Texture - / @sugi_cho
Unity
=> hi@[Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
158
4 GPU-Based Cellular Growth Simulation - / @mattatz
Web
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
159
8 - @XJINE
UnityShaderProgramming
• [Link]
• [Link]
• [Link]
160
Unity Graphics Programming vol.3
2018 10 8 5 v1.0.0
IndieVisualLab
IndieVisualLab
IndieVisualLab
161