首页 > 解决方案 > OpenGL ES 2.0 上骨骼动画对象的错误照明

问题描述

我从 Blender 在三个骨骼上导入了一个简单的动画对象。我对蒙皮对象的照明有疑问。我在物体上方设置了一个灯光位置:

const vec3 lightPosition = vec3(0.0, 15.0, 0.0);

您可以看到照明在物体下也受到影响:

在此处输入图像描述

precision mediump float;

attribute vec3 aPosition;
attribute vec4 aNormal;
attribute vec2 aTexCoord;
attribute vec3 aJoints;
attribute vec3 aWeights;

uniform mat4 uMvpMatrix;
uniform mat4 uModelMatrix;
uniform mat4 uNormalMatrix;
uniform mat4 uTransforms[3];

varying vec3 vPosition;
varying vec3 vNormal;
varying vec2 vTexCoord;

void main()
{
    vec4 totalLocalPos = vec4(0.0);
    vec4 totalNormal = vec4(0.0);

    for (int i = 0; i < 3; i++)
    {
        int jointIndex = int(aJoints[i]);
        mat4 jointTransform = uTransforms[jointIndex];
        vec4 posePosition = jointTransform * vec4(aPosition, 1.0);
        totalLocalPos += posePosition * aWeights[i];

        vec4 worldNormal = jointTransform * aNormal;
        totalNormal += worldNormal * aWeights[i];
    }
    
    gl_Position = uMvpMatrix * totalLocalPos;
    vPosition = vec3(uModelMatrix * vec4(aPosition, 1.0));
    vNormal = totalNormal.xyz;
    vTexCoord = aTexCoord;
}
precision mediump float;

const vec3 lightColor = vec3(0.8, 0.8, 0.8);
const vec3 lightPosition = vec3(0.0, 15.0, 0.0);
const vec3 ambientLight = vec3(0.3, 0.3, 0.3);

uniform sampler2D uSampler;

varying vec3 vPosition;
varying vec3 vNormal;
varying vec2 vTexCoord;

void main()
{
    vec4 color = texture2D(uSampler, vTexCoord);
    vec3 normal = normalize(vNormal);
    vec3 lightDirection = normalize(lightPosition - vPosition);
    float nDotL = max(dot(lightDirection, normal), 0.0);
    vec3 diffuse = lightColor * color.rgb * nDotL;
    vec3 ambient = ambientLight * color.rgb;
    gl_FragColor = vec4(diffuse + ambient, color.a);
}

标签: opengl-esglsl

解决方案


Aroch俄罗斯论坛上帮助我:

法线只需要旋转。

现在它可以正常工作了。我从 ThinMatrix的视频教程系列的源代码中获取了着色器(照明模型除外)。它适用于 ThinMatrix。这意味着由于某种原因,它的光照模型不受法线向量平移的影响。以后有必要弄清楚为什么他没有这个问题。我将旋转矩阵数组的传输设为单独的统一:

uniform mat4 uTransforms[3];
uniform mat4 uRotations[3];

...

    for (int i = 0; i < 3; i++)
    {
        int jointIndex = int(aJoints[i]);
        mat4 jointTransform = uTransforms[jointIndex];
        vec4 posePosition = jointTransform * vec4(aPosition, 1.0);
        totalLocalPos += posePosition * aWeights[i];

        mat4 rotation = uRotations[jointIndex];
        vec4 worldNormal = rotation * aNormal;
        totalNormal += worldNormal * aWeights[i];
    }

Gif 动画:https ://gamedev.ru/files/images/solution-with-lighting.gif

在此处输入图像描述


推荐阅读