CParticleSamplerShape

From PopcornFX
Jump to: navigation, search

Particle sampler shape Last update: v1.10.0 - Main page : Particle samplers Particle samplers


The shape sampler allows you to sample different properties of various 3D shape, (including custom meshes). It is a pretty powerful sampler, used extensively in all the particle samples. It's used mainly to initialize particle properties such as Position or Velocity.


Shape samplers are split in two main parts: the sampler, and the shape(s).


Particles sampling a shape mesh


Particle sampler shape Node properties

The sampler contains the high-level sampling config, telling how the shapes should be sampled (surface, or volume), how the samples should be transformed.

Field name Default value Description
Particle sampler shape General
SamplerName Auto-generated name Name of the sampler, published to the rest of the effect
SamplerDescription Empty Sampler Description (optional)
UserData Empty Use this if you need to pass custom data to your game engine's integration (custom PopcornFX SDK). If you're Using UE4 or Unity, you can ignore this.
SampleDimensionality Surface
  • Vertex : sample with 1-dimensional coordinates, samples at discrete vertices, if applicable on the shape
  • Surface : sample with 2-dimensional coordinates, samples on the shape surface
  • Volume : sample with 3-dimensional coordinates, samples within the shape's volume
Sampler Random
  • Random : random sampling
  • Regular : not implemented.
TransformTranslate true
TransformRotate true
FixedLocationsCount 0 if not 0, the sampler will precompute the given number of samples, and sample these at runtime. trades memory and diversity for speed.
FixedLocationsSeed 0 random seed used to change the generated fixed locations.
Particle sampler shape

Note the 'FixedLocationsCount' field. If non-zero, the sampler will allocate an array as big as 'FixedLocationsCount', and precompute the samples, so that the runtime sampling is faster.


Particle sampler shape Shape Types

Field name Default value Description
Particle sampler shape General
Weight 1
ShapeType BOX
  • BOX
  • SPHERE
  • COMPLEX_ELLIPSOID
  • CYLINDER
  • CAPSULE
  • CONE
  • PLANE
  • MESH
Particle sampler shape Localization
Position {0,0,0} Shape local position
EulerOrientation {0,0,0} Shape local orientation along each axis, in degrees
Particle sampler shape generic properties


Box

Field name Default value Description
Particle sampler shape box General
BoxDimensions {0.5,0.5,0.5}
Shape sampling : BOX Shape visualization : BOX
Left: Volume sampling. Right: Surface sampling Shape
Shape sampler properties : BOX



Sphere

Field name Default value Description
Particle sampler shape sphere General
Radius 1
InnerRadius 0 Coupled with 'NormalizedInnerRadius'
NormalizedInnerRadius 0 Coupled with 'InnerRadius'. InnerRadius = Radius * NormalizedInnerRadius
Shape sampling : SPHERE Shape visualization : SPHERE
Left: Volume sampling. Right: Surface sampling Shape
Shape sampling : SPHERE (hollow) Shape visualization : SPHERE (hollow)
Left: Volume sampling. Right: Surface sampling Shape, InnerRadius = 75%
Shape sampler properties : SPHERE



Complex ellipsoid

Field name Default value Description
Particle sampler shape complex ellipsoid General
Radius 1
InnerRadius 0 Coupled with 'NormalizedInnerRadius'
NormalizedInnerRadius 0 Coupled with 'InnerRadius'. InnerRadius = Radius * NormalizedInnerRadius
CutPlane 1 range : [0,1]. Fraction of the sphere. 1 is the full sphere, 0.5 is an hemisphere, 0.2 is a small spherical cap, etc...

NOTE: the cut plane is only implemented for the values 1 and 0.5

NonUniformScale {1,1,1} Radius scale along each axis, allowing to create ellipsoids
Shape sampling : COMPLEX_ELLIPSOID Shape visualization : COMPLEX_ELLIPSOID
Left: Volume sampling. Right: Surface sampling Shape
Shape sampling : COMPLEX_ELLIPSOID (hollow) Shape visualization : COMPLEX_ELLIPSOID (hollow)
Left: Volume sampling. Right: Surface sampling Shape, InnerRadius = 75%
Shape sampler properties : COMPLEX_ELLIPSOID



Cylinder

Field name Default value Description
Particle sampler shape cylinder General
Radius 1
InnerRadius 0 Coupled with 'NormalizedInnerRadius'
NormalizedInnerRadius 0 Coupled with 'InnerRadius'. InnerRadius = Radius * NormalizedInnerRadius
Height 0
Shape sampling : CYLINDER Shape visualization : CYLINDER
Left: Volume sampling. Right: Surface sampling Shape
Shale sampling : CYLINDER (hollow) Shape visualization : CYLINDER (hollow)
Left: Volume sampling. Right: Surface sampling Shape, InnerRadius = 75%
Shape sampler properties : CYLINDER



Capsule

