
10 分钟调出复古半色调点阵three.js DotScreenPass 实战指南【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.jsthree.js 的DotScreenPass是一个半色调后处理通道场景渲染完成后它把整幅画面重绘成密集圆点阵列让屏幕看起来像报纸印刷或老式点阵屏。读完这篇你能拿到一段可直接粘贴的接入代码以及一套运行时调节网点旋转与脉冲的配方。先让画面变味儿——最小可运行接入DotScreenPass是 addon 模块不在核心包里必须显式引入。下面这段代码把它接进场景渲染之后的后处理链import * as THREE from three; import { EffectComposer } from three/addons/postprocessing/EffectComposer.js; import { RenderPass } from three/addons/postprocessing/RenderPass.js; import { DotScreenPass } from three/addons/postprocessing/DotScreenPass.js; const composer new EffectComposer( renderer ); composer.addPass( new RenderPass( scene, camera ) ); composer.addPass( new DotScreenPass( new THREE.Vector2( 0, 0 ), 0.5, 0.8 ) ); function animate() { requestAnimationFrame( animate ); composer.render(); } animate();跑起来后整块画面被圆点阵列覆盖亮的地方点又大又亮暗的地方几乎沉进黑里颜色信息被点阵的明暗代替——就是报纸放大看的那种质感。这个构造写法在官方运行示例 examples/webgl_postprocessing_advanced.html 里原样出现。三个旋钮怎么拧——参数调优速查构造函数收三个参数对应三个旋钮网点从哪开始旋转、点阵斜多少、点有多大。new DotScreenPass( center, angle, scale );三个参数都是可选的省略就沿用着色器默认值参数含义默认值推荐范围center网点相位原点( 0.5, 0.5 )屏幕中心( 0, 0 )屏幕角落angle网点旋转角弧度1.57约 π/20 ~ 6.28scale网点密度越大点越小1.00.5 ~ 2.0把scale从 1.0 拖到 0.5颗粒感立刻粗一倍——相当于同一张网点底片是放大打印还是缩小打印的差别。angle设成0.5点阵会微微倾斜多几分手绘报纸的味道。让网点动起来——运行时动态调参 ✨pass.uniforms和材质共享同一份引用改完下一帧就生效无需重建 pass。把angle在动画帧里每次加一点网点就开始缓慢转圈const dotScreen new DotScreenPass( new THREE.Vector2( 0, 0 ), 0.5, 0.8 ); composer.addPass( dotScreen ); function animate() { requestAnimationFrame( animate ); dotScreen.uniforms.angle.value 0.01; dotScreen.uniforms.scale.value 0.6 0.3 * Math.sin( Date.now() * 0.001 ); composer.render(); } animate();跑起来后angle每帧加 0.01 让点阵慢转scale由正弦波驱动网点粗细来回呼吸。想让网点相位挪位置用dotScreen.uniforms.center.value.copy( new THREE.Vector2( 0.3, 0.7 ) )一行搞定。滤镜背后那 20 行着色器——半色调算法拆解视觉效果的核心是 DotScreenShader.js 里的片元着色器算法沿用了 glfx.js 的实现。关键代码就这么多float pattern() { float s sin( angle ), c cos( angle ); vec2 tex vUv * tSize - center; vec2 point vec2( c * tex.x - s * tex.y, s * tex.x c * tex.y ) * scale; return ( sin( point.x ) * sin( point.y ) ) * 4.0; } void main() { vec4 color texture2D( tDiffuse, vUv ); float average ( color.r color.g color.b ) / 3.0; gl_FragColor vec4( vec3( average * 10.0 - 5.0 pattern() ), color.a ); }拆成三步理解1取 RGB 平均值average当这个像素的灰度亮度2把 UV 换算到像素空间以center为原点按angle旋转、再乘scale——两个旋钮的数学来源就藏在这几行3对旋转后坐标分别取sin再相乘得到 [-1, 1] 间的周期性调制值放大 4 倍后叠加到average * 10.0 - 5.0的亮度基底上形成明暗靠点阵表达的半色调观感原图 alpha 原样保留。想自定义网点造型——45° 新闻纸排布、CMYK 彩色分色——改pattern()这一个函数再把自己的 ShaderMaterial 传给 pass 即可。组合拳实战——后处理链级联配置网点滤镜单飞能看级联出味道场景渲染 → 伽马校正 → 网点 → 渐晕。通道顺序直接决定最终观感比如伽马校正放在网点后面网点本身的黑白也会被校正整体色调明显变亮。下面这条链可直接嵌入项目import { ShaderPass } from three/addons/postprocessing/ShaderPass.js; import { GammaCorrectionShader } from three/addons/shaders/GammaCorrectionShader.js; import { VignetteShader } from three/addons/shaders/VignetteShader.js; const composer new EffectComposer( renderer ); composer.addPass( new RenderPass( scene, camera ) ); composer.addPass( new ShaderPass( GammaCorrectionShader ) ); const dotScreen new DotScreenPass( new THREE.Vector2( 0, 0 ), 0.5, 0.8 ); composer.addPass( dotScreen ); const vignette new ShaderPass( VignetteShader ); vignette.uniforms[ offset ].value 1.6; vignette.uniforms[ darkness ].value 0.95; composer.addPass( vignette );运行后画面是点阵质感加四角压暗一股老电影放映机的味道。offset/darkness取 1.6 和 0.95 来自官方 advanced 示例照抄不会出错。踩坑清单与资源释放 ⚠️漏调 dispose 会泄漏 GPU 资源动态重建后处理链时先把旧 pass 摘掉再释放chrome://gpu里 WebGL 纹理数不再上涨才算干净dotScreen.dispose();这一行会释放 ShaderMaterial 和全屏四边形几何体不执行的话这两块显存就一直挂着。scale与网点密度是反比数值越大点越小越细密越小点越大越粗。新手最常搞反第一次想调细结果调出一颗大圆点。渲染管线边界Pass基类模块注释明确只服务WebGLRenderer后处理。项目走 WebGPU TSL 的话请改用 DotScreenNode 文档 里的 Node 实现这个 Pass 不能原样搬过去。别手动设tDiffuse和tSizerender()每帧自动写入上一通道纹理和缓冲区宽高你自己设了也会被覆盖白忙活。如果你只带走这几句引入路径three/addons/postprocessing/DotScreenPass.js挂进EffectComposer才生效构造三参center/angle/scale全部可省省了就用默认值想要更细的网点把scale往大了调——它是反比动画帧里改uniforms下一帧即生效不用重建移除通道前dispose()一次显存还给你。参考官方文档Pass 源码着色器源码Pass 基类运行示例【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考