Introduction

Fluid Flow 2 allows you to paint fluid to your objects in real time, and simulate it flowing down the surface dynamically. Use it for blood, paint, or any other kind of fluid.

The main feature of Fluid Flow is the dynamic flow simulation. However, you can also use it just for real-time 3D texture painting/decals, which also supports skinned mesh renderers. Due to its modular structure, you can decide which parts of Fluid Flow you want to use, without unnecessarily bloating your project.

The texture painting and flow simulation are handled fully on the GPU for optimal performance. Fluid Flow is not a physically accurate fluid simulation, but it provides good-looking fluid for your games at a comparable low performance cost!

As fluid is painted and simulated in UV space, your meshes require a UV unwrap with non-overlapping UV islands, so there is a 1:1 correlation between the object's surface and the texture. You can also configure Fluid Flow to use the lightmap UV set, which can be generated by unity automatically.

Important: Please note that your objects require a special shader for overlaying the fluid, or when using the texture atlas system. There are basic surface and shader graph shaders included. Alternatively, you can easily create your own supported shaders with the provided custom shader graph nodes, or shader utility functions.

Required Unity Packages

Features

  • real-time UV space gravity map generation:
    • texture-based flow simulation
    • particle-based flow simulation
  • 3d texture painting on (skinned) renderers
  • draw decals on (skinned) renderers
  • fluid flowing over UV seams
  • fluid effects: evaporation, blur (soaking)
  • caching system
  • custom editor windows
  • modular, optimized and open code-base (no .dlls)

Technical Details

The texture painting and fluid simulation are independent of the render pipeline used. For overlaying fluid over your models, or unpacking the texture atlas you might have to adjust your custom shaders. There are custom shader graph nodes, and surface shader utility functions included to make this as easy as possible.

Limitations

  • NOT a physically-based navier-stokes fluid solver. Fluid just moves based on gravity.
  • Requires non overlapping UV map , as fluid is simulated in UV space.
  • Renderers require a specialized shader for overlaying the fluid texture.

Frequently Asked Questions

Feel free to send me your questions, so I can add them here (mr3d.cs@gmail.com).

  • Does FluidFlow support URP, HDRP, etc.?

    Yes, FluidFlow is largely independent of the rendering pipeline your project is using. However, for overlaying the fluid texture you will need a shader, supported by your rendering pipeline, which is able to overlay the fluid texture.

  • How can I increase the speed at which the fluid flows?

    In each fluid simulation step, the fluid moves from one pixel to the neighboring pixels depending on gravity. Therefore, the maximum fluid speed is limited by one pixel per simulation step. The trivial way for altering the fluid speed is decreasing the fluid texture resolution, so each pixel is larger, or increasing the update rate of the fluid simulation. However, keep in mind, that the latter has a performance cost, so you should not go too far with this approach.

  • Does FluidFlow work on mobile platforms?

    Yes, FluidFlow was successfully tested on a Google Pixel 3a, and should also be able to run on older devices. iOS based devices should also work, however, I am not able to test this myself. I would greatly appreciate it, if you share your experiences using FluidFlow on Apple devices.

  • How can I access/safe the generated textures?

    You can access the internal texture, by accessing the TextureChannels property on your FFCanvas. E.g. myCanvas.TextureChannels["Fluid"]. As the texture data is stored inside a RenderTexture, it does only exist in GPU memory. If you want to access the texture data from C#, or save the texture, you will have to read it to CPU memory first. FluidFlow allows you to call the myRenderTexture.RequestReadback() method, to simplify this process. Check the SaveTextureChannel() function in Scripts/Extensions/FFCanvasExtensions.cs for a more elaborate example.

Getting Started

Demo Scenes

Example scenes using FluidFlow can be found in FluidFlow/Example/Scenes. Each example scene contains a RP Material Switcher object at the top of the Hierarchy which allows swapping the materials in the scene to match your current rendering pipeline.

