<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>wacki</title>
    <description>Personal blog.
</description>
    <link>http://wacki.me/</link>
    <atom:link href="http://wacki.me/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 19 Nov 2024 16:40:59 +0000</pubDate>
    <lastBuildDate>Tue, 19 Nov 2024 16:40:59 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>UE4 Smoothed Normal from Line Trace in Packaged Builds</title>
        <description>&lt;p&gt;I needed a way to get a smoothed surface normal from a line trace in Unreal Engine 4. So of course the first thing I did was research the topic. I found a lot of good resources that I linked at the bottom of this post. However none of the forum posts mentioned the solution to accessing mesh data in a packaged build. This might’ve been because I was searching the wrong keywords. I included my code to calculate the interpolated surface normal for both Static Meshes and Spline Meshes in Unreal Engine 4.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Most of the resources I found were talking about getting UV coordinates for a Line Trace hit. And many didn’t consider Spline Meshes at all which is my primary usecase. And one important thing I didn’t find mentioned anywhere is that you need to enable Allow CPUAccess on static meshes that you want to access during runtime in a packaged build. I found that one while digging through the source code, although it’s a pretty obvious thing in hindsight.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2017-04-smoothnormals/allowcpuaccess.png&quot; /&gt;
		
		&lt;p&gt;To be able to access mesh data in a packaged build bAllowCPUAccess must to be set to true.&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;The following code is part of my static c++ function library. It accepts a FHitResult reference and calculates an interpolated normal based on the triangle that was hit. This works for both Static Mesh as well as Spline Mesh Components. However this code is by no means perfect and I am sure there is a lot that could be improved.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSmoothNormalFromTrace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FHitResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugDraw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// We don&apos;t care if this isn&apos;t a blocking hit&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bBlockingHit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// See if a static mesh and/or a spline mesh component were hit&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UStaticMeshComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Cast&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UStaticMeshComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;USplineMeshComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SplineMeshComp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Cast&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USplineMeshComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// If we hit a spline mesh component we should also have hit a static mesh component&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Retrieve static mesh. If we hit a spline mesh component we also hit a static mesh component at the same time.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// So we can just use it to get to the actual static mesh.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UStaticMesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StaticMesh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetStaticMesh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Return if the static mesh isn&apos;t set (shouldn&apos;t happen)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMesh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// In cooked builds we need to have this flag set or we&apos;ll crash when trying to access mesh data&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bAllowCPUAccess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Return if RenderData is invalid&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RenderData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// No valid mesh data on lod 0 (shouldn&apos;t happen)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RenderData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LODResources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsValidIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FaceIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FaceIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FTransform&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ComponentTransform&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetComponentTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FStaticMeshVertexBuffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexBuffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RenderData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LODResources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VertexBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FPositionVertexBuffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PositionVertexBuffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RenderData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LODResources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PositionVertexBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FIndexArrayView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IndexBuffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StaticMesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RenderData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LODResources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IndexBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetArrayView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Storage for the actual triangle verteces&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Get vertex index&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IndexBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FaceIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Get vertex position and normal&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PositionVertexBuffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VertexPosition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexBuffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VertexTangentZ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// Transform position and normal into spline mesh space&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SplineMeshComp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Get transform along spline component&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FTransform&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SliceTransform&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SplineMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CalcSliceTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USplineMeshComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetAxisValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SplineMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForwardAxis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Remove spline forward axis from vertex position, it will be added back by transforming the position into spline mesh space&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;USplineMeshComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetAxisValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SplineMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForwardAxis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Transform position and normal into spline mesh space&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SliceTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransformPosition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SliceTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransformVector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Transform position and normal into world space&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ComponentTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransformPosition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ComponentTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransformVector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Determine the barycentric coordinates&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;V&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;W&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImpactPoint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vCrossW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CrossProduct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vCrossU&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CrossProduct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DotProduct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vCrossW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vCrossU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uCrossW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CrossProduct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uCrossV&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CrossProduct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DotProduct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uCrossW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uCrossV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Denom&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uCrossV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vCrossW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Denom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uCrossW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Denom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Determine the hit normal&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Just to be safe here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Normalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Debug draw&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;#if !UE_BUILD_SHIPPING
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DebugDraw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    	&lt;span class=&quot;c1&quot;&gt;// Quick and dirty debug draw&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;FColor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugColor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FColor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugDrawDuration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;30.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// draw triangle points&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DrawDebugPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugDrawDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// draw triangle edges&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DrawDebugLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugDrawDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// triangle normals&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DrawDebugLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VertexNormals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;200.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugDrawDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// draw actual impact normal&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DrawDebugPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImpactPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugDrawDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DrawDebugLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImpactPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImpactPoint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImpactNormal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;200.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugDrawDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DrawDebugLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StaticMeshComp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImpactPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImpactPoint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Normal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;200.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DebugDrawDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;#endif //!UE_BUILD_SHIPPING
&lt;/span&gt;    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Resources used:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://forums.unrealengine.com/showthread.php?62805-Question-about-traces-and-geometry&quot;&gt;UE4 Forum - Question about traces and geometry.&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://forums.unrealengine.com/showthread.php?8856-Accessing-Vertex-Positions-of-static-mesh&quot;&gt;UE4 Forum - Accessing Vertex Positions of static mesh&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://forums.unrealengine.com/showthread.php?138508-How-to-get-vertex-positions-of-spline-mesh-component-in-world-space&quot;&gt;UE4 Forum - How to get vertex positions of spline mesh component in world space?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://forums.unrealengine.com/showthread.php?8856-Accessing-Vertex-Positions-of-static-mesh&quot;&gt;UE4 Forum - Accessing Vertex Positions of static mesh&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://answers.unrealengine.com/questions/459327/how-can-i-get-polygon-normals-of-a-static-mesh.html&quot;&gt;UE4 AnswerHub - How can I get polygon normals of a static mesh?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://answers.unrealengine.com/questions/340304/how-to-get-triangles-of-a-static-mesh.html&quot;&gt;UE4 AnswerHub - How to get triangles of a Static Mesh?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://answers.unrealengine.com/questions/295318/how-to-use-procedural-mesh-component-in-blueprint.html&quot;&gt;UE4 AnswerHub - How to use Procedural Mesh Component in Blueprint?h&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/EpicGames/UnrealEngine/blob/76085d1106078d8988e4404391428252ba1eb9a7/Engine/Source/Programs/UnrealLightmass/Private/Lighting/StaticMesh.cpp#L151&quot;&gt;UE4 Source Code - Transforming Positions Into SplineMesh Space&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/EpicGames/UnrealEngine/blob/76085d1106078d8988e4404391428252ba1eb9a7/Engine/Plugins/Runtime/ProceduralMeshComponent/Source/ProceduralMeshComponent/Private/KismetProceduralMeshLibrary.cpp#L372&quot;&gt;UE4 Source Code - GetSectionFromStaticMesh&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wiki.unrealengine.com/Accessing_mesh_triangles_and_vertex_positions_in_build&quot;&gt;UE4 Wiki - Accessing mesh triangles and vertex positions in build&lt;/a&gt; (Although this one is a bit older)&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 29 Apr 2017 09:10:00 +0000</pubDate>
        <link>http://wacki.me/blog/2017/04/ue4-smooth-trace-normal/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2017/04/ue4-smooth-trace-normal/</guid>
        
        
        <category>gamedev</category>
        
        <category>programming</category>
        
        <category>ue4</category>
        
      </item>
    
      <item>
        <title>MachX Item Pickup Models</title>
        <description>&lt;p&gt;
