有一个场景,在场景 obj 模型上。需要选择模型的多边形。
按下鼠标右键,然后围绕按下的点绘制一个矩形,在矩形的角上绘制选择性光线。您需要从模型中选择(涂上颜色)落入该区域的三角形。
我使用 LWJGL 和 JOML 库。我发现了这样的函数:unproject,它从屏幕坐标转换为世界坐标intersectRayPlane- 光线是否与多边形相交。
我制作了选择性光束(结果是 6 个平面)。现在有必要在这个截断的金字塔内的三角形上着色。你会如何建议这样做?告诉我不要告诉我几何,而是确切地告诉我如何在着色器中以编程方式完成它。给定:P矩阵,视图矩阵,Q=PV矩阵,模型M矩阵,平面顶点坐标(其中有8个origin(beam end坐标)和dir(不知道什么意思,用了unproject函数)) ,模型顶点坐标及其法线。
我找到了所有 6 个平截头体平面的abcd组件。接下来,我取一个点并测量到 6 个平截头体平面中的每一个平面的距离。如果距离为负,则该点不在截锥体内。下面是其中的着色器,很可能是一个错误:我传递给顶点着色器
vec4[6] planes - a b c d для 6 плоскостей.
out float[6] dis;- это расстояния, которые я передаю во фрагментный шейдер
#version 330
layout(location = 0) in vec3 vertexPos;
layout(location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoord;
out float[6] dis;
out vec3 normal_modelspace;
out vec3 vertex_modelspace;
out vec2 TexCoord;
out vec4 vertexColor;
uniform mat4 P;
uniform mat4 V;
uniform mat4 M;
uniform vec4[6] planes;
void main() {
TexCoord = texCoord;
vertex_modelspace = (M * vec4(vertexPos.xyz, 1.0)).xyz;
vertexColor = vec4(0.5f, 0.0f, 0.0f, 1.0f);
gl_Position = P * V * vec4(vertex_modelspace.xyz, 1.0);
normal_modelspace = (M * vec4(normal.xyz, 1.0)).xyz;
vec3 EyeDirection_cameraspace = vec3(0,0,0) - (V * M * vec4(vertexPos,1)).xyz;
for(int i = 0;i<6;i++){
float denom = sqrt(planes[0].x * planes[0].x + planes[0].y * planes[0].y + planes[0].z * planes[0].z);
dis[i] = float((planes[0].x * vertex_modelspace.x + planes[0].y * vertex_modelspace.y + planes[0].z * vertex_modelspace.z + planes[0].w) / denom);
}
}
片段着色器 在这里我检查循环中点的距离,如果找到负值,则应该用颜色覆盖它。
#version 330 core
in vec3 normal_modelspace;
in vec3 vertex_modelspace;
in vec2 TexCoord;
in vec4 vertexColor;
in float[6] dis;
out vec4 color;
uniform vec3 light_worldspace;
uniform sampler2D ourTexture;
void main() {
vec3 n = normalize(normal_modelspace);
vec3 l = normalize(light_worldspace - vertex_modelspace);
float cosTheta = clamp( dot( n, l), 0,1 );
float ambient = 0.05;
int i=0;
while(i<6 && dis[i]<=0){
i++;
}
if(i==6){
color = texture(ourTexture, TexCoord);
}
else
color = vertexColor;
}

一个简单的算法(没有优化)是这样的:
对于每个顶点,检查其相对于 6 个边界平面中的每一个的位置。检查代码(在Delphi中,但本质是一样的)
如果对于所有平面,多边形的所有点都在“内部”,那么多边形被认为是“在”截锥体“内部”。
PS如果有什么要澄清的 - 在评论中提问。