基于Three.js与GLSL的动态着色器渲染实现解析

2025-04-28 0 814

使用 Three.js 的 WebGL 小实验。一个使用 GLSL 着色器的 3D 渲染场景。通过 Three.js 设置基础的渲染环境,并通过传递给着色器的 uniforms(如时间、分辨率、鼠标位置等)动态调整渲染效果。交互方面,鼠标的位置和点击事件可以控制渲染的视觉效果。

基于Three.js与GLSL的动态着色器渲染实现解析
实现代码

HTML:

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/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">
    // By Liam Egan    // 2018
    uniform vec2 u_resolution;    uniform float u_time;    uniform bool u_complex;
    const int octaves = 6;    const float seed = 43758.5453123;    const float seed2 = 73156.8473192;

    vec2 random2(vec2 st, float seed){        st = vec2dot(st,vec2(127.1,311.7)),                  dot(st,vec2(269.5,183.3)) );        return -1.0 + 2.0*fract(sin(st)*seed);    }
    // Value Noise by Inigo Quilez - iq/2013    // https://www.shadertoy.com/view/lsf3WH    float noise(vec2 st, float seed) {        vec2 i = floor(st);        vec2 f = fract(st);
        vec2 u = f*f*(3.0-2.0*f);
        return mixmixdotrandom2(i + vec2(0.0,0.0), seed ), f - vec2(0.0,0.0) ),                          dotrandom2(i + vec2(1.0,0.0), seed ), f - vec2(1.0,0.0) ), u.x),                    mixdotrandom2(i + vec2(0.0,1.0), seed ), f - vec2(0.0,1.0) ),                          dotrandom2(i + vec2(1.0,1.0), seed ), f - vec2(1.0,1.0) ), u.x), u.y);    }
    float fbm1(in vec2 _st, float seed) {      float v = 0.0;      float a = 0.5;      vec2 shift = vec2(100.0);      // Rotate to reduce axial bias      mat2 rot = mat2(cos(0.5), sin(0.5),                      -sin(0.5), cos(0.50));      for (int i = 0; i < octaves; ++i) {          v += a * noise(_st, seed);          _st = rot * _st * 2.0 + shift;          a *= 0.4;      }      return v;    }
    float pattern(vec2 uv, float seed, float time, inout vec2 q, inout vec2 r) {
      q = vec2fbm1( uv * .1 + vec2(0.0,0.0), seed ),                     fbm1( uv + vec2(5.2,1.3), seed ) );
      r = vec2fbm1( uv * .1 + 4.0*q + vec2(1.7 - time / 2.,9.2), seed ),                     fbm1( uv + 4.0*q + vec2(8.3 - time / 2.,2.8), seed ) );
      vec2 s = vec2fbm1( uv + 5.0*r + vec2(21.7 - time / 2.,90.2), seed ),                     fbm1( uv * .05 + 5.0*r + vec2(80.3 - time / 2.,20.8), seed ) );
      return fbm1( uv * .05 + 4.0*s, seed );    }
    float pattern2(vec2 uv, float seed, float time, inout vec2 q, inout vec2 r) {
      q = vec2fbm1( uv + vec2(0.0,0.0), seed ),                     fbm1( uv + vec2(5.2,1.3), seed ) );
      r = vec2fbm1( uv + 4.0*q + vec2(1.7 - time / 2.,9.2), seed ),                     fbm1( uv + 4.0*q + vec2(8.3 - time / 2.,2.8), seed ) );
      vec2 s = vec2fbm1( uv + 5.0*r + vec2(21.7 - time / 2.,90.2), seed ),                     fbm1( uv + 5.0*r + vec2(80.3 - time / 2.,20.8), seed ) );
      vec2 t = vec2fbm1( uv + 4.0*s + vec2(121.7 - time / 2.,190.2), seed ),                     fbm1( uv + 4.0*s + vec2(180.3 - time / 2.,120.8), seed ) );
      vec2 u = vec2fbm1( uv + 3.0*t + vec2(221.7 - time / 2.,290.2), seed ),                     fbm1( uv + 3.0*t + vec2(280.3 - time / 2.,220.8), seed ) );
      vec2 v = vec2fbm1( uv + 2.0*u + vec2(221.7 - time / 2.,290.2), seed ),                     fbm1( uv + 2.0*u + vec2(280.3 - time / 2.,220.8), seed ) );
      return fbm1( uv + 4.0*v, seed );    }
    void main() {      vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / u_resolution.y;
      float time = u_time / 10.;
      mat2 rot = mat2(cos(time / 10.), sin(time / 10.),                      -sin(time / 10.), cos(time / 10.));
      uv = rot * uv;      uv *= 0.9 * (sin(u_time / 20.)) + 3.;      uv.x -= time / 5.;
      vec2 q = vec2(0.,0.);      vec2 r = vec2(0.,0.);
      float _pattern = 0.;
      if(u_complex) {        _pattern = pattern2(uv, seed, time, q, r);      } else {        _pattern = pattern(uv, seed, time, q, r);      }
      vec3 colour = vec3(_pattern) * 2.;      colour.r -= dot(q, r) * 15.;      colour = mix(colour, vec3(pattern(r, seed2, time, q, r), dot(q, r) * 15., -0.1), .5);      colour -= q.y * 1.5;      colour = mix(colour, vec3(.2.2.2), (clamp(q.x, -1.0.)) * 3.);      // colour += clamp(0.4, 0.8, fract(_pattern * 10.)) / 5.;
      // gl_FragColor = vec4(abs(colour), 1.);      gl_FragColor = vec4(-colour + (abs(colour) * .5), 1.);      // gl_FragColor = vec4(abs(colour), 1.);    }</script>

<div id="container"></div>
CSS:
body {  margin0;  padding0;}
#container {  position: fixed;}

JAVASCRIPT:

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.PlaneBufferGeometry22 );
  uniforms = {    u_time: { type"f"value2001.0 },    u_resolution: { type"v2"valuenew THREE.Vector2() },    u_mouse: { type"v2"valuenew THREE.Vector2() },    u_complex: { type"b"valuefalse }  };
  var material = new THREE.ShaderMaterial( {    uniforms: uniforms,    vertexShaderdocument.getElementById'vertexShader' ).textContent,    fragmentShaderdocument.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.addEventListener'mouseup', onMouseUp, false );
  document.onmousemove = function(e){    uniforms.u_mouse.value.x = e.pageX    uniforms.u_mouse.value.y = e.pageY  }}