Item pickup models for a racing game I am working on as my final project at VFS.

    &lt;div class=&quot;inline-image&quot; style=&quot;display: block;&quot;&gt;&lt;div class=&quot;video-container&quot;&gt;
&lt;iframe width=&quot;640&quot; height=&quot;480&quot; src=&quot;https://sketchfab.com/models/9c9ec6591e7441a9b7d442c49e36f520/embed&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot; mozallowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot; onmousewheel=&quot;&quot;&gt;&lt;/iframe&gt;&lt;p style=&quot;font-size: 13px; font-weight: normal; margin: 5px; color: #4A4A4A;&quot;&gt;
    &lt;a href=&quot;https://sketchfab.com/models/9c9ec6591e7441a9b7d442c49e36f520?utm_medium=embed&amp;amp;utm_source=website&amp;amp;utm_campain=share-popup&quot; target=&quot;_blank&quot; style=&quot;font-weight: bold; color: #1CAAD9;&quot;&gt;Hover racer untextured&lt;/a&gt;
    by &lt;a href=&quot;https://sketchfab.com/wacki?utm_medium=embed&amp;amp;utm_source=website&amp;amp;utm_campain=share-popup&quot; target=&quot;_blank&quot; style=&quot;font-weight: bold; color: #1CAAD9;&quot;&gt;wacki&lt;/a&gt;
    on &lt;a href=&quot;https://sketchfab.com?utm_medium=embed&amp;amp;utm_source=website&amp;amp;utm_campain=share-popup&quot; target=&quot;_blank&quot; style=&quot;font-weight: bold; color: #1CAAD9;&quot;&gt;Sketchfab&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;/div&gt;
&lt;/p&gt;
</description>
        <pubDate>Sun, 23 Apr 2017 09:10:00 +0000</pubDate>
        <link>http://wacki.me/blog/2017/04/racing-game-pickup-model/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2017/04/racing-game-pickup-model/</guid>
        
        
        <category>gamedev</category>
        
        <category>art</category>
        
      </item>
    
      <item>
        <title>Dynamic snow/sand shader for Unity</title>
        <description>&lt;p&gt;A while ago I shared a small project I was working on. I finally had the time to clean up a bit and try a few more things. The goal was to achieve an effect similar to the sand in &lt;a href=&quot;https://en.wikipedia.org/wiki/Journey_(2012_video_game)&quot;&gt;Journey&lt;/a&gt;. Even though in my case it’s snow at the moment.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2017-01-snow/snow.png&quot; /&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The project includes a few example shaders and it’s easy to write your own. The effect is achieved by drawing into a height map texture using a stamp or brush texture. A custom material allows for full control over how we overlay that stamp texture. In the shader we have access to the height map pixels as well as the stamp pixels.&lt;/p&gt;

