Webgl 更新版本中的particlesystem问题

Webgl 更新版本中的particlesystem问题,webgl,three.js,fbo,rendertarget,Webgl,Three.js,Fbo,Rendertarget,在我寻找渲染云状纹理的方法时,我明白我需要使用纹理等来存储下一帧的数据。 通过进一步研究,我找到了一些使用FBO和webgl rendertarget进行粒子渲染的示例。即使它听起来很棒,但似乎任何一个示例都可以在更新版本的threejs(如50或51)中使用。如果我要切换到three49,它将呈现出它应该是什么样子 为了说明这个问题,我做了如下(): 身体{ 字体系列:Monospace; 背景色:#000000; 边际:0px; 溢出:隐藏; } #信息{ 颜色:#ffffff; 字体系列

在我寻找渲染云状纹理的方法时,我明白我需要使用纹理等来存储下一帧的数据。 通过进一步研究,我找到了一些使用FBO和webgl rendertarget进行粒子渲染的示例。即使它听起来很棒,但似乎任何一个示例都可以在更新版本的threejs(如50或51)中使用。如果我要切换到three49,它将呈现出它应该是什么样子

为了说明这个问题,我做了如下():


身体{
字体系列:Monospace;
背景色:#000000;
边际:0px;
溢出:隐藏;
}
#信息{
颜色:#ffffff;
字体系列:Monospace;
字体大小:13px;
文本对齐:居中;
字体大小:粗体;
位置:绝对位置;
顶部:0px;
宽度:100%;
填充物:5px;
}
a{
颜色:#0040ff;
}
var _gaq=_gaq | |[];
_gaq.push([''设置帐户','UA-86951-7']);
_gaq.push([''u trackPageview']);
(功能()
{
var ga=document.createElement('script');
ga.type='text/javascript';
ga.async=true;
ga.src=('https:'==document.location.protocol?'https://ssl' : 'http://www“)+”.google analytics.com/ga.js';
(document.getElementsByTagName('head')[0]| | document.getElementsByTagName('body')[0])。appendChild(ga);
})();
可变vec2 vUv;
void main(){
vUv=vec2(uv.x,1.0-uv.y);
gl_位置=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
}
//模拟
可变vec2 vUv;
vec3来源一致;
均匀采样位置;
均匀浮动定时器;
浮动兰德(vec2公司){
返回分数(sin(dot(co.xy,vec2(12.9898,78.233)))*43758.5453);
}
void main(){
vec3 pos=纹理2d(t位置,vUv).xyz;
如果(随机数(vUv+定时器)>0.99){
pos=原点;
vec3 random=vec3(兰特(vUv+1.0)-1.0,兰特(vUv+2.0)-1.0,兰特(vUv+3.0)-1.0);
pos+=标准化(随机)*随机(vUv+1.0);
}否则{
浮动x=位置x+定时器;
浮动y=位置y;
浮动z=位置z;
位置x+=sin(y*3.3)*cos(z*10.3)*0.005;
位置y+=sin(x*3.5)*cos(z*10.5)*0.005;
pos.z+=sin(x*3.7)*cos(y*10.7)*0.005;
}
//写出新的职位
gl_FragColor=vec4(位置1.0);
}
均匀采样二维地图;
浮动宽度均匀;
均匀浮动高度;
均匀浮点大小;
可变vec2 vUv;
可变的vec4位置;
可变vec4颜色;
void main(){
vec2 uv=位置.xy+vec2(0.5/宽度,0.5/高度);
vec3颜色=纹理2D(贴图,uv).rgb*200.0-100.0;
gl_PointSize=PointSize;
gl_位置=projectionMatrix*modelViewMatrix*vec4(颜色,1.0);
}
颜色均匀;
void main(){
gl_FragColor=点颜色;
}
var容器;
var场景、摄影机、灯光、渲染器;
变量几何体、立方体、网格、材质;
var数据、纹理、点;
风险值控制;
var fboParticles、rtTexturePos、rtTexturePos2、simulationShader;
init();
制作动画();
函数init(){
container=document.createElement('div');
文件.正文.附件(容器);
renderer=new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth、window.innerHeight);
container.appendChild(renderer.doElement);
场景=新的三个。场景();
摄像头=新的三个透视摄像头(50,window.innerWidth/window.innerHeight,11000);
场景。添加(摄影机);
控件=新的三个。轨道控件2(摄像头);
控制半径=400;
速度=3;
//
变量宽度=1024,高度=1024;
//变量宽度=64,高度=64;
//变量宽度=128,高度=128;
if(!renderer.context.getExtension('OES\u texture\u float')){
警报('OES_纹理_浮动不是:(');
}
//开始创建DataTexture
//可以用三个.fbootils.createTextureFromData(textureWidth,textureWidth,data)来简化它吗?
数据=新阵列(宽*高*3);
纹理=新的THREE.DataTexture(数据、宽度、高度、THREE.RGBFormat、THREE.FloatType);
texture.minFilter=3.NearestFilter;
texture.magFilter=3.NearestFilter;
texture.needsUpdate=true;
//zz85-fbo初始化
rtTexturePos=new THREE.WebGLRenderTarget(宽度、高度、{
包装:三。重复包装,
包装:三个。重复包装,
最小过滤器:三个。最近的过滤器,
磁过滤器:三个。最近的过滤器,
格式:THREE.RGBFormat,
类型:三。浮动类型,
模具缓冲区:false
});
rtTexturePos2=rtTexturePos.clone();
simulationShader=new THREE.ShaderMaterial({
制服:{
t位置:{type:“t”,值:0,
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                font-family: Monospace;
                background-color: #000000;
                margin: 0px;
                overflow: hidden;
            }

            #info {
                color: #ffffff;
                font-family: Monospace;
                font-size: 13px;
                text-align: center;
                font-weight: bold;
                position: absolute;
                top: 0px;
                width: 100%;
                padding: 5px;
            }

            a {

                color: #0040ff;
            }
        </style>
    </head>
    <body>

        <script type="text/javascript">
            var _gaq = _gaq || [];
            _gaq.push(['_setAccount', 'UA-86951-7']);
            _gaq.push(['_trackPageview']);

            (function()
            {
                var ga = document.createElement('script');
                ga.type = 'text/javascript';
                ga.async = true;
                ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
                (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
            })();
        </script>

        <!--         <script src="helvetiker_bold.typeface.js"></script> -->

        <script id="texture_vertex_simulation_shader" type="x-shader/x-vertex">

            varying vec2 vUv;

            void main() {

            vUv = vec2(uv.x, 1.0 - uv.y);
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

            }

        </script>
        <script id="texture_fragment_simulation_shader" type="x-shader/x-fragment">

            // simulation
            varying vec2 vUv;

            uniform vec3 origin;
            uniform sampler2D tPositions;

            uniform float timer;

            float rand(vec2 co){
            return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
            }

            void main() {

            vec3 pos = texture2D( tPositions, vUv ).xyz;

            if ( rand( vUv + timer ) > 0.99 ) {

            pos = origin;

            vec3 random = vec3( rand( vUv + 1.0 ) - 1.0, rand( vUv + 2.0 ) - 1.0, rand( vUv + 3.0 ) - 1.0 );
            pos += normalize( random ) * rand( vUv + 1.0 );

            } else {

            float x = pos.x + timer;
            float y = pos.y;
            float z = pos.z;

            pos.x += sin( y * 3.3 ) * cos( z * 10.3 ) * 0.005;
            pos.y += sin( x * 3.5 ) * cos( z * 10.5 ) * 0.005;
            pos.z += sin( x * 3.7 ) * cos( y * 10.7 ) * 0.005;

            }

            // Write new position out
            gl_FragColor = vec4(pos, 1.0);

            }

        </script>

        <!-- zz85 - end simulations -->

        <script id="vs-particles" type="x-shader/x-vertex">

            uniform sampler2D map;

            uniform float width;
            uniform float height;

            uniform float pointSize;

            varying vec2 vUv;
            varying vec4 vPosition;
            varying vec4 vColor;

            void main() {

            vec2 uv = position.xy + vec2( 0.5 / width, 0.5 / height );
            vec3 color = texture2D( map, uv ).rgb * 200.0 - 100.0;

            gl_PointSize = pointSize;
            gl_Position = projectionMatrix * modelViewMatrix * vec4( color, 1.0 );

            }

        </script>

        <script id="fs-particles" type="x-shader/x-fragment">

            uniform vec4 pointColor;

            void main() {

            gl_FragColor = pointColor;

            }

        </script>

        <script>

                        var container;

            var scene, camera, light, renderer;
            var geometry, cube, mesh, material;

            var data, texture, points;

            var controls;

            var fboParticles, rtTexturePos, rtTexturePos2, simulationShader;

            init();
            animate();

            function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );

            scene = new THREE.Scene();

            camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
            scene.add( camera );

            controls = new THREE.OrbitControls2( camera );
            controls.radius = 400;
            controls.speed = 3;

            //

            var width = 1024, height = 1024;
            // var width = 64, height = 64;
            // var width = 128, height = 128;

            if ( ! renderer.context.getExtension( 'OES_texture_float' ) ) {

            alert( 'OES_texture_float is not :(' );

            }

            // Start Creation of DataTexture
            // Could it be simplified with THREE.FBOUtils.createTextureFromData(textureWidth, textureWidth, data); ?

            data = new Float32Array( width * height * 3 );

            texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat, THREE.FloatType );
            texture.minFilter = THREE.NearestFilter;
            texture.magFilter = THREE.NearestFilter;
            texture.needsUpdate = true;

            // zz85 - fbo init

            rtTexturePos = new THREE.WebGLRenderTarget(width, height, {
            wrapS:THREE.RepeatWrapping,
            wrapT:THREE.RepeatWrapping,
            minFilter: THREE.NearestFilter,
            magFilter: THREE.NearestFilter,
            format: THREE.RGBFormat,
            type:THREE.FloatType,
            stencilBuffer: false
            });

            rtTexturePos2 = rtTexturePos.clone();

            simulationShader = new THREE.ShaderMaterial({

            uniforms: {
            tPositions: { type: "t", value: 0, texture: texture },
            origin: { type: "v3", value: new THREE.Vector3() },
            timer: { type: "f", value: 0 }
            },

            vertexShader: document.getElementById('texture_vertex_simulation_shader').textContent,
            fragmentShader:  document.getElementById('texture_fragment_simulation_shader').textContent

            });

            fboParticles = new THREE.FBOUtils( width, renderer, simulationShader );
            fboParticles.renderToTexture(rtTexturePos, rtTexturePos2);

            fboParticles.in = rtTexturePos;
            fboParticles.out = rtTexturePos2;

            geometry = new THREE.Geometry();

            for ( var i = 0, l = width * height; i < l; i ++ ) {

            var vertex = new THREE.Vector3();
            vertex.x = ( i % width ) / width ;
            vertex.y = Math.floor( i / width ) / height;
            geometry.vertices.push( vertex );

            }

            material = new THREE.ShaderMaterial( {

            uniforms: {

            "map": { type: "t", value: 0, texture: rtTexturePos },
            "width": { type: "f", value: width },
            "height": { type: "f", value: height },

            "pointColor": { type: "v4", value: new THREE.Vector4( 0.25, 0.50, 1.0, 0.25 ) },
            "pointSize": { type: "f", value: 1 }

            },
            vertexShader: document.getElementById( 'vs-particles' ).textContent,
            fragmentShader: document.getElementById( 'fs-particles' ).textContent,
            blending: THREE.AdditiveBlending,
            transparent: true,
            depthWrite: false,
            depthTest: false

            } );

            mesh = new THREE.ParticleSystem( geometry, material );
            scene.add( mesh );

            var gui = new dat.GUI();
            gui.add( material.uniforms.pointColor.value, 'x', 0.0, 1.0 ).name( 'red' );
            gui.add( material.uniforms.pointColor.value, 'y', 0.0, 1.0 ).name( 'green' );
            gui.add( material.uniforms.pointColor.value, 'z', 0.0, 1.0 ).name( 'blue' );
            gui.add( material.uniforms.pointColor.value, 'w', 0.0, 1.0 ).name( 'alpha' );
            gui.add( material.uniforms.pointSize, 'value', 0.0, 10.0 ).name( 'size' );
            gui.add( controls, 'enabled' ).name( 'auto move' );

            scene.add( new THREE.Mesh( new THREE.CubeGeometry( 500, 500, 500 ), new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true, opacity: 0.15 } ) ) );

            }

            function animate() {

            requestAnimationFrame( animate );
            render();

            }

            var timer = 0;

            function render() {

            timer += 0.01;

            simulationShader.uniforms.timer.value = timer;
            simulationShader.uniforms.origin.value.x = Math.sin( timer * 2.3 ) * 0.5 + 0.5;
            simulationShader.uniforms.origin.value.y = Math.cos( timer * 2.5 ) * 0.5 + 0.5;
            simulationShader.uniforms.origin.value.z = Math.sin( timer * 2.7 ) * 0.5 + 0.5;

            // swap
            var tmp = fboParticles.in;
            fboParticles.in = fboParticles.out;
            fboParticles.out = tmp;

            simulationShader.uniforms.tPositions.texture = fboParticles.in;
            fboParticles.simulate(fboParticles.out);
            material.uniforms.map.texture = fboParticles.out;

            controls.update();

            renderer.render( scene, camera );

            }

        </script>
    </body>
</html>