Jump to content

shader toy shader to pixi filter


ourvice
 Share

Recommended Posts

Hiya!

I was wondering f there are any tricks to modifying this shader toy snippet to work in pixie filter...

 

https://www.shadertoy.com/view/4s2GRR

 

 

//Inspired by http://stackoverflow.com/questions/6030814/add-fisheye-effect-to-images-at-runtime-using-opengl-es
void mainImage( out vec4 fragColor, in vec2 fragCoord )//Drag mouse over rendering area
{
	vec2 p = fragCoord.xy / iResolution.x;//normalized coords with some cheat
	                                                         //(assume 1:1 prop)
	float prop = iResolution.x / iResolution.y;//screen proroption
	vec2 m = vec2(0.5, 0.5 / prop);//center coords
	vec2 d = p - m;//vector from center to current fragment
	float r = sqrt(dot(d, d)); // distance of pixel from center

	float power = ( 2.0 * 3.141592 / (2.0 * sqrt(dot(m, m))) ) *
				(iMouse.x / iResolution.x - 0.5);//amount of effect

	float bind;//radius of 1:1 effect
	if (power > 0.0) bind = sqrt(dot(m, m));//stick to corners
	else {if (prop < 1.0) bind = m.x; else bind = m.y;}//stick to borders

	//Weird formulas
	vec2 uv;
	if (power > 0.0)//fisheye
		uv = m + normalize(d) * tan(r * power) * bind / tan( bind * power);
	else if (power < 0.0)//antifisheye
		uv = m + normalize(d) * atan(r * -power * 10.0) * bind / atan(-power * bind * 10.0);
	else uv = p;//no effect for power = 1.0

	vec3 col = texture(iChannel0, vec2(uv.x, -uv.y * prop)).xyz;//Second part of cheat
	                                                  //for round effect, not elliptical
	fragColor = vec4(col, 1.0);
}
Link to comment
Share on other sites

I have read through that article.

It seems that we might need a full implementation example , but I have been trying through trial and error.

 

1 hour ago, ivan.popelyshev said:

https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters

Also if you want fullscreen filter, it'll be easier. just specify "container.filterArea = renderer.screen" , nad you wont have to deal with "mapCoord" and clamping.

 

 

Yes using v4

Are there any other outstanding bits that might need to be converted to webgl1?

what does the iChannel0 in vec3 col = texture(iChannel0, vec2(uv.x, -uv.y * prop)).xyz;    come from?

Thanks again!

 

 

20 minutes ago, Exca said:

Also remember to change the code to webgl1 version if you're using v4. For example texture should be texture2D.

 

Link to comment
Share on other sites

Just now, ourvice said:

Are there any other outstanding bits that might need to be converted to webgl1?

what does the iChannel0 in vec3 col = texture(iChannel0, vec2(uv.x, -uv.y * prop)).xyz;    come from?

 

Most of the changes you can catch from shader compilation errors. Cant remember the changes other than texture vs texture2d.

The iChannel0 is a sampler2D from shadertoys first texture slot. It is given in shadertoy, if you are using filters then you should use uniform sampler2D uSampler; to get the texture to which you are applying the filter.

Link to comment
Share on other sites

3 minutes ago, Exca said:

Most of the changes you can catch from shader compilation errors. Cant remember the changes other than texture vs texture2d.

The iChannel0 is a sampler2D from shadertoys first texture slot. It is given in shadertoy, if you are using filters then you should use uniform sampler2D uSampler; to get the texture to which you are applying the filter.

 

Awesome

 

Yeah the major error is it did not recognize it as a webglshader.

Likely because of the non webgl1 bits...  I will keep at it :)

 

 

Link to comment
Share on other sites

Ah, that's because the shadertoy code is not complete webgl program. As in shadertoy the code you provide is injected into their main program that calls the mainImage function. You should pick up some of the existing filters and start from that point and apply the calculations to that.

Link to comment
Share on other sites

8 minutes ago, Exca said:

Ah, that's because the shadertoy code is not complete webgl program. As in shadertoy the code you provide is injected into their main program that calls the mainImage function. You should pick up some of the existing filters and start from that point and apply the calculations to that.

sounds good.

 

this is where I am at for the shader frag ( assuming this is correct )

 

precision mediump float;
uniform vec2 iResolution;
uniform vec4 iMouse;
uniform sampler2D uSampler


