Plasma Shader is not rendering as expected

95 views Asked by At

I am trying to hack this Plasma shader from ShaderToy so it works with Spark AR ... I'm very close but there is a weird issue with the shader being compressed into the corner. Are there any shader guru's who can give me some pointers? Here's what it looks like now in Spark: enter image description here

The inputs are the screen size, a screen touch coordinate, the time, and a direction vec2 that could be the culprit. I'm not entirely sure what this input is doing.

Here's my converted shader code:

precision highp float;

vec4 main( in vec2 direction, in float time, in vec2 touch, in vec2 screen )
{
    vec2 uv = fragment(std::getVertexTexCoord());
    float t = time/.1 + touch.x;
    vec2  R =  uv.xy, S = screen * 0.01,
          p = ( direction+direction - R ) / R * S,
          q = vec2(cos(-t / 165.), cos( t / 45.))  * S - p;
    t = 1. + cos( length( vec2(cos( t / 98.),  sin( t / 178.)) * S - p ) / 30.) 
           + cos( length( vec2(sin(-t / 124.), cos( t / 104.)) * S - p ) / 20.) 
           + sin( length(q) / 25. ) * sin(q.x / 20.) * sin(q.y / 15.);
    return .5 + .5* cos( (time+touch.y) / vec4(63,78,45,1) + ( t + vec4(0,1,-.5,0) ) *3.14 );
}

This is a sca file which is the Spark AR format for shaders.

It is a conversion of this code from ShaderToy:

void mainImage( out vec4 O, vec2 U )
{
    float t = iTime/.1 + iMouse.x;
    vec2  R =  iResolution.xy, S = vec2(160,100),
          p = ( U+U - R ) / R * S,
          q = vec2(cos(-t / 165.), cos( t / 45.))  * S - p;
    t = 1. + cos( length( vec2(cos( t / 98.),  sin( t / 178.)) * S - p ) / 30.) 
           + cos( length( vec2(sin(-t / 124.), cos( t / 104.)) * S - p ) / 20.) 
           + sin( length(q) / 25. ) * sin(q.x / 20.) * sin(q.y / 15.);
    O = .5 + .5* cos( (iTime+iMouse.y) / vec4(63,78,45,1) + ( t + vec4(0,1,-.5,0) ) *3.14 );
}

Hope someone can help.

1

There are 1 answers

3
Cadeyrn On BEST ANSWER

The problem comes from the fact that you misinterpreted the iResolution variable in the shadertoy code as the uv coordinates of the fragment. iResolution is just a variable that stores the dimensions in pixels of the image on the screen. It is the same for each pixel. U on the other side, stores the coordinates of the fragment measured in pixels ( so that uv = U / iResolution ). It is called fragCoord in the default shadertoy shader.

In your case, as you already have uv going from 0 to 1, you don't need R to define p : p = ( U + U - R ) / R * S can become p = ( U/R + U/R - R/R ) * S and then p = (uv + uv - vec2(1)) * S.

I hope this fixes your problem, tell me if it doesn't.

EDIT: I just realized that you can simplify the definition of p even further as the - vec2(1) is a translation that doesn't really affect the result and the uv + uv can be replaced by uv by compensating with S. So it can become p = uv * S.