我刚刚完成了我的iOS应用的第一个版本Corebox,现在正在开发一些新功能。
其中一项新功能是对OpenGL渲染进行“小”调整,以强制某些对象永远不会被绘制为小于最小尺寸。需要此处理的所有对象都是使用GL_LINES绘制的简单2点线。
这个带注释的截图解释了我的追求。忽略灰线,我感兴趣的唯一对象是黄色较宽的线条。
我已经广泛搜索了这个,看起来我需要做的是使用顶点着色器改变线条的几何形状。我对GLSL和大多数着色器示例都很陌生,我可以找到应用光照和其他效果的例子,例如:GLSL Heroku Editor和KicksJS shader editor。
我当前的顶点着色器非常基本:
// GL_LINES vertex shader
uniform mat4 Projection;
uniform mat4 Modelview;
attribute vec4 Position;
attribute vec4 SourceColor;
varying vec4 DestinationColor;
void main(void) {
DestinationColor = SourceColor;
gl_Position = Projection * Modelview * Position;
}
我的片段着色器也是如此:
// GL_LINES fragment shader
varying lowp vec4 DestinationColor;
void main(void) {
gl_FragColor = DestinationColor;
}
我猜是什么需要:
警告和其他说明:
编辑:以下是实施mifortin建议的最终工作版
uniform mat4 Projection;
uniform mat4 Modelview;
uniform float MinimumHeight;
attribute vec4 Position;
attribute vec4 ObjectCenter;
attribute vec4 SourceColor;
varying vec4 DestinationColor;
void main(void) {
// screen-space position of this vertex
vec4 screenPosition = Projection * Modelview * Position;
// screen-space mid-point of the object this vertex belongs to
vec4 screenObjectCenter = Projection * Modelview * ObjectCenter;
// Z should be 0 by this time and the projective transform in w.
// scale so w = 1 (these two should be in screen-space)
vec2 newScreenPosition = screenPosition.xy / screenPosition.w;
vec2 newObjectCenter = screenObjectCenter.xy / screenObjectCenter.w;
float d = distance(newScreenPosition, newObjectCenter);
if (d < MinimumHeight && d > 0.0) {
// Direction of this object, this really only makes sense in the context
// of a line (eg: GL_LINES)
vec2 towards = normalize(newScreenPosition - newObjectCenter);
// Shift the center point then adjust the vertex position accordingly
// Basically this converts: *--x--* into *--------x--------*
newObjectCenter = newObjectCenter + towards * MinimumHeight;
screenPosition.xy = newObjectCenter.xy * screenPosition.w;
}
gl_Position = screenPosition;
DestinationColor = SourceColor;
}
答案 0 :(得分:2)
请注意,我没有测试代码,但它应该说明解决方案。
如果要使用着色器,请添加另一个作为线条中心位置的均匀vec4。然后你可以做类似的事情(注意中心可以在CPU上预先计算一次):
uniform float MIN; //Minimum size of blob on-screen
uniform vec4 center; //Center of the line / blob
...
vec4 screenPos = Projection * Modelview * Position;
vec4 center = Projection * Modelview * Position;
//Z should be 0 by this time and the projective transform in w.
//scale so w = 1 (these two should be in screen-space)
vec2 nScreenPos = screenPos.xy / screenPos.w;
vec2 nCenter = center.xy / center.w;
float d = distance(nScreenPos, nCenter);
if (d < MIN && d > 0)
{
vec2 towards = normalize(nScreenPos - nCenter);
nCenter = nCenter + towards * MIN;
screenPos.xy = nCenter.xy * screenPos.w;
}
gl_Position = screenPos;
在屏幕上找到顶点将被绘制的位置,然后从blob的中心拉伸它,以确保最小尺寸。
此示例适用于圆形对象。对于角点,您可以使MIN
成为属性,以便距离中心的距离在每个顶点的基础上变化。
如果您只想要更像盒子的东西,请分别检查x和y坐标的最小距离。
在CPU上,您可以在提交到GPU之前计算屏幕空间中的坐标并进行相应缩放。