Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

starfield shader - ported, would like feedback
Started by mitchell3 May 22 2016 04:01 AM

6 replies to this topic
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

mitchell3

[GLOBAL: userInfoPane.html]
mitchell3
  • Enthusiast

  • 32 posts
  • Corona SDK

Hi

 

Ported a shader from http://glslsandbox.com/e#32816.0

 

I put it up on code exchange: https://code.coronalabs.com/code/starfield

 
here it is running in playground: https://goo.gl/imfoYr

 

Would be interested in feedback on any errors, or better ways to optimize it for corona

 

thanks!



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,697 posts
  • Enterprise

Nicely done!



[TOPIC: post.html]
#3

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 848 posts
  • Corona SDK

Looks nice.  :)

 

Some feedback:

 

You can replace

 vec2 resolution = vec2(CoronaVertexUserData.x,CoronaVertexUserData.y);

with

 vec2 resolution = CoronaVertexUserData.xy;

or simply use the right-hand side directly in later steps.

 

This

    vec2 position = gl_FragCoord.xy / resolution.xy;
    position.y *= resolution.y/resolution.x;

seems a little odd, unless it's actually exploiting the subtle numerical precision difference between floating point numbers and mathematical ones. If not, the division and multiplication by the y-component cancel, so you could just write

    vec2 position = gl_FragCoord.xy / resolution.xx;

or

    vec2 position = gl_FragCoord.xy / resolution.x;

instead.

 

Lastly, if you'll need to support older devices, the line

      return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);

might be better served with something like

#if GL_FRAGMENT_PRECISION_HIGH == 1
      return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
#else
      return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 437.585453);
#endif

though you'd have to experiment to be sure. (For the constant and the details I'm about to mention, see page 3 of the reference card.) Basically, any floating-point number is interpolated between adjacent powers of 2. If you have 1 / 65536 precision, you can get pretty close to that number (between 32768 and 65536, you can land on multiples of 0.5), but if your device can only muster 1024ths, you won't (in that same range, you'd snap to multiples of 32!), which will probably be too choppy for small objects like your stars. 



[TOPIC: post.html]
#4

mitchell3

[GLOBAL: userInfoPane.html]
mitchell3
  • Enthusiast

  • 32 posts
  • Corona SDK

StarCrunch - thanks for the feedback. 

 

This

    vec2 position = gl_FragCoord.xy / resolution.xy;
    position.y *= resolution.y/resolution.x;

seems a little odd, unless it's actually exploiting the subtle numerical precision difference between floating point numbers and mathematical ones. If not, the division and multiplication by the y-component cancel, so you could just write...

 

a lot of this is still black box to me - afaik - still not entirely clear on use of resolution, and gl_FragCoord - maybe that i need to use the texCoord? Any advice on how to actually examine these values? - eg -i've figured out texCoord is a vec2 with range between 0 - 1.0, so from what i understand ,maybe this whole section is redundant - positions is the texCoord I think

 

#if GL_FRAGMENT_PRECISION_HIGH == 1

return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
#else
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 437.585453);

#endif

 

I can probably get away with the low precision version - from what i see its giving comparable results

 

My next goal is to make it so I can use as a scrolling space BG as my character moves



[TOPIC: post.html]
#5

mitchell3

[GLOBAL: userInfoPane.html]
mitchell3
  • Enthusiast

  • 32 posts
  • Corona SDK

updated the gist - removed more unnecessary bits.



[TOPIC: post.html]
#6

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 848 posts
  • Corona SDK

If the starfield will be a full-screen background, then yes, I think position and texCoord should be the same. A lot of these online shader editors basically assume full-screen, free-standing effects, thus the built-in resolution parameter, whereas that will only occasionally apply in practice.

 

As far as figuring out values goes, if you know something is between 0 and 1, one way is to return it through a color from the fragment kernel, say as

if (true) return vec4(value, 0., 0., 1.); // the "if (true)" is to make the compiler happy,
                                          // so it doesn't complain about the rest of your
                                          // now-unreachable fragment kernel code

(Vertex kernels can likewise pass values to the fragment kernel through a varying, then do this same thing there.)

 

The (per-pixel) result will be black for a value of 0, bright red for a value of 1, otherwise in-between. You can use more color channels for more values, but it obviously takes a little more mental effort to figure out the components.

 

For values that can go higher than 1, you'll want to figure out the maximum value and divide by that. (I'm not sure that returning colors outside [0, 1] has well-defined behavior. I think it clamps on some platforms, but also seem to recall less predictable results elsewhere. In any case, you'll be getting false positives and / or negatives.) For values with a minimum other than 0, use the more general (x - min) / (max - min) to put x in the [0, 1] range.



[TOPIC: post.html]
#7

mitchell3

[GLOBAL: userInfoPane.html]
mitchell3
  • Enthusiast

  • 32 posts
  • Corona SDK

so, hit a little snag. for some reason, shader works fine in simulator, but not on real device. started a new thread for that, will update here once figureout the problem

 

https://forums.coronalabs.com/topic/63270-works-in-simulator-not-on-device-iosipad-air/




[topic_controls]
[/topic_controls]