Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sprites are positioned upside down or sometimes are streched #277

Closed
72lions opened this issue Jun 18, 2011 · 34 comments
Closed

Sprites are positioned upside down or sometimes are streched #277

72lions opened this issue Jun 18, 2011 · 34 comments
Labels

Comments

@72lions
Copy link

72lions commented Jun 18, 2011

Hey guys, most of the times that I am adding a sprite on a webg scene, the texture is upside down, or stretched. Why is this happening. Is there a way so that I won't have to rotate it and change the scale of the object so that it matches the with, height and rotation of the texture image?

@anilshanbhag
Copy link

It is difference in coordinate system that leads to texture loading upside down . Images treat topleft as origin whereas scene is cartesian co-od system . You can rotate,scale the object on which texture loaded .

@mrdoob
Copy link
Owner

mrdoob commented Jun 18, 2011

We should be handling the vertical flipping. Not sure what you mean with stretched. Screenshot?

@jsermeno
Copy link
Contributor

Textures are pretty much always upside down for me as well, unless I'm using an orthographic camera.

@jsermeno
Copy link
Contributor

It fixes it for me, if I add this line

_gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, true);

into the setTexture() function in WebGLRenderer.js

@mrdoob
Copy link
Owner

mrdoob commented Jun 18, 2011

Interesting. Do you mind pasting the whole setTexture method? (Just to know where exactly you added it...)

@jsermeno
Copy link
Contributor

sure

function setTexture( texture, slot ) {

    /*
    if ( texture.needsUpdate ) {

        if ( !texture.__webglInit ) {

            texture.__webglTexture = _gl.createTexture();

            _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
            _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );

            texture.__webglInit = true;

        } else {

            _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
            // _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
            _gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );

        }

        setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
        _gl.bindTexture( _gl.TEXTURE_2D, null );

        texture.needsUpdate = false;

    }

    _gl.activeTexture( _gl.TEXTURE0 + slot );
    _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
    */

    if ( texture.needsUpdate ) {

        if ( texture.__webglTexture ) {

            texture.__webglTexture = _gl.deleteTexture( texture.__webglTexture );

        }

        texture.__webglTexture = _gl.createTexture();

        _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
        _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, true);
        _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );

        setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );

        _gl.bindTexture( _gl.TEXTURE_2D, null );

        texture.needsUpdate = false;

    }

    _gl.activeTexture( _gl.TEXTURE0 + slot );
    _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

};

@alteredq
Copy link
Contributor

_gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, true);

If you do this than all other non-sprite textures will be flipped.

Seems like sprites do not do any flipping by themselves - other things do flippings in UVs or in shaders. The simplest fix would be to flip UVs in sprites vertex shader, a bit faster would be to flip sprite geometry UVs.

@mrdoob
Copy link
Owner

mrdoob commented Jun 18, 2011

Hmmm.... Wouldn't it be better to remove those UV flippings in shaders instead?

@alteredq
Copy link
Contributor

If you mean to do everything properly then not - we have been at this point multiple times.

I myself tried at least twice to clean up this damn texture flipping business, plus somebody else also tried. After big efforts always there was something left that was messed up so overall effect was always worse than before cleaning.

But feel free to try ;) Hard parts are - minecraft AO example and stuff that does multipass rendering (there may be more, don't remember, for example tangents / normal mapping use UVs).

Meanwhile I committed fix for Sprite that is flipping geometry UVs - advantage compared to flipping in shader is that this is done only once, as opposed to in every frame for every vertex.

@rdad
Copy link

rdad commented Jun 21, 2011

I have the same problem with a plane post processed (with a ortho camera).
a idea to fixe it ?

@jsermeno
Copy link
Contributor

Not using sprites right? The texture on the plane is stretched you mean?

@rdad
Copy link

rdad commented Jun 21, 2011

No sprites, only Plane Onject3D.
The texture is displayed upside down.
It append only on ONE plane, the other planes display their texture right.

@jsermeno
Copy link
Contributor

Well I think there are probably different ways, but the first way I can think of is to flip the face uv coordinates by multiplying by -1.

    // Create plane texture mapping
    for ( i = 0; i < plane.faceVertexUvs[ 0 ].length; i ++ ) {

        uvs = plane.faceVertexUvs[ 0 ][ i ];

        for ( j = 0; j < uvs.length; j ++ ) {

            uvs[ j ].u *= -1;
            uvs[ j ].v *= -1;

        }
    }

https://gist.github.com/985901

@rdad
Copy link

rdad commented Jun 21, 2011

ok, thanks for your quick answer.
I'll try this night and come back later to you.

@rdad
Copy link

rdad commented Jun 22, 2011

unfortunally, it doesn't work for me :(

Info:I apply a WebGlRenderTarget to the plane.

@mrdoob
Copy link
Owner

mrdoob commented Jun 22, 2011

This hack should work:

plane.doubleSided = true;
plane.scale.y = - 1;

But I'll definitely take a look at all this.

@rdad
Copy link

rdad commented Jun 22, 2011

this hack work great ;)