A minimal example for setting up a FFCanvas

  • Add a FFCanvas component to an object in your scene.

  • Assign the renderers of the objects you want to draw on, to the Surfaces of the FFCanvas, and set up the surface as described in FFCanvas.

  • Add the Texture Channels you want to draw on, and set their Texture Channel Format.

  • Assign a material to your Surfaces' renderers, that supports drawing to the selected Texture Channels. Fluid Flow provides basic shaders (integrated RP, URP, HDRP) that support drawing to the Color, Normal, and Fluid texture channels.

  • When the internal texture channels of a FFCanvas are shared by multiple Surfaces (UV Scale != (1,1), UV Offset != (0,0)), the renderers' materials need to transform their UVs before sampling the texture set by the FFCanvas. Most shaders support this out-of-the-box via the Tiling and Offset of the texture property. In the Material Property Overrides of the FFCanvas you can you can set the name of this property for a given shader (if no target shader is set, it applies to all shaders). Unity's default naming scheme for accessing the Tiling and Offset of a given texture property, e.g. _MainTex, is adding _ST to the property name (_MainTex_ST).

  • You should now be able to draw to the FFCanvas as described in Drawing. For testing you can simply add a Simple Project Decal component, and assign a camera and FFCanvas. This should allow you to project a decal onto the canvas by clicking on the objects in the Game window while playing.

Texture-based fluid simulation

  • Add a Fluid texture channel using the FluidFormat and BLACK initialization to your FFCanvas.

  • Make sure, your renderers have a material assigned, which is able to overlay the Fluid texture channel. FluidFlow provides example shaders for all rendering pipelines.

  • Add a FFGravityMap component and assign the targeted FFCanvas.

  • Add a FFSimulator component, assign the FFGravityMap created before, and select Fluid as the targeted texture channel.

  • When paining to the FFCanvas' Fluid texture channel (using the FLUID type instead of COLOR while painting), the painted fluid should flow according to gravity.

Particle-based fluid simulation

  • Add a Fluid texture channel using the FluidFormat and BLACK initialization to your FFCanvas.

  • Make sure, your renderers have a material assigned, which is able to overlay the Fluid texture channel. FluidFlow provides example shaders for all rendering pipelines.

  • Add a FFGravityMap component and assign the targeted FFCanvas.

  • Add a FFSimulatorParticle component, assign the FFGravityMap created before, and select Fluid as the targeted texture channel.

  • Instead of drawing to the FFCanvas, fluid-particles have to be added directly to the FFSimulatorParticle component, using AddParticle or ProjectParticles. Check out the SimpleDrawParticle component for a simple example.

Drawing

In order to draw on a texture channel of a FFCanvas a set of extension methods for the FFCanvas are provided. There are currently two main approaches for drawing:

  • Decal projection: a decal, defined by a FFDecal, is projected on the surfaces. The projection is defined by a projection-view matrix, similar to a camera, that describes a projection volume or frustum in world-space (Matrix4x4.Perspective). To project a decal on a FFCanvas, call the ProjectDecal() extension method.

  • Brushes: a brush is a 3D shape in the scene (e.g. a sphere) and the parts of the surfaces' renderers intersecting this shape are painted. How exactly the texture is painted is defined using a FFBrush. To draw a brush on a FFCanvas, call the DrawSphere(), DrawDisc(), or DrawCapsule() extension methods.

For example code snippets on how these methods can be used, take a look at FluidFlow/Example/Scripts/DrawExamples.cs.

FFDecal

A FFDecal allows drawing on multiple texture channels of a FFCanvas at once. Each decal channel is identified by the shader property name of the texture channel it affects. Additionally, setting the decal channel type to FLUID allows setting the fluid amount. Setting the type to NORMAL sets a flag internally, so normal maps are projected properly.

