我一直在尝试学习 THREEJS 着色器材料。到目前为止,我了解制服、vertexShader 和 fragmentShader 如何在 glsl 和 webgl 的世界中对顶点和片段进行投影和着色。我一直在尝试找到一些使用 THREE.ShaderLib 扩展 THREEJS 的 ShaderMaterial 的好例子。
假设我想扩展一个标准的threejs材质(THREE.ShaderLib['standard'])来编写envmap纹理,这可能吗?还是绝对有必要从头开始编写所有内容?
我一直在尝试学习 THREEJS 着色器材料。到目前为止,我了解制服、vertexShader 和 fragmentShader 如何在 glsl 和 webgl 的世界中对顶点和片段进行投影和着色。我一直在尝试找到一些使用 THREE.ShaderLib 扩展 THREEJS 的 ShaderMaterial 的好例子。
假设我想扩展一个标准的threejs材质(THREE.ShaderLib['standard'])来编写envmap纹理,这可能吗?还是绝对有必要从头开始编写所有内容?
着色器只是字符串,取决于您如何处理它们以及如何获取它们。话虽如此,three.js 有许多工具可以帮助您更好地构建它们。
在最高级别,有一个形式为 的抽象THREE.Material
。您在其中描述抽象属性和三个配置引擎盖下的着色器。
//no shaders involved
var redPlastic = new THREE.MeshStandardMaterial({
color: 'red',
roughness: notVeryRough
})
ShaderMaterial
期望您编写原始 GLSL,但仍包含一些您必须手动执行的操作。所以“从头开始写”并不完全正确。与RawShaderMaterial
您一起从头开始编写所有内容。THREE.ShaderMaterial
:
varying vec2 vUv;
void main(){
vUv = uv; // <- magic! where does uv come from?
vec4 worldPosition = modelMatrix * vec4( position, 1.); // <- more magic! where do modelMatrix and position come from?
gl_Position = projectionMatrix * viewMatrix * worldPosition; // more!
}
在运行时,当三个被编译并包含在一个页面中时,三个命名空间有THREE.ShaderChunk
字典。这些是构建所有材料的各种命名的 GLSL 片段。
您可以从它们的源文件中复制这些片段,并将它们粘贴到您自己的着色器文件或字符串中。
您可以使用字符串模板编写它:
`${THREE.ShaderChunk.some_chunk}
void main(){
...
${anotherChunk}
gl_Position = ...
`
但是,如果您想扩展内置材料,则材料有一个(恕我直言,错误的:))特性,称为onBeforeCompile
. 这样,您可以将回调传递给任何内置材质,并在编译之前获取着色器对象。在这里,您可以注入自己的 glsl、交换块或任何您能想到的对字符串执行的操作。
为了使用这个需要熟悉从以下构建的着色器的结构: https ://github.com/mrdoob/three.js/tree/dev/src/renderers/shaders/ShaderChunk