Field name Default value Description
Particle sampler shape capsule General
Radius 1
InnerRadius 0 Coupled with 'NormalizedInnerRadius'
NormalizedInnerRadius 0 Coupled with 'InnerRadius'. InnerRadius = Radius * NormalizedInnerRadius
Height 0
Shape sampling : CAPSULE Shape visualization : CAPSULE
Left: Volume sampling. Right: Surface sampling Shape
Shape sampler properties : CAPSULE



Cone

Field name Default value Description
Particle sampler shape cone General
Radius 1
Height 0
Shape sampling : CONE Shape visualization : CONE
Left: Volume sampling. Right: Surface sampling Shape
Shape sampler properties : CONE



Mesh

Field name Default value Description
Particle sampler shape mesh General
MeshResource Virtual path to the FBX mesh resource (Editor will auto-replace the ".fbx" extension with ".pkmm")
MeshScale {1,1,1}
MeshSamplingMode Uniform
  • Fast : a bit faster, but the sample distribution isn't constant, and depends on the local tesselation
  • Uniform : uniform samples distribution, regardless of mesh density
  • Weighted : v1.8.0 uses vertex-colors to weight the sampling probability. See the 'DensityColorStream' and 'DensityChannel' properties
SubMeshIndex 0 If the mesh contains multiple sub-meshes, this value tells the sampler which sub-mesh to use.
DefaultUvStream 0 If the mesh contains multiple UV streams, this value is the ID of the UV stream that will be sampled by a call to 'sampleTexcoord()' with no extra parameter.
DefaultColorStream 0 If the mesh contains multiple Color streams, this value is the ID of the Color stream that will be sampled by a call to 'sampleColor()' with no extra parameter.
DensityColorStream 0 v1.8.0 ID of the color stream to be used as a sampling density/probability weight.

Default: 0 (first color channel)

DensityChannel Red v1.8.0 Specifies which RGBA channel to use in the color stream to weight sampling density
  • Red
  • Green
  • Blue
  • Alpha


! WARNING ! The volume sampling is still experimental, and to use it, you will need to explicitely build tetrahedral indices from the mesh importer. There is (willingly) no easy interface to do this in v1.10, as it is still under development and will change a lot in the future releases. See the mesh importer page for guidelines on building the tetrahedral mesh.


Shape sampling : MESH Shape visualization : MESH
Left: Volume sampling (v1.10.0). Middle: Surface sampling. Right: Vertex sampling Shape
Shape sampler properties : MESH

MeshSamplingMode

Here is a visual example of what changing the 'MeshSamplingMode' property does:

Base mesh
Base mesh : non-uniformly tesselated plane
'Fast' sampling mode: uniform triangle density 'Uniform' sampling mode: uniform surface density
Fast sampling Uniform sampling

Note that from v1.5.5 the 'uniform' sampling algorithm has been considerably optimized, and now runs in constant time per-sample, which is almost as fast as the 'Fast' sampling, so there is no reason to use the 'Fast' sampling anymore, unless you want by-design a constant density per-triangle, instead of per unit of surface.

Vertex-color weighted mesh sampling
v1.8.0 Left: Regular uniform sampling, Right: Weighed sampling using vertex colors (hands white, feet black)


Particle sampler shape Shape Collections

The shape sampler only samples a single shape. So, in order to sample an arbitrary number of aggregate shapes, when you add more than one shape to a sampler in the editor, a shape collection is generated, and the shapes are stored as childs.

The shape collection will allow you to set a few parameters to control its runtime behavior, related to how it will distribute the samples across its sub-shapes:


To create a shape collection, right click on the sampler, and select 'Create shape collection':

Create shape collection


You can add other shapes by right-clicking on the sampler and selecting 'Add Shape':

Shape collection : Add sub-shape


To remove a shape collection, right click on the sampler, and select 'Remove shape collection':

Remove shape collection


Note that if you try removing a shape collection that contains more than 1 sub-shape, you'll get the following warning:

Invalid shape collection removal


Choosing 'Yes' will remove all but the first shape in the collection before reverting to a regular shape


Field name Default value Description
Particle sampler shape collection General
SamplingHeuristic NoWeight
  • NoWeight
  • WeightWithVolume
  • WeightWithSurface
UseSubShapeWeights true
PermutateMultiSamples true If true, uses a random-permute after each sampling batch to randomly distribute the samples across each shape.

If false, will be faster, but lower quality.

Shape sampling : SHAPE COLLECTION Shape visualization : SHAPE COLLECTION
No weights, same sample count on all subshapes

Left: Volume sampling. Right: Surface sampling

Shape collection
Shape sampling : SHAPE COLLECTION Shape visualization : SHAPE COLLECTION
Left: Weight by volume. Right: Weight by surface

Left: Volume sampling. Right: Surface sampling

Shape collection
Shape sampling : SHAPE COLLECTION Shape visualization : SHAPE COLLECTION
Cone weight=100, Box weight=10, Sphere weight=1

Left: Volume sampling. Right: Surface sampling

Shape collection
Shape sampler properties : SHAPE COLLECTION