function onWindowResize( event ) {  renderer.setSizewindow.innerWidthwindow.innerHeight );  uniforms.u_resolution.value.x = renderer.domElement.width;  uniforms.u_resolution.value.y = renderer.domElement.height;}
function onMouseUp() {  uniforms.u_complex.value = !uniforms.u_complex.value;}
function animate() {  requestAnimationFrame( animate );  render();}
function render() {  uniforms.u_time.value += 0.05 * (1 + uniforms.u_mouse.value.x / 200.);  renderer.render( scene, camera );}


init();animate();

源码:

https://codepen.io/shubniggurath/pen/NXGbBo

体验:

https://codepen.io/shubniggurath/full/NXGbBo

基于Three.js与GLSL的动态着色器渲染实现解析

初识 Three.js 的奇妙世界
走进三维空间,与小编一起拥抱前端技术

——————————–

基于Three.js与GLSL的动态着色器渲染实现解析

感谢您的阅读      

在看点赞 好文不断  基于Three.js与GLSL的动态着色器渲染实现解析

Three.js特效 · 目录
上一篇Three.js 催眠粒子漩涡与鼠标反应性运动(源码)
阅读 56
写留言
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

免责声明 1、百创网作为第三方中介平台,依据交易合同(商品描述、交易前商定的内容)来保障交易的安全及买卖双方的权益; 2、非平台线上交易的项目,出现任何后果均与百创网无关;无论卖家以何理由要求线下交易的,请联系管理举报。 3. 百创网网站的资源均由店家上传出售,本站无法判断和识别资源的版权等合法性属性。如果您对本网站上传的信息资源的版权存有异议,请您及时联系 我们。如果需要删除链接,请下载下面的附件,正确填写信息后并发给我们,本站核实信息真实性后,在24小时内对商品进行删除处理。 联系邮箱:baicxx@baicxx.com (相关事务请发函至该邮箱)

百创网-源码交易平台_网站源码_商城源码_小程序源码 行业资讯 基于Three.js与GLSL的动态着色器渲染实现解析 https://www.baicxx.com/30475.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、百创会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、百创无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在百创上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于百创介入快速处理。
查看详情
  • 1、百创作为第三方中介平台,依据交易合同(商品描述、交易前商定的内容)来保障交易的安全及买卖双方的权益; 2、非平台线上交易的项目,出现任何后果均与百创无关;无论卖家以何理由要求线下交易的,请联系管理举报。
查看详情
  • 免责声明 1、百创网作为第三方中介平台,依据交易合同(商品描述、交易前商定的内容)来保障交易的安全及买卖双方的权益; 2、非平台线上交易的项目,出现任何后果均与百创网无关;无论卖家以何理由要求线下交易的,请联系管理举报。 3. 百创网网站的资源均由店家上传出售,本站无法判断和识别资源的版权等合法性属性。如果您对本网站上传的信息资源的版权存有异议,请您及时联系 我们。如果需要删除链接,请下载下面的附件,正确填写信息后并发给我们,本站核实信息真实性后,在24小时内对商品进行删除处理。 联系邮箱:baicxx@baicxx.com (相关事务请发函至该邮箱)
查看详情

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务

  • 0 +

    访问总数

  • 0 +

    会员总数

  • 0 +

    文章总数

  • 0 +

    今日发布

  • 0 +

    本周发布

  • 0 +

    运行天数

你的前景,远超我们想象