three.js

Three.js easy round / circular particles

Today I came across a question on stackoverflow asking how to make round particles in Three.js ( Three.js - give particles round form ).
I have seen questions like this a few times and the answers always seem to be to load an image and use it as a texture. People seem to forget that you can use a canvas as a texture map and you can draw pretty much what ever you want on a canvas.
I have demonstrated this before when someone asked " Is it possible to use 2 textures (one on top of the other) as a Material without using custom Shaders? ". See the fiddle HERE .

Basically, all you have to do is create a function that draws your canvas and returns a THREE.Texture object, assigning this THREE.Texture object to the map property of the Material.

Here is a function that creates a circle on a canvas:

 function createCircleTexture(color, size) { 
var matCanvas = document.createElement('canvas');
matCanvas.width = matCanvas.height = size;
var matContext = matCanvas.getContext('2d');
// create texture object from canvas.
var texture = new THREE.Texture(matCanvas);
// Draw a circle
var center = size / 2;
matContext.beginPath();
matContext.arc(center, center, size/2, 0, 2 * Math.PI, false);
matContext.closePath();
matContext.fillStyle = color;
matContext.fill();
// need to set needsUpdate
texture.needsUpdate = true;
// return a texture made from the canvas
return texture;
}

Here is how to use it:

 var pointMaterial = new THREE.PointsMaterial({ 
size: 20,
map: createCircleTexture('#00ff00', 256),
transparent: true,
depthWrite: false
});

depthWrite must be set to false as per THIS issue on stack.

Three.js car paint shader - recreating the Radeon 9700 demo

Recently while experimenting with three.js shader materials I stumbled across RenderMonkey . It is old software that is no longer supported and the description on the website says: "RenderMonkey is a rich shader development environment for both programmers and artists that facilitates the collaborative creation of real-time shader effects."

As I was going through the different shader examples that RenderMonkey comes with, I noticed a car paint shader which I remember was a demo when ATI released the Radeon 9700 back in 2002 (I actually had one of these video cards and the demo can be seen here ). As I have an interest in creating cars in Three.js, I thought it would be a good exercise to try to recreate the demo with a shader in Three.js.

Notes:

  • I did not use the original model, I used a model available here as it was free and included a normal map which the original RenderMonkey shader used.
  • I computed normals form the normal map the same way as the PhongMaterial in three.js rather than the way it was done in the original shader.
  • The normal is quite rough, turn the normalScale down to see the effect with a more smooth surface.
  • I used a different environment map with a brightly lit floor so the reflections will look different. You can turn on the cube map with the controls on the right.
  • I am in no way a GLSL expert, I am barely even a novice and have pathetic math skills so there are probably better ways to do it or there may be errors. It was really just a learning experience for me that I thought I would share.
  • I really hate writing long blog posts so wont be
  • ...

Three.js standard materials vertex and fragment shaders reference

When playing around and experimenting with Three.js ShaderMaterial I often want to take a look at how the standard Three.js materials are done. Looking through the code or constantly outputting the shaders in the javascript console is a pain in the arse. I though I would post them here for future reference and in case anyone else was interested. These were output from Three.js version 70.

MeshBasicMaterial Vertex Shader
 #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) 

varying vec2 vUv;
uniform vec4 offsetRepeat;

#endif

#ifdef USE_LIGHTMAP

varying vec2 vUv2;

#endif
#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )

varying vec3 vReflect;

uniform float refractionRatio;

#endif

#ifdef USE_COLOR

varying vec3 vColor;

#endif
#ifdef USE_MORPHTARGETS

#ifndef USE_MORPHNORMALS

uniform float morphTargetInfluences[ 8 ];

#else

uniform float morphTargetInfluences[ 4 ];

#endif

#endif
#ifdef USE_SKINNING

uniform mat4 bindMatrix;
uniform mat4 bindMatrixInverse;

#ifdef BONE_TEXTURE

uniform sampler2D boneTexture;
uniform int boneTextureWidth;
uniform int boneTextureHeight;

mat4 getBoneMatrix( const in float i ) {

float j = i * 4.0;
float x = mod( j, float( boneTextureWidth ) );
float y = floor( j / float( boneTextureWidth
...

Experimenting with Three.js shaders and the ShaderMaterial

Lately when using Three.js I have needed some very specific material qualities that the built in Three.js materials did not allow for so I have started experimenting with the Three.ShaderMaterial . This material allows you to write you own GLSL shaders for Three.js. My hope is that I can get a good understanding of GLSL and implement some of my own shaders and materials in Three.js even with my limited math skills and no prior experience with GLSL.

On this page I will link to some of my own Three.ShaderMaterial experiments and try to update it as I learn more.

You may also want to take a look at my implementation of a three.js car paint shader (a recreartion of the Radeon 9700 demo).

NOTE: these examples are using R70 of THREE.js and material implementation seems to have changed a bit since the R70 release, so some of these may not work on the current release of THREE.js

Custom Mesh Shader Materials

On most of my experiments there are buttons under "Source" to view both the vertex shader source and the fragment shader source.

  • Basic color

    basic color shader

    This is the most basic of shaders, simple applying a color via the fragment shader.

  • Vertex position color

    Vertex position color shader

    Takes the fragment color from the vertex position. Simple experiment trying to understand how to send varyings from the vertex shader to the fragment shader

  • Uv position color

    Uv position color shader

    Takes the fragment color from the uv position. Again trying to understand how to send varyings from the vertex shader to the fragment shader

  • ...

Using Three.js with jsfiddle

Using Three.js in a fiddle on the site jsfiddle.net is really quite easy but I keep coming across people having trouble with it. So here are a couple of tips when trying to set up a Three.js scene in a fiddle

Including the Three.js source

When creating a fiddle to use Three.js the most important part is including the Three.js library itself. You can select to include Three.js from the "Framework and Extensions" section but this will probably not be the latest version of Three.js. To include the latest version it is best to include it from the github repository itself, so you want to enter the path in the "External resources" section. But directly including the github path will result in an error, even with the github raw path. What you need to do is include the path from rawgit.com/ , which is rawgit.com/mrdoob/three.js/master/build/three.min.js.
Now you have Three.js included in the page correctly, you can start creating your 3D scene. If you prefer to work from a base, I have created on here .

Here is how the base looks.

Using images in materials

When using images in Three.js materials in a fiddle you will probably come across the CORS (Cross-Origin Resource Sharing) problem.
A way to get around this problem is to add the image DataURL as a variable, the same as if you call toDataURL() on a canvas element.
You can get an images DataURL DatURL.net
Here is an example that uses a variable with image data as the source for the THREE.ImageUtils.loadTexture() function.

Here is an example of using image data as a texture in a fiddle.

Update:
Instead of using a dataURL...

Useful Three.js Links

Here is a list of useful Three.js links, mainly for my own reference but other may find it useful too.

  • Three.js homepage
  • Three.js documentation
  • Three.js Google+
  • Tutorials
    • Intro to WegGL with Three.js
  • Tools
    • Three.js template generator
  • Articles
    • The Hobbit Experience - a Good article to read up on three.js performance optimisations

  • Demos
    • Three.js examples
    • stemkoski.github.io