mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-09 06:04:03 +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
d966304803
commit
80d454e2d6
3 changed files with 56 additions and 22 deletions
|
@ -126,7 +126,10 @@ struct BlendSettigs {
|
||||||
// LinearGradient
|
// LinearGradient
|
||||||
const MAX_LINEAR_GRADIENT_STOPS = 4;
|
const MAX_LINEAR_GRADIENT_STOPS = 4;
|
||||||
struct LinearGradient {
|
struct LinearGradient {
|
||||||
nStops : vec4f,
|
nStops : u32,
|
||||||
|
spread : u32,
|
||||||
|
dummy0 : u32,
|
||||||
|
dummy1 : u32,
|
||||||
gradStartPos : vec2f,
|
gradStartPos : vec2f,
|
||||||
gradEndPos : vec2f,
|
gradEndPos : vec2f,
|
||||||
stopPoints : vec4f,
|
stopPoints : vec4f,
|
||||||
|
@ -166,10 +169,18 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
||||||
let ba: vec2f = ed - st;
|
let ba: vec2f = ed - st;
|
||||||
|
|
||||||
// get interpolation factor
|
// 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
|
// get stops count
|
||||||
let last: i32 = i32(uLinearGradient.nStops[0]) - 1;
|
let last: i32 = i32(uLinearGradient.nStops) - 1;
|
||||||
|
|
||||||
// closer than first stop
|
// closer than first stop
|
||||||
if (t <= uLinearGradient.stopPoints[0]) {
|
if (t <= uLinearGradient.stopPoints[0]) {
|
||||||
|
@ -216,7 +227,10 @@ struct BlendSettigs {
|
||||||
// RadialGradient
|
// RadialGradient
|
||||||
const MAX_RADIAL_GRADIENT_STOPS = 4;
|
const MAX_RADIAL_GRADIENT_STOPS = 4;
|
||||||
struct RadialGradient {
|
struct RadialGradient {
|
||||||
nStops : vec4f,
|
nStops : u32,
|
||||||
|
spread : u32,
|
||||||
|
dummy0 : u32,
|
||||||
|
dummy1 : u32,
|
||||||
centerPos : vec2f,
|
centerPos : vec2f,
|
||||||
radius : vec2f,
|
radius : vec2f,
|
||||||
stopPoints : vec4f,
|
stopPoints : vec4f,
|
||||||
|
@ -250,10 +264,18 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
||||||
var color = vec4(1.0);
|
var color = vec4(1.0);
|
||||||
|
|
||||||
// get interpolation factor
|
// 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
|
// get stops count
|
||||||
let last: i32 = i32(uRadialGradient.nStops[0]) - 1;
|
let last: i32 = i32(uRadialGradient.nStops) - 1;
|
||||||
|
|
||||||
// closer than first stop
|
// closer than first stop
|
||||||
if (t <= uRadialGradient.stopPoints[0]) {
|
if (t <= uRadialGradient.stopPoints[0]) {
|
||||||
|
|
|
@ -127,8 +127,8 @@ void WgShaderTypeLinearGradient::update(const LinearGradient* linearGradient)
|
||||||
const Fill::ColorStop* stops = nullptr;
|
const Fill::ColorStop* stops = nullptr;
|
||||||
auto stopCnt = linearGradient->colorStops(&stops);
|
auto stopCnt = linearGradient->colorStops(&stops);
|
||||||
|
|
||||||
nStops[0] = stopCnt;
|
nStops = stopCnt;
|
||||||
nStops[1] = 0.5f;
|
spread = uint32_t(linearGradient->spread());
|
||||||
|
|
||||||
for (uint32_t i = 0; i < stopCnt; ++i) {
|
for (uint32_t i = 0; i < stopCnt; ++i) {
|
||||||
stopPoints[i] = stops[i].offset;
|
stopPoints[i] = stops[i].offset;
|
||||||
|
@ -153,8 +153,8 @@ void WgShaderTypeRadialGradient::update(const RadialGradient* radialGradient)
|
||||||
const Fill::ColorStop* stops = nullptr;
|
const Fill::ColorStop* stops = nullptr;
|
||||||
auto stopCnt = radialGradient->colorStops(&stops);
|
auto stopCnt = radialGradient->colorStops(&stops);
|
||||||
|
|
||||||
nStops[0] = stopCnt;
|
nStops = stopCnt;
|
||||||
nStops[1] = 0.5f;
|
spread = uint32_t(radialGradient->spread());
|
||||||
|
|
||||||
for (uint32_t i = 0; i < stopCnt; ++i) {
|
for (uint32_t i = 0; i < stopCnt; ++i) {
|
||||||
stopPoints[i] = stops[i].offset;
|
stopPoints[i] = stops[i].offset;
|
||||||
|
|
|
@ -73,7 +73,10 @@ struct WgShaderTypeSolidColor
|
||||||
|
|
||||||
// const MAX_LINEAR_GRADIENT_STOPS = 4;
|
// const MAX_LINEAR_GRADIENT_STOPS = 4;
|
||||||
// struct LinearGradient {
|
// struct LinearGradient {
|
||||||
// nStops : vec4f,
|
// nStops : u32,
|
||||||
|
// spread : u32,
|
||||||
|
// dummy0 : u32,
|
||||||
|
// dummy1 : u32,
|
||||||
// gradStartPos : vec2f,
|
// gradStartPos : vec2f,
|
||||||
// gradEndPos : vec2f,
|
// gradEndPos : vec2f,
|
||||||
// stopPoints : vec4f,
|
// stopPoints : vec4f,
|
||||||
|
@ -82,11 +85,14 @@ struct WgShaderTypeSolidColor
|
||||||
#define MAX_LINEAR_GRADIENT_STOPS 4
|
#define MAX_LINEAR_GRADIENT_STOPS 4
|
||||||
struct WgShaderTypeLinearGradient
|
struct WgShaderTypeLinearGradient
|
||||||
{
|
{
|
||||||
alignas(16) float nStops[4]{};
|
uint32_t nStops{};
|
||||||
alignas(16) float startPos[2]{};
|
uint32_t spread{};
|
||||||
alignas(8) float endPos[2]{};
|
uint32_t dummy0{}; // allign with WGSL struct
|
||||||
alignas(8) float stopPoints[MAX_LINEAR_GRADIENT_STOPS]{};
|
uint32_t dummy1{}; // allign with WGSL struct
|
||||||
alignas(16) float stopColors[4 * MAX_LINEAR_GRADIENT_STOPS]{};
|
float startPos[2]{};
|
||||||
|
float endPos[2]{};
|
||||||
|
float stopPoints[MAX_LINEAR_GRADIENT_STOPS]{};
|
||||||
|
float stopColors[4 * MAX_LINEAR_GRADIENT_STOPS]{};
|
||||||
|
|
||||||
WgShaderTypeLinearGradient(const LinearGradient* linearGradient);
|
WgShaderTypeLinearGradient(const LinearGradient* linearGradient);
|
||||||
void update(const LinearGradient* linearGradient);
|
void update(const LinearGradient* linearGradient);
|
||||||
|
@ -94,7 +100,10 @@ struct WgShaderTypeLinearGradient
|
||||||
|
|
||||||
// const MAX_RADIAL_GRADIENT_STOPS = 4;
|
// const MAX_RADIAL_GRADIENT_STOPS = 4;
|
||||||
// struct RadialGradient {
|
// struct RadialGradient {
|
||||||
// nStops : vec4f,
|
// nStops : u32,
|
||||||
|
// spread : u32,
|
||||||
|
// dummy0 : u32,
|
||||||
|
// dummy1 : u32,
|
||||||
// centerPos : vec2f,
|
// centerPos : vec2f,
|
||||||
// radius : vec2f,
|
// radius : vec2f,
|
||||||
// stopPoints : vec4f,
|
// stopPoints : vec4f,
|
||||||
|
@ -103,11 +112,14 @@ struct WgShaderTypeLinearGradient
|
||||||
#define MAX_RADIAL_GRADIENT_STOPS 4
|
#define MAX_RADIAL_GRADIENT_STOPS 4
|
||||||
struct WgShaderTypeRadialGradient
|
struct WgShaderTypeRadialGradient
|
||||||
{
|
{
|
||||||
alignas(16) float nStops[4]{};
|
uint32_t nStops{};
|
||||||
alignas(16) float centerPos[2]{};
|
uint32_t spread{};
|
||||||
alignas(8) float radius[2]{};
|
uint32_t dummy0{}; // allign with WGSL struct
|
||||||
alignas(8) float stopPoints[MAX_RADIAL_GRADIENT_STOPS]{};
|
uint32_t dummy1{}; // allign with WGSL struct
|
||||||
alignas(16) float stopColors[4 * MAX_RADIAL_GRADIENT_STOPS]{};
|
float centerPos[2]{};
|
||||||
|
float radius[2]{};
|
||||||
|
float stopPoints[MAX_RADIAL_GRADIENT_STOPS]{};
|
||||||
|
float stopColors[4 * MAX_RADIAL_GRADIENT_STOPS]{};
|
||||||
|
|
||||||
WgShaderTypeRadialGradient(const RadialGradient* radialGradient);
|
WgShaderTypeRadialGradient(const RadialGradient* radialGradient);
|
||||||
void update(const RadialGradient* radialGradient);
|
void update(const RadialGradient* radialGradient);
|
||||||
|
|
Loading…
Add table
Reference in a new issue