void main(void)
{
  vec2 p = fragCoord.xy / iResolution.x;//normalized coords with some cheat
                                                           //(assume 1:1 prop)
  float prop = iResolution.x / iResolution.y;//screen proroption
  vec2 m = vec2(0.5, 0.5 / prop);//center coords
  vec2 d = p - m;//vector from center to current fragment
  float r = sqrt(dot(d, d)); // distance of pixel from center

  float power = ( 2.0 * 3.141592 / (2.0 * sqrt(dot(m, m))) ) *
        (iMouse.x / iResolution.x - 0.5);//amount of effect

  float bind;//radius of 1:1 effect
  if (power > 0.0) bind = sqrt(dot(m, m));//stick to corners
  else {if (prop < 1.0) bind = m.x; else bind = m.y;}//stick to borders

  //Weird formulas
  vec2 uv;
  if (power > 0.0)//fisheye
    uv = m + normalize(d) * tan(r * power) * bind / tan( bind * power);
  else if (power < 0.0)//antifisheye
    uv = m + normalize(d) * atan(r * -power * 10.0) * bind / atan(-power * bind * 10.0);
  else uv = p;//no effect for power = 1.0

  vec3 col = texture2D(uSampler, vec2(uv.x, -uv.y * prop)).xyz;//Second part of cheat
                                                    //for round effect, not elliptical
  fragColor = vec4(col, 1.0);
}

 

Link to comment
Share on other sites

 

32 minutes ago, Exca said:

Ah, that's because the shadertoy code is not complete webgl program. As in shadertoy the code you provide is injected into their main program that calls the mainImage function. You should pick up some of the existing filters and start from that point and apply the calculations to that.

 

yeah it still does not recognize it as a WebGLShader...

https://jsfiddle.net/parsab1h/686/

 

Uncaught TypeError: Failed to execute 'attachShader' on 'WebGLRenderingContext': parameter 2 is not of type 'WebGLShader'.
    at compileProgram (pixi.js:2575)
    at Shader (pixi.js:1792)
    at new Shader (pixi.js:8057)
    at FilterManager.applyFilter (pixi.js:18335)
    at Filter.apply (pixi.js:17833)
    at FilterManager.popFilter (pixi.js:18278)
    at Sprite.renderAdvancedWebGL (pixi.js:9233)
    at Sprite.renderWebGL (pixi.js:9170)
    at Container.renderWebGL (pixi.js:9176)
    at WebGLRenderer.render (pixi.js:17052)

 

Link to comment
Share on other sites

> ERROR: 0:6: 'uniform' : syntax error
That's important. You forgot ";" after "uSampler"

> ERROR: 0:12: 'fragCoord' : undeclared identifier

fragColor and fragCoord are "gl_FragColor" and "gl_FragCoord" respectively.

> iResolution , dimensions

look up the article, you have to add applyFilter method to pass dimensions there. Are you sure that you need it? Why not use "varying vTextureCoord" that is passed from default vert shader? Also in case of part of screen (you didnt specify filterArea!!!), you have to normalize it differently, look in the article.

>   vec3 col = texture2D(uSampler, vec2(uv.x, -uv.y * prop)).xyz;//Second part of cheat
                                                    //for round effect, not elliptical

>  fragColor = vec4(col, 1.0);

Pixi works with premultiplied textures by default. That's not how you remove alpha channel there.

Link to comment
Share on other sites

8 hours ago, ivan.popelyshev said:

> ERROR: 0:6: 'uniform' : syntax error
That's important. You forgot ";" after "uSampler"

> ERROR: 0:12: 'fragCoord' : undeclared identifier

fragColor and fragCoord are "gl_FragColor" and "gl_FragCoord" respectively.

> iResolution , dimensions

look up the article, you have to add applyFilter method to pass dimensions there. Are you sure that you need it? Why not use "varying vTextureCoord" that is passed from default vert shader? Also in case of part of screen (you didnt specify filterArea!!!), you have to normalize it differently, look in the article.

>   vec3 col = texture2D(uSampler, vec2(uv.x, -uv.y * prop)).xyz;//Second part of cheat
                                                    //for round effect, not elliptical

>  fragColor = vec4(col, 1.0);

Pixi works with premultiplied textures by default. That's not how you remove alpha channel there.

right on man.

 

I am trying.

 

I will update the fiddle link as I try to rework it to get it to play well.

 

https://jsfiddle.net/parsab1h/698/

 

 

 

Link to comment
Share on other sites

9 hours ago, ivan.popelyshev said:

> ERROR: 0:6: 'uniform' : syntax error
That's important. You forgot ";" after "uSampler"

> ERROR: 0:12: 'fragCoord' : undeclared identifier

fragColor and fragCoord are "gl_FragColor" and "gl_FragCoord" respectively.

> iResolution , dimensions

look up the article, you have to add applyFilter method to pass dimensions there. Are you sure that you need it? Why not use "varying vTextureCoord" that is passed from default vert shader? Also in case of part of screen (you didnt specify filterArea!!!), you have to normalize it differently, look in the article.

>   vec3 col = texture2D(uSampler, vec2(uv.x, -uv.y * prop)).xyz;//Second part of cheat
                                                    //for round effect, not elliptical

>  fragColor = vec4(col, 1.0);

