PDA

View Full Version : Trouble plotting a particular equation



hashbrown
11-08-2017, 05:56 PM
I'm trying to plot the following equation : y = random( floor(uv.x) ):

https://s1.postimg.org/7jjvlsjxsb/plot1.png (https://postimg.org/image/7jjvlsjxsb/)
figure 1

I've tried other equations and they work just fine:

https://s1.postimg.org/4add90877f/Screen_Shot_2017-11-09_at_1.37.08_AM.png (https://postimg.org/image/4add90877f/)

https://s1.postimg.org/5vfvmmzhej/Screen_Shot_2017-11-09_at_1.37.33_AM.png (https://postimg.org/image/5vfvmmzhej/)


The problem starts when I try equations with steep angles like y = random(floor(uv.x)), they get their horizontal lines cut off :(

https://s1.postimg.org/9184zr1h63/Screen_Shot_2017-11-09_at_1.39.14_AM.png (https://postimg.org/image/9184zr1h63/)

The color gets cut off at a certain angle.

https://s1.postimg.org/67zm5x93fv/Screen_Shot_2017-11-09_at_2.11.15_AM.png (https://postimg.org/image/67zm5x93fv/)

I'm not sure what I'm doing wrong, but this is what I've tried so far:



out vec4 color;

float Random(in float x) {
return fract(sin(x) * 1e4);
}

void main () {

vec2 uv = gl_FragCoord.xy/ screen.xy;
vec2 ndc = vec2(uv.x * 2.0 - 1.0, uv.y * 2.0 - 1.0);
uv.x *= screen.x / screen.y;

uv -= 0.5; // -0.5 <-> 0.5
uv *= 5.0; // Zoom Out, if not we don't see much

vec4 final = vec4(0.0);
final.a = 1.0;

float i = floor(uv.x); // Integer Coords
float f = fract(uv.x); // Fractional Coords

// Calculate Graph

// This Works
// float u = f * f * (3.0 - 2.0 * f );
// float x = mix(Random(i), Random(i + 1.0), u);

float x = Random(i); // No horizontal Lines :(
float y = uv.y;

// Plot
float blur = 0.01;
final.r = smoothstep(x - blur, x, y); // bottom
final.r -= smoothstep(x - blur, x, y - blur);

color = final;

}


I'm clearly not understanding something :/ I re-edited the entire question with new and shorter code. As always, thanks!

john_connor
11-13-2017, 07:47 AM
I'm trying to plot the following equation : y = random( floor(uv.x) ):

https://s1.postimg.org/7jjvlsjxsb/plot1.png (https://postimg.org/image/7jjvlsjxsb/)
figure 1

that is not a y=f(x) equation, simply because there are x-values which lead to different y-values. besides that, why are you are using the fragment shader ? a better way is to compute the xyz value of a vertex in the vertex shader, and let the fragment shader just compute the color for a pixel.

for example:
you call glDrawArrays(GL_LINE_STRIP, 0, 100); to invoke the vertex shader 100 times. let z be const, just determine x dependent on gl_VertexID (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/gl_VertexID.xhtml), that ranges from 0 to 99. 0 means most left, 99 means most right. dependent on x, you call a separate function in the vertex shader:


#version 450 core

/* no input !! */

float f(float x)
{
return sin(6.28f * x); /* or whatever function you want to plot ... */
}

void main()
{
/* there are 100 invocations, hence 0.01f ... */
float x = -1.0f + 2.0f * float(gl_VertexID) * 0.01f;
float y = f(x);
float z = 0.5f; /* or any constant ... */
gl_Position = vec4(x, y, z, 1.0f);
}

that should work, the fragment shader just gives the fragment its color, for example:


#version 450 core

/* no input !! but output color */
layout (location = 0) out vec4 fragment0;

vec4 color(float y)
{
vec4 green = vec4(0, 1, 0, 1);
vec4 red= vec4(1, 0, 0, 1);
return mix(red, green, y);
}

void main()
{
float y = gl_FragCoord.y;
fragment0 = color(y);
}

the problem with that the f(x) that it is "hardcoded" in the program, to change it you have to re-compile + re-link the shaders again with different source code

hashbrown
11-13-2017, 12:33 PM
Thanks a lot for the reply John!



why are you are using the fragment shader ? a better way is to compute the xyz value of a vertex in the vertex shader, and let the fragment shader just compute the color for a pixel.


I agree, nonetheless I'm using the frag shader in order to use sites like ShaderToy (https://www.shadertoy.com/). As far as I know, users can only edit the fragment shader on that platform. For a game I would have used the vertex shader though. If you're curious, I'm learning most of my glsl skills at The Book of Shaders (https://thebookofshaders.com/), where they too use the Fragment shader for everything. I'm aware that this is not the most optimal approach though.



just determine x dependent on gl_VertexID


I'm also compiling my shaders on WebGL 1, so I might have to make my own gl_VertexID implementation via an attribute I guess.

Since I'm doing a lot of generative art, I'd love to keep working from the frag shader instead of compiling all the time, and perhaps later refactor my code a little to use the vertex shader and GL_LINES like you recommend once I'm satisfied with my design.

Oh before I end the post, I found some online shader editors similar to ShaderToy. You CAN use the vertex shader on these sites.

- Shdr Editor (http://shdr.bkcore.com/)
- Vertex Shader Art (https://www.vertexshaderart.com/)


Again thanks a lot for the help :)