&lt;p&gt;
    &lt;div class=&quot;inline-image&quot; style=&quot;display: block;&quot;&gt;&lt;div class=&quot;video-container&quot;&gt;
        &lt;iframe src=&quot;https://www.youtube.com/embed/REIcwL8hE-w&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;
        &lt;/div&gt;      
        &lt;p&gt;Included stamp shader variants.&lt;/p&gt;
    &lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;I like how it turned out so far, but there are still a few things I want to do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Clean up some more, make it easier to use.&lt;/li&gt;
  &lt;li&gt;Optimize.&lt;/li&gt;
  &lt;li&gt;Make the effect work with Unity’s terrain system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I haven’t really thought about how to get this to work with Unity’s terrain yet. One option might be to use a seperate tiling system for the snow tiles overlaying the terrain. The shader is already using distance based tessellation, so LOD shouldn’t be an issue. However this approach will most certainly lead to stitching issues along LOD seams. This sounds like a completely separate terrain system already, ugh… Maybe I could augment Unity’s terrain shader and add some tesselation to it? Then just use a big enough texture atlas for the dynamic height map tiles. I guess I have some research to do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source code:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;github-card&quot; id=&quot;repo-wacki-Unity-IndentShader&quot;&gt;
	&lt;div class=&quot;header&quot;&gt;
		&lt;span class=&quot;octicon octicon-repo&quot;&gt;&lt;/span&gt;
		&lt;span class=&quot;repo-name&quot;&gt;
			&lt;span class=&quot;author&quot;&gt;&lt;a href=&quot;https://github.com/wacki&quot; class=&quot;url fn&quot; itemprop=&quot;url&quot; rel=&quot;author&quot; target=&quot;_blank&quot;&gt;&lt;span itemprop=&quot;title&quot;&gt;wacki&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;
			&lt;span class=&quot;path-divider&quot;&gt;/&lt;/span&gt;
			&lt;strong&gt;&lt;a href=&quot;https://github.com/wacki/Unity-IndentShader&quot; data-pjax=&quot;#js-repo-pjax-container&quot; target=&quot;_blank&quot;&gt;Unity-IndentShader&lt;/a&gt;&lt;/strong&gt;
		&lt;/span&gt;
	&lt;/div&gt;
	&lt;div class=&quot;footer&quot;&gt;&lt;span class=&quot;status&quot;&gt;&lt;strong class=&quot;fork-count&quot;&gt;0&lt;/strong&gt;Forks&lt;/span&gt;&lt;span class=&quot;status&quot;&gt;&lt;strong class=&quot;star-count&quot;&gt;0&lt;/strong&gt;Stars&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
 $(function () {
	$.ajax({
	   url: &apos;https://api.github.com/repos/wacki/Unity-IndentShader&apos;,
	   success: function(data) {		
		$(&apos;div[id=&quot;repo-wacki-Unity-IndentShader&quot;] .fork-count&apos;).html(data.forks_count);
		$(&apos;div[id=&quot;repo-wacki-Unity-IndentShader&quot;] .star-count&apos;).html(data.stargazers_count);
	   }	   
	});
	});
&lt;/script&gt;

&lt;p&gt;
    &lt;div class=&quot;inline-image&quot; style=&quot;display: block;&quot;&gt;&lt;div class=&quot;video-container&quot;&gt;
        &lt;iframe src=&quot;https://www.youtube.com/embed/WugpdLUP8A8&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;
        &lt;/div&gt;      
        &lt;p&gt;First video about this project.&lt;/p&gt;
    &lt;/div&gt;
&lt;/p&gt;

</description>
        <pubDate>Mon, 02 Jan 2017 12:10:00 +0000</pubDate>
        <link>http://wacki.me/blog/2017/01/dynamic-snow-sand-shader-for-unity/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2017/01/dynamic-snow-sand-shader-for-unity/</guid>
        
        
        <category>gamedev</category>
        
        <category>programming</category>
        
        <category>art</category>
        
      </item>
    
      <item>
        <title>Khaya - VFS 2D project</title>
        <description>&lt;p&gt;I am currently working on a 2D platformer as part of a student team. The project is part of the Game Design course at VFS. I am handling the programming side of things as well as some special effects and UI. The prototype version of the game is done and we should hit alpha in about three weeks.&lt;/p&gt;

&lt;p&gt;At its core the game is about speed and skillful traversal of levels. The twist is an aura surrounding the character that shrinks should the player stand still for too long. If this aura gets too small the player will die.&lt;/p&gt;

&lt;p&gt;
    &lt;div class=&quot;inline-image&quot; style=&quot;display: block;&quot;&gt;&lt;div class=&quot;video-container&quot;&gt;
        &lt;iframe src=&quot;https://www.youtube.com/embed/0v06lCwkuHg&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;
        &lt;/div&gt;      
        &lt;p&gt;Current state of the prototype. Note: Art, animations and audio are still only placeholders for now.&lt;/p&gt;
    &lt;/div&gt;
&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The movement in its current form feels fun and engaging. However there are still quite a few areas where we need to tweak and balance things. The most difficult being the aura mechanic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How the aura works:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the player is moving at an average velocity larger than a set threshold then the aura will grow / stay at maximum size. As soon as the player falls below that velocity threshold a timer will start after which the aura starts to shrink. If the aura gets too small the player will start taking damage. The aura is also responsible to trigger frozen objects in the level should it come in contact with them.&lt;/p&gt;

&lt;p&gt;There are still a bunch of design challanges ahead of us. Most of them involve giving the player proper feedback for their actions. Especially the aura will be hard to get right in this regard. And of course some smaller tweaking and balancing is still necessary as well.&lt;/p&gt;
</description>
        <pubDate>Wed, 28 Dec 2016 09:10:00 +0000</pubDate>
        <link>http://wacki.me/blog/2016/12/khaya-vfs-2d-project/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2016/12/khaya-vfs-2d-project/</guid>
        
        
        <category>gamedev</category>
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Unfinished digital raptor drawing</title>
        <description>&lt;p&gt;
Tried myself at digital drawing again. It&apos;s unfinished but given the time constraints I had to work with I am quite happy how far I got. This is about 2h worth of work. 




&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2016-11-raptor/raptor-1024.png&quot; /&gt;
		
		&lt;p&gt;Current state of the drawing.&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;




&lt;!--more--&gt;

I was debating wheather or not I should post this but I think I should just go ahead and post more stuff in the first place, so from now on that is what I&apos;m going to be doing. 

&lt;p&gt;
    &lt;div class=&quot;inline-image&quot; style=&quot;display: block;&quot;&gt;&lt;div class=&quot;video-container&quot;&gt;
        &lt;iframe src=&quot;https://www.youtube.com/embed/J26ub4oro4g&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;
        &lt;/div&gt;      
        &lt;p&gt;Timelapse of the drawing process.&lt;/p&gt;
    &lt;/div&gt;
&lt;/p&gt;
&lt;/p&gt;
</description>
        <pubDate>Thu, 10 Nov 2016 11:00:00 +0000</pubDate>
        <link>http://wacki.me/blog/2016/11/unfinished-raptor-drawing/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2016/11/unfinished-raptor-drawing/</guid>
        
        
        <category>art</category>
        
      </item>
    
      <item>
        <title>Hover Racer 3D model made in blender</title>
        <description>&lt;p&gt;
My first try at actually modelling something from scratch. 

    &lt;div class=&quot;inline-image&quot; style=&quot;display: block;&quot;&gt;&lt;div class=&quot;video-container&quot;&gt;
&lt;iframe width=&quot;640&quot; height=&quot;480&quot; src=&quot;https://sketchfab.com/models/c051579c3b894d59a411b4c161ea0375/embed&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot; mozallowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot; onmousewheel=&quot;&quot;&gt;&lt;/iframe&gt;&lt;p style=&quot;font-size: 13px; font-weight: normal; margin: 5px; color: #4A4A4A;&quot;&gt;
    &lt;a href=&quot;https://sketchfab.com/models/c051579c3b894d59a411b4c161ea0375?utm_medium=embed&amp;amp;utm_source=website&amp;amp;utm_campain=share-popup&quot; target=&quot;_blank&quot; style=&quot;font-weight: bold; color: #1CAAD9;&quot;&gt;Hover racer untextured&lt;/a&gt;
    by &lt;a href=&quot;https://sketchfab.com/wacki?utm_medium=embed&amp;amp;utm_source=website&amp;amp;utm_campain=share-popup&quot; target=&quot;_blank&quot; style=&quot;font-weight: bold; color: #1CAAD9;&quot;&gt;wacki&lt;/a&gt;
    on &lt;a href=&quot;https://sketchfab.com?utm_medium=embed&amp;amp;utm_source=website&amp;amp;utm_campain=share-popup&quot; target=&quot;_blank&quot; style=&quot;font-weight: bold; color: #1CAAD9;&quot;&gt;Sketchfab&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;/div&gt;
&lt;/p&gt;

&lt;!--more--&gt;
</description>
        <pubDate>Sat, 11 Jun 2016 16:46:00 +0000</pubDate>
        <link>http://wacki.me/blog/2016/06/hover-racer-3d-model-made-in-blender/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2016/06/hover-racer-3d-model-made-in-blender/</guid>
        
        
        <category>gamedev</category>
        
        <category>art</category>
        
        <category>blender</category>
        
      </item>
    
      <item>
        <title>Painting a pavement texture</title>
        <description>&lt;p&gt;My first try at hand painting a texture in Photoshop.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2016-06-texturepainting/pavement_render2.jpg&quot; /&gt;
		
		&lt;p&gt;Finished texture.&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;I wanted to dive into this topic for a while but couldn’t find a good starting point until recently. While browsing youtube for some good photoshop painting introductions I came across a &lt;a href=&quot;https://www.youtube.com/watch?v=c_GWVez_UHM&quot;&gt;texturing workshop&lt;/a&gt; led by Jamin Shoulet at the Academy of Art University. Through this video I found the channel Metric Meditation and &lt;a href=&quot;https://www.youtube.com/watch?v=udMjSV6cFmE&quot;&gt;this video&lt;/a&gt; which is using many of the same techniques that Jamin introduced in his workshop. So I thought trying to make something similar would be a good way to get my feet wet.&lt;/p&gt;

