- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试制作一个立方体,它是不规则的三角剖分,但几乎共面,阴影正确。
这是我目前的结果:
带线框:
在我的程序中计算的法线:
由 meshlabjs.net 计算的法线:
当为立方体使用常规大小的三角形时,照明工作正常。如您所见,我正在复制顶点并使用角度权重。lighting.frag
vec4 scene_ambient = vec4(1, 1, 1, 1.0);
struct material
{
vec4 ambient;
vec4 diffuse;
vec4 specular;
float shininess;
};
material frontMaterial = material(
vec4(0.25, 0.25, 0.25, 1.0),
vec4(0.4, 0.4, 0.4, 1.0),
vec4(0.774597, 0.774597, 0.774597, 1.0),
76
);
struct lightSource
{
vec4 position;
vec4 diffuse;
vec4 specular;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent;
vec3 spotDirection;
};
lightSource light0 = lightSource(
vec4(0.0, 0.0, 0.0, 1.0),
vec4(100.0, 100.0, 100.0, 100.0),
vec4(100.0, 100.0, 100.0, 100.0),
0.1, 1, 0.01,
180.0, 0.0,
vec3(0.0, 0.0, 0.0)
);
vec4 light(lightSource ls, vec3 norm, vec3 deviation, vec3 position)
{
vec3 viewDirection = normalize(vec3(1.0 * vec4(0, 0, 0, 1.0) - vec4(position, 1)));
vec3 lightDirection;
float attenuation;
//ls.position.xyz = cameraPos;
ls.position.z += 50;
if (0.0 == ls.position.w) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection = normalize(vec3(ls.position));
}
else // point light or spotlight (or other kind of light)
{
vec3 positionToLightSource = vec3(ls.position - vec4(position, 1.0));
float distance = length(positionToLightSource);
lightDirection = normalize(positionToLightSource);
attenuation = 1.0 / (ls.constantAttenuation
+ ls.linearAttenuation * distance
+ ls.quadraticAttenuation * distance * distance);
if (ls.spotCutoff <= 90.0) // spotlight?
{
float clampedCosine = max(0.0, dot(-lightDirection, ls.spotDirection));
if (clampedCosine < cos(radians(ls.spotCutoff))) // outside of spotlight cone?
{
attenuation = 0.0;
}
else
{
attenuation = attenuation * pow(clampedCosine, ls.spotExponent);
}
}
}
vec3 ambientLighting = vec3(scene_ambient) * vec3(frontMaterial.ambient);
vec3 diffuseReflection = attenuation
* vec3(ls.diffuse) * vec3(frontMaterial.diffuse)
* max(0.0, dot(norm, lightDirection));
vec3 specularReflection;
if (dot(norm, lightDirection) < 0.0) // light source on the wrong side?
{
specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
}
else // light source on the right side
{
specularReflection = attenuation * vec3(ls.specular) * vec3(frontMaterial.specular)
* pow(max(0.0, dot(reflect(lightDirection, norm), viewDirection)), frontMaterial.shininess);
}
return vec4(ambientLighting + diffuseReflection + specularReflection, 1.0);
}
vec4 generateGlobalLighting(vec3 norm, vec3 position)
{
return light(light0, norm, vec3(2,0,0), position);
}
mainmesh.frag
#version 430
in vec3 f_color;
in vec3 f_normal;
in vec3 f_position;
in float f_opacity;
out vec4 fragColor;
vec4 generateGlobalLighting(vec3 norm, vec3 position);
void main()
{
vec3 norm = normalize(f_normal);
vec4 l0 = generateGlobalLighting(norm, f_position);
fragColor = vec4(f_color, f_opacity) * l0;
}
m_vertices_buf.resize(m_mesh.num_faces() * 3, 3);
m_normals_buf.resize(m_mesh.num_faces() * 3, 3);
m_faces_buf.resize(m_mesh.num_faces(), 3);
std::map<vertex_descriptor, std::list<Vector3d>> map;
GLDebugging* deb = GLDebugging::getInstance();
auto getAngle = [](Vector3d a, Vector3d b) {
double angle = 0.0;
angle = std::atan2(a.cross(b).norm(), a.dot(b));
return angle;
};
for (const auto& f : m_mesh.faces()) {
auto f_hh = m_mesh.halfedge(f);
//auto n = PMP::compute_face_normal(f, m_mesh);
vertex_descriptor vs[3];
Vector3d ps[3];
int i = 0;
for (const auto& v : m_mesh.vertices_around_face(f_hh)) {
auto p = m_mesh.point(v);
ps[i] = Vector3d(p.x(), p.y(), p.z());
vs[i++] = v;
}
auto n = (ps[1] - ps[0]).cross(ps[2] - ps[0]).normalized();
auto a1 = getAngle((ps[1] - ps[0]).normalized(), (ps[2] - ps[0]).normalized());
auto a2 = getAngle((ps[2] - ps[1]).normalized(), (ps[0] - ps[1]).normalized());
auto a3 = getAngle((ps[0] - ps[2]).normalized(), (ps[1] - ps[2]).normalized());
auto area = PMP::face_area(f, m_mesh);
map[vs[0]].push_back(n * a1);
map[vs[1]].push_back(n * a2);
map[vs[2]].push_back(n * a3);
auto p = m_mesh.point(vs[0]);
deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(n.x(), n.y(), n.z()) * 4);
p = m_mesh.point(vs[1]);
deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(n.x(), n.y(), n.z()) * 4);
p = m_mesh.point(vs[2]);
deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(n.x(), n.y(), n.z()) * 4);
}
int j = 0;
int i = 0;
for (const auto& f : m_mesh.faces()) {
auto f_hh = m_mesh.halfedge(f);
for (const auto& v : m_mesh.vertices_around_face(f_hh)) {
const auto& p = m_mesh.point(v);
m_vertices_buf.row(i) = RowVector3d(p.x(), p.y(), p.z());
Vector3d n(0, 0, 0);
//auto n = PMP::compute_face_normal(f, m_mesh);
Vector3d norm = Vector3d(n.x(), n.y(), n.z());
for (auto val : map[v]) {
norm += val;
}
norm.normalize();
deb->drawLine(Vector3d(p.x(), p.y(), p.z()), Vector3d(p.x(), p.y(), p.z()) + Vector3d(norm.x(), norm.y(), norm.z()) * 3,
Vector3d(1.0, 0, 0));
m_normals_buf.row(i++) = RowVector3d(norm.x(), norm.y(), norm.z());
}
m_faces_buf.row(j++) = RowVector3i(i - 3, i - 2, i - 1);
}
m_vertexAttrLoc = program.attributeLocation("v_vertex");
m_colorAttrLoc = program.attributeLocation("v_color");
m_normalAttrLoc = program.attributeLocation("v_normal");
m_mvMatrixLoc = program.uniformLocation("v_modelViewMatrix");
m_projMatrixLoc = program.uniformLocation("v_projectionMatrix");
m_normalMatrixLoc = program.uniformLocation("v_normalMatrix");
//m_relativePosLoc = program.uniformLocation("v_relativePos");
m_opacityLoc = program.uniformLocation("v_opacity");
m_colorMaskLoc = program.uniformLocation("v_colorMask");
//bool for unmapping depth color
m_useDepthMap = program.uniformLocation("v_useDepthMap");
program.setUniformValue(m_mvMatrixLoc, modelView);
//uniform used for Color map to regular model switch
program.setUniformValue(m_useDepthMap, (m_showColorMap &&
(m_showProblemAreas || m_showPrepMap || m_showDepthMap || m_showMockupMap)));
QMatrix3x3 normalMatrix = modelView.normalMatrix();
program.setUniformValue(m_normalMatrixLoc, normalMatrix);
program.setUniformValue(m_projMatrixLoc, projection);
//program.setUniformValue(m_relativePosLoc, m_relativePos);
program.setUniformValue(m_opacityLoc, m_opacity);
program.setUniformValue(m_colorMaskLoc, m_colorMask);
glEnableVertexAttribArray(m_vertexAttrLoc);
m_vertices.bind();
glVertexAttribPointer(m_vertexAttrLoc, 3, GL_DOUBLE, false, 3 * sizeof(GLdouble), NULL);
m_vertices.release();
glEnableVertexAttribArray(m_normalAttrLoc);
m_normals.bind();
glVertexAttribPointer(m_normalAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
m_normals.release();
glEnableVertexAttribArray(m_colorAttrLoc);
if (m_showProblemAreas) {
m_problemColorMap.bind();
glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
m_problemColorMap.release();
}
else if (m_showPrepMap) {
m_prepColorMap.bind();
glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
m_prepColorMap.release();
}
else if (m_showMockupMap) {
m_mokupColorMap.bind();
glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
m_mokupColorMap.release();
}
else {
//m_colors.bind();
//glVertexAttribPointer(m_colorAttrLoc, 3, GL_DOUBLE, false, 0, NULL);
//m_colors.release();
}
m_indices.bind();
glDrawElements(GL_TRIANGLES, m_indices.size() / sizeof(int), GL_UNSIGNED_INT, NULL);
m_indices.release();
glDisableVertexAttribArray(m_vertexAttrLoc);
glDisableVertexAttribArray(m_normalAttrLoc);
glDisableVertexAttribArray(m_colorAttrLoc);
最佳答案
您的问题中的图像“在我的程序中计算的法线”清楚地解释了这个问题。立方体边角处的法 vector 不正常perpendicular脸:
为了在平面上进行适当的镜面反射,法 vector 必须是 perpendicular到立方体的侧面。
来自具有 6 个分量(x、y、z、nx、ny、nz)的元组的顶点坐标及其法 vector 。
立方体边缘上的顶点坐标与立方体的 2 个边和 2 个(面)法 vector 相邻。立方体 8 个角上的 8 个顶点坐标分别与 3 个边(3 个法 vector )相邻。
要使用面法 vector (垂直于边)定义顶点属性,您必须定义多个具有相同顶点坐标但法 vector 不同的元组。您必须使用不同的属性元组在立方体的不同边上形成三角形基元。
例如如果定义了一个立方体,左、前、底坐标为 (-1, -1, -1),右、后、顶坐标为 (1, 1, 1),则顶点坐标 (-1, -1, -1) 与立方体的左侧、前侧和底侧相邻:
x y z nx ny nz
left: -1 -1 -1 -1 0 0
front: -1 -1 -1 0 -1 0
bottom: -1 -1 -1 0 0 -1
left
属性元组形成左侧的三角形基元,
front
形成正面和
bottom
对于底部的三角形。
关于c++ - 使用 Phong 方法的不良照明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60043924/
我正在练习我的 Javascript,所以我制作了一个跟随鼠标的功能。我成功了,但现在我有了一个新想法,但我不确定是否可行。 有没有办法让“视觉球体”跟随鼠标,以便该区域中的所有内容都可见?。有点像使
对my question的回答表明 DOT3 光照可以帮助 OpenGL ES 渲染,但我很难找到 DOT3 光照的合适定义。 编辑 1 非常感谢 iPhone 相关信息。 最佳答案 DOT3 照明通
所以我一直在研究照明,为了阴影贴图的目的,我根据半径而不是三个衰减因子(常数、线性和二次)进行光衰减,而且,嗯......它看起来不太好靠近边缘。 /image/H680a.png 它切断得非常快,着
我已经问过这个问题了,但没有得到答案。顺便说一句,我发现了一些新东西。我想显示由 Solid Works 导出的 WRL 文件的 3D 模型。该文件包含三角形的顶点,我用 glBegin(GL_TRI
我在我的 JOGL 项目中添加了一个光源,当物体静止时,它似乎工作得很好,当我移动相机时,它随着它旋转而逐渐变暗,这是我所期望的,但一旦它旋转 90 度屏幕完全黑了,有人知道这是为什么吗?另一侧是否需
我正在尝试使用 iPhone LED 执行渐进式照明。为此,我尝试使用 setTorchModeOnWithLevel 方法, float 值定期增加,从 0.1 到 AVCaptureMaxAvai
我有一个我无法解决的问题。我刚刚在我的项目中添加了一个点光源,它使纹理完全变黑。我不知道为什么。 我认为这可能是法线没有正确更新,也可能是 s.x、s.y 和 s.z 的计算。 如果有人有时间看一下并
我有一张碰撞图,有些地方我想成为光源。光源提供的光实际上是我可以看到地面的形状。现在看起来像这样: 所以光线穿过墙壁。我想让它看起来像这样: (我用深黄色标记了与墙壁的碰撞) 因此光线在遇到墙壁时停止
我正在阅读 opengl.org 中的以下 Phong 照明着色器: Phong Illumination in Opengl.org 顶点和片段着色器如下: 顶点着色器: varying vec3
我读过的几乎所有文章和书籍都指出最终颜色的构成是:finalColor = ambientColor + lambertianTerm * diffuseColor (= material color
我一直在尝试检测移动的车辆。但是由于云的不同光照条件(不是云的阴影,只是照明)背景减法失败。 我已经在这里上传了我的输入视频 --> Youtube (30secs) 这是我使用 opencv 中可用
我只想点亮键盘上的一个键 (Logitech G910),同时设置鼠标颜色(罗技G303)。 在键盘上设置一个键可以正常工作,但是如果不同时将键盘上的所有键都设置为该颜色,我就无法设置鼠标的颜色。 我
我正在尝试获取 Logitech's own LED SDK使用我的 G502,但我不能。我使用的是 SDK 版本 8.82.7,这是目前最新的版本。我在 SO 或互联网的其他部分也找不到任何东西,所
因为我是着色器的完全菜鸟,所以我在尝试使用 2D 照明系统时遇到了一些问题,该系统基本上用 2D 黑色纹理覆盖屏幕,在亮区所在的位置有透明孔。 因为我只使用一个纹理,所以我想我必须在片段着色器中执行此
我试图使用此处的代码在 Laravel 中创建迁移。但不幸的是它会弹出一个像这里给出的错误。我看到了一些我手动创建表的答案..但这与迁移的整个想法非常相悖..不是吗? 迁移文件 2018_05_05_
我是一名优秀的程序员,十分优秀!