如何在THREE.js中将自定义着色器应用于sprite

Vas*_*nko 2 javascript shader glsl three.js

我希望能够将一些程序结构应用于面部.第一个任务,当我面临这样的需求时,就是制造广告牌,在广场上绘制核爆炸.我希望把它作为一个动画径向渐变,我部分成功.

主要的是每个片段着色器 - 可以访问UV统一var.

看起来像渲染精灵的主要内容 - 是访问顶点着色器中的相机投影矩阵.

这是http://goo.gl/A7pY01的例子!

现在我想把它画到广告牌精灵上.我本来应该用THREE.SpriteTHREE.ShaderMaterial,但在这方面没有运气.看起来,这THREE.SpriteMaterial只是精灵的好材料.在检查了一些源代码后,我揭示了为什么Sprites使用插件以一种特殊的方式绘制.

所以,在我发现自己发明自己的自行车之前,我觉得有必要问人们如何在我自己的自定义精灵上放置我自己的自定义着色器而不用黑客攻击THREE.js?

Vas*_*nko 9

所以.经过一个小小的研究和工作,我认为THREE.ShaderMaterial是完成这个小任务的最佳选择.多亏了/extras/renderers/plugins/SpritePlugin,我意识到如何使用顶点着色器来形成和定位精灵.我还有一些问题,但我找到了一个很好的解决方案.

为了完成我的任务,首先我创建一个简单的平面几何:

 var geometry = new THREE.PlaneGeometry( 1, 1 );
Run Code Online (Sandbox Code Playgroud)

并在以下网格中使用它ShaderMaterial:

            uniforms = {
                cur_time: {type:"f", value:1.0},
                beg_time:{type:"f", value:1.0},
                scale:{type: "v3", value:new THREE.Vector3()}
            };

            var material = new THREE.ShaderMaterial( {

                uniforms: uniforms,
                vertexShader: document.getElementById( 'vertexShader' ).textContent,
                fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
                transparent: true,
                blending:THREE.AdditiveBlending // It looks like real blast with Additive blending!!!

            } );


 var mesh = new THREE.Mesh( geometry, material );
Run Code Online (Sandbox Code Playgroud)

这是我的着色器:顶点着色器:

        varying vec2 vUv;
        uniform vec3 scale;

        void main() {
            vUv = uv;
            float rotation = 0.0;

            vec3 alignedPosition = vec3(position.x * scale.x, position.y * scale.y, position.z*scale.z);

            vec2 pos = alignedPosition.xy;

            vec2 rotatedPosition;
            rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
            rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;

            vec4 finalPosition;

            finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
            finalPosition.xy += rotatedPosition;
            finalPosition = projectionMatrix * finalPosition;

            gl_Position =  finalPosition;

        }
Run Code Online (Sandbox Code Playgroud)

我从原始的Sprite Plugin源代码中获得了顶点着色器,并略微改变了它.BTW,+=改为=使精灵屏幕粘.这件事浪费了我很多时间.

这是我的片段着色器:

        uniform float cur_time;
        uniform float beg_time;

        varying vec2 vUv;

        void main() {
            float full_time = 5000.;

            float time_left = cur_time - beg_time;
            float expl_step0 = 0.;
            float expl_step1 = 0.3;
            float expl_max   = 1.;

            float as0 = 0.;
            float as1 = 1.;
            float as2 = 0.;

            float time_perc = clamp( (time_left / full_time), 0., 1. ) ;
            float alphap; 
            alphap = mix(as0,as1, smoothstep(expl_step0, expl_step1, time_perc));
            alphap = mix(alphap,as2, smoothstep(expl_step1, expl_max, time_perc));


            vec2 p = vUv;
            vec2 c = vec2(0.5, 0.5);
            float max_g = 1.;
            float dist = length(p - c) * 2. ;

            float step1 = 0.;
            float step2 = 0.2;
            float step3 = 0.3;

            vec4 color;
            float a0 = 1.;
            float a1 = 1.;
            float a2 = 0.7;
            float a3 = 0.0;


            vec4 c0 = vec4(1., 1., 1., a0 * alphap);
            vec4 c1 = vec4(0.9, 0.9, 1., a1 * alphap);
            vec4 c2 = vec4(0.7, 0.7, 1., a2 * alphap);
            vec4 c3 = vec4(0., 0., 0., 0.);



            color = mix(c0, c1, smoothstep(step1, step2, dist));
            color = mix(color, c2, smoothstep(step2, step3, dist));
            color = mix(color, c3, smoothstep(step3, max_g, dist));

            gl_FragColor = color;
   }
Run Code Online (Sandbox Code Playgroud)

以下是如何制作多点渐变的示例,按时间动画.有很多优化和几个想法如何使这更美丽.

但这个几乎就是我想要的.