@danbri
Copy link

danbri commented Dec 4, 2011

I hit this too. Rotating the images proved easier than figuring out a fix. But could someone explain how the hack/fix shown here would work in terms of http://alteredqualia.com/three/examples/particles_sprites_gl.html i.e. with a ParticleSystem? I couldn't find the equivalent of the plane object...

@alteredq
Copy link
Contributor

alteredq commented Dec 4, 2011

Do you mean you have ParticleSystem with just normally loaded texture that you see upside down?

Or do you have correctly displayed texture that you want to flip to be upside down?

If for some reason you want to have flipped texture on point sprites, you could either flip the image in 2d canvas before creating Texture or use custom shader for particles that would flip gl_PointCoord in the fragment shader.

@danbri
Copy link

danbri commented Dec 4, 2011

It was a very naive experiment: I took http://alteredqualia.com/three/examples/particles_sprites_gl.html and replaced the snowflake image URLs with other images; at which point it became clear the textures were upside down.

@alteredq
Copy link
Contributor

alteredq commented Dec 4, 2011

Could you try that with more recent version of that example (version on my site is very ancient)?

Just clone dev branch, it's now named webgl_particles_sprites.html.

I tried and it works ok for me, no upside down turning.

@danbri
Copy link

danbri commented Dec 4, 2011

Not sure if 'git clone https://github.com/mrdoob/three.js.git -b dev' is the right voodoo to get dev branch, but I was working from a v recent stand git clone; the link to your site was lazyness, I just googled a working copy to illustrate the remark.

Trying afresh, I still get the flipping. An image of some text now seems to be showing me its backside and upside down. This is in Firefox on OSX, I guess the graphics card is the only thing that might even matter? Chipset Model: AMD Radeon HD 6750M

@alteredq
Copy link
Contributor

alteredq commented Dec 4, 2011

Where do you see white dots here, up or down?

http://alteredqualia.com/three/examples/webgl_particles_sprites2.html

Edit: I tried on my other notebook with ATI card and I think it's a bug in ATI OpenGL driver (probably in handling of gl_PointCoord).

I get different orientations on ATI when using ANGLE (dot is up) vs OpenGL (dot is down), while on notebook with Nvidia I get the same orientation for both ANGLE and OpenGL (dot is up, which I believe is correct one).

I'm afraid there is not much that could be done about this. No matter how you flip the texture, it'll be wrongly oriented for somebody :S

In theory you could try to serve different versions to different GPUs (that's how games deals with these issues) though in practice you can't due to browsers hiding GPU information.

@danbri
Copy link

danbri commented Dec 4, 2011

Down! Is that good? :)

@alteredq
Copy link
Contributor

alteredq commented Dec 5, 2011

Bad, see my edit in the comment above.

I googled about this and it seems point sprites are notorious problems with ATIs, people have issues with them for years :/.

Seems like "modern" solution to this is just to forget about point sprites and use geometry shaders to create quads from points on GPU, but also this is not possible with WebGL.

If you don't need many "particles", you could use just regular quads, that's what Sprite does, though quads are much more expensive than point sprites (4x as many vertices).

@danbri
Copy link

danbri commented Dec 5, 2011

On 5 December 2011 01:21, AlteredQualia
reply@reply.github.com
wrote:

Bad, see my edit in the comment above.

I googled about this and it seems point sprites are notorious problems with ATIs, people have issues with them for years  :/.

ah, thanks for investigating

Seems like "modern" solution to this is just to forget about point sprites and use geometry shaders to create quads from points on GPU, but also this is not possible with WebGL.

If you don't need many "particles", you could use just regular quads, that's what Sprite does, though quads are much more expensive than point sprites (4x as many vertices).

