<script id="Mosaic_ComputeVelocity" type="x-shader/x-vertex">
vec3 mod289(vec3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 mod289(vec4 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 permute(vec4 x) {
return mod289(((x*34.0)+1.0)*x);
}
vec4 taylorInvSqrt(vec4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
}
float snoise(vec3 v)
{
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
// First corner
vec3 i = floor(v + dot(v, C.yyy) );
vec3 x0 = v - i + dot(i, C.xxx) ;
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = mod289(i);
vec4 p = permute( permute( permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);
//Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
}
vec3 snoiseVec3( vec3 x ){
float s = snoise(vec3( x ));
float s1 = snoise(vec3( x.y - 19.1 , x.z + 33.4 , x.x + 47.2 ));
float s2 = snoise(vec3( x.z + 74.2 , x.x - 124.5 , x.y + 99.4 ));
vec3 c = vec3( s , s1 , s2 );
return c;
}
vec3 curlNoise( vec3 p ){
const float e = .1;
vec3 dx = vec3( e , 0.0 , 0.0 );
vec3 dy = vec3( 0.0 , e , 0.0 );
vec3 dz = vec3( 0.0 , 0.0 , e );
vec3 p_x0 = snoiseVec3( p - dx );
vec3 p_x1 = snoiseVec3( p + dx );
vec3 p_y0 = snoiseVec3( p - dy );
vec3 p_y1 = snoiseVec3( p + dy );
vec3 p_z0 = snoiseVec3( p - dz );
vec3 p_z1 = snoiseVec3( p + dz );
float x = p_y1.z - p_y0.z - p_z1.y + p_z0.y;
float y = p_z1.x - p_z0.x - p_x1.z + p_x0.z;
float z = p_x1.y - p_x0.y - p_y1.x + p_y0.x;
const float divisor = 1.0 / ( 2.0 * e );
return normalize( vec3( x , y , z ) * divisor );
}
void main() {
vec2 uv = gl_FragCoord.xy / resolution.xy;
float idParticle = uv.y * resolution.x + uv.x;
vec4 tmpVel = texture2D( textureVelocity, uv );
vec4 tmpPos = texture2D( texturePosition, uv );
vec3 vel = curlNoise(tmpPos.xyz*0.04);
tmpVel.w -= 0.8;
// vel.z *= 2.0;
// vec3 vel = tmpVel.xyz;
// vel.x *= 2.0;
// vel. *= 2.0;
// vel.x = abs(vel.x);
// vel.z = abs(vel.z);
if(tmpVel.w < -1.0)
{
tmpVel.w = 100.;
}
gl_FragColor = vec4( vel.xyz, tmpVel.w );
}
</script>
<script id="Mosaic_ComputePosition" type="x-shader/x-vertex">
#define delta 0.08
void main() {
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec4 tmpPos = texture2D( texturePosition, uv );
vec3 pos = tmpPos.xyz;
vec4 tmpVel = texture2D( textureVelocity, uv );
vec4 tmpOrgPos = texture2D( textureOriginal, uv );
vec3 vel = tmpVel.xyz;
pos += vel * delta;
// if(tmpVel.w == 100.)
if(distance(pos,tmpOrgPos.xyz) > 20.)
{
pos = tmpOrgPos.xyz;
}
gl_FragColor = vec4( pos, 1.0 );
}
</script>
<script id="Mosaic_ComputeOriginal" type="x-shader/x-vertex">
uniform sampler2D pre_texturePosition;
void main() {
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec4 q = texture2D( textureOriginal, uv );
gl_FragColor = q;
}
</script>
<script id="Mosaic_ComputeShadow" type="x-shader/x-vertex">
precision highp float;
const float PackUpscale = 256. / 255.;
const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );
const float ShiftRight8 = 1. / 256.;
vec4 packDepthToRGBA( const in float v ) {
vec4 r = vec4( fract( v * PackFactors ), v );
r.yzw -= r.xyz * ShiftRight8; // tidy overflow
return r * PackUpscale;
}
void main() {
gl_FragColor = packDepthToRGBA( gl_FragCoord.z );
}
</script>
<script id="vertex" type="x-shader/x-vertex">
precision highp float;
attribute vec3 offset;
attribute vec2 pos_uv;
attribute vec4 orientation;
varying vec2 vUv;
varying vec2 vTuv;
uniform sampler2D map;
uniform mat4 shadowMatrix;
varying vec4 vShadowCoord;
uniform sampler2D shadowMap;
uniform vec2 shadowMapSize;
uniform float shadowBias;
uniform float shadowRadius;
uniform float time;
uniform sampler2D texturePosition;
uniform sampler2D textureVelocity;
uniform sampler2D textureOriginal;
varying vec4 vPosition;
varying vec3 vColor;
varying vec3 vNormal;
uniform mat4 uMatrix;
varying mat4 vModelMatrix;
uniform float imgWidth;
uniform float imgHeight;
mat3 calcLookAtMatrix(vec3 vector, float roll) {
vec3 rr = vec3(sin(roll), cos(roll), 0.0);
vec3 ww = normalize(vector);
vec3 uu = normalize(cross(ww, rr));
vec3 vv = normalize(cross(uu, ww));
return mat3(uu, ww, vv);
}
const float DEG_TO_RAD = 3.141592653589793 / 180.0;
mat2 rotationMatrix( float a ) {
return mat2( cos( a ), sin( a ),
-sin( a ), cos( a ) );
}
const float PI = 3.141592653589793;
uniform float near;
uniform float far;
uniform vec3 cameraPos;
float fogStart = 0.1;
float fogEnd = 30.0;
varying float fogFactor;
uniform float isStart;
mat2 calcRotate2D(float _time){
float _sin = sin(_time);
float _cos = cos(_time);
return mat2(_cos, _sin, -_sin, _cos);
}
void main() {
vPosition = vec4(position.xyz,1.);
vec4 posTemp = texture2D( texturePosition, pos_uv );
vec4 velTemp = texture2D( textureVelocity, pos_uv );
vec4 orgTemp = texture2D( textureOriginal, pos_uv );
// float scale = 1.0 - velTemp.w/100.0;
float scale = 1.0 - distance(posTemp.xyz,orgTemp.xyz)/20.;
scale = sin(scale*PI)*1.0;
// scale = mix(sin(scale*PI)*1.2,1.0,isStart);
// scale= 1.0;
vTuv = pos_uv;
mat4 localRotationMat = mat4( calcLookAtMatrix( velTemp.xyz, 0.0 ) );
vec2 tUv =vec2( posTemp.x/imgWidth+0.5,posTemp.y/imgHeight+0.5);
vColor = texture2D( map, tUv ).xyz;
vec3 modifiedVertex = (localRotationMat * vec4( position*vec3(0.1,1.3,0.1)*scale,1.0 )).xyz;
vec3 modifiedPosition = modifiedVertex + posTemp.xyz;
modifiedPosition.yz = calcRotate2D(time) * modifiedPosition.yz;
modifiedPosition.xz = calcRotate2D(time) * modifiedPosition.xz;
float linerDepth = 1.0 / (30.0 - 0.01);
float linerPos = length(cameraPos - modifiedPosition.xyz) * linerDepth;
fogFactor = clamp((fogEnd - linerPos) / (fogEnd - fogStart), 0.0, 1.0);
vPosition = vec4( modifiedPosition, 1.0 );
vShadowCoord = shadowMatrix * modelMatrix * vec4( vPosition.xyz, 1. );
gl_Position = projectionMatrix * modelViewMatrix * vec4( modifiedPosition, 1.0 );
}
</script>
<script id="fragment" type="x-shader/x-vertex">
precision highp float;
uniform sampler2D map;
varying vec2 vUv;
varying vec3 vColor;
varying vec4 vShadowCoord;
uniform sampler2D shadowMap;
uniform vec2 shadowMapSize;
uniform float shadowBias;
uniform float shadowRadius;
uniform float bias;
const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)
const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );
const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
float unpackRGBAToDepth( const in vec4 v ) {
return dot( v, UnpackFactors );
}
float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {
return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );
}
float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
float shadow = 1.0;
shadowCoord.xyz /= shadowCoord.w;
shadowCoord.z += shadowBias;
// if ( something && something ) breaks ATI OpenGL shader compiler
// if ( all( something, something ) ) using this instead
bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );
bool inFrustum = all( inFrustumVec );
bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );
bool frustumTest = all( frustumTestVec );
if ( frustumTest ) {
vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
float dx0 = - texelSize.x * shadowRadius;
float dy0 = - texelSize.y * shadowRadius;
float dx1 = + texelSize.x * shadowRadius;
float dy1 = + texelSize.y * shadowRadius;
shadow = (
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
) * ( 1.0 / 9.0 );
}
return shadow;
}
vec3 rgb2hsv(vec3 c)
{
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
varying vec4 vPosition;
uniform sampler2D textureVelocity;
uniform sampler2D texturePosition;
varying vec2 vTuv;
varying mat4 vModelMatrix;
varying vec3 vNormal;
uniform mat4 uMatrix;
uniform float near;
uniform float far;
uniform vec3 cameraPos;
float fogStart = 0.1;
float fogEnd = 10.0;
varying float fogFactor;
vec3 calcIrradiance_dir(vec3 newNormal, vec3 lightPos, vec3 light){
float dotNL = dot(newNormal, normalize(lightPos));
return light * max(0.0, dotNL);
}
vec3 calcIrradiance_hemi(vec3 newNormal, vec3 lightPos, vec3 grd, vec3 sky){
float dotNL = dot(newNormal, normalize(lightPos));
float hemiDiffuseWeight = 0.5 * dotNL + 0.5;
return mix(grd, sky, hemiDiffuseWeight);
}
const vec3 hemiLight_g = vec3(0.86,0.86,0.86);
// hemisphere sky color
const vec3 hemiLight_s_1 = vec3(0.5882352941176471,0.8274509803921568,0.8823529411764706);
const vec3 hemiLight_s_2 = vec3(0.9686274509803922,0.8509803921568627,0.6666666666666666);
const vec3 hemiLight_s_3 = vec3(0.8784313725490196,0.5882352941176471,0.7647058823529411);
const vec3 hemiLightPos_1 = vec3(100.0, 100.0, -100.0);
const vec3 hemiLightPos_2 = vec3(-100.0, -100.0, 100.0);
const vec3 hemiLightPos_3 = vec3(-100.0, 100.0, 100.0);
//uniform sampler2D map;
void main() {
vec4 velTemp = texture2D( textureVelocity, vUv );
vec4 posTemp = texture2D( texturePosition, vTuv );
vec3 _normal = normalize(cross(dFdx(vPosition.xyz), dFdy(vPosition.xyz)));
vec3 hemiColor = vec3(0.0);
hemiColor += calcIrradiance_hemi(_normal, hemiLightPos_1, hemiLight_g, hemiLight_s_1) * 0.38;
hemiColor += calcIrradiance_hemi(_normal, hemiLightPos_2, hemiLight_g, hemiLight_s_2) * 0.26;
hemiColor += calcIrradiance_hemi(_normal, hemiLightPos_3, hemiLight_g, hemiLight_s_3) * 0.36;
vec3 dirColor = vec3(0.0);
dirColor += calcIrradiance_dir(_normal, vec3(0.,0.,1.), vec3(1.));
float shadow = 1.0;
shadow *= getShadow(shadowMap, shadowMapSize, bias, shadowRadius, vShadowCoord);
dirColor.x = max(dirColor.x,0.8);
dirColor.y = max(dirColor.y,0.8);
dirColor.z = max(dirColor.z,0.8);
vec3 color = vColor.xyz*dirColor;
color = mix(vec3(0.,0.,0.),color,fogFactor);
vec3 hsv = rgb2hsv(color);
hsv.z *= 1.3;
color = hsv2rgb(hsv);
gl_FragColor = vec4(color,1.0);
}
</script>
<div id="container"></div>
<div id="info">
<span>
<h1>Impressionists Blobs -The Starry Night-</h1>
</span>
<br>
<span>
<a href="https://twitter.com/murasaki_0606" target="_blank">@murasaki_0606</a>
</span>
<br>
<span>
<p>click: Start / Restart</p>
<br>
<p>key"H": Hide info</p>
</span>
</div>
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}html{height:100%}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-collapse:collapse;border-spacing:0}body{margin:0;font-family:Monospace;font-size:13px;text-align:center}
#container,body{
position:relative;width:100%;height:100%;overflow:hidden
}
#container{
background:radial-gradient(ellipse at center,#7e2f9c 1%,#191325 100%)
}
#stats{display:none}canvas{position:fixed;left:0;top:0}
#info {
width:100%;height:100%;
top: 40px;
left: 40px;
position: fixed;
z-index: 999;
text-align: left;
color: #fff;
font-family: 'Khula', sans-serif;
}
h1 {
font-size: 22px;
display: inline-block;
margin: 0;
margin-bottom: 10px;
padding: 8px;
padding-top: 12px;
background: linear-gradient(135deg, rgba(37,219,237,0.8) 0%,rgba(183,60,210,0.8) 100%);
}
a {
color: #fff;
margin: 0;
font-size: 14px;
display: inline-block;
padding: 6px;
padding-top: 8px;
margin-bottom: 20px;
background: linear-gradient(135deg, rgba(37,219,237,0.8) 0%,rgba(183,60,210,0.8) 100%);
}
p {
color: #fff;
margin: 0;
font-size: 16px;
display: inline-block;
margin-bottom: 14px;
}
var container, stats;
var camera, scene, renderer;
var mesh;
var geometry;
var cube;
var offsetAttribute;
var orientationAttribute;
var lastTime = 0;
var mesh;
var uniforms;
var WIDTH = 128;
var PARTICLES = WIDTH * WIDTH;
var gpuCompute;
var velocityVariable;
var positionVariable;
var quaternionVariable;
var quaternionUniforms;
var material;
var shadowMaterial;
var light;
var shadowCamera;
var imgWidth = 75;
var imgHeight = 50;
var rotateVec = new THREE.Vector3(0,0,0);
var isRotate = false;
var timer = 0.0;
var cameraStartZ = 100;
var startTimer = 0.8;
var enableInfo = true;
var texture;
texture = new THREE.TextureLoader().load('https://s3-us-west-2.amazonaws.com/s.cdpn.io/311372/gogh_small.jpg',function (){
init();
});
function init() {
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = cameraStartZ;
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({antialias: true, alpha:true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.gammaInput = true;
renderer.gammaOutput = true;
container.appendChild( renderer.domElement );
renderer.setClearColor(0xebe8ed,0);
light = new THREE.DirectionalLight( 0xFFAA55,0.5 );
light.position.set(0, 1, 1);
light.castShadow = true;
shadowCamera = light.shadow.camera;
shadowCamera.lookAt( scene.position );
light.shadow.matrix.set(
0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
0.0, 0.0, 0.5, 0.5,
0.0, 0.0, 0.0, 1.0
);
light.shadow.matrix.multiply( shadowCamera.projectionMatrix );
light.shadow.matrix.multiply( shadowCamera.matrixWorldInverse );
if(light.shadow.map === null){
light.shadow.mapSize.x = 2048;
light.shadow.mapSize.y = 2048;
var pars = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
light.shadow.map = new THREE.WebGLRenderTarget( light.shadow.mapSize.x,light.shadow.mapSize.y, pars );
}
initComputeRenderer();
var instances = PARTICLES;
var bufferGeometry = new THREE.BoxBufferGeometry( 2, 1, 1 );
geometry = new THREE.InstancedBufferGeometry();
geometry.index = bufferGeometry.index;
geometry.attributes.position = bufferGeometry.attributes.position;
geometry.attributes.uv = bufferGeometry.attributes.uv;
geometry.attributes.normal = bufferGeometry.attributes.normal;
var offsets = [];
var orientations = [];
var vector = new THREE.Vector4();
var x, y, z, w;
var uvs = new Float32Array( PARTICLES * 2 );
var xywidth = new Float64Array( 3 );
xywidth[2] = WIDTH;
var p = 0;
for ( var j = 1; j < WIDTH; j++ ) {
for ( var i = 1; i < WIDTH; i++ ) {
xywidth[0] = i;
xywidth[1] = j;
uvs[ p++ ] = xywidth[0] / ( xywidth[2] )-(1.0/xywidth[2]);
uvs[ p++ ] = xywidth[1] / ( xywidth[2] )-(1.0/xywidth[2]);
}
}
for ( var i = 0; i < instances; i ++ ) {
x = Math.random() * 50 - 25;
y = Math.random() * 50 - 25;
z = Math.random() *0;
vector.set( x, y, z, 0 ).normalize();
vector.multiplyScalar( 5 );
offsets.push( x + vector.x, y + vector.y, z + vector.z,i );
x = Math.random() * 2 - 1;
y = Math.random() * 2 - 1;
z = Math.random() * 2 - 1;
w = Math.random() * 2 - 1;
vector.set( x, y, z, w ).normalize();
orientations.push( vector.x, vector.y, vector.z, vector.w );
}
offsetAttribute = new THREE.InstancedBufferAttribute( new Float32Array( offsets ), 4 );
orientationAttribute = new THREE.InstancedBufferAttribute( new Float32Array( orientations ), 4 ).setDynamic( true );
texture.wrapS = THREE.ClampToEdgeWrapping;
texture.wrapT = THREE.ClampToEdgeWrapping;
var pos_uvsAttribute = new THREE.InstancedBufferAttribute( uvs, 2 );
geometry.addAttribute( 'offset', offsetAttribute );
geometry.addAttribute( 'orientation', orientationAttribute );
geometry.addAttribute( 'pos_uv', pos_uvsAttribute );
uniforms = {
map: { value: texture},
time:{value:0.0},
texturePosition:{value:null},
textureVelocity:{value:null},
textureOriginal:{value:null},
shadowMap: { type: 't', value: light.shadow.map },
shadowMapSize: {type: "v2", value: light.shadow.mapSize},
shadowBias: {type: "f", value: light.shadow.bias},
shadowRadius: {type: "f", value: light.shadow.radius},
uMatrix:{value:null},
imgWidth:{value:imgWidth},
imgHeight:{value:imgHeight},
near:{value:camera.near},
far:{value:camera.far},
cameraPos:{value:camera.position},
sceneInvMatrix:{value:null},
isStart:{value:startTimer}
};
material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertex' ).textContent,
fragmentShader: document.getElementById( 'fragment' ).textContent,
shading: THREE.FlatShading,
transparent:true
} );
shadowMaterial = new THREE.ShaderMaterial( {
uniforms: {
map: { value: texture},
time:{value:0.0},
texturePosition:{value:null},
textureVelocity:{value:null},
size: { type: "f", value: WIDTH },
timer: { type: 'f', value: 0 },
shadowMatrix: { type: 'm4', value: light.shadow.matrix},
lightPosition: { type: 'v3', value: light.position }
},
vertexShader: document.getElementById( 'vertex' ).textContent,
fragmentShader: document.getElementById( 'Mosaic_ComputeShadow' ).textContent,
});
mesh = new THREE.Mesh( geometry, material );
mesh.frustumCulled = false;
scene.add( mesh );
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener( 'click', click, false);
animate();
}
function initComputeRenderer()
{
gpuCompute = new GPUComputationRenderer( WIDTH, WIDTH, renderer );
var dtPosition = gpuCompute.createTexture();
var dtVelocity = gpuCompute.createTexture();
var dtOriginal = gpuCompute.createTexture();
fillTextures( dtPosition, dtVelocity,dtOriginal );
velocityVariable = gpuCompute.addVariable( "textureVelocity", document.getElementById( 'Mosaic_ComputeVelocity' ).textContent, dtVelocity );
positionVariable = gpuCompute.addVariable( "texturePosition", document.getElementById( 'Mosaic_ComputePosition' ).textContent, dtPosition );
quaternionVariable = gpuCompute.addVariable( "textureOriginal", document.getElementById( 'Mosaic_ComputeOriginal' ).textContent, dtOriginal );
let variables = [ positionVariable, velocityVariable, quaternionVariable ];
gpuCompute.setVariableDependencies( velocityVariable, variables );
gpuCompute.setVariableDependencies( positionVariable, variables );
gpuCompute.setVariableDependencies( quaternionVariable, variables );
quaternionUniforms = quaternionVariable.material.uniforms;
quaternionUniforms.pre_texturePosition = {value:dtPosition};
var error = gpuCompute.init();
if ( error !== null ) {
console.error( error );
}
}
function fillTextures( texturePosition, textureVelocity, textureQuaternion ) {
var posArray = texturePosition.image.data;
var velArray = textureVelocity.image.data;
var qtArray = textureQuaternion.image.data;
for ( var k = 0, kl = posArray.length; k < kl; k += 4 ) {
var x, y, z;
x = Math.random()*imgWidth-imgWidth/2;
y = Math.random()*imgHeight-imgHeight/2;
z = Math.random()*10-5;
posArray[ k + 0 ] = x;
posArray[ k + 1 ] = y;
posArray[ k + 2 ] = z;
posArray[ k + 3 ] = 0;
qtArray[ k + 0 ] = x;
qtArray[ k + 1 ] = y;
qtArray[ k + 2 ] = z;
qtArray[ k + 3 ] = 0;
velArray[ k + 0 ] = Math.random()*2-1;
velArray[ k + 1 ] = Math.random()*2-1;
velArray[ k + 2 ] = Math.random()*2-1;
velArray[ k + 3 ] = 100*Math.random();
}
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function click()
{
isRotate = !isRotate;
startTimer = 3.0;
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var time = performance.now();
if(startTimer > 0)
{
startTimer -=0.008;
} else
{
uniforms.isStart.value = startTimer;
isRotate = true;
}
if(isRotate)
{
timer += 0.003;
timer = timer%(Math.PI*2);
cameraStartZ += (30.0 - cameraStartZ) * 0.02;
camera.position.z = cameraStartZ + Math.sin(timer) * 40.0;
} else
{
var speed = 0.045;
rotateVec.x += (0.0 - rotateVec.x) * speed;
rotateVec.y += (0.0 - rotateVec.y) * speed;
rotateVec.z += (0.0 - rotateVec.z) * speed;
scene.position.z +=(0.0 - scene.position.z) * speed;
mesh.position.z +=(0.0 - scene.position.z) * speed;
camera.position.z +=( cameraStartZ - camera.position.z) * speed;
cameraStartZ += (70.0 - cameraStartZ) * speed;
timer +=(0.0 -timer)*speed;
}
scene.rotation.setFromVector3(rotateVec);
quaternionUniforms.pre_texturePosition = gpuCompute.getCurrentRenderTarget( positionVariable ).texture;
gpuCompute.compute();
uniforms.textureOriginal.value = gpuCompute.getCurrentRenderTarget( quaternionVariable ).texture;
uniforms.texturePosition.value = gpuCompute.getCurrentRenderTarget( positionVariable ).texture;
uniforms.textureVelocity.value = gpuCompute.getCurrentRenderTarget( velocityVariable ).texture;
shadowMaterial.uniforms.texturePosition.value = gpuCompute.getCurrentRenderTarget( positionVariable ).texture;
shadowMaterial.uniforms.textureVelocity.value = gpuCompute.getCurrentRenderTarget( velocityVariable ).texture;
uniforms.time.value = timer;
shadowMaterial.uniforms.time.value = timer;
lastTime = timer;
mesh.material = material;
material.uniforms.shadowMap.value = light.shadow.map;
let m = new THREE.Matrix4();
material.uniforms.uMatrix.value = m.getInverse(mesh.matrix);
renderer.render( scene, camera );
}
document.onkeydown = function (e){
if(!e) e = window.event;
if(e.key === "h")
{
console.log($);
console.log($("#info"));
if(enableInfo)
{
$("#info").fadeOut("0.3");
enableInfo = false;
}else
{
$("#info").fadeIn("0.3");
enableInfo = true;
}
}
};