Skip to main content

Draw Texture

这个实例主要展示了引擎 Texture 纹理的使用。

一个简单的示例

Result
Loading...
Live Editor
function render(props) {
  const drawModelVertex = `
    attribute vec2 uv;
    attribute vec3 position;
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    varying vec2 vUv;

    void main() {
        vUv = uv;

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

  const drawModelFragment = `
    precision highp float;

    uniform sampler2D texture;

    varying vec2 vUv;

    void main() {
        vec3 tex = texture2D(texture, vUv).rgb;
        gl_FragColor.rgb = tex;
        gl_FragColor.a = 1.0;
    }
    `;

  const refDom = useRef(null);

  const store = leva.useCreateStore();

  const fov = 15;
  const nearZ = 0.1;

  const farZ = 100;

  // const { name, aNumber } = leva.useControls({ name: 'World1', aNumber: 2 }, { store });

  const image = useBaseUrl('/assets/posx.jpg');

  const init = () => {
    const canvas = refDom.current;

    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
    const renderer = new Renderer(canvas, {
      alpha: true,
    });

    const camera = new PerspectiveCamera(fov, canvas.width / canvas.height, nearZ, farZ);
    camera.position.z = 15;

    function resize(target) {
      const { width, height } = target.getBoundingClientRect();
      renderer.setSize(width, height);
      camera.aspect = width / height;
    }

    const scene = new Scene();

    const geometry = new Geometry(renderer, {
      position: {
        size: 3,
        data: new Float32Array([
          -1, 1, 0,
          -1, -1, 0,
          1, 1, 0,
          1, -1, 0
        ])
      },
      uv: {
        size: 2,
        data: new Float32Array([0, 1, 1, 1, 0, 0, 1, 0])
      },
      index: {
        data: new Uint16Array([0, 1, 2, 1, 3, 2])
      },
    });

    const texture = new Texture(renderer, {
      generateMipmaps: false,
      flipY: true,
    });

    texture.fromSrc(image);

    const program = new Program(renderer, {
      vertexShader: drawModelVertex,
      fragmentShader: drawModelFragment,
      uniforms: {
        texture: {
          value: texture,
        },
      },
    });

    const triangles = new Mesh(renderer, { mode: renderer.gl.TRIANGLES, geometry, program });
    triangles.setParent(scene);
    triangles.position.set(0, 0, 0);

    const raf = new Raf((t) => {
      triangles.rotation.y -= 0.02;
      renderer.render({ scene, camera });
    });

    return {
      canvas,
      resize,
    }
  }

  useEffect(() => {
    const { canvas, resize } = init();

    observe(canvas, resize);

    return () => {
      unobserve(canvas, resize);
    };
  }, []);

  return (
    <div className="live-wrap">
      <div className="leva-wrap">
        <Leva
          fill
        ></Leva>
        <LevaPanel store={store} fill></LevaPanel>
      </div>
      <canvas className="scene-canvas" ref={refDom}></canvas>
    </div>
  );
}