粒子效果Particle文档

版本: 1.16.200.2(正式版)


Basic Structure Overview

Particle effects consist of basic render parameters, and a set of components. Components can be placed in any order.
Outline:

{
  "format_version": "1.10.0",
  "particle_effect": {
    "description": {
      "identifier": <string>, // e.g. "minecraft:test_effect", this is the name the particle emitter is referred to as
      "basic_render_parameters": {
          "material": <string> // Minecraft material to use for emitter
          "texture": <string> // Minecraft texture to use for emitter
      }
    },
    "curves": {
      // curve details
    },
    "events": {
      // events details
    },
    "components": 
      // emission rate components

      // emission lifetime components

      // emission shape components, or the shape of the effect as defined
      // by particle emission position and directions

      // emitter local space components

      // components that control initial state of particles

      // components that control/direct motion of particles

      // components that affect how the particle is drawn

      // components that affect particle lifetime
    }
  }
}

Component Concept

The particle system is component based. What this means is that particle effects are composed via a set of components. In order for an effect to do something, you add a component that handles that aspect of the effect. For example, an emitter usually needs to have rules for its lifetime, thus the effect should have one or more lifetime components that handle lifetime duties for the emitter and emitted particles.

The idea is that new components can be added later, and one can combine components (where it makes sense) to get different behaviors. A particle might have a Dynamic component for moving around, and a Collision component for handling interaction with the terrain, for example.

Think of components as telling the particle system what you want the emitter or particle to do, rather than exposing a list of particle parameters and having to wrangle those parameters to get the desired behavior.

Current Component List

For fields in these components, the following shorthand is used:

<float> - field takes a floating point input
<float/molang> - field takes a floating point input, or a MoLang expression
<default:val> - specifies the default value used if field isn't specified
<bool> - "true" or "false"
<string> - a string ("this is a string"
<default> - not a part of the particular line, this just says what this field defaults to if not specified

Emitter Components

Initial State Components

Emitter Local Space component

"minecraft:emitter_local_space": {
    "position": <bool>
    "rotation": <bool>
    "velocity": <bool>
}

Emitter Initialization component

"minecraft:emitter_initialization": {
  "creation_expression": <molang>, // this is run once at emitter startup
  "per_update_expression": <molang> // this is run once per emitter update
}


Emitter Rate Components

Emitter Rate Instant component

"minecraft:emitter_rate_instant": {
    // this many particles are emitted at once
    // evaluated once per particle emitter loop
    "num_particles": <float/molang> <default:10>
}

Emitter Rate Steady component

"minecraft:emitter_rate_steady": {
    // how often a particle is emitted, in particles/sec
    // evaluated once per particle emitted
    "spawn_rate": <float/molang> <default:1>

    // maximum number of particles that can be active at once for this emitter
    // evaluated once per particle emitter loop
    "max_particles": <float/molang> <default:50>
}

Emitter Rate Manual component

"minecraft:emitter_rate_manual": {
    // evaluated once per particle emitted
    "max_particles": <float/molang> <default:50>
}

Emitter Lifetime Components

Emitter Lifetime Looping component

"minecraft:emitter_lifetime_looping": {

    // emitter will emit particles for this time per loop
    // evaluated once per particle emitter loop
    "active_time": <float/molang> <default:10>

    // emitter will pause emitting particles for this time per loop
    // evaluated once per particle emitter loop
    "sleep_time": <float/molang> <default:0>
}

Emitter Lifetime Once component

"minecraft:emitter_lifetime_once": {
    // how long the particles emit for
    // evaluated once
    "active_time": <float/molang> <default:10>
}

Emitter Lifetime Expression component

"minecraft:emitter_lifetime_expression": {
    // When the expression is non-zero, the emitter will emit particles.
    // Evaluated every frame
    "activation_expression": <float/molang> <default:1>

    // Emitter will expire if the expression is non-zero.
    // Evaluated every frame
    "expiration_expression": <float/molang> <default:0>
}

Emitter Lifetime Events component

"minecraft:emitter_lifetime_events": {
      // all events use the event names in the event section
      // all events can be an array or a string
      "creation_event": [ <string>, ...] // fires when the emitter is created
      "creation_event": <string>
      "expiration_event": [ <string>, ...] // fires when the emitter expires (does not wait for particles to expire too)
      "expiration_event": <string>

      // event timeline
      "timeline: {
        // a series of times, e.g. 0.0 or 1.0, that trigger the event
        // these get fired on every loop the emitter goes through
        // "time" is the time, e.g. one line might be:
        // "0.4": "event"
        "time": [ <string>, ... ]
        "time": <string>
      }
    }

    // travel_distance_events
    "travel_distance_events: {
        // a series of distances, e.g. 0.0 or 1.0, that trigger the event
        // these get fired when the emitter has moved by the specified input 
    // distance, e.g. one line might be:
        // "0.4": "event"
        "distance": [ <string>, ... ]
        "distance": <string>
    }

    // looping_travel_distance_events
    "looping_travel_distance_events: [
        // a series of events that occur at set intervals
    // these get fired every time the emitter has moved the specified input
    // distance from the last time it was fired.
    // An example for how to format these events would be:
        // {
        //   "distance": 1.0,
        //   "effects": [ "effect_one" ]
        // },
        // {
        //   "distance": 2.0,
        //   "effects": [ "effect_two" ]
        // }
    //
    // Note that "effect_one" and "effect_two" must be defined events within the particle_effect
    ]

}

