Sign in to follow this  
Infernal

Trim and Crop in WebGL and Compressed Textures

Recommended Posts

Hey guys and girls,

we are trying to get WebGL Compressed Textures to work with the texture trim/crop, but get strange effects:

Problems in WebGL:

  1. DDS form a horizontally and vertically repeating pattern
  2. PVR form a horizontally repeating pattern
  3. Not compressed PNGs have the pixels touching the right and bottom border drag on

With CanvasRenderer the PNG gets displayed exactly the way we expected it

 

For our compressed texture conversion we:

  1. Take our base image, usually PNG with lots of empty transparent space, and trim off the empty parts to each side
  2. Save the trim x, y start position and the original width and height of the full texture
  3. Save the width and height of the trimmed image as crop
  4. Add a padding to make our texture a Power of Two size (or square for PVR)

 

Any idea what we could try to fight those problems?

See the attached example replicating the errors:

compressed_texture_padding.7z

Share this post


Link to post
Share on other sites
var croppedOptions = {
            metadata:{
                textureOptions:{
                    crop:{
                        height: 429,
                        width: 1024,
                        x: 0,
                        y: 0
                    },
                    trim:{
                        height: 1000,
                        width: 1600,
                        x: 308,
                        y: 269
                    }
                }
            }
        };

What is that stuff? Can you please tell me which module in pixi parses this metadata? Can you please use separate JSON file for spritesheet, and load it as a spritesheet? You can try to trim/crop it with texturePacker first and then follow the same format.

Share this post


Link to post
Share on other sites

For now it doesnt load for me at all, Im looking at the issue. Yeah, frame/crop/trim thing is kinda wrong in pixi, and I changed wayt how it works in v4. I believe that in your case the only thing you need is to make "frame" and "crop" x:308 y:269 width:1024 height: 429 , and completely ignore "trim" property.

UPD. Im wrong, i didnt understand how you form it :)

Share this post


Link to post
Share on other sites

SOLUTION: assign "trim" AFTER frame. Texture.frame has some strange effect: https://github.com/pixijs/pixi.js/blob/master/src/core/textures/Texture.js#L185 , and I dont know why is that thing there. I removed it in v4.

Its so good tha someone is using that crop/trim stuff and my pixi-compressed-textures lib :)

BTW, to use latest version you have to add this line:

loader.before(PIXI.compressedTextures.extensionChooser(PIXI.compressedTextures.detectExtensions(renderer)));

And you can also make different options for compressed and png, and detect which to use by "resource.isCompressedImage"

Share this post


Link to post
Share on other sites

Thank you SO much, it seems to work, just by setting trim after frame

we patched the resolution out of the Compressed Textures, since we did not need to use it for quite a while

in our software file names are hashes, so the normal resource.baseUrl + ext wouldnt work, since we don't have a baseUrl like that, we basically made our own extension chooser which builds our manifest beforehand

most of our textures tend to be really big, like 2048x2048, but we are looking into spritesheets for the smaller ones, thanks for your time

Share this post


Link to post
Share on other sites

Setting Trim after Frame means that the bounds calculated for things using the texture will be wrong though, since the frame sizes determines the bounds, I got around that problem with monkeypatching, it would be better to find the actual source of the problem, sadly we are not very literate when it comes to WebGL, but since even normal trimmed PNGs are buggy in PIXI WebGL, maybe it is all just a PIXI WebGL Bug?

Share this post


Link to post
Share on other sites
1 hour ago, Infernal said:

Setting Trim after Frame means that the bounds calculated for things using the texture will be wrong though, since the frame sizes determines the bounds, I got around that problem with monkeypatching, it would be better to find the actual source of the problem, sadly we are not very literate when it comes to WebGL, but since even normal trimmed PNGs are buggy in PIXI WebGL, maybe it is all just a PIXI WebGL Bug?

"bounds calculated for things using the texture wlil be wrong" - you can set width and height of texture by hands, I already fixed that in v4. You see that current code in v3 is buggy :) I dont know why it was coded that way.

Its not a webgl bug, source rectangle will be out of bounds. In webGL you will either see CLAMP_TO_EDGE either REPEAT, and that's what you talked about in first post. Canvas mode will crash in firefox, but Chrome will work.

Fix for v4 follows: texture.width is actually the same as texture.crop.width, texture.height is the same as texture.crop.height.

Object.defineProperties(Texture.prototype, {
    width: {
        get: function() {
            return this.crop ? this.crop.width : 0;
        }
    },

    /**
     * The height of the Texture in pixels.
     *
     * @member {number}
     */
    height: {
        get: function() {
            return this.crop ? this.crop.height : 0;
        }
    }
}

 

Share this post


Link to post
Share on other sites

Yes I also looked through the WebGL code of PIXI a bit and found the CLAMP_TO_EDGE, which I now set in the generateWebGLTexture function, it works normally now, even without having to set Frame before Trim.

I did make a ticket for the other, possibly real bug (Uncompressed PNGs with trim in WebGL):

https://github.com/pixijs/pixi.js/issues/2384

 

This fix you posted just makes me understand the usage of trim and crop even less, if we use texture.trim to give the pixels of the texture a padding, then why wouldn't we want this padding to be considered in our texture.width / texture.height, and therefore our sprite bounds? I thought that was the sole purpose of trim?

Share this post


Link to post
Share on other sites

You are discussing problem that I encountered a month ago. I will be happy if you give me new ideas about it.

For now, we have to separate them to trimmed bounds and not-trimmed :) May be we need special object Bounds which will have two rectangles inside? That way texture will have three objects:

1) _frame, which is actual frame in the texture that will be drawn

2) _bounds, which will contain "crop" and "trim", crop will be bigger rectangle and trim smaller. They will use coordinates of original png file, so crop.xy==0.

3) rotation. Yes, frame can be rotated so it will fit "trim".

Share this post


Link to post
Share on other sites

@ivan.popelyshev ivan hi..
 

i test comressed texture with upper example by @Infernal(thx infernal)

using compressed texture is more fast than using png on pc 

and pkm can't load by that example on android

i don't know reason. i was checked by chrome's inspect.  

but there was no error. and pixi.compressed gave me testing machine was compatible .

and loaded and updateTexture. but there was notthing on screen..

only pkm couldn't draw.. T-T...

what can i do for this?


 

texture.pkm

Share this post


Link to post
Share on other sites

@ivan.popelyshev

v4 is coming soon? 
and v4 will have more optimized and have more performance than v3?

if not. i will make new code of etc1  for v3..  

 

 

becuase dds(dxt1 dxt3 dxt5...) can't use on android.. ...

new mobile machine use dxt1.. bu normally it can't...

 

or   how about   RGBA16 ?

..

 

Share this post


Link to post
Share on other sites

@ivan.popelyshev Did the values you have to pass to trim or its usage change in Pixi v4?
Is it not the following anymore? The docs are not really helpful on this

{
    'x': padding_left,
    'y': padding_top,
    'width': original_untrimmed_width,
    'height': original_untrimmed_height
}

 

Im getting strange results using trim in v4

Share this post


Link to post
Share on other sites

Yep, we changed them. I also changed the docs but its very difficult to describe it without examples. I'm sorry i didnt draw examples :) 

You have to look at https://github.com/pixijs/pixi.js/blob/dev/src/core/textures/Spritesheet.js#L150

something like frame=(100,100,20,20), orig = (0,0,40,40)  , trim = (10,10,20,20) means that TRIMMED width height is 20, trimx and trimy are 10, and position in spritesheet is 100.

Btw, latest DEV version of pixi cares about non-premultiplied alpha, so you have to use it with compressed stuff: https://pixijs.github.io/examples/?v=dev#/textures/not-premultiplied-alpha.js . Unfortunately. you still have to specify "premultipliedAlpha=false" in basetexture by yourself, plugin cant do it.

Share this post


Link to post
Share on other sites

Sorry, still not getting it to work right, here an example:

 

I have a 1000x1000 image file with a 100x100 black rectangle centered, surrounded by trimmable space

I trim that image to get a 100x100 black rectangle image

 

My texture.trim should then be set to (450, 450, 900, 900) or (450, 450, 550, 550) or (450, 450, 450, 450)?

My texture.orig should be set to (0, 0, 1000, 1000) ?

 

 

 

trim_example.png

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.