1
\$\begingroup\$

I'm trying to recreate the following shader from shadertoy using Phaser 3: https://www.shadertoy.com/view/wdG3Rz

I managed to fix the errors I was getting but it just loads an empty black square when trying to load it on my scene. Here's a sample code:

const fragmentShader = `
#ifdef GL_ES
precision mediump float;
#endif
uniform float time;
uniform vec2 resolution;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;
varying vec2 fragCoord;
float avg(vec4 color) {
 return (color.r + color.g + color.b)/3.0;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
 // Flow Speed, increase to make the water flow faster.
 float speed = 1.0;
 
 // Water Scale, scales the water, not the background.
 float scale = 0.8;
 
 // Water opacity, higher opacity means the water reflects more light.
 float opacity = 0.5;
 
 // Normalized pixel coordinates (from 0 to 1)
 vec2 uv = (fragCoord/resolution.xy);
 vec2 scaledUv = uv*scale;
 // Water layers, layered on top of eachother to produce the reflective effect
 // Add 0.1 to both uv vectors to avoid the layers stacking perfectly and creating a huge unnatural highlight
 vec4 water1 = texture2D(iChannel0, scaledUv + time*0.02*speed - 0.1);
 vec4 water2 = texture2D(iChannel0, scaledUv.xy + time*speed*vec2(-0.02, -0.02) + 0.1);
 
 // Water highlights
 vec4 highlights1 = texture2D(iChannel2, scaledUv.xy + time*speed / vec2(-10, 100));
 vec4 highlights2 = texture2D(iChannel2, scaledUv.xy + time*speed / vec2(10, 100));
 
 // Background image
 vec4 background = texture2D(iChannel1, vec2(uv) + avg(water1) * 0.05);
 
 // Average the colors of the water layers (convert from 1 channel to 4 channel
 water1.rgb = vec3(avg(water1));
 water2.rgb = vec3(avg(water2));
 
 // Average and smooth the colors of the highlight layers
 highlights1.rgb = vec3(avg(highlights1)/1.5);
 highlights2.rgb = vec3(avg(highlights2)/1.5);
 
 float alpha = opacity;
 
 if(avg(water1 + water2) > 0.3) {
 alpha = 0.0;
 }
 
 if(avg(water1 + water2 + highlights1 + highlights2) > 0.75) {
 alpha = 5.0 * opacity;
 }
 // Output to screen
 fragColor = (water1 + water2) * alpha + background;
}
void main(void)
{
 mainImage(gl_FragColor, fragCoord.xy);
 gl_FragColor.a = 1.0;
}
`;
class Example extends Phaser.Scene {
 constructor() {
 super("Example");
 }
 preload() {
 this.load.image("noise", "https://i.imgur.com/pZfKeRP.png");
 this.load.image("pic", "https://i.imgur.com/NQFMq6r.jpg");
 this.load.image("rocks", "https://i.imgur.com/fvHGrrU.png");
 }
 create() {
 const baseShader = new Phaser.Display.BaseShader(
 "BufferShader",
 fragmentShader
 );
 this.add
 .shader(baseShader, 0, 0, 800, 600, ["noise", "pic", "rocks"])
 .setOrigin(0, 0);
 }
}
const config = {
 type: Phaser.WEBGL,
 parent: "phaser-example",
 width: 800,
 height: 600,
 scene: Example
};
const game = new Phaser.Game(config);

Is there anything I'm doing wrong? Here's the same sample codepen so you can see the problem. https://codepen.io/javiervd/pen/ExMmeYY?editors=1011

Thanks.

asked Jan 19, 2024 at 14:59
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Your code is correct, but the problem has to do with the size of your Images.
You should use images with the "power-of-two" (as stated in the documentation). With other words, if you change the dimensions of your images, to be (for example) 64x64 pixel. The shader should be visible/displayed.

But I think your shader (or the phaser config) would need a bit more tweaking, to match the demo you mentioned.

This is a screenshot of the working shader (in phaser) screenshot of the running shader]

answered Jan 19, 2024 at 18:11
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Thanks, I had to tweak some of the shader values like you mentioned but I managed to get it close to the original: codepen.io/javiervd/pen/ExMmeYY?editors=1010 \$\endgroup\$ Commented Jan 20, 2024 at 16:13
  • \$\begingroup\$ now ot looks really, good. good hob. πŸ‘ \$\endgroup\$ Commented Jan 20, 2024 at 16:23

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.