如何“合并”ShaderMaterial和LambertMaterial?

4

首先,非常感谢您做出的伟大工作和社区。

我正在尝试编写一个简单的低多边形风格水材质。

我知道有不同的编写方式,而且我尽可能地想在js脚本中完成它(我来自C#开发人员,对前端还不是很熟悉)。

经过数小时的编译网络信息,我能理解的一种方法是这样的:

var waterVertexShader =  
                "attribute float vertexDisplacement;" +
                "uniform float time;" +
                "varying vec3 vUv;" +
                "void main() {" +
                "   vUv = position;" +
                "   vUv.y += sin(time) * 0.01;" +
                "   gl_Position = projectionMatrix * modelViewMatrix * vec4(vUv, 1.0);"+     
                "}"
            ;

            var waterFragmentShader =

                "void main() {" +
                "gl_FragColor = vec4(0.65, 0.88, 1, 1);" +
                "}";


                },
                flatShading : true,
                vertexShader: waterVertexShader,

这给了我所需行为的起点,但这不是我的问题所在。

现在,如果我想继承Lambert或Phong材质属性,应该怎样正确地进行?

听起来非常基础,但这是我找到的唯一相关链接: ThreeJS - Extend Lambert Shader with Custom VertexShader 而且没有答案。

感谢您的关注。

1个回答

8

有几种方法可以增强three.js中内置材质:

  • 您可以使用回调函数Material.onBeforeCompile()。这种方法在以下示例中演示。如果您只想对着色器代码进行轻微的增强,那么这应该是您的首选。
  • 使用RawShaderMaterialShaderMaterial从头开始创建自定义材质,并重用库中现有的着色器块。这种方法非常灵活,但需要对three.js的材质系统内部有很好的了解。
  • 当然,您也可以修改/猴子补丁现有的着色器块,但一般不推荐此方法(实际上您会改变库代码并产生所有后果)。
  • 另一种方法是使用前途光明但实验性的NodeMaterial。但是,这种技术没有记录,并且迄今为止不属于核心的一部分。有一些示例演示了使用方法,例如这个示例

2
谢谢,我选择了onBeforeCompile选项(我刚刚花了整整一周的时间尝试实现一个光线投射解决方案,我有点累了),它像魔法一样运行良好。我不能给你点赞,因为我在这里还太新,但你知道我的心在点赞! - GoupilSystem
我也读了pailhead的文章,但他的评论消失了。虽然不确定原因,但无论如何,还是谢谢你,伙计。 - GoupilSystem
可能是因为它是所谓的“仅链接”答案。将此链接放入评论中更为正确。 - Mugen87
顺便说一下:请接受答案^^。即使是新用户也应该可以做到。 - Mugen87
2
这是链接:https://medium.com/@pailhead011/extending-three-js-materials-with-glsl-78ea7bbb9270 - Mugen87

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接