&lt;p&gt;
    &lt;div class=&quot;inline-image&quot; style=&quot;display: block;&quot;&gt;&lt;div class=&quot;video-container&quot;&gt;
        &lt;iframe src=&quot;https://www.youtube.com/embed/zU3FlqjgjEM&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;
        &lt;/div&gt;      
        &lt;p&gt;Timelapse of the painting process.&lt;/p&gt;
    &lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Just like you (should) prototype before going into production or doing a rough blocking out of your animation before adding detail, I think the same applies for making tileable textures. Although I am happy with the style of my texture I don’t like how it repeats. The big stones are way too prominent and stick out when using it on a large area. This would’ve been apparent if I just took an earlier version of the texture and slapped it onto a large plane. I could’ve then tweaked the shapes of the stones until the tiling looked pleasing.&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Jun 2016 16:46:00 +0000</pubDate>
        <link>http://wacki.me/blog/2016/06/pavement-texture-painting/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2016/06/pavement-texture-painting/</guid>
        
        
        <category>gamedev</category>
        
        <category>art</category>
        
        <category>photoshop</category>
        
      </item>
    
      <item>
        <title>VR GUI Input Module for Unity (HTC Vive)</title>
        <description>&lt;p&gt;I created a simple GUI input module for Unity to be used in VR. The project includes an implementation for the HTC Vive controllers.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2016-06-vrgui/gui.png&quot; /&gt;
		
		&lt;p&gt;Unity GUI working with the Vive controllers.&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;I am fortunate enough to be able to use an HTC Vive at my workplace. After starting out in Unity I soon found myself wanting to use Unity’s uGUI system in VR. So of course the first thing I did was head on over to Google and check if someone had already done the work for me. Sure enough I came upon a solution by &lt;a href=&quot;http://www.vrinflux.com/using-the-vive-controllers-for-unity-4-6-ui-ugui/&quot;&gt;vrinflux&lt;/a&gt; who put their results on Github for everyone to use. I liked their solution but I wanted something not as tightly coupled with the vive and that would support more than just two controllers. I am also not too fond of the cursor they used in their project. What I had in mind was more in the line of how the steam VR overlay did things, using a sort of laser pointer as a visual guide.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2016-06-vrgui/steamvr-750x400.jpg&quot; /&gt;
		
		&lt;p&gt;SteamVR Steam overlay.&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;LaserPointerInputModule&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
This is the actual Unity Input Module. It handles GUI interaction and lets &lt;em&gt;IUILaserPointerControllers&lt;/em&gt; know if they enter or exit a GUI element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;IUILaserPointerControllers&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
Is the abstract base class for all controllers that want to interact with &lt;em&gt;LaserPointerInputModule&lt;/em&gt;. Concrete classes have to provide an implementation for button up and down functions. The class also handles the actual laser pointer visualization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;ViveUILaserPointerController&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
Is the (currently) only concrete implementation of the laser pointer controller. It uses the haptic pulse feature of the Vive controllers to let the user know whenever he enters a new GUI element.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;
    &lt;div class=&quot;inline-image&quot; style=&quot;display: block;&quot;&gt;&lt;div class=&quot;video-container&quot;&gt;
        &lt;iframe src=&quot;https://www.youtube.com/embed/mD16LejMc9A&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;
        &lt;/div&gt;      
        &lt;p&gt;Here you see the current state of the project.&lt;/p&gt;
    &lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;You can check it out on Github:&lt;/p&gt;

&lt;div class=&quot;github-card&quot; id=&quot;repo-wacki-Unity-VRInputModule&quot;&gt;
	&lt;div class=&quot;header&quot;&gt;
		&lt;span class=&quot;octicon octicon-repo&quot;&gt;&lt;/span&gt;
		&lt;span class=&quot;repo-name&quot;&gt;
			&lt;span class=&quot;author&quot;&gt;&lt;a href=&quot;https://github.com/wacki&quot; class=&quot;url fn&quot; itemprop=&quot;url&quot; rel=&quot;author&quot; target=&quot;_blank&quot;&gt;&lt;span itemprop=&quot;title&quot;&gt;wacki&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;
			&lt;span class=&quot;path-divider&quot;&gt;/&lt;/span&gt;
			&lt;strong&gt;&lt;a href=&quot;https://github.com/wacki/Unity-VRInputModule&quot; data-pjax=&quot;#js-repo-pjax-container&quot; target=&quot;_blank&quot;&gt;Unity-VRInputModule&lt;/a&gt;&lt;/strong&gt;
		&lt;/span&gt;
	&lt;/div&gt;
	&lt;div class=&quot;footer&quot;&gt;&lt;span class=&quot;status&quot;&gt;&lt;strong class=&quot;fork-count&quot;&gt;0&lt;/strong&gt;Forks&lt;/span&gt;&lt;span class=&quot;status&quot;&gt;&lt;strong class=&quot;star-count&quot;&gt;0&lt;/strong&gt;Stars&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
 $(function () {
	$.ajax({
	   url: &apos;https://api.github.com/repos/wacki/Unity-VRInputModule&apos;,
	   success: function(data) {		
		$(&apos;div[id=&quot;repo-wacki-Unity-VRInputModule&quot;] .fork-count&apos;).html(data.forks_count);
		$(&apos;div[id=&quot;repo-wacki-Unity-VRInputModule&quot;] .star-count&apos;).html(data.stargazers_count);
	   }	   
	});
	});
