I've searched through simple to complex shader examples in three.js but can't seem to find a trivial example of passing a color that vertex holds to the fragment shader. I've made a simple example where the vertex shader that just leaves vertices where they are, but also passes "color" uniform (i think i saw that somewhere but havent been used) to the fragment shader via "vColor" varying, and then in fragment shader i'm trying just to return that same color. The browser renders the triangle black, and i'm guessing the color is empty. I know that it's simple but I can't figure it out myself, and I can't figure out what does ShaderMaterial pass to the shaders that I can play with there. Can someone please explain how?
Here's the code:
<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, 0),
new THREE.Vector3(-120, -200, 0),
new THREE.Vector3(120, -200, 0));
geometry.faces.push(new THREE.Face3(0, 1, 2));
geometry.faces[0].vertexColors[0] = new THREE.Color("rgb(255,0,0)");
geometry.faces[0].vertexColors[1] = new THREE.Color("rgb(0,255,0)");
geometry.faces[0].vertexColors[2] = new THREE.Color("rgb(0,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>
Notice that i have two types of materials for testing - materialShader for shaders and materialBasic as a control material that works fine. I don't have enough reputation to post images, but if stack overflow keeps uploaded images, you should see the rendered examples here: http://i.stack.imgur.com/tjdSt.png