java - 这个“单通道线框着色器”opengl 着色器在我的带有 AMD 集成显卡的旧机器上工作,但它不适用于我的新 nvidea pc
问题描述
我根据本教程创建了这个着色器单通道线框渲染:http ://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/
分段:
#version 450
layout (location = 0) out vec4 outColor;
in vec3 vBC;
const float lineWidth = 0.5;
const vec3 color = vec3(0.7, 0.7, 0.7);
float edgeFactor(){
vec3 d = fwidth(vBC);
vec3 a3 = smoothstep(vec3(0.0), d*1.5, vBC);
return min(min(a3.x, a3.y), a3.z);
}
void main(){
outColor = vec4(min(vec3(edgeFactor()), color), 1.0);
}
顶点:
#version 450
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 baryCentric;
out vec3 vBC;
uniform mat4 T_MVP;
void main() {
//texCoord0 = texCoord;
gl_Position = T_MVP * vec4(position, 1.0);
vBC = baryCentric;
}
这是渲染前的 gl 准备:
wir.bind();
wir.updateUniforms(super.getTransform(), mat, engine);
GL45.glEnable(GL45.GL_SAMPLE_ALPHA_TO_COVERAGE);
GL45.glEnable(GL45.GL_BLEND);
GL45.glBlendFunc(GL45.GL_SRC_ALPHA, GL45.GL_ONE_MINUS_SRC_ALPHA);
mesh.draw("baryCentric", GL15.GL_TRIANGLES);
这是我绑定顶点属性的方法;
着色器在我的旧 AMD 集成显卡上运行良好。但它在我的 rtx 2060 super 上没有。旧版本上的着色器和 Gl 版本:OpenGL 版本:4.5.13399 新版本上的兼容性配置文件上下文 15.200.1062.1004:4.6.0 NVIDIA 445.87
解决方案
首先我不知道是什么原因造成的,但我认为它是模型文件。
我是如何解决这个问题的,而不是预处理以巴里为中心的坐标,而是计算它们,或者像这样在几何着色器中分配它们:
vBC = vec3(1, 0, 0);
gl_Position = gl_in[0].gl_Position;
EmitVertex();
vBC = vec3(0, 1, 0);
gl_Position = gl_in[1].gl_Position;
EmitVertex();
vBC = vec3(0, 0, 1);
gl_Position = gl_in[2].gl_Position;
EmitVertex();
没有别的只是将它们传递给片段着色器,剩下的就交给它了:
#version 400
precision mediump float;
layout (location = 0) out vec4 outColor;
in vec3 vBC;
const float lineWidth = 0.5;
const vec3 lineColor = vec3(0.7, 0.7, 0.7);
float edgeFactor() {
vec3 d = fwidth(vBC);
vec3 f = step(d * lineWidth, vBC);
return min(min(f.x, f.y), f.z);
}
void main(){
outColor = vec4(255, 191, 0.0, (1.0-edgeFactor())*0.95);
}
顶点着色器只定义了最基本的位置。
如果有人需要,这里是完整的几何着色器:
#version 400
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
out vec3 vBC;
void main()
{
vBC = vec3(1, 0, 0);
gl_Position = gl_in[0].gl_Position;
EmitVertex();
vBC = vec3(0, 1, 0);
gl_Position = gl_in[1].gl_Position;
EmitVertex();
vBC = vec3(0, 0, 1);
gl_Position = gl_in[2].gl_Position;
EmitVertex();
}
这是一些图片: 正如您所看到的,它使用透明度完成了以下操作:
这是我看过的文章: https://tchayen.github.io/wireframes-with-barycentric-coordinates/ http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-重心坐标/
还有一本对我帮助很大的很酷的书: https ://people.inf.elte.hu/plisaai/pdf/David%20Wolff%20-%20OpenGL%204.0%20Shading%20Language%20Cookbook%20(2).pdf
以防万一这里是顶点着色器:
#version 400
precision mediump int;
precision mediump float;
layout (location = 0) in vec3 position;
uniform mat4 T_MVP;
void main() {
gl_Position = T_MVP * vec4(position, 1.0);
}
推荐阅读
- sql - 不能 GROUP BY 或 DISTINCT 我对 xml 路径的查询
- python - tkinter 中的窗口自动关闭
- gem5 - 优先读取优先于写入
- tensorflow - Keras LSTM 的维度问题
- apache-spark - VectorAssembler 强制数据进入驱动程序。我们怎样才能避免呢?
- eclipse - 我应该在 LiClipse 中注册哪些“可用软件站点”才能成功升级?
- flutter - 单击复选框或按钮时,如何检测是否按下了键?
- matlab - 图像中的平均像素(Matlab)
- r - 在 R 中使用 rjson 包读取 iso_3166_2.js
- python - 梯度下降图是如何工作的