如何有选择地使 three.js canvas 中的颜色透明?

How to selectively make a colour in three.js canvas transparent?

我有一个 three.js canvas 从 liquidfun.js 生成。

出于某种原因,canvas 不是透明的。在绘制整个 canvas 后,有没有办法选择性地使 canvas 中的颜色完全透明(在本例中为白色背景)?我尝试设置 context.clearColor(0, 0, 0, 0) 但没有任何区别。

您可能需要 post 一些代码。

如果您使用来自 liquidfun 网站的相同代码,它不会直接使用 WebGL,而是使用 three.js,因此您需要通过找到 three.js 渲染器并调用 renderer.setClearColor。您还需要在创建渲染

时使用 alpha 通道初始化 three.js
var renderer = new THREE.WebGLRenderer({alpha: true});

示例:

// shouldnt be a global :(
var particleColors = [
  new b2ParticleColor(0xff, 0x00, 0x00, 0xff), // red
  new b2ParticleColor(0x00, 0xff, 0x00, 0xff), // green
  new b2ParticleColor(0x00, 0x00, 0xff, 0xff), // blue
  new b2ParticleColor(0xff, 0x8c, 0x00, 0xff), // orange
  new b2ParticleColor(0x00, 0xce, 0xd1, 0xff), // turquoise
  new b2ParticleColor(0xff, 0x00, 0xff, 0xff), // magenta
  new b2ParticleColor(0xff, 0xd7, 0x00, 0xff), // gold
  new b2ParticleColor(0x00, 0xff, 0xff, 0xff) // cyan
];
var container;
var world = null;
var threeRenderer;
var renderer;
var camera;
var scene;
var objects = [];
var timeStep = 1.0 / 60.0;
var velocityIterations = 8;
var positionIterations = 3;
var test = {};
var projector = new THREE.Projector();
var planeZ = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
var g_groundBody = null;

var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;

function printErrorMsg(msg) {
  var domElement = document.createElement('div');
  domElement.style.textAlign = 'center';
  domElement.innerHTML = msg;
  document.body.appendChild(domElement);
}

function initTestbed() {
  camera = new THREE.PerspectiveCamera(70
    , windowWidth / windowHeight
    , 1, 1000);

  try {
    threeRenderer = new THREE.WebGLRenderer({alpha: true});
  } catch( error ) {
    printErrorMsg('<p>Sorry, your browser does not support WebGL.</p>'
                + '<p>This testbed application uses WebGL to quickly draw'
                + ' LiquidFun particles.</p>'
                + '<p>LiquidFun can be used without WebGL, but unfortunately'
                + ' this testbed cannot.</p>'
                + '<p>Have a great day!</p>');
    return;
  }

  threeRenderer.setClearColor(0, 0);
  threeRenderer.setSize(windowWidth, windowHeight);

  camera.position.x = 0;
  camera.position.y = 0;
  camera.position.z = 100;
  scene = new THREE.Scene();
  camera.lookAt(scene.position);

  document.body.appendChild( this.threeRenderer.domElement);

  this.mouseJoint = null;

  // hack
  renderer = new Renderer();
  var gravity = new b2Vec2(0, -10);
  world = new b2World(gravity);
  Testbed();
}

function testSwitch(testName) {
  ResetWorld();
  world.SetGravity(new b2Vec2(0, -10));
  var bd = new b2BodyDef;
  g_groundBody = world.CreateBody(bd);
  test = new window[testName];
}

function Testbed(obj) {
  // Init world
  //GenerateOffsets();
  //Init
  var that = this;
  document.addEventListener('keypress', function(event) {
    if (test.Keyboard !== undefined) {
      test.Keyboard(String.fromCharCode(event.which) );
    }
  });
  document.addEventListener('keyup', function(event) {
    if (test.KeyboardUp !== undefined) {
      test.KeyboardUp(String.fromCharCode(event.which) );
    }
  });

  document.addEventListener('mousedown', function(event) {
    var p = getMouseCoords(event);
    var aabb = new b2AABB;
    var d = new b2Vec2;

    d.Set(0.01, 0.01);
    b2Vec2.Sub(aabb.lowerBound, p, d);
    b2Vec2.Add(aabb.upperBound, p, d);

    var queryCallback = new QueryCallback(p);
    world.QueryAABB(queryCallback, aabb);

    if (queryCallback.fixture) {
      var body = queryCallback.fixture.body;
      var md = new b2MouseJointDef;
      md.bodyA = g_groundBody;
      md.bodyB = body;
      md.target = p;
      md.maxForce = 1000 * body.GetMass();
      that.mouseJoint = world.CreateJoint(md);
      body.SetAwake(true);
    }
    if (test.MouseDown !== undefined) {
      test.MouseDown(p);
    }

  });

  document.addEventListener('mousemove', function(event) {
    var p = getMouseCoords(event);
    if (that.mouseJoint) {
      that.mouseJoint.SetTarget(p);
    }
    if (test.MouseMove !== undefined) {
      test.MouseMove(p);
    }
  });

  document.addEventListener('mouseup', function(event) {
    if (that.mouseJoint) {
      world.DestroyJoint(that.mouseJoint);
      that.mouseJoint = null;
    }
    if (test.MouseUp !== undefined) {
      test.MouseUp(getMouseCoords(event));
    }
  });


  window.addEventListener( 'resize', onWindowResize, false );

  testSwitch("TestWaveMachine");

  render();
}

