加法混合

书名:代码本色:用编程模拟自然系统
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
目录

4.13 图像纹理和加法混合

1、加法混合

  • 计算机图形学有很多颜色混合算法,这些算法通常称作“混合(blend)模式”。

  • 在Processing中,如果在一幅图像之上绘制另一幅图像,默认显示最上层图像——这通常称为“常规”混合模式。

  • 如果图像有一定的透明度(就像模拟烟效程序中用到的图像),Processing会使用alpha透明度混合算法将一定比例的背景像素和前景像素结合起来,混合比例根据alpha值确定。

  • 除此之外,我们还可以使用其他混合模式,对粒子系统来说,有一种混合模式非常适
    用,它就是“加法(additive)模式”。
    Processing中的加法混合模式是由Robert Hodgin开发的,他在粒子系统和力的模拟上很有建树。他开发了Magnetosphere,后来成为iTunes的可视化效果。

  • 实际上,加法混合是最简单的混合算法之一,它只是将两个图层的像素值相加(当然,相加结果的最大值是255),最后形成的效果就是:随着图层增多,色彩变得越来越亮。

  • 为了在Processing中使用加法混合,你需要使用P2D或者P3D渲染器。

2、示例

示例代码4-9 加法混合

ParticleSystem ps;

PImage img;

void setup() {
  size(640, 360, P2D);

  // Create an alpha masked image to be applied as the particle's texture
  img = loadImage("texture.png");

  ps = new ParticleSystem(0, new PVector(width/2, 50));
}

void draw() {

  // Additive blending!
  blendMode(ADD);

  background(0);

  ps.run();
  for (int i = 0; i < 10; i++) {
    ps.addParticle();
  }
}

Particle.pde

class Particle {
  PVector pos;
  PVector vel;
  PVector acc;
  float lifespan;

  // Another constructor (the one we are using here)
  Particle(PVector l) {
    // Boring example with constant acceleration
    acc = new PVector(0,0.05,0);
    vel = new PVector(random(-1,1),random(-1,0),0);
    vel.mult(2);
    pos = l.copy();
    lifespan = 255;
  }

  void run() {
    update();
    render();
  }

  // Method to update position
  void update() {
    vel.add(acc);
    pos.add(vel);
    lifespan -= 2.0;
  }

  // Method to display
  void render() {
    imageMode(CENTER);
    tint(lifespan);
    image(img,pos.x,pos.y);
  }
  
  // Is the particle still useful?
  boolean isDead() {
    if (lifespan <= 0.0) {
      return true;
    } else {
      return false;
    }
  }
}

ParticleSystem.pde

class ParticleSystem {

  ArrayList particles;    // An arraylist for all the particles
  PVector origin;        // An origin point for where particles are birthed

  PImage tex;

  ParticleSystem(int num, PVector v) {
    particles = new ArrayList();              // Initialize the arraylist
    origin = v.get();                        // Store the origin point
    for (int i = 0; i < num; i++) {
      particles.add(new Particle(origin));    // Add "num" amount of particles to the arraylist
    }
  }

  void run() {
    for (int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      p.run();
      if (p.isDead()) {
        particles.remove(i);
      }
    }
  }

  void addParticle() {
    particles.add(new Particle(origin));
  }

  void addParticle(Particle p) {
    particles.add(p);
  }

  // A method to test if the particle system still has particles
  boolean dead() {
    if (particles.isEmpty()) {
      return true;
    } 
    else {
      return false;
    }
  }
}

3、运行结果

版权声明:
作者:倾城
链接:https://www.techfm.club/p/42700.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>