如何在THREE JS中的自定义非方形四边形上映射纹理

时间:2013-12-18 15:22:08

标签: three.js webgl shader texture-mapping uv-mapping

玩ThreeJS,我遇到了非方形四边形纹理的经典问题: http://www.xyzw.us/~cass/qcoord/

问题是ThreeJS只允许你用vec2设置纹理坐标(我所知道的......) 花了好几个小时,最后找到了一个有效的解决方案,我想与社区分享,,也许会有更好的想法? 所以这是代码:

首先,用三个JS制作我的Quad的javascript:

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);

现在是自定义着色器代码:

顶点着色器:

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 );
        }

和片段着色器:

uniform sampler2D uSampler;
        varying vec4 textureCoord;

        void main()
        {
            gl_FragColor  = texture2D(uSampler, vec2(textureCoord.x/textureCoord.w, textureCoord.y/textureCoord.w));
        }

voilaaa。我希望它可以帮助一些人,或者也许是我自己几年......;)

0 个答案:

没有答案