简体   繁体   English

OpenGL ES 2.0点光源着色器

[英]OpenGL ES 2.0 Point light shader

I'm currently trying to write a shader that should include a simple point light in OpenGL ES 2.0, but it's not quite working. 我目前正在尝试编写一个着色器,它应该在OpenGL ES 2.0中包含一个简单的点光源,但它并不是很有效。

I built my own small SceneGraph and each Object (currently only Boxes) can have its own translation/rotation/scale and rendering works fine. 我构建了自己的小型SceneGraph,每个Object(目前只有Boxes)可以有自己的平移/旋转/缩放,渲染效果很好。 Each of the boxes assigns its own modelView and normals matrix and all of them use the same projection matrix. 每个框都分配自己的modelView和normals矩阵,所有这些矩阵都使用相同的投影矩阵。

For each object I pass the matrices and the light position to the shader as a uniform. 对于每个对象,我将矩阵和光位置作为制服传递给着色器。

If the Object does not rotate the light works fine, but as soon as the Object rotates the light seems to rotate with the object instead of staying at the same position. 如果物体不旋转,光线工作正常,但一旦物体旋转,光线似乎随物体旋转而不是停留在同一位置。

Here is some Code. 这是一些代码。 First the creating the matrices: 首先创建矩阵:

GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 0.0f);

Each of the nodes computes an own transformation matrix containing the translation/rotation/scale and multiplies it with the modelViewMatrix: 每个节点计算一个包含平移/旋转/缩放的自己的变换矩阵,并将其与modelViewMatrix相乘:

modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, transformation);

This matrix is passed to the shader and after the object has been rendered the old matrix is recovered. 该矩阵被传递到着色器,并且在渲染对象之后,恢复旧矩阵。

The normal matrix is calculated as follows: 正常矩阵计算如下:

GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);

Vertex-Shader: 顶点着色器:

attribute vec4 Position;
attribute vec2 TexCoordIn;
attribute vec3 Normal;

uniform mat4 modelViewProjectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat3 normalMatrix;

uniform vec3 lightPosition;

varying vec2 TexCoordOut;
varying vec3 n, PointToLight;

void main(void) {
    gl_Position =  modelViewProjectionMatrix * Position;
    n = normalMatrix * Normal;

    PointToLight = ((modelViewMatrix * vec4(lightPosition,1.0)) - (modelViewMatrix * Position)).xyz;

    // Pass texCoord
    TexCoordOut = TexCoordIn;
}

Fragment-Shader: 片段着色器:

varying lowp vec2 TexCoordOut;
varying highp vec3 n, PointToLight;

uniform sampler2D Texture;

void main(void) {
    gl_FragColor = texture2D(Texture, TexCoordOut);

    highp vec3 nn = normalize(n);
    highp vec3 L = normalize(PointToLight);

    lowp float NdotL = clamp(dot(n, L), -0.8, 1.0);
    gl_FragColor *= (NdotL+1.)/2.;
}

I guess the PointToLight is computed wrong, but I can't figure out what's going wrong. 我猜PointToLight计算错误,但我无法弄清楚出了什么问题。

I finally figured out what went wrong. 我终于弄清楚出了什么问题。

Instead of multiplying the lightPosition with the modelViewMatrix, I just need to multiply it with the viewMatrix, which only contains the transformations of the camera and not the transformations for the box: 我不需要将lightPosition与modelViewMatrix相乘,而只需将它与viewMatrix相乘,而viewMatrix只包含相机的转换而不包含框的转换:

PointToLight = ((viewMatrix * vec4(lightPosition,1.0)) - (viewMatrix * modelMatrix * Position)).xyz;

Now it works fine. 现在它工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM