Adding an image to atlas that used in shaders brake shaders (SOLVED)


#1

i have a test project that i worked with shaders and physic at the same time. you can see from bellow images i have two atlases named “shader.atlas” and “plank.atlas” that each have just one image in it, in shader.atlas there is a white square image for shader placeholder and in plank.atlas there is one rectangle image just for something that shaders hit them.


(physic debug is On)
and all things works well but if i added my simple plank image to shader.atlas my shader stop working and you can not see any shader, just collision circles from physics debug

is there a general rule about this? am i supposed to separate images in different atlases for each subject?


#2

I can’t see a reason why this would not work, at least from the engine side. Could you share the shader?


#3

of course i uploaded entire project
ShaderTest.zip (6.5 KB)

to repro the bug just add plank.png into shader.atlas


#4

It seems to be an issue with how the texture coordinates are used in the fragment shader. The original atlas with just the placeholder is 16x6, adding plank.png makes it 256x64.

Adjusting for this in the tex coords the fragment shader uses results in the circles being rendered again. At a glance I don’t really understand what the fragment shader does exactly, but remember that the entire atlas gets uploaded to the GPU and not the separate images within an atlas.


#5

OK, i never thought that when i choose a single image from an atlas entire atlas is going to pass to shader fragment.
so is there a way to determine position of just selected image in shader from combined atlas so everytime atlas going to change it selects the right position?


#6

Not currently no. Best bet is if you want to do specific calculations dependent on the atlas don’t modify the atlas once you’ve written your shader and place any additional images in a separate atlas.


#7

Hi! I was writing up a reply, but saw that you already got some good replies! :smiley:

Anyway, here is my initial reply unedited:


Alright, so the issue is that your shader has some expectations on the texture/atlas size. :slight_smile:

To help visualise the error, I changed shaderFP.fp to output the texture coordinates directly, like this;

gl_FragColor = vec4(var_texcoord0, 0.0, 0.0);

Running the game without plank added:

And when adding the plank image to the shader atlas:

As you can see, the sprites are actually drawn in both cases, but due to the shader making some assumptions the output are transparent pixels.


Since atlases will resize and pack differently depending on what images are included, it is not recommended to assume certain texture coordinates in shaders. But, we should be able to work around this by encoding our “own coordinates” inside the shaderPlaceholder image, like this:
shaderPlaceholder

And the result would be like this (with some slight modifications to the shader), with the plank added to the atlas:

I’ll attach the modified project here below. Remember that this solution might not fit your project 100%, but it might give you some ideas how to move forward if you still want to include both images inside the same atlas. :slight_smile:

ShaderTest_modified.zip (34.5 KB)


#8

Wow thats some good work there, thanks @sven, i’m sort of new to defold and shaders and this combined sample project learned a lot to me.
Thanks to you and entire defold team :+1: