为什么我的镜面反射高光在多边形边缘上显示得如此强烈?

用户名

我有一个简单的应用程序,该应用程序用一个定向光绘制一个球体。我通过以八面体开始并将每个三角形细分为4个较小的三角形来创建球体。

仅使用漫射照明,球体看起来非常光滑。但是,当我添加镜面高光时,三角形的边缘显示得相当强烈。这里有些例子:

仅扩散:

仅具有漫射照明的球体

漫反射和镜面反射:

具有漫反射和镜面反射的球体

我相信法线已正确插入。只看法线,我得到这个:

球体法线

实际上,如果我切换到平面阴影,其中法线是每个多边形而不是每个顶点,则可以得到以下信息:

在此处输入图片说明

在我的顶点着色器中,我将模型的法线与转置逆模型视图矩阵相乘:

#version 330 core

layout (location = 0) in vec4 vPosition;
layout (location = 1) in vec3 vNormal;
layout (location = 2) in vec2 vTexCoord;

out vec3 fNormal;
out vec2 fTexCoord;

uniform mat4 transInvModelView;
uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;

void main()
{
    fNormal = vec3(transInvModelView * vec4(vNormal, 0.0));
    fTexCoord = vTexCoord;
    gl_Position = ProjectionMatrix * ModelViewMatrix * vPosition;
}

在片段着色器中,我将如下计算高光高光:

#version 330 core

in vec3 fNormal;
in vec2 fTexCoord;

out vec4 color;

uniform sampler2D tex;
uniform vec4 lightColor;        // RGB, assumes multiplied by light intensity
uniform vec3 lightDirection;    // normalized, assumes directional light, lambertian lighting
uniform float specularIntensity;
uniform float specularShininess;
uniform vec3 halfVector;        // Halfway between eye and light
uniform vec4 objectColor;

void main()
{
    vec4    texColor    = objectColor;

    float   specular    = max(dot(halfVector, fNormal), 0.0);
    float   diffuse     = max(dot(lightDirection, fNormal), 0.0);

    if (diffuse == 0.0)
    {
        specular = 0.0;
    }
    else
    {
        specular = pow(specular, specularShininess) * specularIntensity;
    }

    color = texColor * diffuse * lightColor + min(specular * lightColor, vec4(1.0));
}

我对如何计算该值有些困惑halfVector我正在CPU上进行处理,并将其作为制服传递给它。计算方法如下:

vec3    lightDirection(1.0, 1.0, 1.0);
lightDirection = normalize(lightDirection);
vec3    eyeDirection(0.0, 0.0, 1.0);
eyeDirection = normalize(eyeDirection);
vec3    halfVector  = lightDirection + eyeDirection;
halfVector = normalize(halfVector);
glUniform3fv(halfVectorLoc, 1, &halfVector [ 0 ]);

那是正确的配方halfVector吗?还是也需要在着色器中完成?

尼科·谢特勒

将法线插入脸部可以(并且几乎总是)将法线缩短。这就是为什么高光在脸部中央变暗,在角落和边缘变亮的原因。如果执行此操作,只需在片段着色器中重新规范法线即可:

fNormal = normalize(fNormal);

顺便说一句,您不能预先计算半个向量,因为它取决于视图(这是镜面照明的整个要点)。在当前情况下,仅移动摄像机(保持方向),高光将不会改变。

在着色器中执行此操作的一种方法是为眼睛位置传递一个额外的均匀性,然后将视向计算为eyePosition - vertexPosition然后像在CPU上一样继续操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我的着色器产生不正确的镜面反射结果?[DX11]

来自分类Dev

OpenGL Phong照明:镜面反射高光错误

来自分类Dev

为什么在svg多边形上缺少笔触

来自分类Dev

为什么在svg多边形上缺少笔触

来自分类Dev

HLSL中的镜面反射

来自分类Dev

基本镜面反射底纹

来自分类Dev

多边形边缘的排序

来自分类Dev

多边形未显示在gmap上

来自分类Dev

为什么在力模拟中d3 voronoi多边形拖动事件未在多边形上触发?

来自分类Dev

当我想在Nutiteq上添加新多边形时,为什么会收到InvocationTargetException错误?

来自分类Dev

ThreeJS中的镜面反射怪癖

来自分类Dev

计算像素的镜面反射值?

来自分类Dev

计算累计镜面反射值

来自分类Dev

ThreeJS中的镜面反射怪癖

来自分类Dev

为什么我的win32多边形不起作用?

来自分类Dev

在多边形上显示字符串。

来自分类Dev

如何使用CesiumJs在多边形上显示楼层

来自分类Dev

在SVG中的多边形上显示悬停文字

来自分类Dev

在SVG中的多边形上显示悬停文字

来自分类Dev

如何在svg中对齐多边形外边缘上的点以获得较粗的边框?

来自分类Dev

Blender 2.8 到 ThreeJS GLTF 镜面反射

来自分类Dev

带有孔的多边形在高变焦下无法正确显示(消失)

来自分类Dev

传单内多边形显示的挑战

来自分类Dev

如何显示多边形的纬度/经度?

来自分类Dev

显示从键盘插入的多边形坐标

来自分类Dev

matplotlib-多边形边缘的半径-有可能吗?

来自分类Dev

画布中的多边形边缘处理和检测

来自分类Dev

SVG多边形边缘的厚度不规则

来自分类Dev

如何使用pixijs获取多边形的边缘?