The FFDecal also has an optional mask field. When the mask texture is left empty, no mask is applied. If a mask texture is set, all decal channels are affected by it. The R, G, B, and A buttons allow specifying which channels of the mask texture will be used for calculating the mask value. The mask value for each pixel is calculated by adding the values from the selected color channels, and dividing by the count of selected channels.

For example, when selecting the green and alpha channel, the mask value v = (Mask.g + Mask.a)/2.

FFBrush

A FFBrush can currently only be used for drawing a solid color (triplanar texture mapping might be added in the future). By setting the brush type to FLUID, the fluid amount added can be specified.

The drawing of a FFBrush is internally implemented as a distance function from an arbitrary 3D shape. When drawing a brush, a maximum distance is specified, and all pixels within this distance from the shape are colored. The fade value multiplied by this maximum distance defines the distance from the edge of the shape, where the intensity of the brush starts decreasing. And the intensity of the brush reaches zero, when the distance from the shape is equal to the maximum distance. The interpolation function is currently fixed to a smooth-step function, which has zero for its 1st- and 2nd-order derivatives at x = 0 and x = 1.

Custom Brush Shape

It is possible to add custom brush shapes, by creating a new method in the FluidFlow/Scripts/Draw/BrushExtensions.cs. This requires setting the required variables as global shader values, and writing a custom shader with the distance function of the shape.

The FluidFlow/Resources/InternalShader/Draw/CustomBrushTemplate.shader provides a template for such a custom brush shader, which only requires you to fill in the distance function. To call this custom brush shader from C#, you can add a new MaterialCache to the other brush shaders in the FluidFlow/Scripts/Draw/BrushExtensions.cs.

Custom Shaders

As the FFCanvas combines multiple renderers into a texture atlas, and some renderers might use the lightmapping UVs for drawing, a special material shader is required for displaying the generated textures on the models. Depending on the rendering pipeline used, unity's shader graph can be used, or a custom surface shader can be created.

FluidFlow provides helper functions for both of these options. A set of custom shader graph nodes are defined in FluidFlow/Editor/CustomShaderGraphNodes, and the FluidFlow/Shaders/FFShaderUtil.cginc provides useful helper functions for writing surface shaders. Take a look at the included shaders, for an example of how these helper functions can be utilized.

On initialization the FFCanvas will set a Vector4/float4 uv transformation property (scale.xy, offset.xy) to each material of its Surfaces' renderers. Additional a keyword is enabled, of a float property set to 0/1, if the mesh's secondary uv set should be used. The name of these properties/keyword can be set in the Material Property Overrides of the FFCanvas.

Unity automatically creates a tiling and offset property for each texture property, however, depending on the shader implementation, the tiling and offset transformation may not be applied to the UV before sampling the texture. This float4 property can accessed by adding a _ST postfix to the texture property name (e.g. _MainTex $\rightarrow$ _MainTex_ST).

The function for transforming a uv coordinate to texture atlas coordinates of the FFCanvas given a float4 uvTransform; is:

float2 TransformUV(float2 uv, float4 uvTransform)
{
    return uv * uvTransform.xy + uvTransform.zw;
}

Shader Graph

Accessing the Tiling and Offset of a texture in Shader Graph can be done using the Split Texture Transform Node. On older versions of Shader Graph, you have to manually add a float4 property named after the texture property + _ST postfix (e.g. _FluidTex_ST).

If your meshes may use secondary/lightmap uvs, define a local multi compile boolean keyword e.g. FF_UV1 or float property, for detecting if the secondary uv should be used.

The helper FF Atlas Transformed UV node will automatically switch between uv0 and uv1, depending on if the Use Secondary UV flag is set, and transform the uv using a provided transformation vector. For performing texture coordinate transformation manually, you can use the FF Atlas Transform helper node.

When sampling a fluid texture, use the custom FF Unpack Fluid node, for easy access to the fluid's color, normal and fluid amount information. Optionally you can use the FF Distort UV node, to add a small random offset to the uv before sampling the fluid texture for a more natural look.

