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)
|
||||
{
|
||||
const WGPUBindGroupEntry bindGroupEntrys[] = {
|
||||
|
@ -164,6 +177,18 @@ void WgBindGroupLayouts::initialize(WgContext& context)
|
|||
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
|
||||
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
|
||||
{ .binding = 0, .visibility = visibility_frag, .storageTexture = storageTextureWO }
|
||||
|
|
|
@ -31,6 +31,7 @@ private:
|
|||
public:
|
||||
WGPUBindGroupLayout layoutTexSampled{};
|
||||
WGPUBindGroupLayout layoutTexSampledBuff1Un{};
|
||||
WGPUBindGroupLayout layoutTexSampledBuff2Un{};
|
||||
WGPUBindGroupLayout layoutTexStrorage1WO{};
|
||||
WGPUBindGroupLayout layoutTexStrorage1RO{};
|
||||
WGPUBindGroupLayout layoutTexStrorage2RO{};
|
||||
|
@ -41,6 +42,7 @@ public:
|
|||
public:
|
||||
WGPUBindGroup createBindGroupTexSampled(WGPUSampler sampler, WGPUTextureView texView);
|
||||
WGPUBindGroup createBindGroupTexSampledBuff1Un(WGPUSampler sampler, WGPUTextureView texView, WGPUBuffer buff);
|
||||
WGPUBindGroup createBindGroupTexSampledBuff2Un(WGPUSampler sampler, WGPUTextureView texView, WGPUBuffer buff0, WGPUBuffer buff1);
|
||||
WGPUBindGroup createBindGroupStrorage1WO(WGPUTextureView texView);
|
||||
WGPUBindGroup createBindGroupStrorage1RO(WGPUTextureView texView);
|
||||
WGPUBindGroup createBindGroupStrorage2RO(WGPUTextureView texView0, WGPUTextureView texView1);
|
||||
|
|
|
@ -176,7 +176,7 @@ void WgPipelines::initialize(WgContext& context)
|
|||
const WGPUBindGroupLayout bindGroupLayoutsGradient[] = {
|
||||
layouts.layoutBuffer1Un,
|
||||
layouts.layoutBuffer2Un,
|
||||
layouts.layoutTexSampledBuff1Un
|
||||
layouts.layoutTexSampledBuff2Un
|
||||
};
|
||||
const WGPUBindGroupLayout bindGroupLayoutsImage[] = {
|
||||
layouts.layoutBuffer1Un,
|
||||
|
|
|
@ -212,6 +212,13 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_
|
|||
// setup fill properties
|
||||
if ((flags & (RenderUpdateFlag::Gradient)) && fill) {
|
||||
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;
|
||||
if (fill->type() == Type::LinearGradient) {
|
||||
gradient.update((LinearGradient*)fill);
|
||||
|
@ -222,8 +229,9 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_
|
|||
}
|
||||
// update gpu assets
|
||||
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);
|
||||
if (bufferGradientSettingsChanged || textureGradientChanged) {
|
||||
if (bufferGradientSettingsChanged || textureGradientChanged || bufferGradientTransformChanged) {
|
||||
// update texture view
|
||||
context.releaseTextureView(texViewGradient);
|
||||
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;
|
||||
// update bind group
|
||||
context.pipelines->layouts.releaseBindGroup(bindGroupGradient);
|
||||
bindGroupGradient = context.pipelines->layouts.createBindGroupTexSampledBuff1Un(
|
||||
sampler, texViewGradient, bufferGroupGradient);
|
||||
bindGroupGradient = context.pipelines->layouts.createBindGroupTexSampledBuff2Un(
|
||||
sampler, texViewGradient, bufferGroupGradient, bufferGroupTransfromGrad);
|
||||
}
|
||||
skip = false;
|
||||
} else if ((flags & (RenderUpdateFlag::Color)) && !fill) {
|
||||
|
@ -256,6 +264,7 @@ void WgRenderSettings::release(WgContext& context)
|
|||
context.pipelines->layouts.releaseBindGroup(bindGroupGradient);
|
||||
context.releaseBuffer(bufferGroupSolid);
|
||||
context.releaseBuffer(bufferGroupGradient);
|
||||
context.releaseBuffer(bufferGroupTransfromGrad);
|
||||
context.releaseTexture(texGradient);
|
||||
context.releaseTextureView(texViewGradient);
|
||||
};
|
||||
|
|
|
@ -82,6 +82,7 @@ struct WgRenderSettings
|
|||
WGPUTexture texGradient{};
|
||||
WGPUTextureView texViewGradient{};
|
||||
WGPUBuffer bufferGroupGradient{};
|
||||
WGPUBuffer bufferGroupTransfromGrad{};
|
||||
WGPUBindGroup bindGroupGradient{};
|
||||
WgRenderSettingsType fillType{};
|
||||
WgRenderRasterType rasterType{};
|
||||
|
|
|
@ -84,7 +84,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
|||
|
||||
const char* cShaderSrc_Linear = R"(
|
||||
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
|
||||
@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(1) var uTextureGrad : texture_2d<f32>;
|
||||
@group(2) @binding(2) var<uniform> uSettingGrad : vec4f;
|
||||
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
||||
|
||||
@vertex
|
||||
fn vs_main(in: VertexInput) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
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;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
||||
let pos = in.vScreenCoord;
|
||||
let pos = in.vScreenCoord.xy;
|
||||
let st = uSettingGrad.xy;
|
||||
let ed = uSettingGrad.zw;
|
||||
let ba = ed - st;
|
||||
|
@ -121,7 +122,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
|||
|
||||
const char* cShaderSrc_Radial = R"(
|
||||
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(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(1) var uTextureGrad : texture_2d<f32>;
|
||||
@group(2) @binding(2) var<uniform> uSettingGrad : vec4f;
|
||||
@group(2) @binding(3) var<uniform> uTransformGrad : mat4x4f;
|
||||
|
||||
@vertex
|
||||
fn vs_main(in: VertexInput) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
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;
|
||||
}
|
||||
|
||||
@fragment
|
||||
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 So = uBlendSettings.a;
|
||||
return vec4f(Sc.rgb * Sc.a * So, Sc.a * So);
|
||||
|
|
Loading…
Add table
Reference in a new issue