Emitter Shape Components

Emitter Shape Point component

"minecraft:emitter_shape_point": {
    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // specifies the direciton of particles.  
    // evaluated once per particle emitted
    "direction": [<float/molang>, <float/molang>, <float/molang>]
}

Emitter Shape Sphere component

"minecraft:emitter_shape_sphere": {
    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // sphere radius
    // evaluated once per particle emitted
    "radius": <float/molang> <default:1>

    // emit only from the surface of the sphere
    "surface_only": <bool> <default:false>

    // specifies the direction of particles.  Defaults to "outwards"
    "direction": "inwards" // particle direction towards center of sphere
    "direction": "outwards" // particle direction away from center of sphere
    // evaluated once per particle emitted
    "direction": [<float/molang>, <float/molang>, <float/molang>]
}

Emitter Shape Box component

"minecraft:emitter_shape_box": {
    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // box dimensions
    // these are the half dimensions, the box is formed centered on the emitter
    // with the box extending in the 3 principal x/y/z axes by these values
    "half_dimensions": [ <float/molang>, <float/molang> <float/molang ],

    // emit only from the surface of the sphere
    "surface_only": <bool> <default:false>

    // specifies the direction of particles.  Defaults to "outwards"
    // evaluated once per particle emitted
    "direction": "inwards" // particle direction towards center of sphere
    "direction": "outwards" // particle direction away from center of sphere
    "direction": [<float/molang>, <float/molang>, <float/molang>]
}


Emitter Shape Custom component

"minecraft:emitter_shape_custom": {
    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // specifies the direciton for the particle
    // evaluated once per particle emitted
    "direction": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]    
}

Emitter Shape Entity-AABB component

"minecraft:emitter_shape_entity_aabb": {
    // emit only from the surface of the sphere
    "surface_only": <bool> <default:false>

    // evaluated once per particle emitted
    // defaults to outwards
    "direction": "inwards" // particle direction towards center of sphere
    "direction": "outwards" // particle direction away from center of sphere
    "direction": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]    
}


Emitter Disc component

"minecraft:emitter_shape_disc": {
    // specifies the normal of the disc plane, the disc will be perpendicular to this direction
    // defaults to [ 0, 1, 0 ]
    "plane_normal": "x", // this variant has the normal in the x axis
    "plane_normal": "y", // this variant has the normal in the y axis
    "plane_normal": "z", // this variant has the normal in the z axis
    "plane_normal": [ <float/molang>, <float/molang>, <float/molang> ], // custom direction for the normal

    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // disc radius
    // evaluated once per particle emitted
    "radius": <float/molang> <default:1>

    // emit only from the edge of the disc
    "surface_only": <bool> <default:false>

    // specifies the direction of particles.  Defaults to "outwards"
    "direction": "inwards" // particle direction towards center of disc
    "direction": "outwards" // particle direction away from center of disc
    // evaluated once per particle emitted
    "direction": [<float/molang>, <float/molang>, <float/molang>]
}

Particle Components

Particle Initial State Components

Particle Initial State component

"minecraft:particle_initial_spin": {
    // specifies the initial rotation in degrees
    // evaluated once
    "rotation": <float/molang> <default:0>

    // specifies the spin rate in degrees/second
    // evaluated once
    "rotation_rate": <float/molang> <default:0>
}

