我一直在尝试使用this link在three.js中学习着色器的用法,不幸的是,这已经有些过时了,在尝试更新代码时,我到目前为止:
<script id="vshader" type="x-shader/x-vertex">
attribute float displacement;
varying vec3 vNormal;
void main() {
vNormal = normal;
vec3 newPosition = position + normal * vec3(displacement);
gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
}
</script>
<script id="fshader" type="x-shader/x-fragment">
varying vec3 vNormal;
void main() {
vec3 light = vec3(0.5, 0.2, 1.0);
light = normalize(light);
float dprod = max(0.0, dot(vNormal, light));
gl_FragColor = vec4(dprod, dprod, dprod, 1.0);
}
</script>
var shaderProperties = {
vertexShader: document.getElementById("vshader").textContent,
fragmentShader: document.getElementById("fshader").textContent
};
var shaderMaterial = new THREE.ShaderMaterial(shaderProperties);
var geometry = new THREE.SphereGeometry(3, 12, 12);
var bufgeometry = new THREE.BufferGeometry().fromGeometry(geometry);
var verts = geometry.vertices;
var displacement = new Float32Array(verts);
for (var v = 0; v < verts.length; v++) {
displacement[v] = Math.random() * 3;
}
bufgeometry.addAttribute("displacement", new THREE.BufferAttribute(displacement, 1));
var sphere = new THREE.Mesh(bufgeometry, shaderMaterial);
scene.add(sphere);
但这会产生以下错误:
GL错误:GL_INVALID_OPERATION:glDrawArrays:尝试访问属性2中超出范围的顶点
我在这里做错了什么?
最佳答案
似乎问题出在最新版本的three.js中,该版本要求使用BufferGeometry.addAttribute()将属性附加到缓冲区几何体。我试图做类似的事情,但是不正确。
This example很有帮助,我所做的更改如下所示:
var shaderMaterial = new THREE.ShaderMaterial(shaderProperties);
var geometry = new THREE.SphereBufferGeometry(3, 90, 90);
var displacement = new Float32Array(geometry.attributes.position.count);
for (var v = 0; v < displacement.length; v++) {
displacement[v] = Math.random() * 2;
}
geometry.addAttribute("displacement", new THREE.BufferAttribute(displacement, 1));
使用SphereBufferGeometry跳过创建SphereGeometry然后从中创建BufferGeometry的步骤。并使用缓冲区几何图形上的位置属性计数,而不是球体几何图形上的顶点数组长度。
Here it is在行动。