Particle sampler shape Script bindings

for each shape, the following methods are published: (see the Scripting reference page for more details)

Function\ShapeType Box Sphere Ellipsoid Cylinder Capsule Cone Mesh Collection
float3 samplePosition() YES YES YES YES YES YES YES YES
float3 sampleNormal() YES YES YES YES YES YES YES YES
float4 sampleTangent() N/A N/A N/A N/A N/A N/A YES YES
float2 sampleTexcoord() N/A N/A N/A N/A N/A N/A YES YES
float4 sampleColor() N/A N/A N/A N/A N/A N/A YES YES
float3 sampleVelocity() YES YES YES YES YES YES YES YES
float3 sampleParametricCoords() YES YES YES YES YES YES YES NO
int3 buildParametricCoordsBox() YES N/A N/A N/A N/A N/A N/A N/A
int3 buildParametricCoordsSphere() N/A YES N/A N/A N/A N/A N/A N/A
int3 buildParametricCoordsCapsule() N/A N/A N/A YES N/A N/A N/A N/A
int3 buildParametricCoordsCylinder() N/A N/A N/A N/A YES N/A N/A N/A
int3 buildParametricCoordsCone() N/A N/A N/A N/A N/A YES N/A N/A
int3 buildParametricCoordsMesh() N/A N/A N/A N/A N/A N/A YES N/A
float sampleDistanceField() YES YES YES YES YES YES YES YES
int contains() YES YES YES YES YES YES NO YES
float4 intersect() YES YES YES YES YES YES YES YES
float4 project() YES YES YES YES YES YES YES YES
int3 projectParametricCoords() YES YES YES YES YES YES YES NO
float surface() YES YES YES YES YES YES YES YES
float volume() YES YES YES YES YES YES YES YES
float3 boxDim() YES N/A N/A N/A N/A N/A N/A N/A
float radius() N/A YES YES YES YES YES N/A N/A
float innerRadius() N/A YES YES YES YES N/A N/A N/A
float height() N/A N/A N/A YES YES YES N/A N/A
int vertexCount() N/A N/A N/A N/A N/A N/A YES N/A
int triangleCount() N/A N/A N/A N/A N/A N/A YES N/A
int tetraCount() N/A N/A N/A N/A N/A N/A YES N/A
float3 meshScale N/A N/A N/A N/A N/A N/A YES N/A
int type() YES YES YES YES YES YES YES YES
float3 position() YES YES YES YES YES YES YES YES
float3 axisSide() YES YES YES YES YES YES YES YES
float3 axisUp() YES YES YES YES YES YES YES YES
float3 axisForward() YES YES YES YES YES YES YES YES


The red "NO" slots mean this feature is not implemented, but might be in a future release.
The grey "N/A" slots mean this feature is not applicable.


Particle sampler shape Parametric coordinates

Parametric coordinates are special sampling coordinates that allow the sampler to find a given sample. They uniquely identify a sample on the shape.


Not using parametric coordinates :
Not using parametric coordinates Not using parametric coordinates : spawn-script

Position and Normal are unrelated,
and picked randomly at different locations on the shape.


Using parametric coordinates :
Using parametric coordinates Not using parametric coordinates : spawn-script

The parametric coordinates are picked randomly on the shape,
and used to retrieve the correlated Position and Normal.


Typically, when sampling a mesh, if you need to sample more than one mesh property (for example, Positions and Normals), if you call samplePosition() and sampleNormals(), they will both sample different points, and the data won't match. you need first to sample parametric coordinates, then give the same coordinates to samplePosition() and sampleNormals(). Then and only then will they both sample identical points on the shape.


If fixed locations are used, the parametric coordinates are ints, otherwise, they are of type 'int3'


Parametric coords only have to be sampled once, and need to be fed WITHOUT MODIFICATION ! to the sampling functions.
Be advised that the parametric coords real contents is entirely up to the discretion of the specific sampler internal workings. it can vary from one platform to the other, from one shape setting to the other, from one version of the hh-FX runtime to the other, etc...
It could be anything from 96 1-bit random values up to a single large 96-bits floating-point value. Don't assume anything. It should be left completely opaque.


example of using parametric coordinates:

	int3	pCoords = Sampler_0.sampleParametricCoords();	// samples a point on the shape, stores it into a temporary variable
	Position = Sampler_0.samplePosition(pCoords);		// samples the position of that point, and moves the particle onto it
	Velocity = Sampler_0.sampleNormal(pCoords);		// samples the normal of that same point, and sets it as the particle's velocity


That's what is used in the skinned mesh samples. Parametric coordinates are sampled at the particle spawn, then stored in a special particle field.

Then in an evolve script, the dynamic skinned mesh positions are sampled at those same parametric coordinates. this will ensure a given particle is always located on the same point on the mesh, regardless of how the mesh moves, and will effectively make the particle "stick" to the animated mesh, and follow it around.
Retrieved from "https://wiki.popcornfx.com/index.php?title=CParticleSamplerShape&oldid=6448"