mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
wg_engine: wrong gradient transformation fixed
issue: https://github.com/thorvg/thorvg/issues/2620
This commit is contained in:
parent
91a538d1f2
commit
7a6a89cf26
6 changed files with 49 additions and 10 deletions
|
@ -45,6 +45,19 @@ WGPUBindGroup WgBindGroupLayouts::createBindGroupTexSampledBuff1Un(WGPUSampler s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WGPUBindGroup WgBindGroupLayouts::createBindGroupTexSampledBuff2Un(WGPUSampler sampler, WGPUTextureView texView, WGPUBuffer buff0, WGPUBuffer buff1)
|
||||||
|
{
|
||||||
|
const WGPUBindGroupEntry bindGroupEntrys[] = {
|
||||||
|
{ .binding = 0, .sampler = sampler },
|
||||||
|
{ .binding = 1, .textureView = texView },
|
||||||
|
{ .binding = 2, .buffer = buff0, .size = wgpuBufferGetSize(buff0) },
|
||||||
|
{ .binding = 3, .buffer = buff1, .size = wgpuBufferGetSize(buff1) }
|
||||||
|
};
|
||||||
|
const WGPUBindGroupDescriptor bindGroupDesc { .layout = layoutTexSampledBuff2Un, .entryCount = 4, .entries = bindGroupEntrys };
|
||||||
|
return wgpuDeviceCreateBindGroup(device, &bindGroupDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WGPUBindGroup WgBindGroupLayouts::createBindGroupStrorage1WO(WGPUTextureView texView)
|
WGPUBindGroup WgBindGroupLayouts::createBindGroupStrorage1WO(WGPUTextureView texView)
|
||||||
{
|
{
|
||||||
const WGPUBindGroupEntry bindGroupEntrys[] = {
|
const WGPUBindGroupEntry bindGroupEntrys[] = {
|
||||||
|
@ -164,6 +177,18 @@ void WgBindGroupLayouts::initialize(WgContext& context)
|
||||||
assert(layoutTexSampledBuff1Un);
|
assert(layoutTexSampledBuff1Un);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ // bind group layout tex sampled with buffer uniforms
|
||||||
|
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
|
||||||
|
{ .binding = 0, .visibility = visibility_frag, .sampler = sampler },
|
||||||
|
{ .binding = 1, .visibility = visibility_frag, .texture = texture },
|
||||||
|
{ .binding = 2, .visibility = visibility_vert, .buffer = bufferUniform },
|
||||||
|
{ .binding = 3, .visibility = visibility_vert, .buffer = bufferUniform }
|
||||||
|
};
|
||||||
|
const WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc { .entryCount = 4, .entries = bindGroupLayoutEntries };
|
||||||
|
layoutTexSampledBuff2Un = wgpuDeviceCreateBindGroupLayout(device, &bindGroupLayoutDesc);
|
||||||
|
assert(layoutTexSampledBuff1Un);
|
||||||
|
}
|
||||||
|
|
||||||
{ // bind group layout tex storage 1 WO
|
{ // bind group layout tex storage 1 WO
|
||||||
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
|
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
|
||||||
{ .binding = 0, .visibility = visibility_frag, .storageTexture = storageTextureWO }
|
{ .binding = 0, .visibility = visibility_frag, .storageTexture = storageTextureWO }
|
||||||
|
|
|
@ -31,6 +31,7 @@ private:
|
||||||
public:
|
public:
|
||||||
WGPUBindGroupLayout layoutTexSampled{};
|
WGPUBindGroupLayout layoutTexSampled{};
|
||||||
WGPUBindGroupLayout layoutTexSampledBuff1Un{};
|
WGPUBindGroupLayout layoutTexSampledBuff1Un{};
|
||||||
|
WGPUBindGroupLayout layoutTexSampledBuff2Un{};
|
||||||
WGPUBindGroupLayout layoutTexStrorage1WO{};
|
WGPUBindGroupLayout layoutTexStrorage1WO{};
|
||||||
WGPUBindGroupLayout layoutTexStrorage1RO{};
|
WGPUBindGroupLayout layoutTexStrorage1RO{};
|
||||||
WGPUBindGroupLayout layoutTexStrorage2RO{};
|
WGPUBindGroupLayout layoutTexStrorage2RO{};
|
||||||
|
@ -41,6 +42,7 @@ public:
|
||||||
public:
|
public:
|
||||||
WGPUBindGroup createBindGroupTexSampled(WGPUSampler sampler, WGPUTextureView texView);
|
WGPUBindGroup createBindGroupTexSampled(WGPUSampler sampler, WGPUTextureView texView);
|
||||||
WGPUBindGroup createBindGroupTexSampledBuff1Un(WGPUSampler sampler, WGPUTextureView texView, WGPUBuffer buff);
|
WGPUBindGroup createBindGroupTexSampledBuff1Un(WGPUSampler sampler, WGPUTextureView texView, WGPUBuffer buff);
|
||||||
|
WGPUBindGroup createBindGroupTexSampledBuff2Un(WGPUSampler sampler, WGPUTextureView texView, WGPUBuffer buff0, WGPUBuffer buff1);
|
||||||
WGPUBindGroup createBindGroupStrorage1WO(WGPUTextureView texView);
|
WGPUBindGroup createBindGroupStrorage1WO(WGPUTextureView texView);
|
||||||
WGPUBindGroup createBindGroupStrorage1RO(WGPUTextureView texView);
|
WGPUBindGroup createBindGroupStrorage1RO(WGPUTextureView texView);
|
||||||
WGPUBindGroup createBindGroupStrorage2RO(WGPUTextureView texView0, WGPUTextureView texView1);
|
WGPUBindGroup createBindGroupStrorage2RO(WGPUTextureView texView0, WGPUTextureView texView1);
|
||||||
|
|
|
@ -176,7 +176,7 @@ void WgPipelines::initialize(WgContext& context)
|
||||||
const WGPUBindGroupLayout bindGroupLayoutsGradient[] = {
|
const WGPUBindGroupLayout bindGroupLayoutsGradient[] = {
|
||||||
layouts.layoutBuffer1Un,
|
layouts.layoutBuffer1Un,
|
||||||
layouts.layoutBuffer2Un,
|
layouts.layoutBuffer2Un,
|
||||||
layouts.layoutTexSampledBuff1Un
|
layouts.layoutTexSampledBuff2Un
|
||||||
};
|
};
|
||||||
const WGPUBindGroupLayout bindGroupLayoutsImage[] = {
|
const WGPUBindGroupLayout bindGroupLayoutsImage[] = {
|
||||||
layouts.layoutBuffer1Un,
|
layouts.layoutBuffer1Un,
|
||||||
|
|
|
@ -212,6 +212,13 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_
|
||||||
// setup fill properties
|
// setup fill properties
|
||||||
if ((flags & (RenderUpdateFlag::Gradient)) && fill) {
|
if ((flags & (RenderUpdateFlag::Gradient)) && fill) {
|
||||||
rasterType = WgRenderRasterType::Gradient;
|
rasterType = WgRenderRasterType::Gradient;
|
||||||
|
// get gradient transfrom matrix
|
||||||
|
Matrix fillTransform = fill->transform();
|
||||||
|
Matrix invFillTransform;
|
||||||
|
WgShaderTypeMat4x4f gradientTrans; // identity by default
|
||||||
|
if (inverse(&fillTransform, &invFillTransform))
|
||||||
|
gradientTrans.update(invFillTransform);
|
||||||
|
// get gradient rasterisation settings
|
||||||
WgShaderTypeGradient gradient;
|
WgShaderTypeGradient gradient;
|
||||||
if (fill->type() == Type::LinearGradient) {
|
if (fill->type() == Type::LinearGradient) {
|
||||||
gradient.update((LinearGradient*)fill);
|
gradient.update((LinearGradient*)fill);
|
||||||
|
@ -222,8 +229,9 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_
|
||||||
}
|
}
|
||||||
// update gpu assets
|
// update gpu assets
|
||||||
bool bufferGradientSettingsChanged = context.allocateBufferUniform(bufferGroupGradient, &gradient.settings, sizeof(gradient.settings));
|
bool bufferGradientSettingsChanged = context.allocateBufferUniform(bufferGroupGradient, &gradient.settings, sizeof(gradient.settings));
|
||||||
|
bool bufferGradientTransformChanged = context.allocateBufferUniform(bufferGroupTransfromGrad, &gradientTrans.mat, sizeof(gradientTrans.mat));
|
||||||
bool textureGradientChanged = context.allocateTexture(texGradient, WG_TEXTURE_GRADIENT_SIZE, 1, WGPUTextureFormat_RGBA8Unorm, gradient.texData);
|
bool textureGradientChanged = context.allocateTexture(texGradient, WG_TEXTURE_GRADIENT_SIZE, 1, WGPUTextureFormat_RGBA8Unorm, gradient.texData);
|
||||||
if (bufferGradientSettingsChanged || textureGradientChanged) {
|
if (bufferGradientSettingsChanged || textureGradientChanged || bufferGradientTransformChanged) {
|
||||||
// update texture view
|
// update texture view
|
||||||
context.releaseTextureView(texViewGradient);
|
context.releaseTextureView(texViewGradient);
|
||||||
texViewGradient = context.createTextureView(texGradient);
|
texViewGradient = context.createTextureView(texGradient);
|
||||||
|
@ -233,8 +241,8 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_
|
||||||
if (fill->spread() == FillSpread::Repeat) sampler = context.samplerLinearRepeat;
|
if (fill->spread() == FillSpread::Repeat) sampler = context.samplerLinearRepeat;
|
||||||
// update bind group
|
// update bind group
|
||||||
context.pipelines->layouts.releaseBindGroup(bindGroupGradient);
|
context.pipelines->layouts.releaseBindGroup(bindGroupGradient);
|
||||||
bindGroupGradient = context.pipelines->layouts.createBindGroupTexSampledBuff1Un(
|
bindGroupGradient = context.pipelines->layouts.createBindGroupTexSampledBuff2Un(
|
||||||
sampler, texViewGradient, bufferGroupGradient);
|
sampler, texViewGradient, bufferGroupGradient, bufferGroupTransfromGrad);
|
||||||
}
|
}
|
||||||
skip = false;
|
skip = false;
|
||||||
} else if ((flags & (RenderUpdateFlag::Color)) && !fill) {
|
} else if ((flags & (RenderUpdateFlag::Color)) && !fill) {
|
||||||
|
@ -256,6 +264,7 @@ void WgRenderSettings::release(WgContext& context)
|
||||||
context.pipelines->layouts.releaseBindGroup(bindGroupGradient);
|
context.pipelines->layouts.releaseBindGroup(bindGroupGradient);
|
||||||
context.releaseBuffer(bufferGroupSolid);
|
context.releaseBuffer(bufferGroupSolid);
|
||||||
context.releaseBuffer(bufferGroupGradient);
|
context.releaseBuffer(bufferGroupGradient);
|
||||||
|
context.releaseBuffer(bufferGroupTransfromGrad);
|
||||||
context.releaseTexture(texGradient);
|
context.releaseTexture(texGradient);
|
||||||
context.releaseTextureView(texViewGradient);
|
context.releaseTextureView(texViewGradient);
|
||||||
};
|
};
|
||||||
|
|
|
@ -82,6 +82,7 @@ struct WgRenderSettings
|
||||||
WGPUTexture texGradient{};
|
WGPUTexture texGradient{};
|
||||||
WGPUTextureView texViewGradient{};
|
WGPUTextureView texViewGradient{};
|
||||||
WGPUBuffer bufferGroupGradient{};
|
WGPUBuffer bufferGroupGradient{};
|
||||||
|
WGPUBuffer bufferGroupTransfromGrad{};
|
||||||
WGPUBindGroup bindGroupGradient{};
|
WGPUBindGroup bindGroupGradient{};
|
||||||
WgRenderSettingsType fillType{};
|
WgRenderSettingsType fillType{};
|
||||||
WgRenderRasterType rasterType{};
|
WgRenderRasterType rasterType{};
|
||||||
|
|
|
@ -84,7 +84,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) vScreenCoord : vec2f };
|
struct VertexOutput { @builtin(position) position : vec4f, @location(0) vScreenCoord : vec4f };
|
||||||
|
|
||||||
// uniforms
|
// uniforms
|
||||||
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
@group(0) @binding(0) var<uniform> uViewMat : mat4x4f;
|
||||||
|
@ -93,18 +93,19 @@ struct VertexOutput { @builtin(position) position : vec4f, @location(0) vScreenC
|
||||||
@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 : vec4f;
|
||||||
|
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_main(in: VertexInput) -> VertexOutput {
|
fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0);
|
out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0);
|
||||||
out.vScreenCoord = in.position.xy;
|
out.vScreenCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
||||||
let pos = in.vScreenCoord;
|
let pos = in.vScreenCoord.xy;
|
||||||
let st = uSettingGrad.xy;
|
let st = uSettingGrad.xy;
|
||||||
let ed = uSettingGrad.zw;
|
let ed = uSettingGrad.zw;
|
||||||
let ba = ed - st;
|
let ba = ed - st;
|
||||||
|
@ -121,7 +122,7 @@ 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) vScreenCoord : vec2f };
|
struct VertexOutput { @builtin(position) position : vec4f, @location(0) vScreenCoord : 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;
|
||||||
|
@ -129,18 +130,19 @@ struct VertexOutput { @builtin(position) position : vec4f, @location(0) vScreenC
|
||||||
@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 : vec4f;
|
||||||
|
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_main(in: VertexInput) -> VertexOutput {
|
fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0);
|
out.position = uViewMat * uModelMat * vec4f(in.position.xy, 0.0, 1.0);
|
||||||
out.vScreenCoord = in.position.xy;
|
out.vScreenCoord = uTransformGrad * vec4f(in.position.xy, 0.0, 1.0);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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.vScreenCoord) / uSettingGrad.r;
|
let t: f32 = distance(uSettingGrad.zw, in.vScreenCoord.xy) / uSettingGrad.r;
|
||||||
let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(t, 0.5));
|
let Sc = textureSample(uTextureGrad, uSamplerGrad, vec2f(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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue