gpt4 book ai didi

ios - 在 iOS Open GL ES 中使用 GL_LINES 渲染对象的最小尺寸

转载 作者:行者123 更新时间:2023-11-29 11:15:48 25 4
gpt4 key购买 nike

我刚刚完成了我的 iOS 应用程序的第一个版本,Corebox ,现在正在开发一些新功能。

其中一项新功能是对 OpenGL 渲染进行“小”调整,以强制某些对象永远不会被绘制为小于最小尺寸。所有需要这种处理的对象都是使用 GL_LINES 绘制的简单的 2 点线。

这个带注释的屏幕截图解释了我所追求的。忽略灰色线条,我唯一想改变的对象是黄色较宽的线条。

Corebox OpenGL scene

我用谷歌搜索了很多,看来我需要做的是使用顶点着色器改变线条的几何形状。我对 GLSL 很陌生,我能找到的大多数着色器示例都涉及应用照明和其他效果,例如:GLSL Heroku EditorKicksJS 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;
}

我对需要什么的猜测:

  • 确定观察者(相机位置)和物体之间的距离
  • 根据物体的大小和与相机的距离,确定物体在屏幕上的大小
  • 如果对象太小,则调整其顶点,使其变得足够大,以便在屏幕上轻松看到。

注意事项和其他注意事项:

  1. 但是如果你缩小,这不会导致模型在屏幕上只是一团橙色吗?是的,这正是我想要的效果。

编辑:这是实现 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;
}

最佳答案

请注意,我没有测试代码,但它应该说明了解决方案。

如果你想使用着色器,在你的线的中心位置添加另一个统一的 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 的中心拉伸(stretch)它以确保最小尺寸。

此示例适用于圆形对象。对于拐角,您可以将 MIN 设置为一个属性,这样距中心的距离会因顶点而异。

如果您只是想要更像盒子的东西,请分别检查 x 和 y 坐标的最小距离。

在 CPU 上,您可以计算屏幕空间中的坐标并相应地缩放,然后再提交给 GPU。

关于ios - 在 iOS Open GL ES 中使用 GL_LINES 渲染对象的最小尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9471197/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com