Skip to content

Instantly share code, notes, and snippets.

@likr
Last active May 31, 2016 07:21
Show Gist options
  • Save likr/591c4d10d732ac5d307581255d0105c4 to your computer and use it in GitHub Desktop.
Save likr/591c4d10d732ac5d307581255d0105c4 to your computer and use it in GitHub Desktop.
const THREE = require('three')
const EffectComposer = require('three-effectcomposer')(THREE)
const width = 500
const height = 500
const r = 5
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
camera.position.z = r
const renderer1 = new THREE.WebGLRenderer()
renderer1.setSize(width, height)
document.getElementById('screen1').appendChild(renderer1.domElement)
const renderer2 = new THREE.WebGLRenderer()
renderer2.setSize(width, height)
document.getElementById('screen2').appendChild(renderer2.domElement)
// const scene = (() => {
// const scene = new THREE.Scene()
// const geometry = new THREE.BoxGeometry(1, 1, 1)
// const material = new THREE.MeshBasicMaterial({color: 0x00ff00})
// const cube = new THREE.Mesh(geometry, material)
// scene.add(cube)
// return scene
// })()
const scene = (() => {
const scene = new THREE.Scene()
const geometry = new THREE.BufferGeometry()
const material = new THREE.ShaderMaterial({
uniforms: {
alphaZero: {type: 'f', value: 0.3},
rZero: {type: 'f', value: 0.9}
},
vertexColors: THREE.VertexColors,
vertexShader: `
attribute float alpha;
uniform float alphaZero;
uniform float rZero;
${THREE.ShaderChunk['common']}
${THREE.ShaderChunk['color_pars_vertex']}
void main() {
${THREE.ShaderChunk['color_vertex']}
${THREE.ShaderChunk['begin_vertex']}
${THREE.ShaderChunk['project_vertex']}
gl_PointSize = rZero * sqrt( log(1.0 - alpha) / log(1.0 - alphaZero) );
}
`,
fragmentShader: `
${THREE.ShaderChunk['common']}
${THREE.ShaderChunk['color_pars_fragment']}
void main() {
vec3 n;
n.xy = gl_PointCoord * 2.0 - 1.0;
n.z = 1.0 - dot( n.xy, n.xy );
if ( n.z < 0.0 ) discard;
vec4 diffuseColor = vec4(1.0, 1.0, 1.0, 1.0);
${THREE.ShaderChunk['color_fragment']}
gl_FragColor = diffuseColor;
}
`
})
const n = 10000
const coords = new Float32Array(n * 3)
const colors = new Float32Array(n * 4)
const opacities = new Float32Array(n)
for (let i = 0; i < n; ++i) {
coords[i * 3] = Math.random() - 0.5
coords[i * 3 + 1] = Math.random() - 0.5
coords[i * 3 + 2] = Math.random() - 0.5
colors[i * 4] = Math.random()
colors[i * 4 + 1] = Math.random()
colors[i * 4 + 2] = Math.random()
colors[i * 4 + 3] = 1
opacities[i] = 0.2
}
const points = new THREE.Points(geometry, material)
scene.add(points)
geometry.addAttribute('position', new THREE.BufferAttribute(coords, 3))
geometry.addAttribute('color', new THREE.BufferAttribute(colors, 4))
geometry.addAttribute('alpha', new THREE.BufferAttribute(opacities, 1))
return scene
})()
const composer = new EffectComposer(renderer2, new THREE.WebGLRenderTarget(width, height, {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBFormat,
stencilBuffer: false
}))
composer.addPass(new EffectComposer.RenderPass(scene, camera))
const effect = new EffectComposer.ShaderPass(EffectComposer.CopyShader)
effect.renderToScreen = true
composer.addPass(effect)
const start = new Date()
const render = () => {
window.requestAnimationFrame(render)
const theta = Math.PI * (new Date() - start) / 2500
camera.position.z = r * Math.cos(theta)
camera.position.x = r * Math.sin(theta)
camera.lookAt({x: 0, y: 0, z: 0})
renderer1.render(scene, camera)
composer.render()
}
render()
document.getElementById('capture-button').addEventListener('click', () => {
const n = width * height * 4
const buffer1 = new THREE.WebGLRenderTarget(width, height, {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBFormat,
stencilBuffer: false
})
renderer1.render(scene, camera, buffer1)
const result1 = new Uint8Array(n)
renderer1.readRenderTargetPixels(buffer1, 0, 0, width, height, result1)
const buffer2 = new THREE.WebGLRenderTarget(width, height, {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBFormat,
stencilBuffer: false
})
renderer2.render(EffectComposer.scene, EffectComposer.camera, buffer2)
const result2 = new Uint8Array(n)
renderer2.readRenderTargetPixels(buffer2, 0, 0, width, height, result2)
for (let i = 0; i < n; ++i) {
if (result1[i] !== result2[i]) {
console.log(i, result1[i], result2[i])
}
}
console.log('capture ok')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment