- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将 Phong 照明添加到我已经加载了带有纹理的网格的场景中。这是我的网格加载类:
#define INVALID_OGL_VALUE 0xFFFFFFFF
#define INVALID_MATERIAL 0xFFFFFFFF
#define SAFE_DELETE(p) if (p) { delete p; p = NULL; }
Mesh::MeshEntry::MeshEntry()
{
VB = INVALID_OGL_VALUE;
IB = INVALID_OGL_VALUE;
NumIndices = 0;
MaterialIndex = INVALID_MATERIAL;
};
Mesh::MeshEntry::~MeshEntry()
{
if (VB != INVALID_OGL_VALUE)
{
glDeleteBuffers(1, &VB);
}
if (IB != INVALID_OGL_VALUE)
{
glDeleteBuffers(1, &IB);
}
}
void Mesh::MeshEntry::Init(const std::vector<Vertex>& Vertices,
const std::vector<unsigned int>& Indices)
{
NumIndices = Indices.size();
glGenBuffers(1, &VB);
glBindBuffer(GL_ARRAY_BUFFER, VB);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * Vertices.size(), &Vertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &IB);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IB);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * NumIndices, &Indices[0], GL_STATIC_DRAW);
}
Mesh::Mesh()
{
}
Mesh::~Mesh()
{
Clear();
}
void Mesh::Clear()
{
for (unsigned int i = 0 ; i < textures_cnt.size() ; i++) {
SAFE_DELETE(textures_cnt[i]);
}
}
/*Loads mesh
*@Filename - name of the .obj file
**********************************************************/
bool Mesh::LoadMesh(const std::string& Filename){
Assimp::Importer Importer;
bool rc = false;
//clear previous loaded mesh
Clear();
//read file content
const aiScene* oScene = Importer.ReadFile(Filename.c_str(), aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs );
if(oScene){
printf (" %i animations\n", oScene->mNumAnimations);
printf (" %i cameras\n", oScene->mNumCameras);
printf (" %i lights\n", oScene->mNumLights);
printf (" %i materials\n", oScene->mNumMaterials);
printf (" %i meshes\n", oScene->mNumMeshes);
printf (" %i textures\n", oScene->mNumTextures);
submeshes_cnt.resize(oScene->mNumMeshes);
textures_cnt.resize(oScene->mNumMaterials);
/*.........Initialize the meshes in the scene one by one...........*/
for (unsigned int i = 0 ; i < submeshes_cnt.size() ; i++) {
const aiMesh* paiMesh = oScene->mMeshes[i];
InitMesh(i, paiMesh);
}
// Extract the directory part from the file name
std::string::size_type SlashIndex = Filename.find_last_of("/");
std::string Dir;
if (SlashIndex == std::string::npos) {
Dir = ".";
}
else if (SlashIndex == 0) {
Dir = "/";
}
else {
Dir = Filename.substr(0, SlashIndex);
}
/*.................Initialization of meshes end....................*/
/*.............Initialize the materials.............................*/
for(unsigned int i = 0 ; i < oScene->mNumMaterials ; i++) {
const aiMaterial* pMaterial = oScene->mMaterials[i];
textures_cnt[i] = NULL;
if (pMaterial->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
aiString Path;
if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) {
std::string FullPath = Dir + "/" + Path.data;
textures_cnt[i] = new Texture(GL_TEXTURE_2D, FullPath.c_str());
if (!textures_cnt[i]->Load()) {
printf("Error loading texture '%s'\n", FullPath.c_str());
delete textures_cnt[i];
textures_cnt[i] = NULL;
rc = false;
}
else {
printf("Loaded texture '%s'\n", FullPath.c_str());
}
}
}
}
/*.................Initialization of materials end....................*/
}
else {
printf("Error parsing '%s': '%s'\n", Filename.c_str(), Importer.GetErrorString());
}
return rc;
}
void Mesh::InitMesh(unsigned int Index, const aiMesh* paiMesh)
{
submeshes_cnt[Index].MaterialIndex = paiMesh->mMaterialIndex;
std::vector<Vertex> Vertices;
std::vector<unsigned int> Indices;
const aiVector3D Zero3D(0.0f, 0.0f, 0.0f);
for (unsigned int i = 0 ; i < paiMesh->mNumVertices ; i++) {
const aiVector3D* pPos = &(paiMesh->mVertices[i]);
const aiVector3D* pNormal = &(paiMesh->mNormals[i]);
const aiVector3D* pTexCoord = paiMesh->HasTextureCoords(0) ? &(paiMesh->mTextureCoords[0][i]) : &Zero3D;
Vertex v(Vector3f(pPos->x, pPos->y, pPos->z),
Vector2f(pTexCoord->x, pTexCoord->y),
Vector3f(pNormal->x, pNormal->y, pNormal->z));
Vertices.push_back(v);
}
for (unsigned int i = 0 ; i < paiMesh->mNumFaces ; i++) {
const aiFace& Face = paiMesh->mFaces[i];
assert(Face.mNumIndices == 3);
Indices.push_back(Face.mIndices[0]);
Indices.push_back(Face.mIndices[1]);
Indices.push_back(Face.mIndices[2]);
}
submeshes_cnt[Index].Init(Vertices, Indices);
}
void Mesh::Render(){
//enable VAOs for vertices, normals, textures
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
for(unsigned int i = 0 ; i < submeshes_cnt.size() ; i++){
glBindBuffer(GL_ARRAY_BUFFER, submeshes_cnt[i].VB);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, submeshes_cnt[i].IB);
const unsigned int MaterialIndex = submeshes_cnt[i].MaterialIndex;
if (MaterialIndex < textures_cnt.size() && textures_cnt[MaterialIndex]) {
textures_cnt[MaterialIndex]->Bind(GL_TEXTURE0);
}
glDrawElements(GL_TRIANGLES, submeshes_cnt[i].NumIndices, GL_UNSIGNED_INT, 0);
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
}
顶点着色器:
#version 420
uniform mat4 camera;
uniform mat4 model;
in vec3 vert;
in vec2 vertTexCoord;
out vec2 fragTexCoord;
void main() {
// Pass the tex coord straight through to the fragment shader
fragTexCoord = vertTexCoord;
// Apply all matrix transformations to vert
gl_Position = camera * model * vec4(vert, 1);
}
片段着色器:
#version 420
uniform sampler2D tex;
in vec2 fragTexCoord;
out vec4 finalColor;
void main() {
//note: the texture function was called texture2D in older versions of GLSL
finalColor = texture(tex, fragTexCoord);
}
这是我得到的: before
但是当我尝试添加 phong 照明时,当我将法线属性添加到我的顶点着色器时,这就是我得到的: after
问题出在哪里?感谢您的帮助。
//编辑着色器加载和链接
shprogram::shprogram(const std::vector<shader>& shaders) :
_object(0)
{
if(shaders.size() <= 0)
throw std::runtime_error("No shaders were provided to create the program");
//create the program object
_object = glCreateProgram();
if(_object == 0)
throw std::runtime_error("glCreateProgram failed");
//attach all the shaders
for(unsigned i = 0; i < shaders.size(); ++i)
glAttachShader(_object, shaders[i].getObject());
//link the shaders together
glLinkProgram(_object);
//detach all the shaders
for(unsigned i = 0; i < shaders.size(); ++i)
glDetachShader(_object, shaders[i].getObject());
//throw exception if linking failed
GLint status;
glGetProgramiv(_object, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
std::string msg("Program linking failure: ");
GLint infoLogLength;
glGetProgramiv(_object, GL_INFO_LOG_LENGTH, &infoLogLength);
char* strInfoLog = new char[infoLogLength + 1];
glGetProgramInfoLog(_object, infoLogLength, NULL, strInfoLog);
msg += strInfoLog;
delete[] strInfoLog;
glDeleteProgram(_object); _object = 0;
throw std::runtime_error(msg);
}
}
shprogram::~shprogram() {
//might be 0 if ctor fails by throwing exception
if(_object != 0) glDeleteProgram(_object);
}
GLuint shprogram::object() const {
return _object;
}
void shprogram::use() const {
glUseProgram(_object);
}
bool shprogram::isInUse() const {
GLint currentProgram = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram);
return (currentProgram == (GLint)_object);
}
void shprogram::stopUsing() const {
assert(isInUse());
glUseProgram(0);
}
GLint shprogram::attrib(const GLchar* attribName) const {
if(!attribName)
throw std::runtime_error("attribName was NULL");
GLint attrib = glGetAttribLocation(_object, attribName);
if(attrib == -1)
throw std::runtime_error(std::string("Program attribute not found: ") + attribName);
return attrib;
}
GLint shprogram::uniform(const GLchar* uniformName) const {
if(!uniformName)
throw std::runtime_error("uniformName was NULL");
GLint uniform = glGetUniformLocation(_object, uniformName);
if(uniform == -1)
throw std::runtime_error(std::string("Program uniform not found: ") + uniformName);
return uniform;
}
void shprogram::setUniformMatrix2(const GLchar* name, const GLfloat* v, GLsizei count, GLboolean transpose) {
assert(isInUse());
glUniformMatrix2fv(uniform(name), count, transpose, v);
}
void shprogram::setUniformMatrix3(const GLchar* name, const GLfloat* v, GLsizei count, GLboolean transpose) {
assert(isInUse());
glUniformMatrix3fv(uniform(name), count, transpose, v);
}
void shprogram::setUniformMatrix4(const GLchar* name, const GLfloat* v, GLsizei count, GLboolean transpose) {
assert(isInUse());
glUniformMatrix4fv(uniform(name), count, transpose, v);
}
void shprogram::setUniform(const GLchar* name, const glm::mat2& m, GLboolean transpose) {
assert(isInUse());
glUniformMatrix2fv(uniform(name), 1, transpose, glm::value_ptr(m));
}
void shprogram::setUniform(const GLchar* name, const glm::mat3& m, GLboolean transpose) {
assert(isInUse());
glUniformMatrix3fv(uniform(name), 1, transpose, glm::value_ptr(m));
}
void shprogram::setUniform(const GLchar* name, const glm::mat4& m, GLboolean transpose) {
assert(isInUse());
glUniformMatrix4fv(uniform(name), 1, transpose, glm::value_ptr(m));
}
void shprogram::setUniform(const GLchar* uniformName, const glm::vec3& v) {
setUniform3v(uniformName, glm::value_ptr(v));
}
void shprogram::setUniform(const GLchar* uniformName, const glm::vec4& v) {
setUniform4v(uniformName, glm::value_ptr(v));
}
设置制服
//bind shader program
gProgram->use();
//set the "camera" uniform
gProgram->setUniform("camera", gCamera.matrix());
//set the "model" uniform in the vertex shader, based on the gDegreesRotated global
gProgram->setUniform("model", glm::rotate(glm::mat4(), 150.0f ,glm::vec3(0,1,0)));
gProgram->setUniform("light.position", gLight.position);
gProgram->setUniform("light.intensities", gLight.intensities);
最佳答案
您既没有在着色器源代码中明确设置属性位置,也没有在链接着色器之前绑定(bind)它们,也没有查询它们。 GL 可以自由地为任何事件输入属性使用任何有效的属性索引。
您只需假设 0 是位置,1 是纹理坐标,2 是正常值。对于 position+texcoord 情况,它可能会意外工作,但是当您添加法线时,索引可能会全部混淆。在 GLSL 代码中使用 layout(location=...)
(详见 GL_ARB_explicit_attrib_location
),或者使用 glBindAttribLocation()
指定您想要的映射。
关于c++ - 使用 phong 照明的纹理映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19467238/
我的类笔记已经清楚地表明这两者是不一样的。我知道 Phong 照明模型是环境光 + 漫反射 + 镜面反射,但是在照明方面,Phong Shading 在哪里发挥作用? BRDF 呢? 最佳答案 照明模
我目前有一项任务是在 openGL/GLSL 中实现 Phong 光照模型。我目前正在使用的两个着色器如下。问题是,在片段着色器中,如果我不将 vColor 添加到 gl_FragColor,那么整个
问题:谁能告诉我网络摄像头拍摄的面部图像的 Phong 反射模型参数? 详细信息: 我正在使用本文中的 3D 可变形模型对 2D 图像进行 3D 重建 Vetter & Blanz, 2003 . 有
我正在根据 Phong Model 编写着色器.我正在尝试实现这个等式: 其中 n 是法线,l 是光的方向,v 是相机的方向,r 是光反射。维基百科文章中更详细地描述了方程式。 截至目前,我只在定向光
我正在学习 Phong 着色并遇到一些困惑: Phong 着色中光线位置的坐标是多少? (模型空间、模型 View 或其他什么?) 根据这个:http://www.ozone3d.net/tutori
我试图弄清楚如何使用 phong 模型通过照明照明来缩放颜色。例如,给定 I = KaAx,其中 ka 是环境系数,Ax 是环境照明强度,其中 x 可以是 r b 或 g,我想将其应用于纹理颜色为 (
我正在尝试实现 Phong 着色模型,但我不确定如何选择光源。更具体地说,我不明白光源应该是什么样子。它应该是vec3吗?或者也许是我在 Java 代码中定义的矩阵?另外,如果我们假设我希望相机作为光
我正在尝试制作一个立方体,它是不规则的三角剖分,但几乎共面,阴影正确。 这是我目前的结果: 带线框: 在我的程序中计算的法线: 由 meshlabjs.net 计算的法线: 当为立方体使用常规大小的三
我需要为我的地形网格创建一个相当简单的着色器。着色器必须根据世界地图(图像)的颜色使用不同的漫反射和法线纹理,必须接收阴影并使用灯光。 默认的 phong 着色器由许多包含项组成,我可以在哪里更改或只
所以我在使用 Phong 模型时遇到了问题,特别是漫反射分量以及使用正确的法 vector 和光 vector 的方向。这是一个学校项目,但我不在乎我是否没有完成它,只要有人能告诉我我做错了什么。我已
我正在尝试将 Phong 照明添加到我已经加载了带有纹理的网格的场景中。这是我的网格加载类: #define INVALID_OGL_VALUE 0xFFFFFFFF #define INVALID_
(编辑):我发布的原始代码适用于 gouraud 和 phong 着色选项。我已经改变了它所以它只是 phong 阴影并在下面发布。网格太大,无法在此处进行描述,因为它是从 Bezier Patch
我正在世界空间坐标中实现法线/凹凸贴图(我发现它们更容易使用)并且我的照明在没有法线贴图的情况下也能正常工作,但是当引入法线贴图(以及使用 TBN 矩阵计算的新 vector )时我的照明的镜面反射组
我正在尝试创建一个基本的 Phong 照明着色器以了解着色器中的照明。另外,我正在使用 openframeworks。我创建了 3 个立方体,它们有一个围绕它们旋转的相机。照明似乎正常工作(有点),但
我目前正在用 C++ 实现一个基本的光线追踪器。到目前为止效果很好,哑光 Material (具有环境光和漫反射 brdf)到目前为止按预期工作。 添加镜面高光会导致完整的 Phong Model这正
我正在尝试使用 phong Material 实现平面着色。正如文档所说,我们必须在创建 Material 时在配置中设置 flatShading:true。我用这些设置创建了一个立方体,并创建了一个
据我了解,Gouraud shading 计算每个顶点的光色并对该颜色进行插值,而 Phong shading 为每个像素插值法线并根据该插值计算光色。 然而,当我试图从数学上推导出浅色时,我最终得到
过去几周我一直在学习 OpenGL,但在实现 Phong 着色器时遇到了一些麻烦。尽管我使用了 smooth 限定符,但它似乎没有在顶点之间进行插值。我在这里错过了什么吗?为了给予应有的赞扬,顶点和片
我正在尝试在 Vulkan 着色器中为单个光源实现 Blinn-Phong 着色,但我得到的结果不是我所期望的。 输出如下所示: 灯光位置应在相机右侧的后面,这在图里上正确表示,但在圆圈上却没有。我不
我正在阅读 opengl.org 中的以下 Phong 照明着色器: Phong Illumination in Opengl.org 顶点和片段着色器如下: 顶点着色器: varying vec3
我是一名优秀的程序员,十分优秀!