mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
wg_engine: fill spread
[issues 1479: LinearGradient, RadialGradient](#1479) Introduced fill spreads: Pad, Reflect, Repeat Pad: Reflect: Repeat:
This commit is contained in:
parent
44da074d58
commit
4b2f5ca510
3 changed files with 56 additions and 22 deletions
|
@ -126,7 +126,10 @@ struct BlendSettigs {
|
|||
// LinearGradient
|
||||
const MAX_LINEAR_GRADIENT_STOPS = 4;
|
||||
struct LinearGradient {
|
||||
nStops : vec4f,
|
||||
nStops : u32,
|
||||
spread : u32,
|
||||
dummy0 : u32,
|
||||
dummy1 : u32,
|
||||
gradStartPos : vec2f,
|
||||
gradEndPos : vec2f,
|
||||
stopPoints : vec4f,
|
||||
|
@ -166,10 +169,18 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
|||
let ba: vec2f = ed - st;
|
||||
|
||||
// get interpolation factor
|
||||
let t: f32 = clamp(dot(pos - st, ba) / dot(ba, ba), 0.0, 1.0);
|
||||
var t: f32 = abs(dot(pos - st, ba) / dot(ba, ba));
|
||||
|
||||
// fill spread
|
||||
switch uLinearGradient.spread {
|
||||
/* Pad */ case 0u: { t = clamp(t, 0.0, 1.0); }
|
||||
/* Reflect */ case 1u: { t = select(1.0 - fract(t), fract(t), u32(t) % 2 == 0); }
|
||||
/* Repeat */ case 2u: { t = fract(t); }
|
||||
default: { t = t; }
|
||||
}
|
||||
|
||||
// get stops count
|
||||
let last: i32 = i32(uLinearGradient.nStops[0]) - 1;
|
||||
let last: i32 = i32(uLinearGradient.nStops) - 1;
|
||||
|
||||
// closer than first stop
|
||||
if (t <= uLinearGradient.stopPoints[0]) {
|
||||
|
@ -216,7 +227,10 @@ struct BlendSettigs {
|
|||
// RadialGradient
|
||||
const MAX_RADIAL_GRADIENT_STOPS = 4;
|
||||
struct RadialGradient {
|
||||
nStops : vec4f,
|
||||
nStops : u32,
|
||||
spread : u32,
|
||||
dummy0 : u32,
|
||||
dummy1 : u32,
|
||||
centerPos : vec2f,
|
||||
radius : vec2f,
|
||||
stopPoints : vec4f,
|
||||
|
@ -250,10 +264,18 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
|||
var color = vec4(1.0);
|
||||
|
||||
// get interpolation factor
|
||||
let t: f32 = clamp(distance(uRadialGradient.centerPos, in.vScreenCoord) / uRadialGradient.radius.x, 0.0, 1.0);
|
||||
var t: f32 = distance(uRadialGradient.centerPos, in.vScreenCoord) / uRadialGradient.radius.x;
|
||||
|
||||
// fill spread
|
||||
switch uRadialGradient.spread {
|
||||
/* Pad */ case 0u: { t = clamp(t, 0.0, 1.0); }
|
||||
/* Reflect */ case 1u: { t = select(1.0 - fract(t), fract(t), u32(t) % 2 == 0); }
|
||||
/* Repeat */ case 2u: { t = fract(t); }
|
||||
default: { t = t; }
|
||||
}
|
||||
|
||||
// get stops count
|
||||
let last: i32 = i32(uRadialGradient.nStops[0]) - 1;
|
||||
let last: i32 = i32(uRadialGradient.nStops) - 1;
|
||||
|
||||
// closer than first stop
|
||||
if (t <= uRadialGradient.stopPoints[0]) {
|
||||
|
|
|
@ -127,8 +127,8 @@ void WgShaderTypeLinearGradient::update(const LinearGradient* linearGradient)
|
|||
const Fill::ColorStop* stops = nullptr;
|
||||
auto stopCnt = linearGradient->colorStops(&stops);
|
||||
|
||||
nStops[0] = stopCnt;
|
||||
nStops[1] = 0.5f;
|
||||
nStops = stopCnt;
|
||||
spread = uint32_t(linearGradient->spread());
|
||||
|
||||
for (uint32_t i = 0; i < stopCnt; ++i) {
|
||||
stopPoints[i] = stops[i].offset;
|
||||
|
@ -153,8 +153,8 @@ void WgShaderTypeRadialGradient::update(const RadialGradient* radialGradient)
|
|||
const Fill::ColorStop* stops = nullptr;
|
||||
auto stopCnt = radialGradient->colorStops(&stops);
|
||||
|
||||
nStops[0] = stopCnt;
|
||||
nStops[1] = 0.5f;
|
||||
nStops = stopCnt;
|
||||
spread = uint32_t(radialGradient->spread());
|
||||
|
||||
for (uint32_t i = 0; i < stopCnt; ++i) {
|
||||
stopPoints[i] = stops[i].offset;
|
||||
|
|
|
@ -73,7 +73,10 @@ struct WgShaderTypeSolidColor
|
|||
|
||||
// const MAX_LINEAR_GRADIENT_STOPS = 4;
|
||||
// struct LinearGradient {
|
||||
// nStops : vec4f,
|
||||
// nStops : u32,
|
||||
// spread : u32,
|
||||
// dummy0 : u32,
|
||||
// dummy1 : u32,
|
||||
// gradStartPos : vec2f,
|
||||
// gradEndPos : vec2f,
|
||||
// stopPoints : vec4f,
|
||||
|
@ -82,11 +85,14 @@ struct WgShaderTypeSolidColor
|
|||
#define MAX_LINEAR_GRADIENT_STOPS 4
|
||||
struct WgShaderTypeLinearGradient
|
||||
{
|
||||
alignas(16) float nStops[4]{};
|
||||
alignas(16) float startPos[2]{};
|
||||
alignas(8) float endPos[2]{};
|
||||
alignas(8) float stopPoints[MAX_LINEAR_GRADIENT_STOPS]{};
|
||||
alignas(16) float stopColors[4 * MAX_LINEAR_GRADIENT_STOPS]{};
|
||||
uint32_t nStops{};
|
||||
uint32_t spread{};
|
||||
uint32_t dummy0{}; // allign with WGSL struct
|
||||
uint32_t dummy1{}; // allign with WGSL struct
|
||||
float startPos[2]{};
|
||||
float endPos[2]{};
|
||||
float stopPoints[MAX_LINEAR_GRADIENT_STOPS]{};
|
||||
float stopColors[4 * MAX_LINEAR_GRADIENT_STOPS]{};
|
||||
|
||||
WgShaderTypeLinearGradient(const LinearGradient* linearGradient);
|
||||
void update(const LinearGradient* linearGradient);
|
||||
|
@ -94,7 +100,10 @@ struct WgShaderTypeLinearGradient
|
|||
|
||||
// const MAX_RADIAL_GRADIENT_STOPS = 4;
|
||||
// struct RadialGradient {
|
||||
// nStops : vec4f,
|
||||
// nStops : u32,
|
||||
// spread : u32,
|
||||
// dummy0 : u32,
|
||||
// dummy1 : u32,
|
||||
// centerPos : vec2f,
|
||||
// radius : vec2f,
|
||||
// stopPoints : vec4f,
|
||||
|
@ -103,11 +112,14 @@ struct WgShaderTypeLinearGradient
|
|||
#define MAX_RADIAL_GRADIENT_STOPS 4
|
||||
struct WgShaderTypeRadialGradient
|
||||
{
|
||||
alignas(16) float nStops[4]{};
|
||||
alignas(16) float centerPos[2]{};
|
||||
alignas(8) float radius[2]{};
|
||||
alignas(8) float stopPoints[MAX_RADIAL_GRADIENT_STOPS]{};
|
||||
alignas(16) float stopColors[4 * MAX_RADIAL_GRADIENT_STOPS]{};
|
||||
uint32_t nStops{};
|
||||
uint32_t spread{};
|
||||
uint32_t dummy0{}; // allign with WGSL struct
|
||||
uint32_t dummy1{}; // allign with WGSL struct
|
||||
float centerPos[2]{};
|
||||
float radius[2]{};
|
||||
float stopPoints[MAX_RADIAL_GRADIENT_STOPS]{};
|
||||
float stopColors[4 * MAX_RADIAL_GRADIENT_STOPS]{};
|
||||
|
||||
WgShaderTypeRadialGradient(const RadialGradient* radialGradient);
|
||||
void update(const RadialGradient* radialGradient);
|
||||
|
|
Loading…
Add table
Reference in a new issue