首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >运动物体的漫射照明

运动物体的漫射照明
EN

Stack Overflow用户
提问于 2020-02-07 08:16:50
回答 1查看 352关注 0票数 3

在计算移动物体的漫射照明时,我必须将发光源与物体本身一起移动:

代码语言:javascript
复制
@Override
public void draw() { // draw frame
  ...
  // Move object
  GLES20.glVertexAttribPointer(aPositionLink, 3, GLES30.GL_FLOAT,
                    false, 0, object3D.getVertices());
  // The luminous source moves nearby the object, so the 
  // object is always illuminated from one side
  GLES20.glUniform3f(lightPositionLink, object3D.getX(),
        object3D.getY(), object3D.getZ() + 2.0f);
  ...
}

顶点着色器片段:

代码语言:javascript
复制
#version 300 es
uniform mat4 u_mvMatrix; // model-view matrix of object
uniform vec3 u_lightPosition; // position of the luminous source
in vec4 a_position; // vertex data is loaded here
in vec3 a_normal; // normal data is loaded here
struct DiffuseLight { 
  vec3 color; 
  float intensity; 
};
uniform DiffuseLight u_diffuseLight;
...
void main() {
  ...
  vec3 modelViewNormal = vec3(u_mvMatrix * vec4(a_normal, 0.0));
  vec3 modelViewVertex = vec3(u_mvMatrix * a_position);
  // calculate the light vector by subtracting the
  // position of the object from the light position
  vec3 lightVector = normalize(u_lightPosition - modelViewVertex);
  float diffuse = max(dot(modelViewNormal, lightVector), 0.1);
  float distance = length(u_lightPosition - modelViewVertex);
  diffuse = diffuse * (1.0 / (1.0 + pow(distance, 2.0)));
  // calculate the final color for diffuse lighting
  lowp vec3 diffuseColor = diffuse * u_diffuseLight.color * u_diffuseLight.intensity;
  v_commonLight = vec4((ambientColor + diffuseColor), 1.0);
  ...
}

这样做对吗?还是有另一个合理的选择,固定光源,以不花费资源计算的位置发光源每帧?注意:增加距离没有帮助。提前谢谢。

解决方案:

根据Rabbid76的建议,我采用了here所描述的方向光。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-07 08:44:49

我必须移动发光源和对象本身

为什么光源和物体一起移动?

如果光是世界上的点光源,物体移动,那么物体的照度就会改变(在“真实”世界中)。

在您的情况下,照明是在视图空间中计算的。如果光源是世界上的一个点,那么您必须通过视图矩阵来转换位置(视图矩阵从世界空间转换到视图空间)。例如:

代码语言:javascript
复制
uniform mat4 u_viewMatrix;

void main()
{
    // [...]

    vec3 lightPosView = vec3(u_viewMatrix * vec4(u_lightPosition.xyz, 1.0)); 
    vec3 lightVector  = normalize(u_lightPosition - modelViewVertex);

    // [...]
}

无论如何,如果物体移动,光源以某种方式锚定在物体上,你就必须将转换应用到对象的顶点,也应用到光源。

在这种情况下,u_lightPosition必须是对象模型空间中的一个位置,这意味着它相对于对象(u_lightModelPosition)。然后你就可以:

代码语言:javascript
复制
uniform vec3 u_lightModelPosition; 

void main()
{
    mat3 normalMat       = inverse(transpose(mat3(u_mvMatrix)));
    vec3 modelViewNormal = normalMat * a_normal;
    vec3 modelViewVertex = vec3(u_mvMatrix * a_position);
    vec3 modelViewLight  = vec3(u_mvMatrix * vec4(u_lightModelPosition, 1.0));

    vec3 lightVector = normalize(modelViewLight - modelViewVertex);

    // [...]
}

如果你想要一个灯,那不取决于位置,你必须使用方向灯。在这种情况下,光源不是世界上的一个点,它只是一个方向。例如:

代码语言:javascript
复制
vec3 lightVector = -u_lightRayDirection;

u_lightRayDirection必须在光计算的空间。由于照明是在视图空间中计算的,所以u_lightRayDirection也必须是视图空间中的一个方向。如果u_lightRayDirection是世界空间中的一个向量,那么它必须由mat3(u_viewMatrix)变换。

方向灯没有距离(或恒定距离)。

如果光源锚定在摄像机上,则根本不需要转换(因为您可以看到空间中的光线计算)。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60109487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档