The FF Color Scatter node approximates light scattering while traveling through the fluid, making sections with more fluid appear darker.

Surface Shader

Overview of a basic surface shader with FluidFlow support:

Shader "FluidFlow/MyCustomShader"
{
	Properties
	{
		[...]
		[HideInInspector] _FluidTex("Fluid", 2D) = "black" {}
	}
	SubShader
	{
		Tags { "RenderType" = "Opaque" }
		LOD 200

		CGPROGRAM
		#include "UnityCG.cginc"
		#include "FFShaderUtil.cginc"

		#pragma target 3.0
		#pragma surface surf Standard fullforwardshadows vertex:vert

		#pragma multi_compile_local __ FF_UV1

		struct Input
		{
			[...]            
			FF_SURFACE_INPUT
		};

		sampler2D _FluidTex;
		float4 _FluidTex_ST;

		void vert(inout appdata_full v, out Input o) {
			UNITY_INITIALIZE_OUTPUT(Input, o);
			FF_INITIALIZE_OUTPUT(v, o, _FluidTex_ST);
		}

		void surf(Input IN, inout SurfaceOutputStandard o)
		{
            // basic shader stuff
            float3 base_color = [...]
            float3 base_normal = [...]
            [...]

            // sample fluid texture
			fixed4 fluid = tex2D(_FluidTex, IN.FF_UV_NAME);
			float3 fluid_color = fluid.FF_FLUID_COLOR;
			float fluid_height = min(fluid.FF_FLUID_AMOUNT, 1);
			float3 fluid_normal = FF_UNPACK_FLUID_NORMAL(IN, _FluidTex, 1);

            // interpolate
			o.Albedo = lerp(base_color, fluid_color, fluid_height);
			o.Normal = lerp(base_normal, fluid_normal, fluid_height);
		}
		ENDCG
	}
	FallBack "Diffuse"
}

