mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-14 12:04:29 +00:00
wg_engine: support gradient focal point
Implemented gradien focal points Issue https://github.com/thorvg/thorvg/issues/2728 Issue https://github.com/thorvg/thorvg/issues/2936
This commit is contained in:
parent
95d99ee74b
commit
627f358f49
3 changed files with 30 additions and 12 deletions
|
@ -111,6 +111,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
||||||
const char* cShaderSrc_Linear = R"(
|
const char* cShaderSrc_Linear = R"(
|
||||||
struct VertexInput { @location(0) position: vec2f };
|
struct VertexInput { @location(0) position: vec2f };
|
||||||
struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f };
|
struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f };
|
||||||
|
struct GradSettings { settings: vec4f, focal: vec4f };
|
||||||
|
|
||||||
// uniforms
|
// uniforms
|
||||||
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
||||||
|
@ -118,7 +119,7 @@ struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoo
|
||||||
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
|
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
|
||||||
@group(2) @binding(0) var uSamplerGrad : sampler;
|
@group(2) @binding(0) var uSamplerGrad : sampler;
|
||||||
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
|
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
|
||||||
@group(2) @binding(2) var<uniform> uSettingGrad : vec4f;
|
@group(2) @binding(2) var<uniform> uSettingGrad : GradSettings;
|
||||||
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
|
@ -132,8 +133,8 @@ fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
||||||
let pos = in.vGradCoord.xy;
|
let pos = in.vGradCoord.xy;
|
||||||
let st = uSettingGrad.xy;
|
let st = uSettingGrad.settings.xy;
|
||||||
let ed = uSettingGrad.zw;
|
let ed = uSettingGrad.settings.zw;
|
||||||
let ba = ed - st;
|
let ba = ed - st;
|
||||||
let t = dot(pos - st, ba) / dot(ba, ba);
|
let t = dot(pos - st, ba) / dot(ba, ba);
|
||||||
let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(t, 0.5));
|
let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(t, 0.5));
|
||||||
|
@ -149,13 +150,14 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
||||||
const char* cShaderSrc_Radial = R"(
|
const char* cShaderSrc_Radial = R"(
|
||||||
struct VertexInput { @location(0) position: vec2f };
|
struct VertexInput { @location(0) position: vec2f };
|
||||||
struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f };
|
struct VertexOutput { @builtin(position) position : vec4f, @location(0) vGradCoord : vec4f };
|
||||||
|
struct GradSettings { settings: vec4f, focal: vec4f };
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
||||||
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
|
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
|
||||||
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
|
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
|
||||||
@group(2) @binding(0) var uSamplerGrad : sampler;
|
@group(2) @binding(0) var uSamplerGrad : sampler;
|
||||||
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
|
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
|
||||||
@group(2) @binding(2) var<uniform> uSettingGrad : vec4f;
|
@group(2) @binding(2) var<uniform> uSettingGrad : GradSettings;
|
||||||
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
|
@ -168,8 +170,16 @@ fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
||||||
let t: f32 = distance(uSettingGrad.zw, in.vGradCoord.xy) / uSettingGrad.r;
|
// orignal data
|
||||||
let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(t, 0.5));
|
let d0 = in.vGradCoord.xy - uSettingGrad.settings.xy;
|
||||||
|
let d1 = uSettingGrad.settings.xy - uSettingGrad.focal.xy;
|
||||||
|
let r0 = uSettingGrad.settings.z;
|
||||||
|
let rd = uSettingGrad.focal.z - uSettingGrad.settings.z;
|
||||||
|
let a = 1.0*dot(d1, d1) - 1.0*rd*rd;
|
||||||
|
let b = 2.0*dot(d0, d1) - 2.0*r0*rd;
|
||||||
|
let c = 1.0*dot(d0, d0) - 1.0*r0*r0;
|
||||||
|
let t = (-b + sqrt(b*b - 4*a*c))/(2*a);
|
||||||
|
let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(1.0 - t, 0.5));
|
||||||
let So = uBlendSettings.a;
|
let So = uBlendSettings.a;
|
||||||
return vec4f(Sc.rgb * Sc.a * So, Sc.a * So);
|
return vec4f(Sc.rgb * Sc.a * So, Sc.a * So);
|
||||||
}
|
}
|
||||||
|
@ -286,6 +296,7 @@ fn postProcess(d: FragData, R: vec4f) -> vec4f { return R; };
|
||||||
const char* cShaderSrc_Linear_Blend = R"(
|
const char* cShaderSrc_Linear_Blend = R"(
|
||||||
struct VertexInput { @location(0) position: vec2f };
|
struct VertexInput { @location(0) position: vec2f };
|
||||||
struct VertexOutput { @builtin(position) position: vec4f, @location(0) vGradCoord : vec4f, @location(1) vScrCoord: vec2f };
|
struct VertexOutput { @builtin(position) position: vec4f, @location(0) vGradCoord : vec4f, @location(1) vScrCoord: vec2f };
|
||||||
|
struct GradSettings { settings: vec4f, focal: vec4f };
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
||||||
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
|
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
|
||||||
|
@ -335,13 +346,14 @@ fn postProcess(d: FragData, R: vec4f) -> vec4f { return R; };
|
||||||
const char* cShaderSrc_Radial_Blend = R"(
|
const char* cShaderSrc_Radial_Blend = R"(
|
||||||
struct VertexInput { @location(0) position: vec2f };
|
struct VertexInput { @location(0) position: vec2f };
|
||||||
struct VertexOutput { @builtin(position) position: vec4f, @location(0) vGradCoord : vec4f, @location(1) vScrCoord: vec2f };
|
struct VertexOutput { @builtin(position) position: vec4f, @location(0) vGradCoord : vec4f, @location(1) vScrCoord: vec2f };
|
||||||
|
struct GradSettings { settings: vec4f, focal: vec4f };
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
||||||
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
|
@group(1) @binding(0) var<uniform> uModelMat : mat4x4f;
|
||||||
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
|
@group(1) @binding(1) var<uniform> uBlendSettings : vec4f;
|
||||||
@group(2) @binding(0) var uSamplerGrad : sampler;
|
@group(2) @binding(0) var uSamplerGrad : sampler;
|
||||||
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
|
@group(2) @binding(1) var uTextureGrad : texture_2d<f32>;
|
||||||
@group(2) @binding(2) var<uniform> uSettingGrad : vec4f;
|
@group(2) @binding(2) var<uniform> uSettingGrad : GradSettings;
|
||||||
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
||||||
@group(3) @binding(0) var uSamplerDst : sampler;
|
@group(3) @binding(0) var uSamplerDst : sampler;
|
||||||
@group(3) @binding(1) var uTextureDst : texture_2d<f32>;
|
@group(3) @binding(1) var uTextureDst : texture_2d<f32>;
|
||||||
|
@ -358,9 +370,15 @@ fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
|
|
||||||
struct FragData { Sc: vec3f, Sa: f32, So: f32, Dc: vec3f, Da: f32 };
|
struct FragData { Sc: vec3f, Sa: f32, So: f32, Dc: vec3f, Da: f32 };
|
||||||
fn getFragData(in: VertexOutput) -> FragData {
|
fn getFragData(in: VertexOutput) -> FragData {
|
||||||
// get source data
|
let d0 = in.vGradCoord.xy - uSettingGrad.settings.xy;
|
||||||
let t: f32 = distance(uSettingGrad.zw, in.vGradCoord.xy) / uSettingGrad.r;
|
let d1 = uSettingGrad.settings.xy - uSettingGrad.focal.xy;
|
||||||
let colorSrc = textureSample(uTextureGrad, uSamplerGrad, vec2f(t, 0.5));
|
let r0 = uSettingGrad.settings.z;
|
||||||
|
let rd = uSettingGrad.focal.z - uSettingGrad.settings.z;
|
||||||
|
let a = 1.0*dot(d1, d1) - 1.0*rd*rd;
|
||||||
|
let b = 2.0*dot(d0, d1) - 2.0*r0*rd;
|
||||||
|
let c = 1.0*dot(d0, d0) - 1.0*r0*r0;
|
||||||
|
let t = (-b + sqrt(b*b - 4*a*c))/(2*a);
|
||||||
|
let colorSrc = textureSample(uTextureGrad, uSamplerGrad, vec2f(1.0 - t, 0.5));
|
||||||
let colorDst = textureSample(uTextureDst, uSamplerDst, in.vScrCoord.xy);
|
let colorDst = textureSample(uTextureDst, uSamplerDst, in.vScrCoord.xy);
|
||||||
// fill fragment data
|
// fill fragment data
|
||||||
var data: FragData;
|
var data: FragData;
|
||||||
|
|
|
@ -132,7 +132,7 @@ void WgShaderTypeGradient::update(const RadialGradient* radialGradient)
|
||||||
auto stopCnt = radialGradient->colorStops(&stops);
|
auto stopCnt = radialGradient->colorStops(&stops);
|
||||||
updateTexData(stops, stopCnt);
|
updateTexData(stops, stopCnt);
|
||||||
// update base points
|
// update base points
|
||||||
radialGradient->radial(&settings[2], &settings[3], &settings[0]);
|
radialGradient->radial(&settings[0], &settings[1], &settings[2], &settings[4], &settings[5], &settings[6]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ struct WgShaderTypeSolidColor
|
||||||
#define WG_TEXTURE_GRADIENT_SIZE 512
|
#define WG_TEXTURE_GRADIENT_SIZE 512
|
||||||
struct WgShaderTypeGradient
|
struct WgShaderTypeGradient
|
||||||
{
|
{
|
||||||
float settings[4]{};
|
float settings[4+4]{}; // WGSL: struct GradSettings { settings: vec4f, focal: vec4f; transform: mat4f };
|
||||||
uint8_t texData[WG_TEXTURE_GRADIENT_SIZE * 4];
|
uint8_t texData[WG_TEXTURE_GRADIENT_SIZE * 4];
|
||||||
|
|
||||||
void update(const LinearGradient* linearGradient);
|
void update(const LinearGradient* linearGradient);
|
||||||
|
|
Loading…
Add table
Reference in a new issue