Threejs:使自定义着色器与标准渲染相匹配

时间:2016-12-18 20:23:13

标签: javascript three.js glsl fragment-shader buffer-geometry

出于性能原因,我需要在场景中显示数百个移动的四面体。我使用的是instancedbuffergeometry,它需要一个自定义着色器。

场景还包含具有常规几何体(非缓冲区)和一些灯光的对象(我准备了煮沸的片段:https://jsfiddle.net/negan/xs3k1yz4/)。

我的问题是四面体没有阴影,因此它们的照明似乎适合场景的其余部分。原因可能是我构建的原始着色器:



<script id="vertexShader" type="x-shader/x-vertex">
attribute vec3 offset;
attribute vec4 color;
varying vec4 vColor;
varying vec3 vNormal;
void main() {
	vColor = color;
	vNormal = normalMatrix * vec3(normal);
	gl_Position = projectionMatrix *
				modelViewMatrix *
				vec4(position*1.0+offset,1.0);
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
	varying vec4 vColor;
    varying vec3 vNormal;

	void main() {  
		float di = 0.4*dot(vNormal,normalize(vec3(1.,1.,0.)))+0.4*dot(vNormal,normalize(vec3(1.,0.,1.)));
		di = di+0.2;
		vec4 vColor2= vColor*vec4(1.0,1.,1.,0.2)*di;
		gl_FragColor = vColor2;// adjust the alpha
	}
</script>
&#13;
&#13;
&#13;

有没有办法让自定义着色器适合我在场景中定义的灯光?着色器还以这样的方式渲染面部,这种方式不会产生定向光的印象。我喜欢让单个面部均匀点亮,而是从顶点插入颜色,但我无法实现这一点。

赞赏任何指针或帮助。

2 个答案:

答案 0 :(得分:1)

对于一个Three.js MeshPhongMaterial着色器,

Here's a gist of the full fragment and vertex shader source,截至r83。

Three.js使用字符串连接系统构建着色器,因此通过查看Three.js源来计算着色器的来源几乎是不可能的。

上面的Gist是通过安装shader editor Chrome extension生成的,转到具有MeshPhongMaterial like this one的Three.js示例页面,并使用着色器编辑器检查正在运行的着色器程序的完整来源:

shader editor source

Three.js将所有默认制服(如灯光数据)传递给所有着色器程序,因此如果您使用上面的Gist代码创建自定义着色器,灯光,骨骼等都将自动生效。

我会采用完整的源代码并手动添加您的逻辑,直接将计算结果添加到现有gl_FragColor = ...

将来,我的工具ShaderFrog会让您自动将任何Three.js着色器功能(灯光,骨骼,变形目标等)添加到任何自定义着色器。 ShaderFrog已经可以自动将任何着色器组合在一起,但我还没有完成完全支持三种功能所需的手动工作。

答案 1 :(得分:0)

为three.js提供了InstancedMesh模块。它允许在不使用着色器材质的情况下实例化网格。它修补现有材料。 https://github.com/pailhead/three-instanced-mesh