Pixi works with premultiplied textures by default. That's not how you remove alpha channel there.

 

 

getting there... obviously still not correct....

 

sigh lol

 

https://jsfiddle.net/parsab1h/709/

 

thanks for all your patience.  first foray into modifying shader toy stuff to pixi v4

 

Link to comment
Share on other sites

49 minutes ago, ivan.popelyshev said:

getting there... obviously still not correct....

Especially  vec2 p = "gl_FragCoord.xy , why is there a quote? 

You'll be an expert when you end this. I ported several shaders from shadertoy too, god bless Inigo Quilez :)

ahhhhhh

 

https://jsfiddle.net/parsab1h/716/

 

much closer!

 

all black but now loading the webgl program!

 

 

Link to comment
Share on other sites

58 minutes ago, ivan.popelyshev said:

getting there... obviously still not correct....

Especially  vec2 p = "gl_FragCoord.xy , why is there a quote? 

You'll be an expert when you end this. I ported several shaders from shadertoy too, god bless Inigo Quilez :)

alpha channel?

 

 

Link to comment
Share on other sites

20 hours ago, ivan.popelyshev said:

getting there... obviously still not correct....

Especially  vec2 p = "gl_FragCoord.xy , why is there a quote? 

You'll be an expert when you end this. I ported several shaders from shadertoy too, god bless Inigo Quilez :)

Hopefully an expert soon... trying to get it to display, then I can muss with the IMouse vectors and make it animate..

any insite into what i'm doing wrong here>?

 

https://jsfiddle.net/parsab1h/735/

 

 

Thanks brother!

 

 

 

 

 

Link to comment
Share on other sites

https://jsfiddle.net/parsab1h/764/

The fiddle is using too old version of pixi to have the app.renderer.screen value as defined. So that effect wont work with that if image resolution is not the exact resolution of the screen. Should work with newer pixi also. Might require a bit of adjustments.

I also refactored the iMouse & iResolutions off as they are shadertoy specific stuff and those dont really carry to pixi that well.

Link to comment
Share on other sites

1 hour ago, Exca said:

https://jsfiddle.net/parsab1h/764/

The fiddle is using too old version of pixi to have the app.renderer.screen value as defined. So that effect wont work with that if image resolution is not the exact resolution of the screen. Should work with newer pixi also. Might require a bit of adjustments.

I also refactored the iMouse & iResolutions off as they are shadertoy specific stuff and those dont really carry to pixi that well.

 

this is awesome.

 

I got it up and working fairly smoothly on the end product.

 

However is there a way to center the fisheye center?  It seems that if it is non square it does not really remain circular or the center point in the middle.

 

Im going to take another look.

 

Thank you so much for looking at this.

 

 

Link to comment
Share on other sites

56 minutes ago, Exca said:

You might need to divide or multiply something with the prop value. Not exactly sure what as the fiddle has no screen value so the values dont go exactly as they would with it.

right on will keep fiddling with it :)

 

if you constrain the filter area with the size of the sprite you can see what i mean :0

https://jsfiddle.net/parsab1h/795/

Link to comment
Share on other sites

Yeah, but that would be different when using the screen render as renderarea. Using app.renderer.screen is a special case with filters where the vTextureCoord maps directly from 0 to 1 for the visible area. When using filters with other filterareas, the rendering is done using a texture that is larger than the image (often to the closest power of two in widht & height), so the calculations wont match to 0.5 as the center. And as you want to have fullscreen effect you should use screen as filterarea.

The problem with that with jsfiddle is that they have too old pixi version, it doesn't have the app.renderer.screen available.

Link to comment
Share on other sites

right on :)

on my local build ( its inside a larger react app. ) it still is not centering with  PixiJS 4.8.1 - ✰ WebGL ✰

i am setting it to app.render.screen

 

this.p.containerouter.filterArea = this.app.renderer.screen

 

6 minutes ago, Exca said:

Yeah, but that would be different when using the screen render as renderarea. Using app.renderer.screen is a special case with filters where the vTextureCoord maps directly from 0 to 1 for the visible area. When using filters with other filterareas, the rendering is done using a texture that is larger than the image (often to the closest power of two in widht & height), so the calculations wont match to 0.5 as the center. And as you want to have fullscreen effect you should use screen as filterarea.

The problem with that with jsfiddle is that they have too old pixi version, it doesn't have the app.renderer.screen available.

 

Link to comment
Share on other sites

I updated the fiddle to use another method for calculation of the implosion/explosion https://jsfiddle.net/6f5Lydot/1/ to make it a bit clearer for me as the one in shadertoy does things a lot differently how I usually do.

That should produce uniform changes to center no matter what resolution the renderer is. Changing the formulas used in bulge & implosion can be used to change the look of the effect.

[Edit] Also updated the pixi to latest.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...