i'm playing shader concept radially reveal image using shader in opengl es. end goal create circular progress bar discarding fragments in fragment shader renders full circular progress texture.
i have coded idea here in shadertoy can play it. can't seem work, , since there's no way debug i'm having hard time figuring out why.
here's glsl code fragment shader:
float magnitude(vec2 vec) { return sqrt((vec.x * vec.x) + (vec.y * vec.y)); } float anglebetween(vec2 v1, vec2 v2) { return acos(dot(v1, v2) / (magnitude(v1) * magnitude(v2))); } float gettargetangle() { return clamp(iglobaltime, 0.0, 360.0); } // opengl uses upper left origin default bool shoulddrawfragment(vec2 fragcoord) { float targetangle = gettargetangle(); float centerx = iresolution.x / 2.0; float centery = iresolution.y / 2.0; vec2 center = vec2(centerx, centery); vec2 = vec2(centerx, 0.0) - center; vec2 v2 = fragcoord - center; float anglebetween = anglebetween(up, v2); return (anglebetween >= 0.0) && (anglebetween <= targetangle); } void mainimage( out vec4 fragcolor, in vec2 fragcoord ) { vec2 uv = fragcoord.xy / iresolution.xy; if (shoulddrawfragment(fragcoord)) { fragcolor = texture2d(ichannel0, vec2(uv.x, -uv.y)); } else { fragcolor = texture2d(ichannel1, vec2(uv.x, -uv.y)); } } it sweeps out revealing bottom on both sides. want sweep out vector pointing straight up, , moving in clockwise motion.
try code:
const float pi = 3.1415926; const float two_pi = 6.2831852; float magnitude(vec2 vec) { return sqrt((vec.x * vec.x) + (vec.y * vec.y)); } float anglebetween(vec2 v1, vec2 v2) { return atan( v1.x - v2.x, v1.y - v2.y ) + pi; } float gettargetangle() { return clamp( iglobaltime, 0.0, two_pi ); } // opengl uses upper left origin default bool shoulddrawfragment(vec2 fragcoord) { float targetangle = gettargetangle(); float centerx = iresolution.x / 2.0; float centery = iresolution.y / 2.0; vec2 center = vec2(centerx, centery); float = anglebetween(center, fragcoord ); return <= targetangle; } void mainimage( out vec4 fragcolor, in vec2 fragcoord ) { vec2 uv = fragcoord.xy / iresolution.xy; if (shoulddrawfragment(fragcoord)) { fragcolor = texture2d(ichannel0, vec2(uv.x, -uv.y)); } else { fragcolor = texture2d(ichannel1, vec2(uv.x, -uv.y)); } } explanation:
the main change made way angle between 2 vectors calculated:
return atan( v1.x - v2.x, v1.y - v2.y ) + pi; this angle of difference vector between v1 , v2. if swap x , y values change direction of 0 angle is, i.e. if try this:
return atan( v1.y - v2.y, v1.x - v2.x ) + pi; the circle begins right rather upwards. can invert value of atan change direction of animation.
you don't need worry vector when calculating angle between, notice code takes angle between center , current frag co-ordinates:
float = anglebetween(center, fragcoord ); other notes:
remember calculations in radians, not degrees changed clamp on time (although doesn't affect output):
return clamp( iglobaltime, 0.0, two_pi ); you have variable same name 1 of functions:
float anglebetween = anglebetween(up, v2); which should avoided since not implementations happy this, couldn't compile shader on current machine until changed this.
Comments
Post a Comment