文章目录

动态

请添加图片描述
在three.js中每帧更新时间参数
three.js

/*
 * @Author: hongbin
 * @Date: 2022-10-01 18:31:26
 * @LastEditors: hongbin
 * @LastEditTime: 2022-10-02 16:04:40
 * @Description:绘制一个圆形
 */
import * as THREE from "three";
import vertexShader from "../../shader/circular.vt.glsl";
import fragmentShader from "../../shader/circular.fs.glsl";

export const drawCircular = () => {
    const clock = new THREE.Clock();

    const uniforms = {
        time: { value: clock.getElapsedTime() },
    };

    const box = new THREE.Mesh(
        new THREE.BoxGeometry(5, 6, 10, 20, 20, 20),
        new THREE.ShaderMaterial({
            vertexShader,
            fragmentShader,
            uniforms,
        })
    );
    frameLoop(() => {
        uniforms.time.value = clock.getElapsedTime();
        window.render();
    });
    return box;
};

const frameLoop = (script: () => void) => {
    requestAnimationFrame(() => {
        frameLoop(script);
    });
    script();
};

片元着色器

varying vec2 vUv;
varying vec3 vPosition;
uniform float time;

void circularRange(vec2 face, vec2 center, float r, float d, vec3 color, inout vec3 defColor) {
    vec2 position = vec2(face.xy) - center;
    if(length(position.xy) < r && length(position.xy) > d) {
        // 圆环颜色
        defColor = color;
    }
}

void main() {
    float val = (sin(time));
    // 默认颜色
    vec3 color = vec3(0.1, 0.1, val);

    // 前后
    circularRange(vPosition.xy, vec2(val, val), 1.0, 0.5, vec3(1.0, val, 0.42), color);
    circularRange(vPosition.xy, vec2(val, -val), 1.0, 0.5, vec3(1, 0.47, 0.1), color);
    circularRange(vPosition.xy, vec2(-val, val), 1.0, 0.5, vec3(0.73, val, 0.1), color);
    circularRange(vPosition.xy, vec2(-val, -val), 1.0, 0.5, vec3(0.1, 0.56, 1), color);
    // 上下
    circularRange(vPosition.xz, vec2(1.0, 0.5), 1.0, 0.5, vec3(0.30, 0.5, 0.42), color);
    circularRange(vPosition.xz, vec2(1.0, -1.5), 1.0, 0.5, vec3(0.2, 0.47, 0.1), color);
    circularRange(vPosition.xz, vec2(-1.0, 1.5), 1.0, 0.5, vec3(0.13, 1, 0.1), color);
    circularRange(vPosition.xz, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.6, 0.16, 1), color);
    // 左右
    circularRange(vPosition.zy, vec2(2.0, 0.5), 1.0, 0.5, vec3(2.0, 0.1, 0.42), color);
    circularRange(vPosition.zy, vec2(1.0, -1.5), 1.0, 0.5, vec3(1, 0.47, 0.1), color);
    circularRange(vPosition.zy, vec2(-2.0, 1.5), 1.0, 0.5, vec3(1.73, 1, 0.1), color);
    circularRange(vPosition.zy, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.1, 0.56, 1), color);
    circularRange(vPosition.zy, vec2(-3.0, 1.5), 1.0, 0.5, vec3(0.1, 1, 0.63), color);
    circularRange(vPosition.zy, vec2(-3.0, -1.5), 1.0, 0.5, vec3(0.52, 0.1, 1), color);

    gl_FragColor = vec4(color, 1);
}

顶点着色器

varying vec2 vUv;
varying vec3 vPosition;

void main() {
    vUv = uv;
    vPosition = position;

    gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1.0);
}

静态

在这里插入图片描述
绘制一个圆形案例
顶点着色器

varying vec2 vUv;
varying vec3 vPosition;

void main() {
    vUv = uv;
    vPosition = position;

    gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1.0);
}

片元着色器

void circularRange(vec2 face, vec2 center, float r, float d, vec3 color, inout vec3 defColor) {
    vec2 position = vec2(face.xy) - center;
    if(length(position.xy) < r && length(position.xy) > d) {
        // 圆环颜色
        defColor = color;
    }
}

void main() {
    // 默认颜色
    vec3 color = vec3(0.1, 0.1, 0.42);

    // 前后
    circularRange(vPosition.xy, vec2(1.0, 0.5), 1.0, 0.5, vec3(1.0, 0.1, 0.42), color);
    circularRange(vPosition.xy, vec2(1.0, -1.5), 1.0, 0.5, vec3(1, 0.47, 0.1), color);
    circularRange(vPosition.xy, vec2(-1.0, 1.5), 1.0, 0.5, vec3(0.73, 1, 0.1), color);
    circularRange(vPosition.xy, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.1, 0.56, 1), color);
    // 上下
    circularRange(vPosition.xz, vec2(1.0, 0.5), 1.0, 0.5, vec3(0.30, 0.5, 0.42), color);
    circularRange(vPosition.xz, vec2(1.0, -1.5), 1.0, 0.5, vec3(0.2, 0.47, 0.1), color);
    circularRange(vPosition.xz, vec2(-1.0, 1.5), 1.0, 0.5, vec3(0.13, 1, 0.1), color);
    circularRange(vPosition.xz, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.6, 0.16, 1), color);
    // 左右
    circularRange(vPosition.zy, vec2(2.0, 0.5), 1.0, 0.5, vec3(2.0, 0.1, 0.42), color);
    circularRange(vPosition.zy, vec2(1.0, -1.5), 1.0, 0.5, vec3(1, 0.47, 0.1), color);
    circularRange(vPosition.zy, vec2(-2.0, 1.5), 1.0, 0.5, vec3(1.73, 1, 0.1), color);
    circularRange(vPosition.zy, vec2(-1.0, -1.5), 1.0, 0.5, vec3(0.1, 0.56, 1), color);
    circularRange(vPosition.zy, vec2(-3.0, 1.5), 1.0, 0.5, vec3(0.1, 1, 0.63), color);
    circularRange(vPosition.zy, vec2(-3.0, -1.5), 1.0, 0.5, vec3(0.52, 0.1, 1), color);

    gl_FragColor = vec4(color, 1);
}

应用到three.js中

/*
 * @Author: hongbin
 * @Date: 2022-10-01 18:31:26
 * @LastEditors: hongbin
 * @LastEditTime: 2022-10-01 21:04:21
 * @Description:绘制圆形
 */
import * as THREE from "three";
import vertexShader from "../../shader/circular.vt.glsl";
import fragmentShader from "../../shader/circular.fs.glsl";

export const drawCircular = () => {
    const box = new THREE.Mesh(
        new THREE.BoxGeometry(5, 6, 10, 20, 20, 20),
        new THREE.ShaderMaterial({
            vertexShader,
            fragmentShader,
        })
    );
    return box;
};

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