render target blending, more sliders
This commit is contained in:
parent
997bfac193
commit
53cbbebdc7
49
font.js
49
font.js
@ -86,7 +86,7 @@ class FontRenderer {
|
|||||||
|
|
||||||
const configurationBuffer = device.createBuffer({
|
const configurationBuffer = device.createBuffer({
|
||||||
label: `configuration buffer ${i}`,
|
label: `configuration buffer ${i}`,
|
||||||
size: 4 * 4,
|
size: this.sliderArray.byteLength,
|
||||||
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ class FontRenderer {
|
|||||||
buffer: { type: "read-only-storage" }
|
buffer: { type: "read-only-storage" }
|
||||||
}, { // configuration
|
}, { // configuration
|
||||||
binding: 1,
|
binding: 1,
|
||||||
visibility: GPUShaderStage.VERTEX,
|
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
||||||
buffer: { type: "uniform" }
|
buffer: { type: "uniform" }
|
||||||
}]
|
}]
|
||||||
}),
|
}),
|
||||||
@ -210,6 +210,7 @@ class FontRenderer {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(canvasFormat);
|
||||||
this.renderPipeline = device.createRenderPipeline({
|
this.renderPipeline = device.createRenderPipeline({
|
||||||
label: `${label} pipeline`,
|
label: `${label} pipeline`,
|
||||||
layout: pipelineLayout,
|
layout: pipelineLayout,
|
||||||
@ -221,6 +222,17 @@ class FontRenderer {
|
|||||||
module: shaderModule,
|
module: shaderModule,
|
||||||
entryPoint: "fragmentMain",
|
entryPoint: "fragmentMain",
|
||||||
targets: [{
|
targets: [{
|
||||||
|
blend: {
|
||||||
|
color: {
|
||||||
|
dstFactor: "one-minus-src-alpha",
|
||||||
|
srcFactor: "src-alpha",
|
||||||
|
},
|
||||||
|
alpha: {
|
||||||
|
dstFactor: "one-minus-src-alpha",
|
||||||
|
srcFactor: "src-alpha",
|
||||||
|
},
|
||||||
|
operation: "add",
|
||||||
|
},
|
||||||
format: canvasFormat,
|
format: canvasFormat,
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
@ -229,11 +241,18 @@ class FontRenderer {
|
|||||||
},
|
},
|
||||||
depthStencil: {
|
depthStencil: {
|
||||||
depthWriteEnabled: true,
|
depthWriteEnabled: true,
|
||||||
depthCompare: "less",
|
depthCompare: "always",
|
||||||
format: "depth24plus",
|
format: "depth24plus",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// sliders
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
this.sliders = makeSliders();
|
||||||
|
this.sliderArray = new Float32Array(4 * 4);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// buffers
|
// buffers
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -252,13 +271,6 @@ class FontRenderer {
|
|||||||
resource: { buffer: viewUniformBuffer },
|
resource: { buffer: viewUniformBuffer },
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// sliders
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
this.sliders = makeSliders();
|
|
||||||
this.sliderArray = new Float32Array(4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update(device, frameNumber)
|
update(device, frameNumber)
|
||||||
@ -277,6 +289,19 @@ class FontRenderer {
|
|||||||
this.sliderArray[0] = configuration.scale;
|
this.sliderArray[0] = configuration.scale;
|
||||||
this.sliderArray[1] = configuration.translateX;
|
this.sliderArray[1] = configuration.translateX;
|
||||||
this.sliderArray[2] = configuration.translateY;
|
this.sliderArray[2] = configuration.translateY;
|
||||||
|
|
||||||
|
this.sliderArray[4] = configuration.distanceThreshold;
|
||||||
|
this.sliderArray[5] = configuration.distanceScale;
|
||||||
|
this.sliderArray[6] = configuration.distanceOffset;
|
||||||
|
|
||||||
|
this.sliderArray[8] = configuration.outlineThreshold;
|
||||||
|
this.sliderArray[9] = configuration.outlineScale;
|
||||||
|
this.sliderArray[10] = configuration.outlineOffset;
|
||||||
|
|
||||||
|
this.sliderArray[12] = configuration.colorMix;
|
||||||
|
this.sliderArray[13] = configuration.colorScale;
|
||||||
|
this.sliderArray[14] = configuration.colorOffset;
|
||||||
|
|
||||||
device.queue.writeBuffer(this.frames[frameNumber].configurationBuffer, 0,
|
device.queue.writeBuffer(this.frames[frameNumber].configurationBuffer, 0,
|
||||||
this.sliderArray);
|
this.sliderArray);
|
||||||
}
|
}
|
||||||
@ -289,7 +314,9 @@ class FontRenderer {
|
|||||||
renderPass.setBindGroup(1, this.perFontBindGroup);
|
renderPass.setBindGroup(1, this.perFontBindGroup);
|
||||||
renderPass.setBindGroup(2, this.frames[frameNumber].bindGroup);
|
renderPass.setBindGroup(2, this.frames[frameNumber].bindGroup);
|
||||||
|
|
||||||
renderPass.drawIndexed(6, this.instanceCount);
|
for (let i = 0; i < this.instanceCount; i++) {
|
||||||
|
renderPass.drawIndexed(6, 1, 0, 0, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
51
font.wgsl
51
font.wgsl
@ -10,6 +10,19 @@ struct Config {
|
|||||||
scale: f32,
|
scale: f32,
|
||||||
translateX: f32,
|
translateX: f32,
|
||||||
translateY: f32,
|
translateY: f32,
|
||||||
|
padding0: f32,
|
||||||
|
distanceThreshold: f32,
|
||||||
|
distanceScale: f32,
|
||||||
|
distanceOffset: f32,
|
||||||
|
padding1: f32,
|
||||||
|
outlineThreshold: f32,
|
||||||
|
outlineScale: f32,
|
||||||
|
outlineOffset: f32,
|
||||||
|
padding2: f32,
|
||||||
|
colorMix: f32,
|
||||||
|
colorScale: f32,
|
||||||
|
colorOffset: f32,
|
||||||
|
padding3: f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GlyphBuffer {
|
struct GlyphBuffer {
|
||||||
@ -70,21 +83,45 @@ fn vertexMain(input: VertexInput) -> VertexOutput
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn blend(dst: vec4f, src: vec4f, distance: f32, threshold: f32, scale: f32, offset: f32) -> vec4f
|
||||||
|
{
|
||||||
|
let scaledDistance = (distance - threshold) * scale + offset;
|
||||||
|
let alpha = clamp(scaledDistance, 0.0, 1.0);
|
||||||
|
let opacity = clamp(src.a * alpha - dst.a, 0.0, 1.0);
|
||||||
|
return opacity * src + (1.0 - opacity) * dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn palette(t: f32) -> vec4f
|
||||||
|
{
|
||||||
|
let a = vec3f(0.5, 0.5, 0.5);
|
||||||
|
let b = vec3f(0.5, 0.5, 0.5);
|
||||||
|
let c = vec3f(1.0, 1.0, 1.0);
|
||||||
|
let d = vec3f(0.00, 0.33, 0.67);
|
||||||
|
//0.263,0.416,0.557
|
||||||
|
let color = a + b * cos(6.28318 * (c * t + d));
|
||||||
|
return vec4f(color, 1);
|
||||||
|
}
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f
|
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f
|
||||||
{
|
{
|
||||||
var color = vec3f(input.texture.xy, 0);
|
|
||||||
|
|
||||||
let p = glyphBuffer[input.glyphIndex].texPosition;
|
let p = glyphBuffer[input.glyphIndex].texPosition;
|
||||||
let s = glyphBuffer[input.glyphIndex].texSize;
|
let s = glyphBuffer[input.glyphIndex].texSize;
|
||||||
|
|
||||||
let base = textureSample(fontTexture, linearSampler, input.texture * s + p);
|
let base = textureSample(fontTexture, linearSampler, input.texture * s + p);
|
||||||
|
let distance = base.x;
|
||||||
|
|
||||||
let t = f32(base.x > 0.5);
|
let insideColorW = vec4f(1, 1, 1, 1);
|
||||||
|
let insideColorP = palette(distance * config.colorScale + config.colorOffset);
|
||||||
|
let insideColor = mix(insideColorW, insideColorP, config.colorMix);
|
||||||
|
let outlineColor = vec4f(0, 0, 0, 1);
|
||||||
|
|
||||||
if (base.x < 0.5) {
|
var color = vec4f(0, 0, 0, 0);
|
||||||
discard;
|
color = blend(color, insideColor, distance,
|
||||||
}
|
config.distanceThreshold, config.distanceScale, config.distanceOffset);
|
||||||
|
|
||||||
return vec4f(t, t, t, 1);
|
color = blend(color, outlineColor, distance,
|
||||||
|
config.distanceThreshold - config.outlineThreshold,
|
||||||
|
config.outlineScale, config.outlineOffset);
|
||||||
|
return color;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,18 @@ function makeSliders()
|
|||||||
scale: new Slider("scale", 0.0, 0.05),
|
scale: new Slider("scale", 0.0, 0.05),
|
||||||
translateX: new Slider("translate x", -10, 10),
|
translateX: new Slider("translate x", -10, 10),
|
||||||
translateY: new Slider("translate y", -10, 10),
|
translateY: new Slider("translate y", -10, 10),
|
||||||
|
|
||||||
|
distanceThreshold: new Slider("dist. threshold", 0.0, 1.0),
|
||||||
|
distanceScale: new Slider("distance scale", 0.0, 200.0),
|
||||||
|
distanceOffset: new Slider("distance offset", -20.0, 20.0),
|
||||||
|
|
||||||
|
outlineThreshold: new Slider("outline threshold", 0.0, 1.0),
|
||||||
|
outlineScale: new Slider("outline scale", 0.0, 200.0),
|
||||||
|
outlineOffset: new Slider("outline offset", -20.0, 20.0),
|
||||||
|
|
||||||
|
colorMix: new Slider("color mix", 0.0, 1.0),
|
||||||
|
colorScale: new Slider("color scale", 0.0, 10.0),
|
||||||
|
colorOffset: new Slider("color offset", 0.0, 3.1415),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -41,13 +41,13 @@
|
|||||||
background: #eee;
|
background: #eee;
|
||||||
}
|
}
|
||||||
.control-main {
|
.control-main {
|
||||||
width: 310px;
|
width: 340px;
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
background: #444;
|
background: #444;
|
||||||
}
|
}
|
||||||
.label {
|
.label {
|
||||||
width: calc(30% - 0.3rem);
|
width: calc(35% - 0.3rem);
|
||||||
float: left;
|
float: left;
|
||||||
clear: left;
|
clear: left;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -55,7 +55,7 @@
|
|||||||
margin-top: 0.25rem;
|
margin-top: 0.25rem;
|
||||||
}
|
}
|
||||||
.value {
|
.value {
|
||||||
width: calc(70% - 0.2rem);
|
width: calc(65% - 0.2rem);
|
||||||
float: left;
|
float: left;
|
||||||
margin-top: 0.1rem;
|
margin-top: 0.1rem;
|
||||||
margin-right: 0.2rem;
|
margin-right: 0.2rem;
|
||||||
|
|||||||
1
index.js
1
index.js
@ -25,6 +25,7 @@ const canvasFormat = navigator.gpu.getPreferredCanvasFormat();
|
|||||||
context.configure({
|
context.configure({
|
||||||
device: device,
|
device: device,
|
||||||
format: canvasFormat,
|
format: canvasFormat,
|
||||||
|
alphaMode: 'premultiplied',
|
||||||
});
|
});
|
||||||
|
|
||||||
const encoder = device.createCommandEncoder();
|
const encoder = device.createCommandEncoder();
|
||||||
|
|||||||
@ -57,7 +57,7 @@ class Slider {
|
|||||||
localStorage.setItem(this.label, rawValue);
|
localStorage.setItem(this.label, rawValue);
|
||||||
}
|
}
|
||||||
if (this.high > 10) {
|
if (this.high > 10) {
|
||||||
this.span.innerHTML = value.toFixed(0);
|
this.span.innerHTML = value.toFixed(2);
|
||||||
} else {
|
} else {
|
||||||
this.span.innerHTML = value.toFixed(4);
|
this.span.innerHTML = value.toFixed(4);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,6 @@ extern "C" {
|
|||||||
|
|
||||||
void font_layout__draw(FontLayout * font_layout)
|
void font_layout__draw(FontLayout * font_layout)
|
||||||
{
|
{
|
||||||
font_layout->draw_string("asdf qwer");
|
font_layout->draw_string("hexagon grid");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user