In summary:

  • Add a [HideInInspector] _FluidTex("Fluid", 2D) = "black" {} property.

  • Include "FFShaderUtil.cginc" (may require a relative path e.g. #include "../../FluidFlow/Shaders/FFShaderUtil.cginc") for access to some utility functions.

  • Create a local multi compile shader variant for using the secondary UV set (#pragma multi_compile_local __ FF_UV1).

  • Add a custom vertex function, which initializes the FF_SURFACE_INPUT using the FF_INITIALIZE_OUTPUT macro. Alternatively you can use the FFAtlasTransformUV() function to transform UVs to FFCanvas texture atlas UVs manually.

  • Inside the surface shader, you can now access the atlas transformed texture coordinate, via the FF_UV_NAME field on the input struct. This field was initialized by the FF_INITIALIZE_OUTPUT macro in the vertex shader.

  • When sampling a fluid texture, you can use .FF_FLUID_COLOR (just an alias for .rgb) to access the color of the fluid, and .FF_FLUID_AMOUNT to access the fluid amount (just an alias for .a).

  • Optionally you can use the FFDistortUV function, to add a small random offset to the uv before sampling the fluid texture for a more natural look.

  • Use the FF_UNPACK_FLUID_NORMAL macro to approximate the fluid normal based on the surrounding fluid amount.

FFCanvas

The FFCanvas is the main component of FluidFlow. It manages the RenderTextures used for drawing, and sets up the renderers' materials for displaying the textures.

In order for the drawing to work properly each mesh, that is being drawn on, requires a bijective UV map, meaning that there is a 1-to-1 mapping between the object's surface and its texture coordinates. Consequently, the UV islands must not overlap, and there should be at least a 2 pixel-wide gap between UV islands for the fluid simulation to work properly.

If a models primary UV map does not fulfill these requirements, the secondary/lightmap UVs can be used instead. Unity can automatically generate such a secondary lightmap UVs, by enabling the Generate Lightmap UVs option, in the models import settings. However, it has to be noted that the 'quality' of automatically generated lightmap UVs is lower than a set of handcrafted UVs, as UV seams might be in very prominent places of the model. FluidFlow can deal with UV seams (see FFEffects/FFSeamFixer), but it is impossible to completely hide all artifacts from UV seams. Especially for fluid simulations, UV seams can be noticeable, as fluid has to be teleported between UV islands, and texel density will most likely change at the seam.

Fields

  • Auto Initialize: initialize the FFCanvas automatically OnStart().
  • Initialize Async: don't block the main thread if pre-processing of the meshes is requied. Check out FFModelCache for faster initialization.

Surfaces

The internal textures of a FFCanvas can be shared by multiple renderers and submeshes of these renderers. For each renderer in the Surfaces list, you can define which UV-set should be used for drawing. Additionally, you can define which subset of submeshes of the renderer is included in the FFCanvas, and define the section of the texture atlas the surface should occupy using the UV Scale and UV Offset properties. Optionally, you can assign different section for different sets of submeshes. In general, no UV-island should overlap any other UV-island, even of other submeshes/renderers.

Click the Open In Editor button, for a visual editor for simpler layouting of the uv maps.

Texture Channels

Each Texture Channel is internally represented by a RenderTexure, and is directly (reference) or indirectly (name) identified using a TextureChannel object. The TextureChannel also defines to which texture property of the Surfaces' materials the RenderTexture is applied to.

The format of the internal RenderTexture is determined using a TextureChannelFormat object.

It is either initialized with a solid color, or by copying the contents of the current textures assigned to the renderers' materials.

When the texture channels are initialized, they are assigned corresponding texture properties of the renderers using MaterialPropertyBlocks. So do not be confused, if the textures do not show up in the material's inspector fields, as they are directly assigned to the renderers.

Material Property Overrides

The Material Property Overrides define to which material properties the UV Scale, UV Offset, and selected UV set information is passed.

  • Atlas Transform Propety: refers to a float4 property encoded as (UV_Scale.xy, UV_Offset.xy). This is the same format as used for Unity's default texture tiling and offset property, accessed via the _ST postfix in the shader (e.g. _MainTex_ST).

  • Secondary UV Name: is either set as a keyword, if the secondary UV set is used, or a float property with the given name is set to 0/1, depending on the UV set used.

FFGravityMap

The FFGravityMap is the base for the texture-/particle-based fluid simulation.

It transform world-space gravity to UV-space gravity and saves it in an internal RenderTexture, which can be accessed via the FlowTexture property.

The FFGravityMap is initialized automatically as soon as the targeted FFCanvas is fully initialized.

Flow Texture Generation

The flow texture is updated lazily when the FlowTexture property is accessed, and an update is required. In the CONTINUOUS update mode, it is updated once per frame (upon request), and in FIXED mode after the set time in seconds. In the CUSTOM mode, you have to trigger updates manually using the UpdateGravity() method.

Optionally, the gravity map generation can be influenced by a normal map (identified by a Texture Channel), and by random noise, which can be set to change over time, for less uniform flow.

Fields

Check the tooltip hints for additional information of individual fields.

FFSimulator

The FFSimulator provides a basic texture-based flow simulation, for a referenced TextureChannel.

Note that the TextureChannelFormat of the targeted TextureChannel should have 4 channels (RGBA) and support values >1 (optimally floating point/HDR).

The FFSimulator is initialized automatically as soon as the targeted FFGravityMap is fully initialized.

Flow Speed

Each simulation step, fluid flow into/out of the current texel to the direct neighbors. Thus, the flow speed is directly dependent on the update frequency.

As texel-density on the mesh can vary, the fluid can appear to flow faster/slower on parts of the mesh.

Performance

A timeout can be used to halt simulation after a specified amount of time after the last edit of the targeted TextureChannel in order to save computation cost.

In general, the performance impact of the simulation is directly proportional to the TextureChannel resolution, and simulation update frequency.

Fields

Check the tooltip hints for additional information of individual fields.

FFSimulatorParticle

The FFSimulatorParticle provides a basic particle-based flow simulation. The Particle data is saved in two internal RenderTextures containing the particles' UV position, fluid amount, speed, and color.

The FFSimulatorParticle is initialized automatically as soon as the targeted FFGravityMap is fully initialized.

Flow Simulation

Each simulation step, the particles sample the FFGravityMap's flow texture at their position and move in their corresponding 'down' direction. A small circle is then drawn for each active particle to the targeted TextureChannel of the FFCanvas. Over multiple update steps, this results in a trail as the particle is moving down the surface.

Adding Particles to the Simulation

Compared the the FFSimulator particles have to be added to the FFSimulatorParticle directly instead of to a FFCanvas texture channel.

The particle-data textures behave similar to a First-In-First-Out (FIFO) buffer, meaning that older active particles may be overwritten by newer ones, if the internal particle-data texture size is too small for the amount of particles you are adding.

The next best section, new particles are added to, is determined in the FFParticleUtil.Data.Request(Vector2Int size) method.

There are two approaches for introducing new particles to the simulation:

  • ProjectParticles(): project particles onto the renderer using a FFProjector. This renders the surfaces to a small section of the particles data RenderTextures using the projector's view-projection matrix. The UV coordinates of the rendered fragments within the projector's frustum are used as the new particles' starting position.
  • AddParticles(): define the position, fluid amount, speed, and color of the new particles, and upload it to the data-buffer texture. However, the particle's position is the UV position within the FFCanvas texture atlas, and thus non trivial to compute. FFCanvasExtensions contains two helper functions for computing these texture atlas UV positions (AtlasTransformUV(), TryGetCanvasUV()).

Checkout FluidFlow/Examples/Scripts/SimpleDrawParticle.cs for basic examples of these two approaches.

Flow Speed

Each simulation step, particles must only move one pixel, to ensure that they do not step into a different UV island. Thus, the flow speed is directly dependent on the update frequency.

As texel-density on the mesh can vary, the particles can appear to move faster/slower on parts of the mesh.

Performance

A timeout can be used to halt simulation after a specified amount of time after the last edit to the particles in order to save computation cost. You can reset the timeout manually using the ResetTimeout() method.

In general, the performance impact of the simulation is proportional to the size of the particle data textures, and simulation update frequency.

Fields

Check the tooltip hints for additional information of individual fields.

FFEffects

FFEffects provides some basic additional effects for the fluid simulation, to the targeted TextureChannel on the FFCanvas referenced by the FFGravityMap.

Effects

  • Stitch Seams: the FFSimulatorParticle does not automatically deal with UV seam artifacts like the FFSimulator. This option uses the FFGravityMap's flow texture for stitching the seams. This should be used instead of the FFSeamFixer, when a FFGravityMap is available.

  • Evaporation: reduce total fluid amount over time.

    • LINEAR: the same amount of fluid is removed each update
    • EXPONENTIAL: a fraction of the remaining fluid is removed each update
  • Blur: when a texel contains a lot of fluid, some will spread to surrounding texels containing less fluid. This can for example be useful for making fluid appear to soak into clothing.

FFSeamFixer

During rasterization, only pixels are drawn, which center points lie withing a triangle. This means, that pixels of the texture, which lie barely outside of an UV island, are not drawn during paining/decal projection, but can be visible during rendering of the model. This will be visible as artifacts at UV seams of the mesh.

The FFSeamFixer solves this problem, by expanding the color at the border of the UV islands outwards a few pixels.

Note! when using fluid simulation, these seam artifacts are fixed for the fluid TextureChannel by the FFSimulator automatically, or FFEffects when using a FFParticleSimulator

Performance

The FFSeamFixer only fixes seams on targeted Texture Channels which have been marked as updated by the FFCanvas. You can manually mark a Texture Channel as modified by calling the MarkModified(textureChannel); method.

When using the CUSTOM update mode, call the FixModifiedChannels() method, to trigger an update manually.

Cache

For finding the UV islands' borders, the Surfaces have to be rendered to an internal RenderTexture first. The Use Cache field allows to cache this internal texture for future use, instead of regenerating it each update. This requires some memory on the GPU, but reduces drawcalls/overhead of fixing seam.

FFModelCache

  • Assets/Create/Fluid Flow/Model Cache

A FFModelCache allows to pregenerate and cache secondary UV transformation and stitching data, required for the gravity map generation and fluid simulation. This can reduce performance overhead and time needed for initializing a FFCanvas/FFGravityMap.

After selecting a model asset in the Project window, navigate to Assets/Create/Fluid Flow/Model Cache to generate a cache asset for the selected model. When the FFModelCache is set up, hit the Apply button, to start generation and save the settings.

Secondary UV Caches

When using secondary UV for fluid simulation, a UV1 to UV0 tangent-space transformation matrix has to be calculated for each vertex, so the gravity is projected to secondary-UV-space properly. Additionally, when approximating the fluid normal, this transformation is needed to transform the fluid normal back to UV0 tangent-space.

Simply add a mesh to the Secondary UV Caches list, by clicking the + button. If the selected mesh does not have a secondary UV set, Unity's internal Unwrapping Utility is used for automatically generating lightmap UVs.

Stitch Caches

As fluid is simulated in UV space, seams in the UV unwrap would stop the flow. Therefore FluidFlow analyzes the meshes in a FFCanvas to find seams in the UV map, and generates 'stitches' for stitching UV islands together.

Add a new entry, and set the desired mesh/UV-set, for which stitches should be pre-generated for. When UV1 is selected, but the mesh does not have a secondary UV set, the mesh is automatically added to the Secondary UV Caches.

Global Cache

The cached data from all loaded FFModelCache scriptable objects is loaded during the start of the game to a global cache manager internally. To ensure a FFModelCache is included in the build, it either has to be put in a 'Resources' folder in the project, or be referenced by an object in the scene. So in theory, a FFModelCache only has to be referenced once by a FFCanvas, and the cached data can still be accessed by all other FFCanvas components in the game. However, as a best practice, the FFModelCache should be referenced by all FFCanvas components which need to access the data, to make sure the FFModelCache is included in the final build.

All mesh/stitch data generated at runtime is automatically also added to this global cache, so the same data is not compute multiple times.

In the 'Global Settings' section, an update of all FFModelCache objects in the project can be triggered. This checks for each FFModelCache if the model it targets has been modified, and if so recalculates the cache.

This updating of the caches can also be scheduled each time before entering the play mode, by enabling the 'Auto Update Before Play' toggle. However, please note that this adds an overhead to entering the play mode.

Texture Channel

  • Assets/Create/Fluid Flow/Texture Channel

A TextureChannel abstracts away a shader's texture property name from the usage of the texture. For example a Color TextureChannel may correspond to the _MainTex texture property of one shader, but to the _BaseMap property of another shader.

The name of a TextureChannel has to be unique within a project, as the name can be used for indirectly referencing a TextureChannel using TextureChannel.TryResolve("name", out var textureChannel).

A TextureChannelReference allows referencing a TextureChannel directly, or indirectly and resolving at runtime.

Texture Channel Format

  • Assets/Create/Fluid Flow/Texture Channel Format

Provides a list of possible GraphicsFormat for a Texture Channel of a FFCanvas.

On startup the first GraphicsFormat in the list available on the current platform is selected.

If none from the list are available, similar compatible formats are searched.

Contact

Any questions or suggestions?

  • Christian Schott
  • E-Mail: mr3d.cs@gmail.com
  • YouTube: https://www.youtube.com/playlist?list=PLH6XAuNbhBuukHLbeF1FId0-m2FzyJZiP
  • Unity AssetStore: https://assetstore.unity.com/publishers/16528