如何在 OpenGL 中为金属(如银)设置材质?有谁知道?
4 回答
如何在 OpenGL 中为金属(如银)设置材质?有谁知道?
如果您希望您的材质有时看起来“有点”像金属,您需要设置相应的漫反射、环境光、镜面反射和“光泽”参数。您可以调查现有的 3d 编辑器(如blender)的材质库,看看他们是如何做到的。这很便宜,但看起来也很便宜。通常具有低 GL_SHININESS 值的材料(我认为是 3..12?)看起来“有点”像金属表面。
如果您希望您的材质看起来更像金属,但在某些光照条件下,您需要编写像素着色器,该着色器将使用银的照片级真实纹理,以及控制镜面反射颜色和强度的附加纹理贴图。只要仔细选择照明条件,好的纹理可以让您摆脱可怕而简单的着色器。这需要具有 GLSL 知识的程序员和优秀的美术师来制作纹理,而美术师会更重要——即使是像 per-pixel phong 这样的非金属着色器也可以手动微调,使其看起来像你想要的那样(进动可能很无聊且乏味)。着色器本身只需要具有镜面反射(任何镜面反射)、法线贴图支持和环境反射贴图(具有菲涅耳项支持)的逐像素光照。对弱反射抛光表面使用 HDR 也会有所帮助。
如果您想要真正和完美的白银,那么您就有麻烦了,应该重新考虑。金属表面具有“模糊”反射,快速实施可能会很痛苦,具体取决于您的硬件。另一个问题是你必须对金属本身进行大量研究,检查那里存在的每个金属表面演示,阅读 GDC 论文等。即进行研究,这可能需要大量时间/精力并且不会最终得到回报,因为最终结果很可能会有糟糕的表现。重要的是你不需要模拟真实的材料来让它看起来正确——你需要让观众误以为这是银。
如果您查看此站点,您可以找到一系列不同的材料设置,这些设置旨在模仿各种材料,包括银。但是,正如其他人在评论中所说,请记住 Phong 着色(OpenGL 使用此类材质设置来执行的操作)很难以逼真的方式渲染某些现实世界的物质,尤其是像银这样的反射性物质。但是该站点的材料设置应该给你一些银一样的东西,至少初步近似。(确保你在最后看到关于将光泽度乘以 128 的注释)
正如 Solaraeus 所说,您可以创建一个“材质”类来定义材质对象,例如:
#ifndef _MATERIAL
#define _MATERIAL
#include <GL/gl.h>
class material{
private:
GLfloat ambient_r;
GLfloat ambient_g;
GLfloat ambient_b;
GLfloat diffuse_r;
GLfloat diffuse_g;
GLfloat diffuse_b;
GLfloat specular_r;
GLfloat specular_g;
GLfloat specular_b;
public:
material(GLfloat ar, GLfloat ag, GLfloat ab, GLfloat dr, GLfloat dg, GLfloat db, GLfloat sr, GLfloat sg, GLfloat sb){
ambient_r=ar; ambient_g=ag; ambient_b=ab;
diffuse_r=dr; diffuse_g=dg; diffuse_b=db;
specular_r=sr; specular_g=sg; specular_b=sb;
}
void active(){
GLfloat ambient[]={ambient_r, ambient_g, ambient_b, 1.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
GLfloat diffuse[]={diffuse_r, diffuse_g, diffuse_b};
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
GLfloat specular[]={specular_r, specular_g, specular_b};
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
}
};
#endif
之后您可以定义一个包含多种材料的文件 .h 以供以后使用,例如:
#ifndef _MATERIALS
#define _MATERIALS
#include "material.h"
// ### specification of materials ### //
material turquesa(0.1, 0.18725, 0.1745, 0.396, 0.74151, 0.69102, 0.297254, 0.30829, 0.306678);
material esmeralda(0.0215, 0.1745, 0.0215, 0.07568, 0.61424, 0.07568, 0.633, 0.727811, 0.633);
material jade(0.135, 0.2225, 0.1575, 0.54, 0.89, 0.63, 0.316228, 0.316228, 0.316228);
material obsidian(0.05375, 0.05, 0.06625, 0.18275, 0.17, 0.22525, 0.332741, 0.328634, 0.346435);
//more and more...
#万一
因此,您可以在任何地方使用它们,包括在需要时激活材料的 materials.h:
例子:
#include "materials.h"
...
...
turquesa.active();
glBegin(GL_TRIANGLES);
for(unsigned i=0; i<faces.size(); i++){
glNormal3f(x, y, z);
glVertex3f(x, y, z);
glVertex3f(x, y, z);
glVertex3f(x, y, z);
}
glEnd();
...
...
如果您考虑对象,则更容易。
使用 PBR(基于物理的渲染)技术可以获得高质量的金属外观。基本上,PBR 使用着色器和以下纹理输入:
- 反照率(漫反射)颜色;
- 法线贴图;
- 粗糙度 - 映射表面粗糙度/光滑度;
- metalness - 金属/非金属区域的地图表面;
网上有很多关于 PBR 的文章。可能的最爱之一是这个。
此外,结合环境效果(立方体贴图或其他反射技术)突出金属效果。