流动粒子

这是一个使用ParticleBlinkScript节点可以实现的目标的稍微复杂的示例,其结果是使粒子在对象周围流动。

以下示例流动粒子内核的结果

无法从ParticleBlinkScript节点访问几何,因此可以在translaterotatescale ParticleBlinkScript节点的旋钮可访问translaterotatescale来自的值Cylinder几何节点。的radius也可以使用表达式链接。

以下内核的示例节点图

该内核的基本原理是生成一个矢量场,该矢量场给出空间中每个点处粒子的流动方向。每个粒子的速度矢量都会更改为指向流动方向。

小费:  避免物体只是该示例的一种使用方式,通过使用不同的流场函数可以实现许多不同的效果。

这是实现此功能的内核的相关部分。的fieldAt函数返回空间中某一点的流动方向,并且处理函数将每个粒子的速度矢量重定向为沿流矢量指向其位置。

float3 fieldAt( float3 pos )

{

return pos; // A field which just points away from the origin

}

void process()

{

float3 p = p_position();

float3 v = p_velocity();

float3 field = fieldAt( p );

field.normalize();

p_velocity() = field*v.length();

}

以下示例内核实现了一个函数,该函数使粒子围绕虚构的圆柱体流动。

kernel ParticleCylinderFlowKernel : ImageComputationKernel<ePixelWise>

{

Image<eReadWrite> p_position;

Image<eReadWrite> p_velocity;

Image<eReadWrite> p_orientation;

param:

float3 _origin; // Origin of the cylinder

float3 _axis; // Axis of the cylinder

float _radius; // Radius of the cylinder

float3 _flow; // Direction of flow

float _strength; // The strength of the interaction with the flow

float _falloff; // The speed at which the force falls off with distance from the surface

local:

float3 _normalizedAxis;

void define() {

defineParam(_origin, "pa_origin", float3(0.0f, 0.0f, 0.0f));

defineParam(_axis, "pa_axis", float3(0.0f, 1.0f, 0.0f));

defineParam(_flow, "pa_flow", float3(0.0f, 0.0f, -1.0f));

defineParam(_radius, "pa_radius", 1.0f);

defineParam(_strength, "pa_strength", 1.0f);

defineParam(_falloff, "pa_falloff", 1.0f);

}

void init() {

_normalizedAxis = normalize(_axis);

}

float3 mix(float3 a, float3 b, float t ) {

return a+t*(b-a);

}

void process() {

float3 p = p_position()-_origin;

float l = length(p);

if ( l != 0.0f ) {

float3 axis = _axis/l;

p -= _origin+_normalizedAxis*dot(p, _normalizedAxis);

float r = length(p);

float3 normal = p;

float3 d = cross(normal, _flow);

float3 tangent = cross(d, normal);

float fall;

if ( r >= _radius )

fall = exp(-_ falloff *(r-_radius));

else

下降= 1.0f;

float3 force = tangent*_strength;

force = mix( _flow, force, fall );

l = length(force);

if ( l != 0.0f ) {

力=力/ l;

浮动速度=长度(p_velocity());

p_velocity()=速度*力;

p_orientation()= float4(0.0,force.x,force.y,force.z);

}

}

}

};

小费:  有很多方法可以使用此内核进行实验,请尝试使用流体模拟来生成用于模拟烟雾的流场。