Particle Initial Speed component

// evaluated once
"minecraft:particle_initial_speed": <float/molang> <default:0>

"minecraft:particle_initial_speed" [<float/molang>, <float/molang>, <float/molang>],


Particle Motion Components

Particle Motion Dynamic component

"minecraft:particle_motion_dynamic": {
    // the linear acceleration applied to the particle, defaults to [0, 0, 0].
    // Units are blocks/sec/sec
    // An example would be gravity which is [0, -9.8, 0]
    // evaluated every frame
    "linear_acceleration": [<float/molang>, <float/molang>, <float/molang>],

    // using the equation:
    // acceleration = -linear_drag_coefficient*velocity
    // where velocity is the current direction times speed
    // Think of this as air-drag.  The higher the value, the more drag
    // evaluated every frame
    "linear_drag_coefficient": <float/molang> <default:0>

    // acceleration applies to the rotation speed of the particle
    // think of a disc spinning up or a smoke puff that starts rotating
    // but slows down over time
    // evaluated every frame
    // acceleration is in degrees/sec/sec
    "rotation_acceleration" <float/molang> <default:0>

    // drag applied to retard rotation
    // equation is rotation_acceleration += -rotation_rate*rotation_drag_coefficient
    // useful to slow a rotation, or to limit the rotation acceleration
    // Think of a disc that speeds up (acceleration) 
    // but reaches a terminal speed (drag)
    // Another use is if you have a particle growing in size, having
    // the rotation slow down due to drag can add "weight" to the particle's
    // motion
    "rotation_drag_coefficient" <float/molang> <default:0>
}

Particle Motion Parametric component

"minecraft:particle_motion_parametric": {
    // directly set the position relative to the emitter. 
    // E.g. a spiral might be:
    // "relative_position": ["Math.cos(Params.LifeTime)", 1.0, 
    //                       "Math.sin(Params.Lifetime)"]
    // defaults to [0, 0, 0]
    // evaluated every frame
    "relative_position": [<float/molang> <float/molang> <float/molang>]

    // directly set the 3d direction of the particle
    // doesn't affect direction if not specified
    // evaluated every frame
    "direction": [<float/molang> <float/molang> <float/molang]

    // directly set the rotation of the particle
    // evaluated every frame
    "rotation": <float/molang> <default:0>
}}

Particle Motion Collision component

"minecraft:particle_motion_collision": {
    // enables collision when true/non-zero.
    // evaluated every frame
    "enabled": <bool/molang> <default:true>

    // alters the speed of the particle when it has collided
    // useful for emulating friction/drag when colliding, e.g a particle
    // that hits the ground would slow to a stop.
    // This drag slows down the particle by this amount in blocks/sec
    // when in contact
    "collision_drag": <float>

    // used for bouncing/not-bouncing
    // Set to 0.0 to not bounce, 1.0 to bounce back up to original hight
    // and in-between to lose speed after bouncing.  Set to >1.0 to gain energy on each bounce
    "coefficient_of_restitution": <float>

    // used to minimize interpenetration of particles with the environment
    // note that this must be less than or equal to 1/2 block
    "collision_radius": <float>

    // triggers expiration on contact if true
    "expire_on_contact": <bool>

    // triggers an event
    // array of individual events
    "events": [
        {
          // triggers the specified event if the conditions are met
          "event": <string>
          // optional minimum speed for event triggering
          "min_speed": <float> // default/minimum is 2 blocks/sec
        },
    ],
    "events": { // can be an individual event as well
        // triggers the specified event if the conditions are met
        "event": <string>
        // optional minimum speed for event triggering
        "min_speed": <float> // default/minimum is 2 blocks/sec
    }
}


Particle Appearance Components

Particle Appearance Billboard component

