0

Using three.js I would like to create the effect of a bright light shining out of the center of a sphere.

Using THREE.lensflare() I get a nice light, but once I put it in a sphere, it disappears. I tried different values for renderOrder, but to no avail.

My JSFiddle is here: http://jsfiddle.net/blwoodley/ds8ydm4t/8/

You can confirm that the lens flare is working by simply commenting out the line where I add the sphere mesh to the scene (line 33).

r71.

var SCREEN_WIDTH = window.innerWidth - 100;
var SCREEN_HEIGHT = window.innerHeight - 100;

var camera, scene, _planeMesh;
var canvasRenderer, webglRenderer;

var container, mesh, geometry, plane;

container = document.createElement('div');
document.body.appendChild(container);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 100000);
camera.position.set( 380, 80, 100 );
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 180, 160, 0 );
var grid = new THREE.Mesh( new THREE.PlaneGeometry( 10000, 10000 ),
                                   new THREE.MeshBasicMaterial( { color: 0xaaaaaa } ) );
var grid = new THREE.GridHelper(400, 40);
//grid.rotation.x = -1.57;
grid.position.y = -20;
scene.add(grid);       

scene.add(spotLight);

camera.lookAt( scene.position );
var transparentmaterial = new THREE.MeshLambertMaterial( {
    color: 0xaaaa00,
    shading: THREE.SmoothShading,
    opacity: .5, transparent: true } );

var sphereGeo = new THREE.SphereGeometry( 32.0, 32, 16 );
var mesh = new THREE.Mesh( sphereGeo,transparentmaterial);
scene.add(mesh);

addLight(scene,0.55, 0.9, 0.5,0,0,0);

// RENDERER
webglRenderer = new THREE.WebGLRenderer({antialias: true, alpha: true });
webglRenderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
webglRenderer.domElement.style.position = "relative";
webglRenderer.setClearColor( 0x000000 );

container.appendChild(webglRenderer.domElement);
animate();

function addLight(scene, h, s, l, x, y, z ) {
        THREE.ImageUtils.crossOrigin = '';
        var textureFlare0 = THREE.ImageUtils.loadTexture('https://s3.amazonaws.com/jsfiddle1234/lensflare0.png');

    var light = new THREE.PointLight( 0xffffff, 1.5, 10 );
    light.color.setHSL( h, s, l );
    light.position.set( x, y, z );
    scene.add( light );
    light = light;

    var flareColor = new THREE.Color( 0xffffff );
    flareColor.setHSL( h, s, l + 0.5 );

    var lensFlare = new THREE.LensFlare( textureFlare0, 200, 0.0, THREE.AdditiveBlending, flareColor );

    lensFlare.position.copy( light.position );
    var lensFlare = lensFlare;

    scene.add( lensFlare );

}   


function animate() {
    requestAnimationFrame(animate);
    render();
}

function render() {
    webglRenderer.render(scene, camera);
}
Bob Woodley
  • 1,246
  • 15
  • 30

1 Answers1

1

Lens flares are rendered last -- after transparent objects.

The problem is the lens flare is not rendered because of the depth test.

One solution to the problem is to prevent depth writes when you renderer the transparent sphere:

transparentmaterial.depthWrite = false;

updated fiddle: http://jsfiddle.net/ds8ydm4t/10/

Another solution is to have two scenes and two render passes -- clearing the depth buffer after the first pass. (How to change the zOrder of object with Threejs?)

three.js r.71

Community
  • 1
  • 1
WestLangley
  • 102,557
  • 10
  • 276
  • 276