&lt;/script&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;I am pleased with the current state of this project. The only thing I’d like to change whenever I get the time is the laser pointer visualization. Currently the &lt;em&gt;IUILaserPointerController&lt;/em&gt; handles the visualization of the laser pointer. I do this mostly because I require the &lt;em&gt;LaserPointerInputModule&lt;/em&gt; to tell me the results of GUI raycasts and this way I can just do it all at one point. It would be much better though if I could have a self contained laser pointer visualization component that can do GUI raycasts without having to rely on an Input module. It shouldn’t be that big of an issue actually and when I get the time to do it I’ll update the project.&lt;/p&gt;

</description>
        <pubDate>Sat, 04 Jun 2016 07:00:00 +0000</pubDate>
        <link>http://wacki.me/blog/2016/06/vr-gui-input-module-for-unity-htc-vive/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2016/06/vr-gui-input-module-for-unity-htc-vive/</guid>
        
        
        <category>gamedev</category>
        
        <category>unity</category>
        
        <category>vr</category>
        
        <category>vive</category>
        
      </item>
    
      <item>
        <title>Creating sand footprints in Unreal Engine 4</title>
        <description>&lt;p&gt;I wanted to keep with the theme from my last post and do something with sand again. My rough goal was to use Unreal Engine 4’s (UE4) third person template and enable the character to leave footprints in the sand. I used this to look at blueprints, particle systems, materials and finally working with C++ in UE4. The “finished” project can be found on github, a link is included at the bottom of the post.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/result.png&quot; /&gt;
		
		&lt;p&gt;The final look of the terrain material and footprint effects&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The first step when starting something new and unfamiliar is to always look for similar examples. While doing that I stumbled on &lt;a href=&quot;https://www.youtube.com/watch?v=JI84nFuLMSo&quot;&gt;this&lt;/a&gt; tutorial series by Kodi Myatt. It is a four part video tutorial about creating footprints in UE4, exactly what I need. The tutorial seems to be on hiatus at the moment, but the first video has quite enough information to get me started.&lt;/p&gt;

&lt;p&gt;I found the best way to develop something in 3D space is to visualize every step of the way. But first we need to figure out when something has to be drawn. So let’s find a way to get a message on screen whenever the character’s feet touch the ground. This is actually quite simple in UE4. All we have to do is add a custom AnimNotify to the animation blueprint at the timestamps where a foot touches the ground.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/add_notify.png&quot; /&gt;
		
		&lt;p&gt;Adding custom AnimNotify to the third person character&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;We can now use these notify events in the graph of the animation blueprint to do something. For now we’ll print the string “left” and “right” based on which foot hit the ground to see if it works.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/anim_notify_print.png&quot; /&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;I made progress with my own footprints by using a ray shoot, or rather line trace as UE4 calls it. I am able to figure out where on the terrain a foot “hit” the ground. I then spawn a decal actor using the floors orientation at that point to display any texture I want.&lt;/p&gt;

&lt;p&gt;Instead of printing a message we will shoot a ray from the foot’s position downward to find out where on our terrain we have to draw a footprint. This ray shoot or rather line trace as it is called in UE4 also returns the surface normal of where we hit the ground. Using the normal and location we can position a decal actor and orient it to match the floor. All that is left now is to create the actual decal to look like a footprint. Let’s dust off Blender and try to create a footprint.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/blender_footprint.png&quot; /&gt;
		
		&lt;p&gt;Blender footprint model&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;This looks good enough for now I think, a bit too artificial for my taste but we can always come back later and change it.&lt;/p&gt;

