Threejs 中学shader002----基于three.js的shader框架

前言
传统shader学习只能在opengl中学习,现如今借助webgl,在浏览器中就可以轻松写shader代码。
诸如shadertoy等实现了非常炫酷的网页效果。本教程就使用three.js库开始shader学习之旅。

参考资料

shader教程: https://thebookofshaders.com/

shader 框架

搭建一个最基本的基于three.js 的 shader框架。

<style>
  body {
    margin: 0;
    padding: 0;
  }

  #container {
    position: fixed;
  }
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/108/three.min.js"></script>
<script id="vertexShader" type="x-shader/x-vertex">
    void main() {
        gl_Position = vec4( position, 1.0 );
    }
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
    // u_resolution.xy, 当前屏幕的xy, eg: u_resolution.xy=(100, 200)
    uniform vec2 u_resolution;
    void main(){
        // gl_FragCoord.xy 当前像素的xy, eg: gl_FragCoord.xy=(50, 50)
        // st 归一化的坐标(x,y都映射到了0~1), eg: st=(0.5, 0.25)
        vec2 st = gl_FragCoord.xy / u_resolution.xy;
        // aspect 宽高比, eg: aspect = 100/200 = 0.5
        float aspect = u_resolution.x / u_resolution.y;
        // 保持宽高比统一, eg: st=(0.25, 0.25)
        // 也可以这样理解:
        //    像素 x 的范围是0~100,像素 y 的范围是0~200,
        //    归一化后, st.x 和 st.y 的映射都是0~1范围,
        //    归一化后, st.x 和 st.y 应该保持归一化后相同的宽高比,
        //    所以, 需要 st.x *= u_resolution.x / u_resolution.y;
        st.x *= aspect;
        vec3 color = vec3(0.0);

        // if( st.x > 0.1 && st.y > 0.1) {
        //   paint white(1)
        // } else {
        //   paint black(0)
        // }
        float left = step(0.1,st.x);
        float bottom = step(0.1,st.y);

        // The multiplication of left*bottom will be similar to the logical AND.
        // vec3(0) => (0,0,0), vec3(1) => (1,1,1)
        color = vec3(left * bottom);
        gl_FragColor = vec4(color,1.0);
    }
</script>
<div id="container"></div>

<script>
  let container;
  let camera, scene, renderer;
  let uniforms;

  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() {
    requestAnimationFrame(animate);
    render();
  }

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

  init();
  animate();
</script>

详细说明

shader的内部细节,详细参考, three.js中使用GLSL指南.md

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值