gpt4 book ai didi

c++ - 片段着色器莫名其妙的行为

转载 作者:行者123 更新时间:2023-11-28 03:24:12 25 4
gpt4 key购买 nike

我编写了一个 C++ 程序,我在其中绘制茶壶并应用光照。它本身很简单,但我也使用着色器。简单 我是 GLSL 的新手 我只是尝试了一个简单的片段着色器,但是屏幕输出是莫名其妙的。

在这个文件中,我在 init 方法中初始化了 glew,我还编译了顶点和片段着色器。它们位于“vertex_shader”和“fragment_shader”文件中。

您可能不认识的是光和 Material 。它们只是一些包含有关灯光的所有信息的结构。我已经测试了这些结构,所以我确信它能按预期工作。当我声明 material=BlackPlastic 时,我只是将其设置为使用 define 指令定义的默认值。如果您认为存在问题,我也可以发布此代码。

#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <fstream>
#include <vector>
#include "utility.hpp"

#define MAX_DIM 1000

GLfloat width=600, height=800;
GLuint vertex_shader, fragment_shader;
GLuint program;
const char* vertex_shader_filename= "vertex_shader";
const char* fragment_shader_filename= "fragment_shader";
Light light;
Material material;

void init()
{
// Inizializzazione di GLEW
glewInit();
if(GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)
{
cout << "Supporto GLSL" << endl;
}

// Lettura e compilazione del vertex shader
GLchar* buffer= new GLchar[MAX_DIM];
ifstream stream;
streamsize count;
stream.open(vertex_shader_filename);
stream.read(buffer,MAX_DIM);
count= stream.gcount();
stream.close();
vertex_shader= glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, (const GLchar**)&buffer, &count);
glCompileShader(vertex_shader);

// Lettura, inizializzazione ed esecuzione del fragment shader
stream.open(fragment_shader_filename);
stream.read(buffer,MAX_DIM);
count= stream.gcount();
stream.close();
fragment_shader= glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, (const GLchar**)&buffer, &count);
glCompileShader(fragment_shader);
delete[] buffer;

// Creazione del programma

program= glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glUseProgram(program);

// Inizializzazione materiale e luce
material= BlackPlastic;
light= {vector<GLfloat>{-2,2,2,1} ,vector<GLfloat>{1,1,1,1},vector<GLfloat>{1,1,1,1},vector<GLfloat>{1,1,1,1} };
}

void display()
{
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,width/height,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,-100,0,0,0,0,1,0);

// Illuminazione
glShadeModel(GL_SMOOTH);
material.apply(); // This just causes glMaterialfv to be called for the ambient, diffuse, specular and shininess values.
light.apply(); // This just causes glLightfv to be called for the ambient, diffuse and specular values
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);

// Rendering
glClearColor(0.8,0.8,0.8,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSolidTeapot(10);
glutSwapBuffers();
}

void reshape(int w, int h)
{
width=w;
height=h;
glutPostRedisplay();
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
init();
glutMainLoop();
return 0;
}

我不认为顶点着色器导致任何问题,它只是正确地分配颜色和计算位置。片段着色器显然也是正确的,这是唯一执行的指令:

gl_FragColor = gl_Color;

如果我这样做,我只会看到一个白色的茶壶。相反,如果我将此值更改为任何颜色:

gl_FragColor = vec4{0,0,1,1};

我得到了正确颜色的茶壶:黑色塑料。而且不知道为什么,我这里没有应用光照,我应该计算一下。

我准确地说,我执行了相同的相同程序但没有应用着色器,并且我得到了正确颜色的茶壶。

最佳答案

首先,您将固定功能管道与“较新的东西”混合在一起。这是一个非常糟糕的做法,因为它可能会导致很多问题,因为您真的不知道后台发生了什么。

如果你想用漫反射着色器获得真实的光照,你必须自己计算漫反射颜色。这是很久以前我最后一次使用 ffp 所以我搜索了一些使用它的着色器:

顶点着色器

varying vec3 normal;
varying vec3 v;
varying vec3 lightvec;
void main(void)
{
normal = normalize(gl_NormalMatrix * gl_Normal);
v = vec3(gl_ModelViewMatrix * gl_Vertex);
lightvec = normalize(gl_LightSource[0].position.xyz - v);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

片段着色器

varying vec3 normal;
varying vec3 v;
varying vec3 lightvec;

void main(void)
{
vec3 Eye = normalize(-v);
vec3 Reflected = normalize( reflect( -lightvec, normal ));
vec4 IAmbient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;
vec4 IDiffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * max(dot(normal, lightvec), 0.0);
vec4 ISpecular = gl_LightSource[0].specular * gl_FrontMaterial.specular * pow(max(dot(Reflected, Eye), 0.0), gl_FrontMaterial.shininess);
gl_FragColor = gl_FrontLightModelProduct.sceneColor + IAmbient + IDiffuse + ISpecular;
}

关于c++ - 片段着色器莫名其妙的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14573079/

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