TouchDesigner - GLSL Image Displacement

# Requirements
[TouchDesigner 099 2017.15400+](https://www.derivative.ca/099/Downloads/)
[今回の完成ソースはここ。](https://github.com/brvoigt/GLSL-examples/tree/master/Displacement)

# Description
Open **GLSL_Displacement.toe**

Image Displacement can be easily setup in TouchDesigner using TOPs, SOPs and CHOPs. 
But the SOPs and CHOPs calculate on the CPU, performance will slow down as more points are added to geometry. 
Example **/base_top2sop_displacement** 
Try increasing Grid SOP Rows/Columns = 250.
TOP -> CHOP - can be slow
CHOP -> SOP displacement - can be slow

[GLSL Materials](http://www.derivative.ca/wiki099/index.php?title=GLSL_Material_Writing_Guide) can be used displace geometry on the GPU for better performance so you can use many more points.
Example **/container_glsl_displacement**
TOP -> GLSL displacement - fast!

# Prepare Geometry
Create Grid SOP -> Geometry COMP.
Grid SOP settings
**Rows = 250**
**Columns = 250**

Add Attribute Create SOP to calculate tangents for GLSL shader later.
Attribute Create SOP settings
**Compute Tangents = On**
![Screen Shot 2017-12-19 at 4.32.49 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/303e5c28-4757-8ce2-9b5b-3a0de2383d9c.png)

Basic geometry setup
![Screen Shot 2017-12-19 at 4.33.20 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/afa4bb64-b742-89b1-0f15-47b4cabb84e4.png)


# Create GLSL Material
Easy way to start, output shader from [Phong MAT](http://www.derivative.ca/wiki099/index.php?title=Phong_MAT)

Click **Output Shader** in Phong MAT parameters
![Untitled-1.png](https://qiita-image-store.s3.amazonaws.com/0/216420/aa372a0d-ea51-a424-20a2-877dad27bb6a.png)

Click **OK** on Output GLSL Code... dialog
![GLSLoutput.png](https://qiita-image-store.s3.amazonaws.com/0/216420/945935c5-acde-9c52-90c1-23c876395061.png)

Result is GLSL MAT with all the same settings as Phong MAT
![OutputGLSLPhongMAT.png](https://qiita-image-store.s3.amazonaws.com/0/216420/fec8f1c4-e835-892a-c85b-e88ea03dc2b5.png)

Assign **phong1GLSL** to Geometry COMP
![Screen Shot 2017-12-19 at 7.03.01 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/d262f10b-25eb-13a9-8b2a-fd1948dc089e.png)


# Add Image Sampler to GLSL Shader

Create Noise TOP -> Null TOP
On phong1GLSL Samplers page, assign Null TOP and give it a sampler name **dispTexture**
![Screen Shot 2017-12-19 at 4.54.58 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/2c47b064-0182-d9b1-4571-0b30cd46bb6d.png)

Declare sampler2D **dispTexture** in vertex shader
![Screen Shot 2017-12-19 at 5.05.26 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/77c37b83-3472-c274-0121-f560e176346f.png)

# Displace Point Positions Using Sampler

1. Use `texture()` function to sample red channel of dispTexture
2. Create newPos which adds offset to original position
3. Use newPos in `TDDeform()`

![vertex1.png](https://qiita-image-store.s3.amazonaws.com/0/216420/95d3c01f-c6fe-1df9-b2d8-27f189ca6c24.png)

Displacement! :grinning:
But bad lighting... :cry:

# Calculating Normals For Lighting

For correct lighting, we must re-calculate the normals in vertex shader and pass the data to pixel shader for final lighting.

Get normal information for input image using Normal Map TOP
Normal Map TOP settings
**Heightmap in Alpha Channel = On**

![Screen Shot 2017-12-19 at 5.28.49 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/04157a55-e8d8-6c33-4e13-a784c2b21fcb.png)

Now sample *alpha* channel in vertex shader to get height map
![Screen Shot 2017-12-19 at 5.31.39 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/85cc4f58-4122-1532-be62-562a07c4a672.png)

### Update Vertex Data Structure
From vertex shader, pass *tbn matrix* and *texture coordinates* to pixel shader
**Vertex Shader**
![Screen Shot 2017-12-19 at 5.43.45 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/96a99e79-f619-00a7-f4af-36d8b4681f95.png)
**Pixel Shader**
![Screen Shot 2017-12-19 at 5.45.27 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/41bad9a9-d8bc-205c-9acf-adfd12ccf8ef.png)

### Vertex Shader - Calculate tbn and texCoord0 
In the vertex shader
Declare tangents **T**
![Screen Shot 2017-12-19 at 5.51.41 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/5dadff90-f1a6-9514-076a-ff56bcb05944.png)

Calculate **tbn** matrix (tangent, bitangent, normal matrix) and set **texCoord0** texture coordinates
![Screen Shot 2017-12-19 at 5.48.16 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/fbf516d5-baa4-ecde-d122-463fce870af0.png)
`TDCreateTBNMatrix()` is new in TouchDesigner (Build 2017.15400+)

### Pixel Shader - Normal Recalculation
In the pixel shader
Declare sampler2D **dispTexture**
![Screen Shot 2017-12-19 at 6.00.38 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/22b9b325-41c8-ebcf-765b-b6a21b6a04bf.png)

Do normal recalculation and comment old normal code
![Screen Shot 2017-12-19 at 6.01.01 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/1144b0b1-095b-4f73-4b85-2c6a357a4876.png)

GLSL Displacement should be working!
Try more points in Grid SOP (Rows/Columns = 500 or 1000 depending on your computer)

![Screen Shot 2017-12-19 at 6.16.07 PM.png](https://qiita-image-store.s3.amazonaws.com/0/216420/4e7f7b49-0029-d759-9dfc-58382f452883.png)

# Extras in GLSL_Displacement.toe
Here are some extras to make it more interesting...
1. **In TOP** to input any image or movie for displacement
2. **Fit TOP** so that TOP pixels = Grid SOP points
3. **dispScale** uniform in shader controls amount of displacement
4. **Particle render** mode from Convert SOP
5. **Custom parameters** on component for easier control
6. Use **/container_glsl_displacement viewer** to move camera (arcBall camera component from Palette)
7. Pretty lighting :smile:

# Summary
Using this method you can displace many more points and higher density geometry than with CHOPs and SOPs.

I taught this example in our TouchDesigner 202 *Intro to GLSL* workshop this fall, but the math is easier now because we added `TDCreateTBNMatrix()` to TouchDesigner.

Original inspiration for this displacement example came from Matthew Ragan and his [Make_Some_Noise workshop](https://github.com/raganmd/make_some_noise_2017) earlier this year. Thank you again Matthew!

ごめん、日本語のカレンダーなのに、日本語で教えられない！はは！