Unexpected stretched texture

I have the following code snippets:


    	ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR);	    
	    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR);
	    
	    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.REPEAT);
	    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.REPEAT);

My texture dimension is 256x256.

Option 1 – big polygon


    	const x0 = 100;
	const x1 = -x0;
	const z0 = x0;
	const z1 = -z0;
    var vertices = new Float32Array(
        [  x0, 0, z1,    x1, 0, z1,    x1, 0, z0,   x0, 0, z0]);

The result: The texture is stretched so I lose the detail.

Option 2 – small polygon (notice that this is a much smaller polygon than option 1)


    const x0 = 5;
	const x1 = -x0;
	const z0 = x0;
	const z1 = -z0;
    var vertices = new Float32Array(
        [  x0, 0, z1,    x1, 0, z1,    x1, 0, z0,   x0, 0, z0]);

The result: I can see the details of my texture.

My understanding is that the REPEAT (TEXTURE_WRAP_S and TEXTURE_WRAP_T) option will give me the details even in Option 1. Why is the texture stretched in option 1? Did I misunderstand it?

This is running WebGL on Chrome Canary build.

What did I do wrong?

Thanks in advance for your help.

Note: Cross post it from opengl es - Unexpected stretched texture - Stack Overflow due to lack of answer

It is all down to what texture coordinates you use. You didn’t show us what coordinates you sent.

At any rate, by setting the texture coordinates at each vertex to be bigger on the bigger polygon, the texture will be smaller (“more detailed”) - but you risk it becoming repetitive and boring. For some textures (a brick pattern, perhaps) - this doesn’t matter because bricks are pretty repetitive and boring. But if you do that with (for example) the cloud texture you apply to your sky - then the fact that you’d be able to see the same cloud repeated a dozen times across your screen would look really terrible!

There are many techniques to avoid that - the simplest being to simply use a higher resolution texture with more interesting variety in it - more complicated techniques entail layering multiple textures at differing scales to get a more complex ‘look’ without using too much texture memory.

Sadly, a full discussion of this topic would be a complete book - not just a forum post!

– Steve

Thanks for your reply Steve.

Yes, it is a actually supposed to be a brick which should be applied repeatedly.

My texture coordinate:

    // texCoord array
    var texCoords = new Float32Array(
        [  1, 1,   0, 1,   0, 0,   1, 0]   );

Thanks again for looking into this.

I changed my texture coordinate to the following:

   var texCoords = new Float32Array(
//            [  1, 1,   0, 1,   0, 0,   1, 0]   
            [  100, 100,   -100, 100,   -100, -100,   100, -100]   
       );


It matches the big polygon coordinate. It shows the details of the original small texture on the big polygon. I am not sure if this is the right way technically. But this is the result that I am looking for.

Yeah - that’s exactly the right thing. If you imagine the texture you painted as a little square laid out on a sheet of graph paper - the extent of the map you painted goes from (0,0) to (1,1) - but if you set the wrap modes to REPEAT - then that square of image repeats over and over off to infinity in every direction. Now imagine your polygon laid out on the graph paper - and just like you provide an (x,y,z) for the position of each vertex in 3D space - you have to provide a (u,v) coordinate for each vertex in texture space. If you make your polygon 100 meters across in (x,y,z) space - then if your texture represents (let’s say) a 1 meter x 1 meter section of brickwork - then your polygon needs to cover 100 x 100 units of texture space. But if the texture represents, let’s say 20 meters x 20 meters of brickwork - then you’d only need your 100 meter polygon to cover 5x5 units of texture space.

So you need to think about how big your texture is in real world units - and how big your polygon is in real world units - then divide the size of the polygon by the size of the texture to figure out how big the numbers should be in (u,v) space…your “texture coordinates”.

Thanks Steve!