"minecraft:particle_appearance_billboard": {
    // specifies the x/y size of the billboard
    // evaluated every frame
    "size": [<float/molang>, <float/molang>],

    // used to orient the billboard.  Options are:
    // "rotate_xyz" - aligned to the camera, perpendicular to the view axis
    // "rotate_y" - aligned to camera, but rotating around world y axis
    // "lookat_xyz" - aimed at the camera, biased towards world y up
    // "lookat_y" - aimed at the camera, but rotating around world y axis
    // "direction_x" - unrotated particle x axis is along the direction vector, unrotated y axis attempts to aim upwards
    // "direction_y" - unrotated particle y axis is along the direction vector, unrotated x axis attempts to aim upwards
    // "direction_z" - billboard face is along the direction vector, unrotated y axis attempts to aim upwards
  // emitter_transform_xy, // orient the particles to match the emitter's transform (the billboard plane will match the transform's xy plane).
  // emitter_transform_xz, // orient the particles to match the emitter's transform (the billboard plane will match the transform's xz plane).
  // emitter_transform_yz, // orient the particles to match the emitter's transform (the billboard plane will match the transform's yz plane).
  
    //"face_camera_mode": <string>

    // Specifies how to calculate the direction of a particle, this will be used by facing modes that require a direction as input (for instance: lookat_direction and direction)
    // Options are:
    // "derive_from_velocity" - The direction matches the direction of the velocity.
    // "custom_direction" - The direction is specified in the json definition using a vector of floats or molang expressions.
    // If the direction subsection is not defined, the default will be "derive_from_velocity" mode with a "min_speed_threshold" of 0.01.
    "direction": {
        "mode": "derive_from_velocity" or "custom_direction",
        "min_speed_threshold": <float> // only used in "derive_from_velocity" mode. The direction is set if the speed of the particle is above the threshold. The default is 0.01
        "custom_direction": [ <float/molang>, <float/molang>, <float/molang> ], // only used in "custom_direction" mode. Specifies the direction vector
    }

    // specifies the UVs for the particle.  
    "uv": {
        // specifies the assumed texture width/height
        // defaults to 1
        // when set to 1, UV's work just like normalized UV's
        // when set to the texture width/height, this works like texels
        "texturewidth": <int>,
        "textureheight": <int>,

        // Assuming the specified texture width and height, use these 
        // uv coordinates.  
        // evaluated every frame
        "uv": [<float/molang>, <float/molang>],
        "uv_size": [<float/molang>, <float/molang>],

        // alternate way via specifying a flipbook animation
        // a flipbook animation uses pieces of the texture to animate, by stepping over time from one 
        // "frame" to another
        "flipbook": {
            "base_UV": [ <float/molang>, <float/molang> ], // upper-left corner of starting UV patch
            "size_UV": [ <float>, <float> ], // size of UV patch
            "step_UV": [ <float>, <float> ], // how far to move the UV patch each frame
            "frames_per_second": <float>, // default frames per second
            "max_frame": <float/molang>, // maximum frame number, with first frame being frame 1
            "stretch_to_lifetime": <bool>, // optional, adjust fps to match lifetime of particle. default=false
            "loop":  <bool> // optional, makes the animation loop when it reaches the end? default=false
        }
    }
}

Particle Appearance Tinting component

// color fields are special, they can be either an RGB, or a "#RRGGBB"
// field (or RGBA or "AARRGGBB").  If RGB(A), the channels are
// from 0 to 1.  If the string "#AARRGGBB", then the values are
// hex from 00 to ff.
//
// this pseudo-type will be denoted by <color>
"minecraft:particle_appearance_tinting": {
    // interpolation based color
    "color": {
        // an array of colors
        // there are two ways to specify the array of colors
        // the first method is to just have an array of colors
        // these will be interpreted to be equally spaced, with the entire
        // range going from 0 to 1
        //
        // the second option is to specify a value/color pair list
        // this will cause the colors to appear when their specified value
        // occurs in the interpolant, and interpolated in between.  Note
        // that this will be sorted
        "gradient": [ <color>, <color>, ...],
        "gradient": {
        <float>: <color>,
        <float>: <color>,
        ...
        }
        "interpolant": <float/molang> // hint: use a curve here!
    }

    // directly set the color
    "color": <color>
    // examples of direct color field:
    "color": "#ff0000"
    "color": [1, 0, 0]
},


Particle Appearance Lighting

"minecraft:particle_appearance_lighting": {}

Particle Lifetime Components

Particle Lifetime Expression component

"minecraft:particle_lifetime_expression": {
    // this expression makes the particle expire when true (non-zero)
    // The float/expr is evaluated once per particle
    // evaluated every frame
    "expiration_expression": <float/molang> <default:0>
 
  // alternate way to express lifetime
    // particle will expire after this much time
    // evaluated once
    "max_lifetime": <float/molang>
}