Ah, thanks, that's all good to know. BTW I'm entirely new to all this
front-end stuff (I'm a data standards / backend guy generally). But
since seeing your example at
http://alteredqualia.com/three/examples/webgl_particles_dynamic.html
and a few other things, I decided it's time to learn since amazing
things are becoming possible in the browser. And then glsl.heroku.com
taught me about a new but familiar looking programming language. So
I'm slogging through the back-reading on GL and starting by messing
around with other people's examples. It's also forced me to go back
and learn a bit of linear algebra, which is useful for the machine
learning stuff too.

My immediate particles interest comes from some work with data mining
and recommender tools, eg. where we might have 100,000 book records
(or millions, ...) and similarity measures between those books
computed from library metadata. Previously I've worked in batch mode
with Gephi but taking screenshots is a crappy way of publishing-
http://danbri.org/words/2011/10/11/720 - and I've also done a bit of
work prototyping in Microsoft Silverlight's pivot viewer:
http://danbri.org/words/2011/02/01/658 where items are TV broadcasts
or films.

So all the time each 'item' is not illustrated with its own texture, I
think I'm OK. But of course textures are attractive if we have a
collection of items and a picture for each already....

The trickiest ambition is to do something with Pivot-viewer style
visuals, where each item has its own texture.

http://www.youtube.com/watch?v=DbN3kWenjJs ... Pivot-viewer (if you
didn't see it) is probably the most beautiful thing microsoft have
done inside a browser, http://www.youtube.com/watch?v=ed_2i5grQHk
http://www.youtube.com/watch?v=F2foa4aBn_w but it is heavy to run.

I'm not sure yet how much of that WebGL + Three.js makes easy. So I
thought I'd start towards making some tests...

If I had only 300 or so base textures eg. from BBC TV shows (my
current work) and then individualised them by writing on them via
Canvas, and if I used low-res imagery (maybe monochrome'd?), and made
sure resolution were powers of two, ...? What if we had 3000?
30,000...? I'm not really on top of the basics enough to do scientific
tests but starting seems a good way of learning.

Anyway thanks for the help on this issue. It's a good nudge to get
learning a bit more...

cheers

Dan

@alteredq
Copy link
Contributor

alteredq commented Dec 5, 2011

For applications like you linked to the best would be probably to use texture atlases - concatenate offline many smaller images into fewer bigger ones, keep somewhere metadata about offsets / sizes and then use this to pick out just the relevant subimage in the shader.

That's what I think Google Bookcase does:

http://www.chromeexperiments.com/detail/webgl-bookcase/

@danbri
Copy link

danbri commented Dec 5, 2011

On 5 December 2011 12:50, AlteredQualia
reply@reply.github.com
wrote:

For applications like you linked to the best would be probably to use texture atlases - concatenate offline many smaller images into fewer bigger ones, keep somewhere metadata about offsets / sizes and then use this to pick out just the relevant subimage in the shader.

Great, thanks. I'll try that direction. I also found some interesting
notes here to digest:
http://www.illyriad.co.uk/blog/index.php/2011/11/webgl-experiments-texture-compression/

Dan

@mrdoob mrdoob closed this as completed Dec 5, 2011
@oosmoxiecode
Copy link
Contributor

Sorry to bump this old issue..

But I ran into this problem with y-flipped textures, recently.
Seems to be an issue with Ati+OpenGL+Certain drivers as far as I can tell.
I can´t recreate on my ati-windows-machine using the opengl-switch for example, but people with osx and ati reported it frequently.

Trying to think of a way to detect and work around this. I was thinking, what if I create like a small canvas and render one sprite/particle that is red on the top half and green on the bottom half. And then I guess draw that to a 2dcanvas and pick the color at the top to see if it´s flipped or not. That way I would know if I should flip or not from there on.

Would something like that work? Seems like a kinda hacky way :) Anyone got a better idea?

@alteredq
Copy link
Contributor

I was also thinking about something like this. I don't see easier way how to find out if a system has this bug then to actually induce it.

@danbri
Copy link

danbri commented Feb 15, 2012

Maybe the test could be run on some popular demo page, for a week or so, then the results shared? Do the webgl apis share enough info to cleanly re-identify problem hardware setups?

Dan

@alteredq
Copy link
Contributor

Not directly, browsers intentionally hide GPU identification info (manufacturer, version, driver, even whether renderer is native OpenGL or ANGLE). You would need to do some datamining / machine learning on info that is available for other purposes (like max sizes of textures, available features, etc).

Having small targeted code probe seems better, you can detect the problem directly instead of trying to guess correlation from bunch of unrelated numbers. Also it would be "future proof" - if some new GPU / driver messes up, it would be covered.

@danbri
Copy link

danbri commented Feb 16, 2012

On Thursday, 16 February 2012, AlteredQualia <
reply@reply.github.com>
wrote:

Not directly, browsers intentionally hide GPU identification info
(manufacturer, version, driver, even whether renderer is native OpenGL or
ANGLE). You would need to do some datamining / machine learning on info
that is available for other purposes (like max sizes of textures, available
features, etc).

Having small targeted code probe seems better, you can detect the problem
directly instead of trying to guess correlation from bunch of unrelated
numbers. Also it would be "future proof" - if some new GPU / driver messes
up, it would be covered.

Makes sense. I have a friend at Apple who is happy to receive shader
snippets that are problematic. He would probably be grateful for such a
probe / test case, and perhaps in a position to help get it addressed (on
osx).

Dan


Reply to this email directly or view it on GitHub:
#277 (comment)

@gy134340
Copy link

gy134340 commented Jan 13, 2017

@mrdoob 太棒了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants