Этот шейдер OpenGL "Single-pass wire frame shader" работал на моей старой машине с интегрированной графикой amd, но он не был моим новым ПК nvidea - PullRequest
0 голосов
/ 30 апреля 2020

Я создал этот шейдер из следующего урока по однопроходному рендерингу каркаса: 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);

А вот как я связываю атрибуцию вершин; java show

Шейдер прекрасно работал на моей старой интегрированной видеокарте amd. Но это не сделано на моем RTX 2060 супер. Версия Shader и Gl на старом: версия OpenGL: 4.5.13399 Контекст профиля совместимости 15.200.1062.1004 на новом: 4.6.0 NVIDIA 445.87

1 Ответ

0 голосов
/ 01 мая 2020

Прежде всего, я не знаю, что вызывает это, но я думаю, что это файлы модели.

Как я решил это, вместо предварительной обработки координат Bary centri c, я бы вычислил их или, скорее, назначил бы их в геометрическом шейдере, например, так:

    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);        
}

Вершинный шейдер только ничего не определяет в позициях иначе самое основное c.

Вот шейдер с полной геометрией, если он кому-нибудь нужен:

#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();

 }

Вот несколько картинок: wireframe Как Вы можете увидеть его работу с прозрачностью, которая выполняется с помощью: code

Вот статьи, на которые я смотрел: https://tchayen.github.io/wireframes-with-barycentric-coordinates/ http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/

И классная книга, которая мне очень помогла: https://people.inf.elte.hu/plisaai/pdf/David%20Wolff%20-%20OpenGL%204.0%20Shading%20Language%20Cookbook%20 (2) .pdf

На всякий случай вот шейдер Vertex:

#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);
}
...