function createRenderMaterial (textureSize) {
const textureLoader = new THREE.TextureLoader()
const material = new THREE.RawShaderMaterial( {
uniforms: {
time: { value: 1.0 },
orientation: {type: 'v4', value: new THREE.Quaternion()},
gpgpuOffsets: {type: 't', value: null },
mapper: textureLoader,
colorBase: new THREE.Uniform(new THREE.Color(0xd9ff0e)),
colorStart: new THREE.Uniform(new THREE.Color(0x8674fd)),
colorPeak: new THREE.Uniform(new THREE.Color(0x0ed9ff)),
colorEnd: new THREE.Uniform(new THREE.Color(0x333333)),
},
side: THREE.DoubleSide,
vertexShader: `
precision highp float;
#define PI 3.1415926536
#define PI2 6.28318530718
attribute vec3 position;
attribute vec3 offset;
attribute float scale;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform float time;
attribute vec2 uv;
varying vec2 vUv;
attribute float particleIndex;
uniform sampler2D gpgpuOffsets;
varying float vParticleIndex;
uniform vec4 orientation;
uniform sampler2D mapper;
varying vec4 vColor;
vec3 applyQuaternionToVector( vec4 q, vec3 v ){
return v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );
}
void main(){
vec4 positions = texture2D(gpgpuOffsets, vec2(
mod(particleIndex-1.0, ${textureSize}.0)/${textureSize}.0,
floor((particleIndex-1.0)/${textureSize}.0)/${textureSize}.0)
);
float lifetime = positions.a;
float i = particleIndex - 1.0;
vec4 sample = texture2D(mapper, vec2(
mod(i, ${textureSize}.0) / ${textureSize}.0,
1.0 - i / ${textureSize}.0 / ${textureSize}.0
));
vec3 pos = position * vec3(scale * lifetime * 2.0, scale * lifetime * 2.0, 1.0);
pos = applyQuaternionToVector(orientation, pos);
pos = pos + offset + positions.xyz;
vParticleIndex = particleIndex;
vUv = vec2(uv.x, 1.0-uv.y);
vColor.xyz = sample.xyz;
// vColor.a = lifetime;
vColor.a = sample.a;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0 );
}
`,
fragmentShader: `
precision highp float;
varying vec4 vColor;
varying vec2 vUv;
varying float vParticleIndex;
varying vec2 vLifetime;
uniform float time;
uniform vec3 colorBase;
uniform vec3 colorStart;
uniform vec3 colorPeak;
uniform vec3 colorEnd;
uniform sampler2D mapper;
#define PI 3.1415926536
#define PI2 6.28318530718
float drawBase (in vec2 uv, in float min, in float max) {
float dist = sqrt(dot(uv, uv));
if (dist >= max || dist <= min) {
return 0.0;
}
float sm = smoothstep(max, max - 0.01, dist);
float sm2 = smoothstep(min, min - 0.01, dist);
float alpha = sm * sm2;
return (1.0-alpha);
}
void main() {
float alpha = drawBase(vUv - vec2(0.5), 0.0, 0.5);
// discard if not needed
if (alpha == 0.0) {
discard;
}
gl_FragColor = vColor;
}
`,
side: THREE.FrontSide,
transparent: true,
alphaTest: 0.1,
blending: THREE.AdditiveBlending
})
textureLoader.load(imageURI, (texture) => {
material.uniforms.mapper.value = texture
})
return material
}