{"id":580,"date":"2019-01-29T21:15:02","date_gmt":"2019-01-29T21:15:02","guid":{"rendered":"http:\/\/oneiricworlds.com\/en\/?p=580"},"modified":"2019-01-29T21:18:06","modified_gmt":"2019-01-29T21:18:06","slug":"cartoonish-foam-using-procedural-hand-made-textures","status":"publish","type":"post","link":"https:\/\/oneiricworlds.com\/en\/2019\/01\/cartoonish-foam-using-procedural-hand-made-textures\/","title":{"rendered":"Semi-procedural foam shader"},"content":{"rendered":"<p>Hello everyone,<\/p>\n<p>It&#8217;s been a long time since I last posted a technical tutorial, so finally, here&#8217;s a new one. This one will tackle the problem of creating procedural foam for my game. I&#8217;ll try to explain my thinking process and the different choices I&#8217;ve made to create this:<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_finalMixing.gif\" rel=\"attachment wp-att-642\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-642\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_finalMixing.gif\" alt=\"20190114_finalMixing\" width=\"596\" height=\"373\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>The final foam rendering in my game.<\/em><\/p>\n<p>Here, I use Unity as a game engine, Blender for modeling and texturing, and Krita to paint textures.<\/p>\n<h3>I &#8211; Problem<\/h3>\n<p>My\u00a0game takes place in an ocean-covered world, so having foam on the shores seems necessary. My biggest problem here is that my game is still being modified and island shapes may change or new islands may appear. So, I want to find a way to create foam easily and fast enough.<\/p>\n<p>Moreover, I may change the designs many times for a single island, and I don&#8217;t want to have to re-create foam meshes from scratch\u00a0every\u00a0time.<\/p>\n<p>&nbsp;<\/p>\n<p>A while ago, some friends pointed to me the <a href=\"https:\/\/www.youtube.com\/watch?v=fwKQyDZ4ark\" target=\"_blank\">Rime VFX breakdown video<\/a> by Simon Tr\u00fcmpler. There are many incredible tricks in this one. The foam in particular is very well crafted, and the effect is stunning (as long as you go for a stylized rendering of course).<\/p>\n<p>The only problem I saw with this approach is that it is a bit daunting to create seamless uv maps for each foam mesh. Indeed, in Blender, when you want a ring\/circular mesh to have a seamless mapping, you need to\u00a0 perfectly align\u00a0manually the uvmap so that the image repeats itself without breaking the pattern. It&#8217;s OK for a single asset, but for many unique islands and rocks in my game, it&#8217;s more than I can handle. In addition, with cyclic seamless uv mapping, if you need to tweek the wave length afterwards, you can&#8217;t scale texture coordinates as you want; you are limited to integer multiples. I have to find something else.<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_scalingUV.gif\" rel=\"attachment wp-att-591\"><img decoding=\"async\" class=\"size-large wp-image-591 aligncenter\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_scalingUV.gif\" alt=\"20190113_scalingUV\" width=\"800\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Process of scaling uv map to get rid of the seam. Perfectly matching both sides of the seam\u00a0can be quite long for many assets.<\/em><\/p>\n<h3>II &#8211; What I want<\/h3>\n<p>Ideally, I aim at:<\/p>\n<ul>\n<li>An easy way to create foam in Blender, with as few clicks as possible. Ideally, I would like to only handle modeling, and no uv-mapping at all.<\/li>\n<li>Having moving waves without (too) obvious repeating pattern<\/li>\n<li>Easy parameter tweaks in order to change wave length, speed, or look.<\/li>\n<li>Graphically, as I use deferred shading which is not very transparency-friendly, I want a pure colored foam with some sharp edges. So I&#8217;ll use clipping based on texture values. Here&#8217;s what I&#8217;ll try to achieve:<\/li>\n<\/ul>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamGoal2.jpg\" rel=\"attachment wp-att-606\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-606 aligncenter\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamGoal2.jpg\" alt=\"20190113_foamGoal2\" width=\"512\" height=\"512\" srcset=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamGoal2.jpg 1024w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamGoal2-150x150.jpg 150w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamGoal2-300x300.jpg 300w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamGoal2-768x768.jpg 768w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/a><\/p>\n<h3>III &#8211; Base texture with\u00a0world coordinates<\/h3>\n<p>As usual, my approach is far from perfect and is only a compromise between what matters to me and what is technically reachable (to me too :p).<\/p>\n<p>My first idea was to use automatic uv coordinates, such as vertex world coordinates, which works pretty well\u00a0for my procedural terrain mapping (which I might explain too one day, hopefully). However, world coordinates do not embed any kind of information about an hypothetical &#8220;privileged&#8221; direction.<\/p>\n<p>This means I can&#8217;t have a &#8220;classical&#8221; foam texture with &#8220;lines&#8221; along the shore edge like the one below, because it would be OK on some sides of an island, but not on the other sides:<\/p>\n<div style=\"text-align: center;\"><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoam.jpg\" rel=\"attachment wp-att-596\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-596\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoam.jpg\" alt=\"uvFoam\" width=\"256\" height=\"256\" srcset=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoam.jpg 1024w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoam-150x150.jpg 150w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoam-300x300.jpg 300w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoam-768x768.jpg 768w\" sizes=\"auto, (max-width: 256px) 100vw, 256px\" \/><\/a> <a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamWorldCoordsUnity.jpg\" rel=\"attachment wp-att-598\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-598\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamWorldCoordsUnity.jpg\" alt=\"20190113_foamWorldCoordsUnity\" width=\"540\" height=\"403\" \/><\/a><\/div>\n<p style=\"text-align: center;\"><em>In this texture there is a strong global direction (horizontal). The corresponding\u00a0ingame look with world coordinates doesn&#8217;t work.<\/em><\/p>\n<p>When I use automatic mapping, I must have some neutral\/uniform texture (direction wise) for example something like this:<\/p>\n<div style=\"text-align: center;\"><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoamWorld.jpg\" rel=\"attachment wp-att-597\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-597\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoamWorld.jpg\" alt=\"uvFoamWorld\" width=\"256\" height=\"256\" srcset=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoamWorld.jpg 1024w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoamWorld-150x150.jpg 150w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoamWorld-300x300.jpg 300w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/uvFoamWorld-768x768.jpg 768w\" sizes=\"auto, (max-width: 256px) 100vw, 256px\" \/><\/a> <a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamWorldCoordsUnityBetter.jpg\" rel=\"attachment wp-att-599\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-599\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamWorldCoordsUnityBetter.jpg\" alt=\"20190113_foamWorldCoordsUnityBetter\" width=\"540\" height=\"403\" \/><\/a><\/div>\n<p style=\"text-align: center;\"><em>A simple foam texture with no\u00a0main direction. The corresponding\u00a0ingame look \u00a0is a\u00a0bit better&#8230;<\/em><\/p>\n<p>OK, this is better, but it&#8217;s still a bit stiff and disappointing, but that&#8217;s the price to pay for an automatic method.\u00a0Anyways, it doesn&#8217;t seem to be enough to get visually interesting foam.<\/p>\n<h3>IV &#8211; Adding procedural\u00a0\u00a0waves from v coordinate<\/h3>\n<p>Now, if I want some lines along the shore, or the foam moving towards (or away from) the shore, it is\u00a0absolutely mandatory that I have an additional &#8220;direction&#8221; information embedded in the mesh. This is also necessary to make the foam &#8220;vanish&#8221; when it is far away from the shore. This specific direction changes for each rendered triangle, so I need to encapsulate it in a way or another\u00a0on\u00a0the mesh vertices.<\/p>\n<p>Thus, I guess I still need to use a basic uv mapping to specify this &#8220;shore direction&#8221;. To achieve this, I only need 1 texture coordinate, which I choose to set to v (see picture below). The idea is to have <strong>v<\/strong>=0 on the outer edge loop of the foam (the &#8220;sea side&#8221;), <strong>v<\/strong> = 1 on the\u00a0middle edge loop of the foam (the &#8220;ground side&#8221;), and <strong>v<\/strong> = 2 for the edge loop that will be &#8220;inside&#8221; the island.<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamVMapping2.jpg\" rel=\"attachment wp-att-608\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-608\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamVMapping2-1024x428.jpg\" alt=\"20190113_foamVMapping2\" width=\"840\" height=\"351\" srcset=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamVMapping2-1024x428.jpg 1024w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamVMapping2-300x125.jpg 300w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamVMapping2-768x321.jpg 768w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamVMapping2-1200x502.jpg 1200w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_foamVMapping2.jpg 1299w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>The basic texture mapping. Here I don&#8217;t really care about the seam problem (you can see it at the bottom of the mesh). I only work on the <strong>v<\/strong> coordinate.<\/em><\/p>\n<p>So the movement towards or away from the shore will be built from this simple texture coordinate. The easiest way to create the famous &#8220;foam lines&#8221; is so use a <strong>sinus<\/strong> of <strong>v<\/strong>.\u00a0To make it move, I offset it depending on the current <strong>time<\/strong> and the wave <strong>speed<\/strong>.<\/p>\n<div style=\"text-align: center;\"><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinus.jpg\" rel=\"attachment wp-att-671\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-671\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinus-300x300.jpg\" alt=\"20190116_sinus\" width=\"300\" height=\"300\" srcset=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinus-300x300.jpg 300w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinus-150x150.jpg 150w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinus.jpg 512w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a> <a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_movingSinus.gif\" rel=\"attachment wp-att-615\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-615\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_movingSinus.gif\" alt=\"20190113_movingSinus\" width=\"488\" height=\"356\" \/><\/a><\/div>\n<p style=\"text-align: center;\"><em><strong>sinus(frequency*v + speed*time)<\/strong> ; <strong>clipped<\/strong> at 0<\/em><\/p>\n<p>Keep in mind that, in order to get sharp edges, I clip any fragment\u00a0value below a certain threshold.<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_movingSinusLoweredThresholdChange.gif\" rel=\"attachment wp-att-619\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-619\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_movingSinusLoweredThresholdChange.gif\" alt=\"20190114_movingSinusLoweredThresholdChange\" width=\"596\" height=\"373\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Changing the <strong>clipping<\/strong> threshold creates larger or smaller waves<\/em><\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_sinusGlobalFrequencyChangePrinciple.gif\" rel=\"attachment wp-att-630\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-630\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_sinusGlobalFrequencyChangePrinciple.gif\" alt=\"20190114_sinusGlobalFrequencyChangePrinciple\" width=\"596\" height=\"373\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Changing the\u00a0<strong>frequency<\/strong> creates more or less waves<\/em><\/p>\n<p>Now if I want the sinus foam to wash away as it enters the sea, I need to raise the <strong>sinus\u00a0<\/strong>according to the <strong>v<\/strong> coordinate, like this for example:<\/p>\n<div style=\"text-align: center;\"><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinusPlusV.jpg\" rel=\"attachment wp-att-665\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-665\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinusPlusV-300x300.jpg\" alt=\"20190116_sinusPlusV\" width=\"300\" height=\"300\" srcset=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinusPlusV-300x300.jpg 300w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinusPlusV-150x150.jpg 150w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190116_sinusPlusV.jpg 512w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a> <a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_movingSinusLowered.gif\" rel=\"attachment wp-att-616\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-616\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_movingSinusLowered.gif\" alt=\"20190113_movingSinusLowered\" width=\"488\" height=\"356\" \/><\/a><\/div>\n<p style=\"text-align: center;\"><em><strong>sinus(frequency*v + speed*time)+v<\/strong> ; <strong>clipped<\/strong> at a good threshold <strong>t<\/strong>. Waves get thinner as they vanish in the sea<\/em><\/p>\n<p>Now let&#8217;s have fun a little bit by adding noise to this initial shader, in order to make it more &#8220;natural&#8221;. As a noise-based texture, I use a simple RGB seamless noise texture that I made with GIMP using the &#8220;solid noise&#8221; generator:<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/tileable2DWave.png\" rel=\"attachment wp-att-715\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-715 aligncenter\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/tileable2DWave.png\" alt=\"tileable2DWave\" width=\"256\" height=\"256\" srcset=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/tileable2DWave.png 256w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/tileable2DWave-150x150.png 150w\" sizes=\"auto, (max-width: 256px) 100vw, 256px\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Seamless noise made with GIMP.<\/em><\/p>\n<p>From this, I can randomize the <strong>speed,<\/strong>\u00a0the <strong>frequency<\/strong>\u00a0or any other parameter of the sinus. Randomizing the <strong>frequency<\/strong> is quite interesting; it is a way to locally add more or less wave lines like this:<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_movingSinusLoweredFrequencyChange.gif\" rel=\"attachment wp-att-617\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-617\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190113_movingSinusLoweredFrequencyChange.gif\" alt=\"20190113_movingSinusLoweredFrequencyChange\" width=\"588\" height=\"356\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Adding (world) noise to frequency: <strong>sinus((frequency+noise(xz))*v + speed*time)+v;<\/strong>\u00a0where\u00a0<strong>xz<\/strong> are the world horizontal coordinates. See how some zones get more foam lines, while other zones get fewer.<\/em><\/p>\n<p>The generated sinus part seems\u00a0to work quite OK, but I think it still misses some &#8220;connections&#8221; betweens the foam lines, and, to add them, I need to rely on\u00a0world coordinates. I could use world noise to add these connections, but I wanted to try a more controled approach by using my handmade texture on top of it.<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_movingSinusLoweredPlusBaseTex.gif\" rel=\"attachment wp-att-620\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-620\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_movingSinusLoweredPlusBaseTex.gif\" alt=\"20190114_movingSinusLoweredPlusBaseTex\" width=\"596\" height=\"373\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Mixing the sinus procedural waves and the hand painted texture.<\/em><\/p>\n<p>But if I use a pure binary texture for foam connection on top of the generated sinus waves, I have no control at all on the &#8220;vanishing&#8221; of this texture. That&#8217;s why I chose to use a distance transform texture.<\/p>\n<h3>V &#8211; Distance transform textures<\/h3>\n<p>Distance transform images are created from a pure black or white base pattern. Each pixel of the distance transform image represents the distance to the nearest white pixel in the base pattern, like this:<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_distanceTransformExplained.jpg\" rel=\"attachment wp-att-625\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-625\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_distanceTransformExplained-1024x608.jpg\" alt=\"20190114_distanceTransformExplained\" width=\"840\" height=\"499\" srcset=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_distanceTransformExplained-1024x608.jpg 1024w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_distanceTransformExplained-300x178.jpg 300w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_distanceTransformExplained-768x456.jpg 768w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_distanceTransformExplained-1200x712.jpg 1200w, https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_distanceTransformExplained.jpg 2048w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Well, actually, I used an inverted distance transform here, because it&#8217;s more convenient for the clipping phase, but you get the idea \ud83d\ude09 And yes, I used a different pattern than the previous one.<\/em><\/p>\n<p>Distance transform images are just a way of seeing the data. You might also interpret it as a height map (even if the meaning is slightly different, it might help to grasp the concept). The basic idea is to have an image that embeds some kind of &#8220;evolution\/animation&#8221; of the base pattern.<\/p>\n<p>Distance transform images may be generated through filters, but generally, these filters don&#8217;t handle very well (or even not at all) seamless images. Another way is to paint some pseudo distance transform image directly. Of course, it won&#8217;t be mathematically accurate, but\u00a0as a benefit, we can create more custom animation patterns. An acceptable way I found, is to use the unusual following settings in Krita, (the painting software I use):<\/p>\n<ul>\n<li>Use a &#8220;Build-up&#8221; painting mode (vs Wash by default), so that you can intersect the current stroke properly<\/li>\n<li>Use the\u00a0&#8220;Greater&#8221; brush fusion mode, so that only higher values will be drawn on top of what is already drawn (which is the correct way that real distance transform images are merged together)<\/li>\n<li>Use a soft brush with a linear falloff from 100% to 0%, so that the\u00a0maximum value range is used, which will result in smoother animations. Actually, the falloff will act as an &#8220;ease in\/ease out&#8221; parameter for the animation.<\/li>\n<li>No pressure sensitivity (well, I guess this is personal choice)<\/li>\n<li>Activate the &#8220;Wrap Around&#8221; mode to create seamless textures (as\u00a0I paint a lot of\u00a0textures, this is my favorite option in Krita).<\/li>\n<\/ul>\n<p>which results in this:<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_drawingDistanceTransform.gif\" rel=\"attachment wp-att-633\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-633\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_drawingDistanceTransform.gif\" alt=\"20190114_drawingDistanceTransform\" width=\"596\" height=\"373\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Directly painting a seamless distance transform texture.\u00a0Notice the &#8220;X&#8221;\u00a0pattern appearing on the intersection, this is typical of a distance transform image.<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>Of course, this is a very &#8220;mathematical&#8221; way of approaching this idea. You can always draw with the default soft brush and get something totally OK (even more natural I think), but you have to always keep in mind that you are &#8220;painting an animation&#8221; (never thought I\u00a0would\u00a0say that one day).<\/p>\n<h3>VI &#8211; Tweaking and mixing<\/h3>\n<p>Now, I have more control on the rendering of my hand painted foam texture:<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_movingFoamThreshold2.gif\" rel=\"attachment wp-att-624\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-624\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_movingFoamThreshold2.gif\" alt=\"20190114_movingFoamThreshold2\" width=\"596\" height=\"373\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em><strong>tex(xz)<\/strong>; <strong>clipped<\/strong> at a certain threshold <strong>t<\/strong>; Now I can control the width of the pattern by changing the clipping threshold for my hand painted foam texture.<\/em><\/p>\n<p>Of course, I used a few tricks to make it more interesting:<\/p>\n<ul>\n<li>Adding the <strong>v<\/strong> coordinate (to make foam larger near the shore and thinner on the seaside), just like for the sinus waves<\/li>\n<li>A speed\u00a0parameter <strong>texSpeed\u00a0<\/strong>to make the texture move slowly<\/li>\n<li>A bit of world coordinate moving <strong>noise<\/strong> to create some &#8220;warping&#8221; effect<\/li>\n<\/ul>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_finalHandMadeFoam.gif\" rel=\"attachment wp-att-647\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-647\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_finalHandMadeFoam.gif\" alt=\"20190114_finalHandMadeFoam\" width=\"596\" height=\"373\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><strong><em>tex(xz + noise(xz+noiseSpeed*time)+texSpeed*time)+v<\/em><\/strong><em>;<\/em><strong><em> clipped <\/em><\/strong><em>at<\/em><strong><em> t<\/em><\/strong><\/p>\n<p>And, now, I can finally mix both the procedural sinus waves, and my hand drawn foam. After a few tweaks on threshold, speeds, noises, and other parameters, I ended up with this:<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_finalMixing.gif\" rel=\"attachment wp-att-642\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-642\" src=\"https:\/\/oneiricworlds.com\/en\/wp-content\/uploads\/2019\/01\/20190114_finalMixing.gif\" alt=\"20190114_finalMixing\" width=\"596\" height=\"373\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>The final result mixing procedural and hand drawn foam:<br \/>\n<strong>ratioSinus * [sinus((frequency+noise(xz))*v + speed*time)+v] +<br \/>\nratioTex * [tex(xz + noise(xz+noiseSpeed*time)+texSpeed*time)+v];<br \/>\nclipped <\/strong>at<strong> t<\/strong>.<\/em><\/p>\n<p>In the end, I also added a few parameters to control the noise amplitudes and scales\/frequencies, so each <strong>noise(xz&#8230;)<\/strong> is in reality <strong>noiseAmplitude*noise(noiseScale*xz&#8230;)<\/strong>. This\u00a0gives more control on all the deformations happening. I also replaced the simple &#8220;<strong>+v<\/strong>&#8221; with\u00a0the more versatile affine fonction &#8220;<strong>+a*v+b<\/strong>&#8220;.<\/p>\n<h3>VII &#8211; Building in Blender<\/h3>\n<p>So in the end, I still have to make a uv mapping (or more exactly a v mapping). But the good news about this is that I only have to make it <strong>ONCE<\/strong> for <strong>ALL<\/strong> the game. Indeed, for any new island (or any immersed object), I can copy a base foam mesh already v\u00a0mapped, and I can focus on modifying only the mesh:<\/p>\n<ul>\n<li>If I move vertices, the mapping will still be OK.<\/li>\n<li>If I delete an edge line, the neighbour v mapping won&#8217;t be affected<\/li>\n<li>If I add vertices with a loop cut, the uv mapping for the new vertices will be automatically interpolated from their neighbours, resulting in a good v coordinate.<\/li>\n<\/ul>\n<p>This would not have been the case if I had used the u coordinate to make more classical texture mapping, because any\u00a0 move of vertices\u00a0along the shore\u00a0edge would have stretched the texture (and I would have had the seam problem for each new island).<\/p>\n<h3>VIII &#8211; Going further<\/h3>\n<p>We\u00a0could go even further by working on the following points:<\/p>\n<ul>\n<li>Layering\u00a0two or more hand painted foam textures, with different speeds and scales to create a unique pattern everywhere.<\/li>\n<li>Randomizing the sinus speed to have local flow variations<\/li>\n<li>Adding noise to the threshold or to the affine function part (&#8220;<strong>+v<\/strong>&#8220;\/&#8221;<strong>+a*v+b<\/strong>&#8220;) so that some zones would have foam on a very short or very long distance<\/li>\n<li>Randomizing the world coordinates to create even more warping effect<\/li>\n<li>Put the time offset through a sinus to make waves come and go. Right now they only go away from the shore.<\/li>\n<\/ul>\n<p>By the way, I didn&#8217;t speak at all about optimization here, and there is surely some work to do about it (especially on noise textures that could\u00a0fit on fewer channels than a full RGB image).<\/p>\n<p>Anyways, this was a nice journey to me, and even if the result is not super awesome, I\u00a0really enjoyed the process of mixing a bit of maths with more arty considerations. I hope this will help somebody out there!<\/p>\n<p>Thanks for reading!<\/p>\n<p>Peace!<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello everyone, It&#8217;s been a long time since I last posted a technical tutorial, so finally, here&#8217;s a new one. This one will tackle the problem of creating procedural foam for my game. I&#8217;ll try to explain my thinking process and the different choices I&#8217;ve made to create this: The final foam rendering in my [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":734,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,7],"tags":[],"class_list":["post-580","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev","category-tutorial"],"_links":{"self":[{"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/posts\/580","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/comments?post=580"}],"version-history":[{"count":108,"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/posts\/580\/revisions"}],"predecessor-version":[{"id":736,"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/posts\/580\/revisions\/736"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/media\/734"}],"wp:attachment":[{"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/media?parent=580"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/categories?post=580"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oneiricworlds.com\/en\/wp-json\/wp\/v2\/tags?post=580"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}