基础篇:threejs使用着色器材质做一个纯色的掘金logo

183 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

最近回看了下之前的文章,感觉可能讲的比较粗糙。很多细节方面,被忽略了。于是乎,今天我就来说下threejs使用着色器材质的细节;

着色器材质有哪些?

首先,我们看文档可以知道,着色器材质,一共有两个:ShaderMaterial和RawShaderMaterial。

ShaderMaterial

我一般是使用这个材质来自定义shader渲染材质,顺便介绍下,shader是glsl编写的在gpu上运行的小程序。每个管线都会并发执行,且管线之间不具有互通性。每一个线程之前都是独立的,盲视的。并且,gpu的管道一直都处理数据,一个线程不可能知道它上一刻在做什么。它是无记忆的。因此,也导致glsl是出了名的难学。有兴趣可以挑战下。语法类似c++,数学也要求一定基础。

代码示例:

` const material = new THREE.ShaderMaterial( { 
   uniforms: { time: { value: 1.0 }, 
   resolution: { value: new THREE.Vector2() } }, 
   vertexShader: document.getElementById( 'vertexShader' ).textContent,
   fragmentShader: document.getElementById( 'fragmentShader' ).textContent
   } );`

RawShaderMaterial

至于这个类,其实和ShaderMaterial没啥太大区别,只是内置的uniforms和attributes的定义不会自动添加到glsl中。使用起来比较繁琐,所以,我一般也不用这个。shaderMaterial基本上是够用了。这个类也不是非用不可。

着色器实战案例

定义就这些,说了再多,也不如实际运用。

通常,我们通过uniforms传入一些固定的参数,着色器通过每个点的位置不同来展示各种不同的颜色。比如,我们可以传入一个贴图,每个管线根据uv坐标可以取到当前的位置的在贴图对应位置的颜色。也可以取到周围的颜色。如果我们做一个卷积的操作,也就实现了对图片模糊的操作。实现将贴图打上马赛克的效果。是不是很棒?

回归主题,由于我们是基础篇,我们先实现一个在3d场景显示纯色的效果。 因为3d的场景下,有光影关系的影响,所以我们一般材质展示的颜色,和我们设置的颜色都不一致。会混合其他颜色。如果遇到一定要色值一样的情况,就可以用着色器材质。毕竟前端最重要的是所见即所得(好像不太对)。

我们只要将颜色作为uniforms传给shaderMaterial。剩下的就交给glsl就行了。

glsl部分也是简单的把color给展示出来即可( gl_FragColor = vec4(color,1.0))

代码如下: let material = new THREE.ShaderMaterial({ uniforms: { color: { value: new THREE.Color(0x00d5ff) }, }, //顶点着色器 vertexShader: void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }, //片元着色器 fragmentShader: uniform vec3 color; void main() { gl_FragColor = vec4(color,1.0); }, });

code.juejin.cn/pen/7172871…