如何为这个简单的着色器制作动画

时间:2019-06-21 08:20:37

标签: three.js glsl shader

我是着色器的新手。我写了这个非常简单的片段着色器,看起来像这样(顶部是橙色,底部是红色)

我想要实现的目标: 我想为这两种颜色设置动画。 我希望顶部的橙色颜色转换为底部,然后返回顶部,而底部的红色颜色转换为顶部,然后返回底部。 (模拟日落和日出效果)

谢谢!

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

vec3 colorA = vec3(0.905,0.045,0.045);
vec3 colorB = vec3(0.995,0.705,0.051);

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;

    vec3 pct = vec3(st.y);

    vec3 color = vec3(0.0);

    color = mix(colorA, colorB, pct);

    gl_FragColor = vec4(color,1);
}

enter image description here

2 个答案:

答案 0 :(得分:1)

类似的事情,通过sin时间函数对颜色进行附加混合:

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

vec3 colorA = vec3(0.905,0.045,0.045);
vec3 colorB = vec3(0.995,0.705,0.051);

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;

    float sinF = sin(u_time) * 0.5 + 0.5;

    vec3 colorTop = mix(colorA, colorB, sinF);
    vec3 colorBottom = mix(colorB, colorA, sinF);

    vec3 pct = vec3(st.y);

    vec3 color = vec3(0.0);

    color = mix(colorTop, colorBottom, pct);

    gl_FragColor = vec4(color,1);
}

答案 1 :(得分:1)

最简单的方法是向let filteredString = String("567 THB".filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789.,")) == nil }).trimmingCharacters(in: .whitespacesAndNewlines) //TBH <- prints 添加偏移量。偏移量必须在[-1.0,1.0]范围内。这可以通过sin来实现。 st.y的参数必须取决于sin
注意,u_time以弧度计算角度的正弦函数,因此必须将参数缩放为2.0 * PI(〜sin)。 结果必须钳制(clamp)到[0.0,1.0]范围内。

例如:

2.0*3.1415

请注意,该示例在float interval = 2000.0; // 2000 milliseconds = 2 seconds float p = clamp(st.y + sin(2.0*3.1415 * u_time / interval), 0.0, 1.0); vec3 pct = vec3(p); 是毫秒值的情况下有效。如果u_time是以秒为单位的值,则必须将间隔缩放* 1000.0'(例如,u_time而不是2.0)。

2000.0
var container, camera, scene, renderer, uniforms;

init();
animate();

function init() {
    container = document.getElementById( 'container' );

    camera = new THREE.Camera();
    camera.position.z = 1;

    scene = new THREE.Scene();

    var geometry = new THREE.PlaneBufferGeometry( 2, 2 );

    uniforms = {
        u_time: { type: "f", value: 1.0 },
        u_resolution: { type: "v2", value: new THREE.Vector2() },
        u_mouse: { type: "v2", value: new THREE.Vector2() }
    };

    var material = new THREE.ShaderMaterial( {
        uniforms: uniforms,
        vertexShader: document.getElementById( 'vertexShader' ).textContent,
        fragmentShader: document.getElementById( 'fragmentShader' ).textContent
    } );

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

    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio( window.devicePixelRatio );

    container.appendChild( renderer.domElement );

    onWindowResize();
    window.addEventListener( 'resize', onWindowResize, false );

    document.onmousemove = function(e){
    uniforms.u_mouse.value.x = e.pageX
    uniforms.u_mouse.value.y = e.pageY
    }
}

function onWindowResize( event ) {
    renderer.setSize( window.innerWidth, window.innerHeight );
    uniforms.u_resolution.value.x = renderer.domElement.width;
    uniforms.u_resolution.value.y = renderer.domElement.height;
}

function animate(delta_ms) {
    requestAnimationFrame( animate );
    render(delta_ms);
}

function render(delta_ms) {
    uniforms.u_time.value = delta_ms;
    renderer.render( scene, camera );
}