3. 修改材质shader(彩色图变灰度图)
# 修改材质shader(彩色图变灰度图)
通过上节课学习,大家已经知道,怎么用onBeforeCompile
修改材质shader,这节课算是一个练习题。
打开演示文件代码,你可以看到MeshLambertMaterial
材质渲染的彩色效果图。
const texture = new THREE.TextureLoader().load('./Earth.png');
const material = new THREE.MeshLambertMaterial({
map: texture,
});
任务:修改Lambert网格材质MeshLambertMaterial
默认的shader代码,把彩色图转化为灰度图。
# 灰度图公式
获取彩色图R、G、B三个分量,执行灰度图公式0.299*R+0.587*G+0.114*B
,把计算结果gray作为新的R、G、B值。
// 灰度图公式
gray = 0.299 * R + 0.587 * G + 0.114 * B;
// gray作为新的R、G、B值
gl_FragColor = vec4(gray,gray,gray,1);
提醒:灰度图公式不用记忆,用到了直接复制文档公式或百度下就行
# 思考思路
你可以尝试思考下,怎么才能修改shader代码,才能把彩色图转灰度图。
首先这肯定像素RGB值相关,这样的话,应该是修改片元着色器,而不是修改顶点着色器。再具体点说就是通过片元着色器内置变量gl_FragColor
修改片元的R
、G
、B
分量,变成灰白效果。
# .onBeforeCompile
+.replace
修改着色代码
查看你当前threejs版本,材质片元着色器代码main里面的最后一行,复制出来即可。
material.onBeforeCompile = function (shader) {
console.log('片元着色器', shader.fragmentShader);
}
.replace
处理片元着色器代码,把最后一行替换为最后一行加别的代码。
const material = new THREE.MeshLambertMaterial({
map: texture,
});
// 修改材质material默认的着色器shader代码
material.onBeforeCompile = function (shader) {
console.log('片元着色器', shader.fragmentShader);
// 在片元着色器main函数里面最后一行插入灰度图代码
shader.fragmentShader = shader.fragmentShader.replace(
'#include <dithering_fragment>',
`
#include <dithering_fragment>
// 灰度图公式
float gray = 0.299*gl_FragColor.r+0.587*gl_FragColor.g+0.114*gl_FragColor.b;
gl_FragColor = vec4(gray,gray,gray,gl_FragColor.a);
`
)
}