playing around with ThreeJS, i encoutered a classic problem of non square quad texturing : http://www.xyzw.us/~cass/qcoord/
Problem is ThreeJS only let you set texture coordinates with a vec2 (for what i know ..) And after spending hours on this, and finally found a working solution, i wanted to share it with the community, and maybe get some better ideas ? So here is the code:
First, the javascript to make my Quad using three JS:
var planeGeom = new THREE.Geometry();
planeGeom.vertices.push(new THREE.Vector3(0, 0, 10));
planeGeom.vertices.push(new THREE.Vector3(10, 0, 10));
planeGeom.vertices.push(new THREE.Vector3(20, 0,0));
planeGeom.vertices.push(new THREE.Vector3(-10, 0, 0));
//create the 2 faces , maybe i should play with CW or CCW order... ;)
planeGeom.faces.push(new THREE.Face3(0,1,3));
planeGeom.faces.push(new THREE.Face3(1,2,3));
//Compute widths ratio
var topWidth = Math.abs(Plane.TR.x - Plane.TL.x);
var bottomWidth = Math.abs(Plane.BR.x - Plane.BL.x);
var ratio = topWidth / bottomWidth;
//create UV's as barely explained in the link above (www.xyzw.us)
var UVS = [
new THREE.Vector2(0, ratio),
new THREE.Vector2(0, 0),
new THREE.Vector2(1.0, 0),
new THREE.Vector2(ratio, ratio)
];
//faceVertexUvs[materialID] [face index] [vertex index among face]
planeGeom.faceVertexUvs[0][0] = [UVS[0],UVS[1],UVS[3]];
planeGeom.faceVertexUvs[0][1] = [UVS[1],UVS[2],UVS[3]];
//load the image
var checkerTexture = THREE.ImageUtils.loadTexture('./resources/images/checker_largeColor.gif');
//Now create custom shader parts
customUniforms =
{
uSampler: { type: "t", value: checkerTexture },
};
var customMaterial = new THREE.ShaderMaterial(
{
uniforms: customUniforms,
vertexShader: document.getElementById( 'vertexShader').textContent,
fragmentShader: document.getElementById( 'fragmentShader').textContent,
side: THREE.DoubleSide
} );
//create the mesh with the custom geometry and material
var planeMesh = new THREE.Mesh(planeGeom, customMaterial);
//add the object to the threeJS scene
this.m_Scene.add(planeMesh);
and now the custom shader code:
Vertex shader:
varying vec4 textureCoord;
void main()
{
//here i reCreate the Vec4 i would have liked to have in threeJS
textureCoord = vec4(uv,0.0, 1.0);
if(uv.y != 0.0)
{
textureCoord.w *= (uv.y);
}
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
and the fragment shader:
uniform sampler2D uSampler;
varying vec4 textureCoord;
void main()
{
gl_FragColor = texture2D(uSampler, vec2(textureCoord.x/textureCoord.w, textureCoord.y/textureCoord.w));
}
voilaaa. I hope it could help some, or maybe myself in a few years... ;)