【Webgl_glsl&Threejs】制作流水效果/毛玻璃效果材质

效果预览

shadertory源码

复制代码
source: https://www.shadertoy.com/view/lldyDs 

材质代码

javascript 复制代码
import { DoubleSide, ShaderChunk, ShaderMaterial, TextureLoader } from "three";
/**
* 
* source https://www.shadertoy.com/view/lldyDs 
*/


export default function RangeWaterMat(totalLength) {
    const vertex =/* glsl */ `
        ${ShaderChunk.logdepthbuf_pars_vertex}
        bool isPerspectiveMatrix(mat4) {
            return true;
        }

        varying vec2 vUv;

        uniform float uTime;



        void main () {
            vUv = uv;
            // 从贴图中采样颜色值
            vec3 newPosition = normal*vec3(0,0,0)+position;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);

            ${ShaderChunk.logdepthbuf_vertex}
        }
    `;

    // 片元着色器代码
    const fragment =/*glsl */ `
        ${ShaderChunk.logdepthbuf_pars_fragment}
        precision mediump float;
        varying vec2 vUv;
        uniform float uTime;
        uniform sampler2D iChannel0;
        uniform float totalLength;
      
        float T;

        #define pi 3.1415926

        // iq's hash function from https://www.shadertoy.com/view/MslGD8
        vec2 hash( vec2 p ) { p=vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))); return fract(sin(p)*18.5453); }

        float simplegridnoise(vec2 v)
        {
            float s = 1. / 256.;
            vec2 fl = floor(v), fr = fract(v);
            float mindist = 1e9;
            for(int y = -1; y <= 1; y++)
                for(int x = -1; x <= 1; x++)
                {
                    vec2 offset = vec2(x, y);
                    vec2 pos = .5 + .5 * cos(2. * pi * (T*.1 + hash(fl+offset)) + vec2(0,1.6));
                    mindist = min(mindist, length(pos+offset -fr));
                }
            
            return mindist;
        }

        float blobnoise(vec2 v, float s)
        {
            return pow(.5 + .5 * cos(pi * clamp(simplegridnoise(v)*2., 0., 1.)), s);
        }

        vec3 blobnoisenrm(vec2 v, float s)
        {
            vec2 e = vec2(.01,0);
            return normalize(
                vec3(blobnoise(v + e.xy, s) - blobnoise(v -e.xy, s),
                        blobnoise(v + e.yx, s) - blobnoise(v -e.yx, s),
                        1.0));
        }

        float blobnoises(vec2 uv, float s)
        {
            float h = 0.0;
            const float n = 5.0;
            for(float i = 0.0; i < n; i++)
            {
                vec2 p = vec2(0.0, 1.0 * uTime * (i + 1.0) / n) + 1.0 * uv;
                h += pow(0.5 + 0.5 * cos(pi * clamp(simplegridnoise(p * (i + 1.0)) * 2.0, 0.0, 1.0)), s);
            }
            
            return h / n;
        }

        vec3 blobnoisenrms(vec2 uv, float s)
        {
            float d = 0.01;
            return normalize(
                vec3(blobnoises(uv + vec2(  d, 0.0), s) - blobnoises(uv + vec2( -d, 0.0), s),
                        blobnoises(uv + vec2(0.0,   d), s) - blobnoises(uv + vec2(0.0,  -d), s),
                        d));
        }
    
        void main() {


            vec2 uv =(vUv)*.5;
 
            uv = fract(uv*vec2(totalLength,1.0));
            uv.x = abs (.5-uv.x);

            T = .0;

            vec2 r = vec2(2., 2.);
          
            vec3 n = blobnoisenrms(25. * uv*r , 1.);
     
     
            vec4 vision = texture(iChannel0, (uv)*1.25 + 0.05 * n.xy);


            float a = (vision.r+vision.g+vision.b)/3.;


            gl_FragColor =vision;
            gl_FragColor.a = a;
           
            ${ShaderChunk.logdepthbuf_fragment}
        }
    `;




    const tl0 = new TextureLoader()
    const texture0 = tl0.load('static/threeResources/texture/niminoise.png')
    // const texture0 = tl0.load('/shader_book/textures/italy2.png')
    const material = new ShaderMaterial({
        uniforms: {
            uTime: { value: 1.0 },
            totalLength: { value: totalLength },
            iChannel0: { value: texture0, type: 'sample2d' },

        },
        vertexShader: vertex,
        fragmentShader: fragment,
        side: DoubleSide,
        transparent: true,
    });

    return material
}

贴图资源

不一定用这张,可以换点贴图试试,可能做出别的效果(走马灯,石棉,瓷砖等的都可以模拟)

相关推荐
Solange__10 分钟前
Blender 3D模型优化:普通复制、共享网格、实例、合并怎么选?
人工智能·3d·ai·自然语言处理·编辑器·blender·材质
总要学点什么4 小时前
第108篇:三维特效-图片轨迹线效果——把贴图滚成一串箭头,想用它的本色反而整条消失
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
暴走约伯6 小时前
【VFX工具链源码拆解 09】终极工业化闭环:基于 ID 规则驱动的全自动场景建档、骨骼挂载与男转女场景迁移
unity·c#·游戏引擎·材质
总要学点什么10 小时前
第106篇:三维特效-流动线效果——让一颗光点沿整条线一路滚到头
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
总要学点什么1 天前
第105篇:三维特效-流动图片墙体效果——让箭头沿墙长滚,它俩竟是同一份代码
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
总要学点什么1 天前
第104篇:三维特效-流动墙体效果——让贴图沿墙流动,它却只肯走一条对角线
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
西伯利亚小火龙1 天前
我以为是流体解算,结果只是一张贴图:复刻 Lusion 的屏幕流体特效
webgl·three.js
普通人61 天前
WebGL与WebGPU入门指南
开发语言·webgl·1024程序员节
魂断蓝桥6663 天前
如何用 three.js 把 3D 消防演练落到一栋楼里——第一课:场景搭建与火情定位
webgl·three.js·3d建筑·物联网3d·、3d工厂、3d工业园区、智慧制造、智慧工业、智慧工厂·3d定位、三维室内定位、3d建筑·3d消防
总要学点什么4 天前
第96篇:三维数据加载-城市建筑白模样式+着色器——让色带按体量上色,最白的那档却涂不上去
前端·gis·webgl·cesium·着色器·空间分析·白模