threejs `.onBeforeCompile`修改材质shader

参考资料:threejs中文网

threejs qq交流群:814702116

.onBeforeCompile修改材质shader

上节课给大家说过,你可以通过材质.onBeforeCompile方法查看材质的着色器代码,其实也可以通过函数参数shader获取顶点或片元着色器GLSL ES的字符串进行二次修改。

const material = new THREE.MeshLambertMaterial();
material.onBeforeCompile = function (shader) {
  console.log('顶点着色器', shader.vertexShader);
  console.log('片元着色器', shader.fragmentShader);
  //你可以增删shader.vertexShader字符串
  //你可以增删shader.fragmentShader字符串
}

本节课修改结果:

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>
        gl_FragColor.r = 0.0;
        gl_FragColor.g = 0.0;
        `
    )
}

gl_FragColor多次执行

在片元着色器主函数main中,内置变量gl_FragColor可以多次调用设置RGBA分量的值。

// 片元着色器代码
const fragmentShader = `
void main() {
    gl_FragColor = vec4(0.0,1.0,1.0,1.0);
    //重新访问rgb属性赋值
    gl_FragColor.g = 0.0;
}
`
// 片元着色器代码
const fragmentShader = `
void main() {
    gl_FragColor = vec4(0.0,1.0,1.0,1.0);
    //可以多次赋值
    gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`

查看材质MeshLambertMaterial片元着色器代码

你可以直接去threejs官方文件包目录\src\renderers\shaders\ShaderLib,查看MeshLambertMaterial对应的shader文件meshlambert.glsl.js

meshlambert.glsl.js里面有两个字符串,一个是顶点着色器代码,一个片元着色器代码。

const material = new THREE.MeshLambertMaterial();

也可以直接浏览器控制台log打印

material.onBeforeCompile = function (shader) {
    console.log('片元着色器', shader.fragmentShader);
}

因为threejs经常改变,不太稳定,所以这里强烈提醒不同版本threejs,同一个材质的shader代码可能一样,也可能不一样,代码打印结果,以你使用的threejs版本为准,并不一定要和我视频完全一致。

你可以确定下你当前threejs版本,MeshLambertMaterial片元着色器主函数main里面最后一行代码是什么,我这里是#include <dithering_fragment>

void main() {
    ...
    ...
    ...
    #include <dithering_fragment>
}

.replace()方法介绍

.replace()JavaScript语言处理字符串的一个方法,算是普通前端基础。如果你了解,可以跳过去,如果不熟悉,就跟着视频熟悉下。

.replace()功能就是修改一串字符串,具体方式就是检索字符串是否包含参数1表示的字符串,去替换新的字符串。

const str = '我爱加班';
const newStr = str.replace('爱加班','不爱加班');
console.log('改变后字符串', newStr);

修改MeshLambertMaterial片元着色器代码

目标:在MeshLambertMaterial片元着色器主函数main里面最后一行后面增加代码。

void main() {
    ...
    ...
    ...
    #include <dithering_fragment>
    // 在这里增加代码
}

材质的片元着色器代码shader.fragmentShader本身就是一个字符串,所以我们可以用.replace()去修改替换shader.fragmentShader里面的部分代码。

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>
        gl_FragColor.r = 0.0;
        gl_FragColor.g = 0.0;
        `
    )
}
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在Three.js中使用透明视频着色器,您需要先将视频纹理加载到Three.js中。这可以通过以下代码完成: ``` var video = document.createElement( 'video' ); video.src = 'path/to/video.mp4'; var texture = new THREE.VideoTexture( video ); texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; texture.format = THREE.RGBFormat; ``` 接下来,您需要创建一个着色器材质并将视频纹理传递给它: ``` var material = new THREE.ShaderMaterial({ uniforms: { videoTexture: { value: texture }, opacity: { value: 1.0 } }, vertexShader: document.getElementById( 'vertexShader' ).textContent, fragmentShader: document.getElementById( 'fragmentShader' ).textContent, transparent: true }); ``` 在这个着色器材质中,我们有一个`uniforms`对象,其中包含我们的视频纹理和不透明度值。我们还设置了`transparent`属性为`true`,这是因为我们想要材质是透明的。 接下来,我们需要编写我们的片段着色器代码。这将允许我们在视频上应用透明度。以下是一个简单的透明视频着色器片段着色器代码: ``` uniform sampler2D videoTexture; uniform float opacity; varying vec2 vUv; void main() { vec4 texel = texture2D( videoTexture, vUv ); gl_FragColor = vec4( texel.rgb, opacity * texel.a ); } ``` 在这个着色器中,我们定义了一个`uniform`变量`opacity`,这是我们将要传递给着色器的不透明度值。我们将纹理的alpha值乘以不透明度值,以实现透明度效果。 最后,将材质应用于您的对象: ``` var geometry = new THREE.PlaneGeometry( 10, 10 ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); ``` 这将创建一个平面几何体,并将透明视频材质应用于它。现在,您将能够在Three.js场景中看到您的透明视频。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Threejs可视化

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值