&lt;p&gt;Back in UE4 we create a new deferred decal material and use the baked normal and displacement maps from blender to achieve a sense of depth.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/decal_grey_floor.png&quot; /&gt;
		
		&lt;p&gt;Decal on default grey floor&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;The decal seems to work on the grey flat floor, but what about actual sand terrain? Let’s dive a little deeper into the material editor and create a desert material for testing purposes. We can use some of the assets from Epic’s vehicle example which already has good quality sand textures.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/landscape_material.png&quot; /&gt;
		
		&lt;p&gt;Sand material graph&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;The decal looks too smooth on this new terrain, we have to add some sand grains to it as well so it will blend in a little better with the rest of the terrain.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/decal_detail_normal.png&quot; /&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;rambling-box&quot;&gt;
	&lt;img src=&quot;/assets/posts/images/2015-12-footprints/overlapping.png&quot; style=&quot;width: 18%; float: left;margin: 4px 22px 0px 0px; border:1px solid #0CA0D7;&quot; /&gt;
	
	A big problem when using this decal method is overlapping footprints. It looks really fake when this happens. It might be possible to mitigate the effect through some blending technique, however a more interesting approach might be to use an additional height map. The game Journey has a great sand simulation where you can slide down hills and leave a trail behind. They used additional detail height maps that reacted to players foot prints on top of the terrain (&lt;a href=&quot;http://www.thatgamecompany.com/forum/viewtopic.php?p=11191#p11191&quot;&gt;source&lt;/a&gt;). I guess tessellation for certain ground types like sand and snow might in fact be the ideal solution and I definitely want to come back to this topic at some point in time.
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;We still have a problem: our decals never go away. It would be great if the decals could handle their lifetime themselves and get deleted automatically. We can do this by creating a new blueprint that inherits from DecalActor. In the graph of this blueprint we define a life time and fade out time. Using these values we can then slowly fade out the actor before removing it completely. The fade out works by manipulating a fade parameter in the decal material.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/fooprint_decal_bp.png&quot; /&gt;
		
		&lt;p&gt;Custom DecalActor that fades out after a while&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Finally I want to add a little sand kick up effect whenever a foot touches the ground. This is a job for a particle system. We can create a new particle system by right clicking in the content browser. Double clicking the effect opens up Cascade, which is UE4’s particle system editor. The UI looks a bit overwhelming at first, but it is actually laid out quite logically. Basically we can stack multiple emitters on top of each other in the emitters window. Each emitter has a range of different modules that can be added or removed, such as lifetime, velocity control or acceleration. These modules can further be controlled by editing them in the details panel or use an animation curve to control their values.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/particle_system.png&quot; /&gt;
		
		&lt;p&gt;Simple sand kick up effect using Cascade&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Let’s see the effect in action by adding it to our decal spawning blueprint.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/bad_decal_color.png&quot; /&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;It is working, but the color doesn’t match the terrain at the moment. This is because I used height based coloring for the terrain to give the sand some variety in color. We have to apply the same coloring system to our particle effect material. This is a great excuse to use material property collections. These collections are just what the name suggest, a collection of properties for a material, like our height color values. We can then use these collections inside our materials and only have to change the values in one place to affect them all.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/material_property_collection.png&quot; /&gt;
		
		&lt;p&gt;Material property collection&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;The blueprint prototype is working properly, everything looks good, we can now go ahead and port some of the functionality to C++. This might not really be necessary in this case but the point is to get a feel for the workflow for future projects.&lt;/p&gt;

&lt;p&gt;We start by adding a foot down function to our third person character which will get called instead of our current blueprint function.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;nl&quot;&gt;protected:&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Trace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FHitResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OutHit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UFUNCTION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BlueprintCallable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Character&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootDown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UArrowComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootArrow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then, in the implementation of the functions, we’re going to just display the surface normal to get something on screen again.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AFootprintsCharacter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Trace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FHitResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OutHit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;20.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;End&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;20.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;//Re-initialize hit info&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;OutHit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FHitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForceInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;FCollisionQueryParams&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TraceParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TEXT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Footprint trace&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;TraceParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bReturnPhysicalMaterial&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LineTraceSingleByChannel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutHit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;End&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ECC_Visibility&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TraceParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AFootprintsCharacter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FootDown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UArrowComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootArrow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FHitResult&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootWorldPosition&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootArrow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetComponentTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetLocation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;Trace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootWorldPosition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;    

    &lt;span class=&quot;c1&quot;&gt;// Debug vis&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DrawDebugLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Normal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;100.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FColor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Blue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;10.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/normals_on_sand.png&quot; /&gt;
		
		&lt;p&gt;Result of the code above&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;The basics seem to be working again so all that is left is to spawn our decal and particle effect. Let’s go a bit further than the blueprint version however, how about we spawn a different effect based on the ground type that we hit? We can create a custom data asset to hold our effect references per surface type. To determine surface type we use the Physical Material present on a material.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-12-footprints/footprint_types_data_asset.png&quot; /&gt;
		
		&lt;p&gt;Custom data asset for defining footprint effects based on ground type&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Using this data asset we are now able to query the current physical material of the ground and select the correct decal and particle effect to display. All we need to do to support a new ground type is to create a specific effect and add it to the list.&lt;/p&gt;

&lt;p&gt;Updated FootDown function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AFootprintsCharacter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FootDown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UArrowComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootArrow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FHitResult&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootWorldPosition&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootArrow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetComponentTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetLocation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Forward&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootArrow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetForwardVector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;Trace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootWorldPosition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;    
    &lt;span class=&quot;n&quot;&gt;UPhysicalMaterial&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PhysMat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PhysMaterial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Retrieve the particle system and decal object to spawn for our current ground type&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UParticleSystem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParticleFX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootprintTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetFootprintFX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PhysMat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;TSubclassOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ADecalActor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Decal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FootprintTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetFootprintDecal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PhysMat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        
    &lt;span class=&quot;c1&quot;&gt;// Create a rotator using the landscape normal and our foot forward vectors&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Note that we use the function ZX to enforce the normal direction (Z)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FQuat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;floorRot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FRotationMatrix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MakeFromZX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ToQuat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FQuat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offsetRot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FRotator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;90.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FRotator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rotation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;floorRot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offsetRot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Rotator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Spawn decal and particle emitter&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Decal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;AActor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DecalInstance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SpawnActor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Decal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Rotation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParticleFX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;UGameplayStatics&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SpawnEmitterAtLocation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetWorld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParticleFX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HitResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Of course if you’d like to see the rest of the source code or try the project for yourself you can get everything on github:&lt;/p&gt;

&lt;div class=&quot;github-card&quot; id=&quot;repo-wacki-UE4-footprints&quot;&gt;
	&lt;div class=&quot;header&quot;&gt;
		&lt;span class=&quot;octicon octicon-repo&quot;&gt;&lt;/span&gt;
		&lt;span class=&quot;repo-name&quot;&gt;
			&lt;span class=&quot;author&quot;&gt;&lt;a href=&quot;https://github.com/wacki&quot; class=&quot;url fn&quot; itemprop=&quot;url&quot; rel=&quot;author&quot; target=&quot;_blank&quot;&gt;&lt;span itemprop=&quot;title&quot;&gt;wacki&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;
			&lt;span class=&quot;path-divider&quot;&gt;/&lt;/span&gt;
			&lt;strong&gt;&lt;a href=&quot;https://github.com/wacki/UE4-footprints&quot; data-pjax=&quot;#js-repo-pjax-container&quot; target=&quot;_blank&quot;&gt;UE4-footprints&lt;/a&gt;&lt;/strong&gt;
		&lt;/span&gt;
	&lt;/div&gt;
	&lt;div class=&quot;footer&quot;&gt;&lt;span class=&quot;status&quot;&gt;&lt;strong class=&quot;fork-count&quot;&gt;0&lt;/strong&gt;Forks&lt;/span&gt;&lt;span class=&quot;status&quot;&gt;&lt;strong class=&quot;star-count&quot;&gt;0&lt;/strong&gt;Stars&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
 $(function () {
	$.ajax({
	   url: &apos;https://api.github.com/repos/wacki/UE4-footprints&apos;,
	   success: function(data) {		
		$(&apos;div[id=&quot;repo-wacki-UE4-footprints&quot;] .fork-count&apos;).html(data.forks_count);
		$(&apos;div[id=&quot;repo-wacki-UE4-footprints&quot;] .star-count&apos;).html(data.stargazers_count);
	   }	   
	});
	});
&lt;/script&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot; style=&quot;display: block;&quot;&gt;&lt;div class=&quot;video-container&quot;&gt;
		&lt;iframe src=&quot;https://www.youtube.com/embed/SiXxQkc0xMc&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;
		&lt;/div&gt;
		&lt;p&gt;Video of the finished project&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;
</description>
        <pubDate>Sun, 13 Dec 2015 15:13:00 +0000</pubDate>
        <link>http://wacki.me/blog/2015/12/creating-sand-footprints-in-unreal-engine-4/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2015/12/creating-sand-footprints-in-unreal-engine-4/</guid>
        
        
        <category>gamedev</category>
        
        <category>ue4</category>
        
      </item>
    
      <item>
        <title>Using World Machine to create natural looking terrain</title>
        <description>&lt;p&gt;Here it is, the first real post of the blog and already I’m doing something only somewhat related to my main goal, which is learning UE4. I have a game in mind and I’m not going to go into too much detail here, but basically you’re controlling a large vehicle in a desert environment. Well I thought I could try and create small parts of the game as a way to learn how to use the engine. Another idea would be to recreate a simple arcade game like Space Invaders. I might still do that later on but for now I am interested in the topic of terrains. 
&lt;!--more--&gt;
Terrains in UE4 seem to be a big selling point since they released the &lt;a href=&quot;https://www.youtube.com/watch?v=0zjPiGVSnfI&quot;&gt;kite demo&lt;/a&gt;. And their results speak for themselves. So after doing some research I found out that Epic used &lt;a href=&quot;http://www.world-machine.com/&quot;&gt;World Machine&lt;/a&gt; for an errosion pass over their heightmaps to achieve a natural look. This is why I figured World Machine would be a good starting point for me. Luckily there is a trial version of World Machine to play around with.&lt;/p&gt;

&lt;p&gt;After opening up World Machine for the first time it seemed instantly familiar to me. This is because back when I started to learn openGL, some of my first projects involved procedural terrain generation. And although not being anywhere near of what World Machine can do, the basics are the same. Generate and combine some different noises and run a few erosion passes on it.
After playing around with World Machine for a while I decided to try and create a few simple sand dunes for now and then move on to something different. Below you can see my current state.&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-11-worldmachine/wmdunes.png&quot; /&gt;
		
		&lt;p&gt;This is what I came up with after some trial and error in world-machine&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;
	&lt;div class=&quot;inline-image&quot;&gt;
		&lt;img src=&quot;/assets/posts/images/2015-11-worldmachine/ue4dunes.png&quot; /&gt;
		
		&lt;p&gt;This is what it looks like inside UE4&lt;/p&gt;
		
	&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;While looking for terrain examples and stuff other people had done, I stumbled upon &lt;a href=&quot;http://www.planetside.co.uk/forums/index.php?action=dlattach;topic=18400.0;attach=50771;image&quot;&gt;this&lt;/a&gt; (&lt;a href=&quot;http://www.planetside.co.uk/forums/index.php?topic=18400.0&quot;&gt;source&lt;/a&gt;). which is much more in the vein of what I want my dunes to look. When I revisit this topic I’m going to use this as a resource. For now I’m happy to have the basics of World Machine down and will move on to other topics.&lt;/p&gt;
</description>
        <pubDate>Sun, 29 Nov 2015 20:20:02 +0000</pubDate>
        <link>http://wacki.me/blog/2015/11/using-world-machine-to-create-natural-terrain/</link>
        <guid isPermaLink="true">http://wacki.me/blog/2015/11/using-world-machine-to-create-natural-terrain/</guid>
        
        
        <category>gamedev</category>
        
        <category>ue4</category>
        
        <category>terrain</category>
        
      </item>
    
  </channel>
</rss>
