优化线宽度

This commit is contained in:
锦恢 2024-08-25 22:43:08 +08:00
parent 7ff8576bc9
commit 60a370413b
5 changed files with 197 additions and 14 deletions

View File

@ -1,6 +1,6 @@
<mxfile host="65bd71144e"> <mxfile host="65bd71144e">
<diagram id="fareUikBvdjO0hJmng89" name="makeBitVertex 原理图"> <diagram id="fareUikBvdjO0hJmng89" name="makeBitVertex 原理图">
<mxGraphModel dx="1234" dy="929" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0"> <mxGraphModel dx="1353" dy="651" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
<root> <root>
<mxCell id="0"/> <mxCell id="0"/>
<mxCell id="1" parent="0"/> <mxCell id="1" parent="0"/>
@ -838,4 +838,162 @@
</root> </root>
</mxGraphModel> </mxGraphModel>
</diagram> </diagram>
<diagram id="GKIpZteT5tedDBQSRgQ5" name="第 3 页">
<mxGraphModel dx="794" dy="-626" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="JvdDJyfJznzZnJYvxX4_-1" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="850" y="1250" as="sourcePoint"/>
<mxPoint x="650" y="1250" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-2" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="670" y="1470" as="sourcePoint"/>
<mxPoint x="880" y="1350" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-3" value="\[p_0\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
<mxGeometry x="640" y="1540" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-5" value="\[p_1\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
<mxGeometry x="1080" y="1250" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-6" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1030" y="1400" as="sourcePoint"/>
<mxPoint x="880" y="1320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-7" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1330" y="1310" as="sourcePoint"/>
<mxPoint x="1170" y="1310" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-8" value="\[p_2\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
<mxGeometry x="1140" y="1280" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-9" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="880" y="1290" as="sourcePoint"/>
<mxPoint x="670" y="1470" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-10" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="669.58" y="1470" as="sourcePoint"/>
<mxPoint x="669.58" y="1510.0000000000002" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-11" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="880" y="1350" as="sourcePoint"/>
<mxPoint x="880" y="1290" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-12" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="670" y="1510" as="sourcePoint"/>
<mxPoint x="880" y="1350" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-13" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1130" y="1430" as="sourcePoint"/>
<mxPoint x="1130" y="1310" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-14" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1130" y="1310" as="sourcePoint"/>
<mxPoint x="1170" y="1270" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-15" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1210" y="1470" as="sourcePoint"/>
<mxPoint x="1210" y="1350" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-16" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1330" y="1350" as="sourcePoint"/>
<mxPoint x="1210" y="1350" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-17" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1330" y="1270" as="sourcePoint"/>
<mxPoint x="1164" y="1270" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-18" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1330" y="1350" as="sourcePoint"/>
<mxPoint x="1330" y="1270" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-19" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1210" y="1470" as="sourcePoint"/>
<mxPoint x="1130" y="1430" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-20" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1210" y="1350" as="sourcePoint"/>
<mxPoint x="1130" y="1430" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-21" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1210" y="1350" as="sourcePoint"/>
<mxPoint x="1130" y="1310" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-22" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1210" y="1350" as="sourcePoint"/>
<mxPoint x="1170" y="1270" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-23" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1210" y="1350" as="sourcePoint"/>
<mxPoint x="1330" y="1270" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-25" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="670" y="1490" as="sourcePoint"/>
<mxPoint x="880" y="1320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-26" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="570" y="1450" as="sourcePoint"/>
<mxPoint x="650" y="1450" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-27" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="570" y="1530" as="sourcePoint"/>
<mxPoint x="650" y="1530" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-28" value="" style="endArrow=classic;startArrow=classic;html=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="610" y="1530" as="sourcePoint"/>
<mxPoint x="610" y="1450" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="JvdDJyfJznzZnJYvxX4_-29" value="\[w&lt;br style=&quot;font-size: 18px;&quot;&gt;\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" vertex="1" parent="1">
<mxGeometry x="550" y="1460" width="50" height="60" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile> </mxfile>

View File

@ -30,6 +30,7 @@ class ShaderMaker {
const colorsLength = gl_Colors_template.length << 1; const colorsLength = gl_Colors_template.length << 1;
const vertexShader = new ShaderMaker('VERTEX_SHADER', `#version 300 es const vertexShader = new ShaderMaker('VERTEX_SHADER', `#version 300 es
precision mediump float;
in ivec2 pos; in ivec2 pos;
in ivec3 control; in ivec3 control;
out vec4 v_color; out vec4 v_color;
@ -50,8 +51,8 @@ void main() {
float posY = float(pos.y) / posYFactor; float posY = float(pos.y) / posYFactor;
// 偏移包括三部分:用户滚动时发生的全局位移、为了设置线宽发生的位移、与 scale 无关的额外位移 // 偏移包括三部分:用户滚动时发生的全局位移、为了设置线宽发生的位移、与 scale 无关的额外位移
float offsetX = offset.x + float(ws.x) + float(shift.x); float offsetX = offset.x + ws.x + shift.x;
float offsetY = offset.y + float(ws.y) + float(shift.y); float offsetY = offset.y + ws.y + shift.y;
gl_Position = vec4( gl_Position = vec4(
posX * scale.x + offsetX, posX * scale.x + offsetX,

View File

@ -109,6 +109,7 @@ const gl_Shifts_for_bar = new Float32Array([
const lineWidth = 0.004 * 3800 / screenWidthPixel; // 不能写为 0.0045 这样会因为插值造成不同线段的宽度不一致的问题 const lineWidth = 0.004 * 3800 / screenWidthPixel; // 不能写为 0.0045 这样会因为插值造成不同线段的宽度不一致的问题
const widthShift = 0.002; const widthShift = 0.002;
const gl_WidthShifts = new Float32Array([ const gl_WidthShifts = new Float32Array([
0, widthShift, // 0 0, widthShift, // 0
- widthShift, widthShift, // 1 - widthShift, widthShift, // 1
@ -121,6 +122,23 @@ const gl_WidthShifts = new Float32Array([
]); ]);
// TODO: 之前的波形的竖向线条的宽度在缩放式有时会变窄。一直不一致,不知道是为什么,
// 我认为是glsl内部精度损失的问题稍微把横向的宽度拉大后可以大幅度改善
// 如果未来有时间,搞清楚这里是怎么回事。复现方法:把 wsMdFactor 修改为 1
const wsMdFactorX = 1.2;
const wsMdFactorY = 1.3;
const ladderAnalog_GL_WidthShifts = new Float32Array([
0, widthShift * wsMdFactorY, // 0
- widthShift * wsMdFactorX, widthShift * wsMdFactorY, // 1
- widthShift * wsMdFactorX, 0, // 2
- widthShift * wsMdFactorX, - widthShift * wsMdFactorY, // 3
0, - widthShift * wsMdFactorY, // 4
widthShift * wsMdFactorX, - widthShift * wsMdFactorY, // 5
widthShift * wsMdFactorX, 0, // 6
widthShift * wsMdFactorX, widthShift * wsMdFactorY // 7
]);
function prettyPrint(array) { function prettyPrint(array) {
const stack = []; const stack = [];
for (const num of array) { for (const num of array) {
@ -148,5 +166,6 @@ export {
gl_Shifts_for_bar, gl_Shifts_for_bar,
barShift, barShift,
glslInputLength, glslInputLength,
prettyPrint prettyPrint,
ladderAnalog_GL_WidthShifts
}; };

View File

@ -1,6 +1,6 @@
import { globalSetting, globalStyle } from '../global'; import { globalSetting, globalStyle } from '../global';
import { gl_Colors, gl_Shifts, gl_Shifts_for_bar, gl_WidthShifts, barShift, getRatio, screenHeightPixel, maskColorIndexOffset, posYFactor, glslInputLength, prettyPrint } from './render-utils.js'; import { gl_Colors, gl_Shifts, gl_Shifts_for_bar, gl_WidthShifts, barShift, getRatio, screenHeightPixel, maskColorIndexOffset, posYFactor, glslInputLength, prettyPrint, ladderAnalog_GL_WidthShifts } from './render-utils.js';
import { vertexShader, fragmentShader } from './render-shader.js'; import { vertexShader, fragmentShader } from './render-shader.js';
import { renderAsBit, renderAsCommonDigital, renderAsLadderAnalog, renderAsLineAnalog } from './toolbar/renderModal'; import { renderAsBit, renderAsCommonDigital, renderAsLadderAnalog, renderAsLineAnalog } from './toolbar/renderModal';
@ -304,7 +304,6 @@ class WebGL2WaveRender {
const webglLocation = this.webglLocation; const webglLocation = this.webglLocation;
const gl = webglLocation.gl; const gl = webglLocation.gl;
gl.uniform4fv(webglLocation.colors, gl_Colors); gl.uniform4fv(webglLocation.colors, gl_Colors);
gl.uniform2fv(webglLocation.widthShifts, gl_WidthShifts);
gl.uniform2fv(webglLocation.shifts, gl_Shifts); gl.uniform2fv(webglLocation.shifts, gl_Shifts);
gl.uniform1f(webglLocation.posYFactor, posYFactor); gl.uniform1f(webglLocation.posYFactor, posYFactor);
} }
@ -411,8 +410,13 @@ class WebGL2WaveRender {
const yDuty = cubicBezierAnimation(animationDelta, pstate.oldYDuty, pstate.yDuty); const yDuty = cubicBezierAnimation(animationDelta, pstate.oldYDuty, pstate.yDuty);
// 设置 glsl 变量 // 设置 glsl 变量
const scaleX = 2 * xScale / canvasWidth; let scaleX = 2 * xScale / canvasWidth;
const scaleY = yStep * yDuty / canvasHeight; let scaleY = yStep * yDuty / canvasHeight;
// console.log(scaleX);
// // scaleX 保留6位有效数字
// scaleX = parseInt(scaleX * 10000) / 10000;
// console.log(scaleX);
gl.uniform2f(webglLocation.scale, scaleX, scaleY); gl.uniform2f(webglLocation.scale, scaleX, scaleY);
// 设置 webgl 和 canvas 大小位置一致 // 设置 webgl 和 canvas 大小位置一致
@ -471,6 +475,8 @@ class WebGL2WaveRender {
if (signal.size === 1) { if (signal.size === 1) {
// 如果是 bit // 如果是 bit
gl.uniform2fv(webglLocation.widthShifts, gl_WidthShifts);
gl.uniform2fv(webglLocation.shifts, gl_Shifts); gl.uniform2fv(webglLocation.shifts, gl_Shifts);
gl.bindVertexArray(signalItem.lineVao); gl.bindVertexArray(signalItem.lineVao);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / glslInputLength); gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / glslInputLength);
@ -481,7 +487,8 @@ class WebGL2WaveRender {
// 如果是 vec根据设定的渲染模式和进行设置 // 如果是 vec根据设定的渲染模式和进行设置
const vecRenderModal = _this.getVecRenderModal(globalLookup, signal.link); const vecRenderModal = _this.getVecRenderModal(globalLookup, signal.link);
if (vecRenderModal === 0) { if (vecRenderModal === 0) {
// 普通数字渲染模式 // 普通数字渲染模式、
gl.uniform2fv(webglLocation.widthShifts, gl_WidthShifts);
gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar); gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar);
gl.bindVertexArray(signalItem.lineVao); gl.bindVertexArray(signalItem.lineVao);
gl.drawArrays(gl.TRIANGLES, 0, lineVertices.length / glslInputLength); gl.drawArrays(gl.TRIANGLES, 0, lineVertices.length / glslInputLength);
@ -490,6 +497,7 @@ class WebGL2WaveRender {
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength); gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength);
} else if (vecRenderModal === 1) { } else if (vecRenderModal === 1) {
// 梯形渲染模式 // 梯形渲染模式
gl.uniform2fv(webglLocation.widthShifts, ladderAnalog_GL_WidthShifts);
gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar); gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar);
gl.bindVertexArray(signalItem.lineVao); gl.bindVertexArray(signalItem.lineVao);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / glslInputLength); gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / glslInputLength);
@ -498,6 +506,7 @@ class WebGL2WaveRender {
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength); gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / glslInputLength);
} else { } else {
// 折线渲染模式 // 折线渲染模式
gl.uniform2fv(webglLocation.widthShifts, gl_WidthShifts);
gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar); gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar);
gl.bindVertexArray(signalItem.lineVao); gl.bindVertexArray(signalItem.lineVao);
gl.drawArrays(gl.TRIANGLES, 0, lineVertices.length / glslInputLength); gl.drawArrays(gl.TRIANGLES, 0, lineVertices.length / glslInputLength);

View File

@ -530,10 +530,6 @@ export function renderAsLadderAnalog(lookup, link, wave, time) {
const wsIndex = makeWidthShiftIndexByPoints(p0, p1, p2); const wsIndex = makeWidthShiftIndexByPoints(p0, p1, p2);
if (wsIndex === undefined) {
console.log(p0, p1, p2);
}
lineVertices.push( lineVertices.push(
// uvec2 pos; uvec3 control; // uvec2 pos; uvec3 control;
p1.x, p1.y * posYFactor, 0, wsIndex, p1.color, p1.x, p1.y * posYFactor, 0, wsIndex, p1.color,
@ -606,5 +602,5 @@ export function renderAsLineAnalog(lookup, link, wave, time) {
const lineVertices = []; const lineVertices = [];
const maskVertices = []; const maskVertices = [];
} }