webgl - 在片段着色器中绘制椭圆曲线
问题描述
我想要 webgl 中的平滑曲线,所以我尝试在顶点着色器中绘制一个矩形,并将位置发送到片段着色器中的标准化大小和大小参数,这是正方形的实际大小
in vec2 Position;
in vec2 Size;
out vec2 vPosition;
out vec2 vSize;
void main() {
vSize = Size;
vPosition = Position
gl_Position = Position * Size
}
当 size = [width, height] of square 并且对于每个顶点都相等时,position = [
-1 , -1 ,
-1 , 1 ,
1 , -1 ,
1 , 1 ,
]
因此我的矩形将在 [2 * width , 2 * height] 中绘制,但我可以在片段着色器中使用 2 * 2 正方形进行几何操作,即归一化,但是当我想用厚度参数制作空心圆时,我在片段着色器中绘制椭圆(或具有这种大小的圆)时遇到问题,它在水平方向的厚度与垂直方向的厚度不同,我知道这是因为我' m 对水平和垂直方向(2,2)使用相同的尺寸,但在显示时它们是不同的,这是导致您看到的所有厚度都不相同的问题。
我想要一个几何公式来计算每个方向的厚度,然后我可以画一个空心椭圆。
提前致谢。抱歉英语不好
解决方案
如果你在片段着色器中投入大量的数学计算,它会很慢。诀窍可以是使用视觉上可以接受的近似值。
您的问题是垂直轴和水平轴上的厚度不同。如果当前点的半径大于 1 且小于radiusMin ,您需要丢弃片段。让uniWidth和uniHeight成为矩形的大小。* 当y为空时,在水平轴上,radiusMin = 1.0 - BORDER / uniWidth。* 当x为空时,在垂直轴上,radiusMin = 1.0 - BORDER / uniHeight。
诀窍是使用mix()函数在这两个半径之间进行插值。看看我下面的例子,让你相信结果还不错。
这是进行此类计算的片段着色器:
precision mediump float;
uniform float uniWidth;
uniform float uniHeight;
varying vec2 varCoords;
const float BORDER = 32.0;
void main() {
float x = varCoords.x;
float y = varCoords.y;
float radius = x * x + y * y;
if( radius > 1.0 ) discard;
radius = sqrt( radius );
float radiusH = 1.0 - BORDER / uniWidth;
float radiusV = 1.0 - BORDER / uniHeight;
float radiusAverage = (radiusH + radiusV) * 0.5;
float minRadius = 0.0;
x = abs( x );
y = abs( y );
if( x > y ) {
minRadius = mix( radiusH, radiusAverage, y / x );
}
else {
minRadius = mix( radiusV, radiusAverage, x / y );
}
if( radius < minRadius ) discard;
gl_FragColor = vec4(1, .5, 0, 1);
}
这是一个活生生的例子:https ://jsfiddle.net/7rh2eog1/5/
推荐阅读
- null - IE11 window.opener 访问其他站点后为空
- jenkins - 如何在 Jenkins 的 changeSet 中获取修订/提交 ID
- xcode - React Native - 多个目标
- mongodb - MongoDB索引一个可能不存在的字段
- postgresql - 时区从冬季更改为夏季 rails 根据新时区显示时间戳
- php - 如何从相关表中获取所有行,包括数据透视表中的列?
- jakarta-ee - 服务器崩溃和重启时的 CDI 事件观察器处理
- javascript - 使这个 dob 计算器工作的步骤是什么?JavaScript
- ef-core-2.1 - abp.io 项目模板中的多个 DbContext
- here-api - 如何为我的 getroute 请求获取 RouteId?