我在three.js中搜索了简单到复杂的着色器示例,但似乎无法找到一个将顶点保存到片段着色器的颜色传递的简单示例.我已经做了一个简单的例子,其中顶点着色器只是将顶点留在它们所在的位置,但也将“颜色”均匀(我认为我看到某处但未使用过)通过“vColor”改变为片段着色器,然后在片段着色器中我试图返回相同的颜色.浏览器呈现黑色三角形,我猜测颜色是空的.我知道这很简单,但我自己无法弄清楚,而且我无法弄清楚ShaderMaterial传递给我可以在那里玩的着色器.有人可以解释一下吗?
这是代码:
<script id="vertexShader" type="x-shader/x-vertex"> uniform vec3 color; varying vec3 vColor; void main(){ vColor = color; gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); } </script> <script id="fragmentShader" type="x-shader/x-fragment"> varying vec3 vColor; void main(){ gl_FragColor = vec4( vColor.rgb,1.0 ); } </script> <script> var container,camera,controls,scene,renderer,model; init(); animate(); function init() { camera = new THREE.PerspectiveCamera(70,window.innerWidth / window.innerHeight,1,10000); camera.position.y = 150; camera.position.z = 500; scene = new THREE.Scene(); var geometry = new THREE.Geometry(); geometry.vertices.push( new THREE.Vector3(0,0),new THREE.Vector3(-120,-200,new THREE.Vector3(120,0)); geometry.faces.push(new THREE.Face3(0,2)); geometry.faces[0].vertexColors[0] = new THREE.Color("rgb(255,0)"); geometry.faces[0].vertexColors[1] = new THREE.Color("rgb(0,255,0)"); geometry.faces[0].vertexColors[2] = new THREE.Color("rgb(0,255)"); var materialShader = new THREE.ShaderMaterial({ vertexShader: document.getElementById('vertexShader').textContent,fragmentShader: document.getElementById('fragmentShader').textContent }); var materialBasic = new THREE.LineBasicMaterial({ vertexColors: THREE.VertexColors,linewidth: 1 }); var model = new THREE.Mesh(geometry,materialShader); model.position.y = 150; scene.add(model); renderer = new THREE.WebGLRenderer(); renderer.setClearColor(0xf0f0f0); renderer.setSize(window.innerWidth,window.innerHeight); container = document.createElement('div'); document.body.appendChild(container); container.appendChild(renderer.domElement); window.addEventListener('resize',onWindowResize,false); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth,window.innerHeight); } function animate() { requestAnimationFrame(animate); render(); } function render() { renderer.render(scene,camera); } </script>
请注意,我有两种类型的材料用于测试 – materialShader用于着色器,而materialBasic用作控制材料,可以正常工作.我没有足够的声誉来发布图像,但如果堆栈溢出保持上传的图像,您应该在这里看到渲染的示例:http://i.stack.imgur.com/tjdSt.png
解决方法
我通过玩变量来解决这个问题.我犯的第一个错误是认为顶点着色器代码中的颜色(均匀的vec3颜色;)是一致的,但它实际上是一个属性.其次,我没有定义它,它已经定义了,我发现在接收顶点着色器的堆栈跟踪时,我发现了最终着色器GLSL代码是如何构建的:
1: precision highp float; 2: precision highp int; 3: 4: #define VERTEX_TEXTURES 5: 6: 7: #define MAX_DIR_LIGHTS 0 8: #define MAX_POINT_LIGHTS 0 9: #define MAX_SPOT_LIGHTS 0 10: #define MAX_HEMI_LIGHTS 0 11: #define MAX_SHADOWS 0 12: #define MAX_BONES 58 13: //a lot of blank space was printed in here,i skipped the lines 33: 34: uniform mat4 modelMatrix; 35: uniform mat4 modelViewMatrix; 36: uniform mat4 projectionMatrix; 37: uniform mat4 viewMatrix; 38: uniform mat3 normalMatrix; 39: uniform vec3 cameraPosition; 40: attribute vec3 position; 41: attribute vec3 normal; 42: attribute vec2 uv; 43: attribute vec2 uv2; 44: #ifdef USE_COLOR 45: attribute vec3 color; 46: #endif 47: #ifdef USE_MORPHTARGETS 48: attribute vec3 morphTarget0; 49: attribute vec3 morphTarget1; 50: attribute vec3 morphTarget2; 51: attribute vec3 morphTarget3; 52: #ifdef USE_MORPHNORMALS 53: attribute vec3 morphNormal0; 54: attribute vec3 morphNormal1; 55: attribute vec3 morphNormal2; 56: attribute vec3 morphNormal3; 57: #else 58: attribute vec3 morphTarget4; 59: attribute vec3 morphTarget5; 60: attribute vec3 morphTarget6; 61: attribute vec3 morphTarget7; 62: #endif 63: #endif 64: #ifdef USE_SKINNING 65: attribute vec4 skinIndex; 66: attribute vec4 skinWeight; 67: #endif 68: 69: 70: 71: varying vec3 vColor; 72: 73: void main(){ 74: vColor = color; 75: gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); 76: } 77:
这意味着我不必定义颜色属性.此外,这可以在Three.js文件中看到,但它是一个串联的字符串,因此很难通读.
我需要做的最后一件事是在ShaderMaterial中定义vertexColors:THREE.VertexColors,就像在LineBasicMaterial中那样,我发现这是偶然的(在“让我们看看会发生什么”的方式).
这是最终的代码:
<script id="vertexShader" type="x-shader/x-vertex"> varying vec3 vColor; void main(){ vColor = color; gl_Position = projectionMatrix * modelViewMatrix * vec4(position,10000); camera.position.y = 150; camera.position.z = 500; scene = new THREE.Scene(); var geometry = new THREE.Geometry(); geometry.vertices.push( new THREE.Vector3(0,vertexColors: THREE.VertexColors,camera); } </script>
我希望这可以帮助其他人理解着色器中的变量.干杯.