New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add support for radial gradients #734
Merged
+335
−3
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.
Loading status checks…
add support for radial gradients
- Loading branch information
commit 21924c2d8a2e692290e00a36640c6dd2cc955539
| @@ -0,0 +1,67 @@ | ||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||
| * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
|
||
| float offset(int index) { | ||
| return vOffsets[index / 4][index % 4]; | ||
| } | ||
|
|
||
| float linearStep(float lo, float hi, float x) { | ||
| float d = hi - lo; | ||
| float v = x - lo; | ||
| if (d != 0.0) { | ||
| v /= d; | ||
| } | ||
| return clamp(v, 0.0, 1.0); | ||
| } | ||
|
|
||
| void main(void) { | ||
| vec2 cd = vEndCenter - vStartCenter; | ||
| vec2 pd = vPos - vStartCenter; | ||
| float rd = vEndRadius - vStartRadius; | ||
|
|
||
| // Solve for t in length(t * cd - pd) = vStartRadius + t * rd | ||
| // using a quadratic equation in form of At^2 - 2Bt + C = 0 | ||
| float A = dot(cd, cd) - rd * rd; | ||
| float B = dot(pd, cd) + vStartRadius * rd; | ||
| float C = dot(pd, pd) - vStartRadius * vStartRadius; | ||
|
|
||
| float x; | ||
| if (A == 0.0) { | ||
| // Since A is 0, just solve for -2Bt + C = 0 | ||
| if (B == 0.0) { | ||
| discard; | ||
| } | ||
| float t = 0.5 * C / B; | ||
| if (vStartRadius + rd * t >= 0.0) { | ||
| x = t; | ||
| } else { | ||
| discard; | ||
| } | ||
| } else { | ||
| float discr = B * B - A * C; | ||
| if (discr < 0.0) { | ||
| discard; | ||
| } | ||
| discr = sqrt(discr); | ||
| float t0 = (B + discr) / A; | ||
| float t1 = (B - discr) / A; | ||
| if (vStartRadius + rd * t0 >= 0.0) { | ||
| x = t0; | ||
| } else if (vStartRadius + rd * t1 >= 0.0) { | ||
| x = t1; | ||
| } else { | ||
| discard; | ||
| } | ||
| } | ||
|
|
||
| oFragColor = mix(vColors[0], | ||
|
||
| vColors[1], | ||
| linearStep(offset(0), offset(1), x)); | ||
|
|
||
| for (int i=1 ; i < vStopCount-1 ; ++i) { | ||
| oFragColor = mix(oFragColor, | ||
| vColors[i+1], | ||
| linearStep(offset(i), offset(i+1), x)); | ||
| } | ||
| } | ||
| @@ -0,0 +1,12 @@ | ||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||
| * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
|
||
| flat varying int vStopCount; | ||
| flat varying vec2 vStartCenter; | ||
| flat varying vec2 vEndCenter; | ||
| flat varying float vStartRadius; | ||
| flat varying float vEndRadius; | ||
| varying vec2 vPos; | ||
| flat varying vec4 vColors[MAX_STOPS_PER_RADIAL_GRADIENT]; | ||
| flat varying vec4 vOffsets[MAX_STOPS_PER_RADIAL_GRADIENT/4]; |
| @@ -0,0 +1,35 @@ | ||
| #line 1 | ||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||
| * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
|
||
| void main(void) { | ||
| Primitive prim = load_primitive(); | ||
| RadialGradient gradient = fetch_radial_gradient(prim.prim_index); | ||
|
|
||
| VertexInfo vi = write_vertex(prim.local_rect, | ||
| prim.local_clip_rect, | ||
| prim.z, | ||
| prim.layer, | ||
| prim.tile); | ||
|
|
||
| vStopCount = int(prim.user_data.x); | ||
| vPos = vi.local_clamped_pos; | ||
|
|
||
| // Snap the start/end points to device pixel units. | ||
| // I'm not sure this is entirely correct, but the | ||
| // old render path does this, and it is needed to | ||
| // make the angle gradient ref tests pass. It might | ||
| // be better to fix this higher up in DL construction | ||
| // and not snap here? | ||
| vStartCenter = floor(0.5 + gradient.start_end_center.xy * uDevicePixelRatio) / uDevicePixelRatio; | ||
| vEndCenter = floor(0.5 + gradient.start_end_center.zw * uDevicePixelRatio) / uDevicePixelRatio; | ||
| vStartRadius = gradient.start_end_radius.x; | ||
| vEndRadius = gradient.start_end_radius.y; | ||
|
|
||
| for (int i=0 ; i < vStopCount ; ++i) { | ||
| GradientStop stop = fetch_gradient_stop(prim.sub_index + i); | ||
| vColors[i] = stop.color; | ||
| vOffsets[i/4][i%4] = stop.offset.x; | ||
| } | ||
| } |
Oops, something went wrong.
ProTip!
Use n and p to navigate between commits in a pull request.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Can the radial gradient be masked? I think we are missing a mask fetch here.