var render = function() {
  // bring objects into world
  renderer.currentVertex = 0;
  if (test.Step !== undefined) {
    test.Step();
  } else {
    Step();
  }
  renderer.draw();

  threeRenderer.render(scene, camera);
  requestAnimationFrame(render);
};

var ResetWorld = function() {
  if (world !== null) {
    while (world.joints.length > 0) {
      world.DestroyJoint(world.joints[0]);
    }

    while (world.bodies.length > 0) {
      world.DestroyBody(world.bodies[0]);
    }

    while (world.particleSystems.length > 0) {
      world.DestroyParticleSystem(world.particleSystems[0]);
    }
  }
  camera.position.x = 0;
  camera.position.y = 0;
  camera.position.z = 100;
};

var Step = function() {
  world.Step(timeStep, velocityIterations, positionIterations);
};

/**@constructor*/
function QueryCallback(point) {
  this.point = point;
  this.fixture = null;
}

/**@return bool*/
QueryCallback.prototype.ReportFixture = function(fixture) {
  var body = fixture.body;
  if (body.GetType() === b2_dynamicBody) {
    var inside = fixture.TestPoint(this.point);
    if (inside) {
      this.fixture = fixture;
      return true;
    }
  }
  return false;
};

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  threeRenderer.setSize( window.innerWidth, window.innerHeight );
}

function getMouseCoords(event) {
  var mouse = new THREE.Vector3();
  mouse.x = (event.clientX / windowWidth) * 2 - 1;
  mouse.y = -(event.clientY / windowHeight) * 2 + 1;
  mouse.z = 0.5;

  projector.unprojectVector(mouse, camera);
  var dir = mouse.sub(camera.position).normalize();
  var distance = -camera.position.z / dir.z;
  var pos = camera.position.clone().add(dir.multiplyScalar(distance));
  var p = new b2Vec2(pos.x, pos.y);
  return p;
}
body {
        font-family: Monospace;
        background-color: #f0f0f0;
        margin: 0;
        overflow: hidden;
        background-color: red;  /* just in case image doesn't load */
        background-image: url(https://i.imgur.com/v38pV.jpg);
        background-size: cover;
    }
<script src="https://google.github.io/liquidfun/testbed/liquidfun.js"></script>

  <!-- testbed code !-->
  <script src="https://google.github.io/liquidfun/testbed/testbed/renderer.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/three.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/testbed.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/utils.js"></script>

  <!-- tests !-->
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testDamBreak.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testDrawingParticles.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testElasticParticles.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testImpulse.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testLiquidTimer.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testParticles.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testRigidParticles.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testSoup.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testSoupStirrer.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testSparky.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testSurfaceTension.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testTheoJansen.js"></script>
  <script src="https://google.github.io/liquidfun/testbed/testbed/tests/testWaveMachine.js"></script>

  <body onload="initTestbed()"></body>

  <div style="position:absolute;float:right;z-index:1;border:1px solid #ccc;font:16px/26px Georgia, Garamond, Serif;overflow:auto;background:white">

      <select id="tests" onchange="testSwitch(this.value)">
        <option value="TestDamBreak">Dam Break</option>
        <option value="TestDrawingParticles">Drawing Particles</option>
        <option value="TestElasticParticles">Elastic Particles</option>
        <option value="TestImpulse">Impulse</option>
        <option value="TestLiquidTimer">Liquid Timer</option>
        <option value="TestParticles">Particles</option>
        <option value="TestRigidParticles">Rigid Particles</option>
        <option value="TestSoup">Soup</option>
        <option value="TestSoupStirrer">Soup Stirrer</option>
        <option value="TestSparky">Sparky</option>
        <option value="TestSurfaceTension">SurfaceTension</option>
        <option value="TestTheoJansen">Theo Jansen</option>
        <option value="TestWaveMachine" selected="selected">Wave Machine</option>
      </select>

  </div>

另一方面,如果您直接使用 WebGL,则默认情况下 canvas 具有 alpha 且其清晰颜色为 0,0,0,0,因此如果您看不到透明度,那是您的事情'已经完成了您自己的代码或您用来设置 WebGL 的任何库。

注意:使用 WebGL, canvas and transparency

还应注意其他问题