Particle Lifetime Events component

"minecraft:particle_lifetime_events": {
      // all events use the event names in the event section
      // all events can be either an array or a string
      "creation_event": [<string>, ...] // fires when the particle is created
      "creation_event": <string> 
      "expiration_event": [<string>, ...] // fires when the particle expires (does not wait for particles to expire too)
      "expiration_event": <string>,

      "custom_events: {
        {
          "eventtrigger" molang,
          "eventname": event
        },
        ...
      }

      // event timeline
      "timeline": {
        // a series of times, e.g. 0.0 or 1.0, that trigger the event
        // "time" is the time, e.g. one line might be:
        // "0.4": "event"
        "time": [<string>", ...]
        "time": <string>
      }
}

Particle Expire If In Blocks component

"minecraft:particle_expire_if_in_blocks" [
    // minecraft block names, e.g. 'minecraft:water', 'minecraft:air'
    // these are typically the same name as in the /setblock command
    // except for the minecraft: prefix
    "blockname1",
    "blockname2", 
    ...
],

Particle Expire If Not In Blocks component

"minecraft:particle_expire_if_not_in_blocks" [
    // minecraft block names, e.g. 'minecraft:water', 'minecraft:air'
    // these are typically the same name as in the /setblock command
    // except for the minecraft: prefix
    "blockname1",
    "blockname2", 
    ...
],

Particle Lifetime Kill-Plane component

// A*x + B*y + C*z + D = 0
// with the parameters being [ A, B, C, D ]
"minecraft:particle_kill_plane": [ <float>, <float>, <float>, <float> ]


Curves

Curves are interpolation values, with inputs from 0 to 1, and outputs based on the curve. The result of the curve is a MoLang variable of the same name that can be referenced in MoLang in components. For each rendering frame for each particle, the curves are evaluated and the result is placed in a MoLang variable of the name of the curve.

    "curves": {
      // "molangvar" is the MoLang variable to be used later in MoLang expressions
      // for example "variable.mycurve" here would make the result of the curve
      // available in MoLang as "variable.mycurve".  Note that all variables must begin with "variable."
      "molangvar": {
        // type can be "linear", "bezier", "bezier_chain", or "catmull_rom"
        // "linear" is a series of nodes, equally spaced between 0 and 1 (after applying input/horizontal_range)
        // "bezier" is a 4-node bezier spline, with the first and last point being the values at 0 and 1
        //   and the middle two points forming the slope lines at 0.33 for the first point and 0.66 for the second
        // "catmull_rom" is a series of curves which pass through all but the last/first node.  The first/last nodes
        // are used to form the slope of the second/second-last points respectively.  All points are evenly spaced.
        // "bezier_chain" is a chain of bezier splines.  See below for the node configuration.  A series of points are
        //   specified, along with their corresponding slopes, and each segment will use it's pair of points and
        //   slopes to form a bezier spline.  Each point other than first/last is shared between it's pair of 
        //   spline segments.
        "type": type, 

        // control nodes for curve.  These are assumed to be equally
        // spaced, e.g. first node is at input value 0, second at 0.25, etc
        // this notation works only for linear, bezier, and catmull_rom
        "nodes": [<float/molang>, <float/molang>, <float/molang>, <float/molang>],

        // control nodes for bezier_chain
        // the nodes will be sorted prior to parsing, so if you declare nodes 0.3, 0.6, 0.5, they will be
        // re-ordered to 0.3, 0.5, 0.6
        "nodes": {
            // the key values map to the "input" field
            "0.3": {
                "value": "5", // the output of the curve
                "left_value": "2", // when curve comes from the left of the node, what point does it use?
                "right_value": "3", // when curve comes from the right side of the node, what point does it use?
                "slope": "3", // the slope of the node, both sides
                "left_slope: "0.4", // the left slope of the node
                "right_slope": "2", // the right slope of the node
            },
            ... // more nodes
        },

        // what is the input value to use
    // for example, "variable.particle_age/variable.particle_lifetime would result in an input from 0 to 1 over
    // the lifetime of the particle, while variable.particle_age would have input of how old the particle is in seconds
        "input": <float/molang>,

        // what is the range the input is mapped onto
        // between 0 and this value
    // note: this field is deprecated and optional (default: 1.0)
    // note: this field is ignored for bezier_chain
        "horizontal_range": <float/molang>
      }
    }