三个.js可以在半透明粒子中渲染半透明网格吗?

时间:2015-10-18 22:34:23

标签: three.js webgl particle-system

我试图在半透明的粒子云中画出半透明的球体。球体在粒子前面是半透明的,但是一旦它在粒子之间变成不透明(即,如果粒子顶点位于相机和球体表面之间,则球体变得不透明)。查看下面的代码段(点击“整页”,它看起来好多了。)

三个已删除.sortParticles的新版本已在此处发挥作用,但我正在通过复制this example中的sortPoints函数解决此问题。

每个粒子和球体的深度似乎都是准确的,只是失去了不透明度。也许混合在某些情况下失败了?

有没有办法在半透明颗粒中绘制半透​​明网格?

var renderer, scene, camera, sphere;

var particleSystem, uniforms, geometry;

var particles = 200;

var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera(40, WIDTH / HEIGHT, 1, 10000);
    camera.position.z = 70;

    scene = new THREE.Scene();

    uniforms = {

        color: {
            type: "c",
            value: new THREE.Color(0xffffff)
        },
        

    };

    var shaderMaterial = new THREE.ShaderMaterial({

        uniforms: uniforms,
        vertexShader: document.getElementById('vertexshader').textContent,
        fragmentShader: document.getElementById('fragmentshader').textContent,

        depthTest: true,
        depthWrite: false,
        transparent: true

    });
  

    var sphere_geometry = new THREE.SphereGeometry(10, 32, 32);
    var sphere_material = new THREE.MeshNormalMaterial();
    sphere_material.transparent = true;
    sphere_material.opacity = 0.6;
    sphere_material.depthTest = true;
    //sphere_material.depthWrite = false;
    sphere = new THREE.Mesh(sphere_geometry, sphere_material);
    //sphere.renderOrder = -1;
    scene.add(sphere);

    camera.lookAt(sphere.position);

    var radius = 30;

    geometry = new THREE.BufferGeometry();

    var positions = new Float32Array(particles * 3);
    var colors = new Float32Array(particles * 3);
    var sizes = new Float32Array(particles);

    var color = new THREE.Color();

    for (var i = 0, i3 = 0; i < particles; i++, i3 += 3) {

        positions[i3 + 0] = i - 50;
        positions[i3 + 1] = i - 50;
        positions[i3 + 2] = 2*i - 100;

        color.setHSL(i / particles, 1.0, 0.5);

        colors[i3 + 0] = color.r;
        colors[i3 + 1] = color.g;
        colors[i3 + 2] = color.b;

        sizes[i] = 3000;

    }

    geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
    geometry.addAttribute('customColor', new THREE.BufferAttribute(colors, 3));
    geometry.addAttribute('size', new THREE.BufferAttribute(sizes, 1));

    particleSystem = new THREE.Points(geometry, shaderMaterial);

    scene.add(particleSystem);

    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(WIDTH, HEIGHT);

    var container = document.getElementById('container');
    container.appendChild(renderer.domElement);

    //

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

}

function onWindowResize() {

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);

}

function animate() {

    requestAnimationFrame(animate);

    render();

}

function render() {

    var time = Date.now() * 0.005;

    var n = 30;
    sphere.position.z = n * (1 + Math.sin(0.2 * time)) - n * 1.5;

    sortPoints();

    renderer.render(scene, camera);

}

function sortPoints() {
    var vector = new THREE.Vector3();
    // Model View Projection matrix
    var matrix = new THREE.Matrix4();
    matrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
    // matrix.multiply( particleSystem.matrixWorld );
    //
    var index = geometry.getIndex();
    var positions = geometry.getAttribute('position').array;
    var length = positions.length / 3;
    if (index === null) {
        var array = new Uint16Array(length);
        for (var i = 0; i < length; i++) {
            array[i] = i;
        }
        index = new THREE.BufferAttribute(array, 1);
        geometry.setIndex(index);
    }
    var sortArray = [];
    for (var i = 0; i < length; i++) {
        vector.fromArray(positions, i * 3);
        vector.applyProjection(matrix);
        sortArray.push([vector.z, i]);
    }

    function numericalSort(a, b) {
        return b[0] - a[0];
    }
    sortArray.sort(numericalSort);
    var indices = index.array;
    for (var i = 0; i < length; i++) {
        indices[i] = sortArray[i][1];
    }
    geometry.index.needsUpdate = true;
}
body {
        color: #ffffff;
        font-family:Monospace;
        font-size:13px;
        text-align:center;
        font-weight: bold;
        background-color: #000000;
        margin: 0px;
        overflow: hidden;
    }
    #info {
        color: #fff;
        position: absolute;
        top: 0px;
        width: 100%;
        padding: 5px;
        z-index:100;
    }
<script src="http://threejs.org/build/three.min.js"></script>
<div id="info">translucent mesh amidst translucent particles</div>
<script type="x-shader/x-vertex" id="vertexshader">
    attribute float size;
    attribute vec3 customColor;

    varying vec3 vColor;

    void main() {

        vColor = customColor;

        vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);

        gl_PointSize = size / length(mvPosition.xyz);

        gl_Position = projectionMatrix * mvPosition;

    }
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
    uniform vec3 color;

    varying vec3 vColor;

    void main() {

        gl_FragColor = vec4(color * vColor, 0.2);

        

    }
</script>

<div id="container"></div>

0 个答案:

没有答案