Android OpenGL ES 2.0:多光源:着色器问题

Android OpenGL ES 2.0:多光源:着色器问题,android,opengl-es-2.0,shader,fragment-shader,vertex-shader,Android,Opengl Es 2.0,Shader,Fragment Shader,Vertex Shader,更新3(非常感谢您的帮助) 我删除了建议的内容。此外,u_IT_MVMatrix似乎是错误的(无论它是什么用途),东西看起来更好一些,但地板应该发光,纹理砖应该有彩色砖(蓝色、红色等)的光 纹理对象的顶点(碎片保持不变) uniform mat4 u_MVPMatrix; // A constant representing the combined model/view/projection matrix. uniform mat4 u_MVMatrix; // A

更新3(非常感谢您的帮助)

我删除了建议的内容。此外,u_IT_MVMatrix似乎是错误的(无论它是什么用途),东西看起来更好一些,但地板应该发光,纹理砖应该有彩色砖(蓝色、红色等)的光

纹理对象的顶点(碎片保持不变)

uniform mat4 u_MVPMatrix;       // A constant representing the combined model/view/projection matrix.
uniform mat4 u_MVMatrix;        // A constant representing the combined model/view matrix.

attribute vec4 a_Position;      // Per-vertex position information we will pass in.
attribute vec3 a_Normal;        // Per-vertex normal information we will pass in.
attribute vec2 a_TexCoordinate; // Per-vertex texture coordinate information we will pass in.

varying vec3 v_Position;        // This will be passed into the fragment shader.
varying vec3 v_Normal;          // This will be passed into the fragment shader.
varying vec2 v_TexCoordinate;   // This will be passed into the fragment shader.

uniform vec4 u_PointLightPositions[3];    // In eye space
uniform vec3 u_PointLightColors[3];
vec4 eyeSpacePosition;
vec3 eyeSpaceNormal;

uniform vec4 v_Color;
varying vec3 lighting;
vec3 materialColor;

vec3 getAmbientLighting();
vec3 getDirectionalLighting();
vec3 getPointLighting();

// The entry point for our vertex shader.
void main()
{
    //materialColor = vec3(v_Color.xyz); // Will be modified by the texture later.
    materialColor = vec3(1.0, 1.0, 1.0);

    // Transform the vertex into eye space.
    v_Position = vec3(u_MVMatrix * a_Position);

    // Pass through the texture coordinate.
    v_TexCoordinate = a_TexCoordinate;

    // Transform the normal's orientation into eye space.
    v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));

    // gl_Position is a special variable used to store the final position.
    // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
    eyeSpacePosition = u_MVMatrix * a_Position;

    // The model normals need to be adjusted as per the transpose of the inverse of the modelview matrix.
    eyeSpaceNormal = normalize(vec3(u_MVMatrix * vec4(a_Normal, 0.0)));
    gl_Position = u_MVPMatrix * a_Position;

    lighting = getAmbientLighting();
    lighting += getPointLighting();
}

vec3 getAmbientLighting()
{
    return materialColor * 0.2;
}

vec3 getPointLighting()
{
    vec3 lightingSum = vec3(0.0);

    for (int i = 0; i < 3; i++) {
        vec3 toPointLight = vec3(u_PointLightPositions[i]) - vec3(eyeSpacePosition);
        float distance = length(toPointLight);
        //distance = distance / 5.0;
        toPointLight = normalize(toPointLight);

        float cosine = max(dot(eyeSpaceNormal, toPointLight), 0.0);
        lightingSum += (materialColor * u_PointLightColors[i] * 20.0 * cosine)
                       / distance;
    }

    return lightingSum;
}

**Vertex for light bricks (no texture)**





uniform mat4 u_MVPMatrix;       // A constant representing the combined model/view/projection matrix.
uniform mat4 u_MVMatrix;        // A constant representing the combined model/view matrix.

attribute vec4 a_Position;      // Per-vertex position information we will pass in.
attribute vec3 a_Normal;        // Per-vertex normal information we will pass in.

varying vec3 v_Position;        // This will be passed into the fragment shader.
varying vec3 v_Normal;          // This will be passed into the fragment shader.

uniform vec4 u_PointLightPositions[3];    // In eye space
uniform vec3 u_PointLightColors[3];
vec4 eyeSpacePosition;
vec3 eyeSpaceNormal;

uniform vec4 v_Color;
varying vec3 lighting;

vec3 getAmbientLighting();
vec3 getDirectionalLighting();
vec3 getPointLighting();

// The entry point for our vertex shader.
void main()
{
    // Transform the vertex into eye space.
    v_Position = vec3(u_MVMatrix * a_Position);

    // Transform the normal's orientation into eye space.
    v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));

    // gl_Position is a special variable used to store the final position.
    // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
    gl_Position = u_MVPMatrix * a_Position;
    eyeSpacePosition = u_MVMatrix * a_Position;

    // The model normals need to be adjusted as per the transpose of the inverse of the modelview matrix.
    eyeSpaceNormal = normalize(vec3(u_MVMatrix * vec4(a_Normal, 0.0)));

    lighting = getAmbientLighting();
    lighting += getPointLighting();
}

vec3 getAmbientLighting()
{
    return v_Color.xyz * 0.2;
}

vec3 getPointLighting()
{
    vec3 lightingSum = vec3(0.0);

    for (int i = 0; i < 3; i++) {
        vec3 toPointLight = vec3(u_PointLightPositions[i]) - vec3(eyeSpacePosition);
        float distance = length(toPointLight);
        toPointLight = normalize(toPointLight);

        float cosine = max(dot(eyeSpaceNormal, toPointLight), 0.0);
        lightingSum += (v_Color.xyz * u_PointLightColors[i] * 20.0 * cosine)
                       / distance;
    }

    return lightingSum;
}
渲染时

    uPointLightPositionsLocation =
                        glGetUniformLocation(mProgramHandle, "u_PointLightPositions");
    uPointLightColorsLocation =
                        glGetUniformLocation(mProgramHandle, "u_PointLightColors");

    glUniform4fv(uPointLightPositionsLocation, 3, mRenderer.pointLightPositions, 0);
    glUniform3fv(uPointLightColorsLocation, 3, mRenderer.pointLightColors, 0);

    // not sure why I need this
    // lighting
    final float[] pointPositionsInEyeSpace = new float[12];
    multiplyMV(pointPositionsInEyeSpace, 0, mVMatrix, 0, mRenderer.pointLightPositions, 0);
    multiplyMV(pointPositionsInEyeSpace, 4, mVMatrix, 0, mRenderer.pointLightPositions, 4);
    multiplyMV(pointPositionsInEyeSpace, 8, mVMatrix, 0, mRenderer.pointLightPositions, 8);

 Matrix.multiplyMM(mRenderer.mMVPMatrix, 0, mVMatrix, 0, mRenderer.mModelMatrix, 0);
着色器(顶点)

片段

precision mediump float;        // Set the default precision to medium. We don't need as high of a 
                                // precision in the fragment shader.
uniform vec3 u_LightPos;        // The position of the light in eye space.
uniform sampler2D u_Texture;    // The input texture.

varying vec3 v_Position;        // Interpolated position for this fragment.
varying vec3 v_Normal;          // Interpolated normal for this fragment.
varying vec2 v_TexCoordinate;   // Interpolated texture coordinate per fragment.

uniform vec4 v_Color;

uniform vec4 u_PointLightPositions[3];    // In eye space
uniform vec3 u_PointLightColors[3];

vec3 getPointLighting();

// The entry point for our fragment shader.
void main()                         
{                              
    // Will be used for attenuation.
    float distance = length(u_LightPos - v_Position);

    // Get a lighting direction vector from the light to the vertex.
    vec3 lightVector =  normalize(u_LightPos - v_Position);

    // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
    // pointing in the same direction then it will get max illumination.
    float diffuse = max(dot(v_Normal, lightVector), 0.0);                                                                                 

    // Add attenuation. 
    diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance)));

    // Add ambient lighting
    diffuse = diffuse + 0.7;  

    // Multiply the color by the diffuse illumination level and texture value to get final output color.
    //gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate));
    gl_FragColor =  diffuse * texture2D(u_Texture, v_TexCoordinate) ;
    gl_FragColor *= (v_Color * vec4(getPointLighting(),v_Color.w));
  }                                                                         

vec3 getPointLighting()
  {
      vec3 lightingSum = vec3(0.0);

      for (int i = 0; i < 3; i++) {
          vec3 toPointLight = vec3(u_PointLightPositions[i])
                            - vec3(v_Position);
          float distance = length(toPointLight);
          toPointLight = normalize(toPointLight);

          float cosine = max(dot(v_Normal, toPointLight), 0.0);

          //lightingSum += vec3(0.0, 0.0, 1.0);
          lightingSum += (vec3(v_Color.xyz) * u_PointLightColors[i] * 5.0 * cosine) / distance;
      }

      return lightingSum;
  }
    uniform vec3 u_LightPos;        // The position of the light in eye space.
uniform sampler2D u_Texture;    // The input texture.

varying vec3 v_Position;        // Interpolated position for this fragment.
varying vec3 v_Normal;          // Interpolated normal for this fragment.
varying vec2 v_TexCoordinate;   // Interpolated texture coordinate per fragment.

uniform vec4 v_Color;
varying vec3 lighting;
// The entry point for our fragment shader.
void main()                         
{

    gl_FragColor = texture2D(u_Texture, v_TexCoordinate) ;
    gl_FragColor *= vec4(lighting,1.0);
 } 
顶点

uniform mat4 u_MVPMatrix;       // A constant representing the combined model/view/projection matrix.                  
uniform mat4 u_MVMatrix;        // A constant representing the combined model/view matrix.              

attribute vec4 a_Position;      // Per-vertex position information we will pass in.                             
attribute vec3 a_Normal;        // Per-vertex normal information we will pass in.      
attribute vec2 a_TexCoordinate; // Per-vertex texture coordinate information we will pass in.       

varying vec3 v_Position;        // This will be passed into the fragment shader.                            
varying vec3 v_Normal;          // This will be passed into the fragment shader.  
varying vec2 v_TexCoordinate;   // This will be passed into the fragment shader.

uniform vec4 u_PointLightPositions[3];    // In eye space
uniform vec3 u_PointLightColors[3];

// The entry point for our vertex shader.  
void main()                                                     
{         

    // Transform the vertex into eye space.     
    v_Position = vec3(u_MVMatrix * a_Position);                 

    // Pass through the texture coordinate.
    v_TexCoordinate = a_TexCoordinate;                                      

    // Transform the normal's orientation into eye space.
    v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));

    // gl_Position is a special variable used to store the final position.
    // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
    gl_Position = u_MVPMatrix * a_Position;                               
}  
    uniform mat4 u_MVPMatrix;       // A constant representing the combined model/view/projection matrix.
uniform mat4 u_MVMatrix;        // A constant representing the combined model/view matrix.

attribute vec4 a_Position;      // Per-vertex position information we will pass in.
attribute vec3 a_Normal;        // Per-vertex normal information we will pass in.
attribute vec2 a_TexCoordinate; // Per-vertex texture coordinate information we will pass in.

varying vec3 v_Position;        // This will be passed into the fragment shader.
varying vec3 v_Normal;          // This will be passed into the fragment shader.
varying vec2 v_TexCoordinate;   // This will be passed into the fragment shader.

uniform vec4 u_PointLightPositions[3];    // In eye space
uniform vec3 u_PointLightColors[3];

uniform vec3 u_VectorToLight;             // In eye space
uniform mat4 u_IT_MVMatrix;
vec4 eyeSpacePosition;
vec3 eyeSpaceNormal;

uniform vec4 v_Color;
varying vec3 lighting;
vec3 materialColor;


vec3 getAmbientLighting();
vec3 getDirectionalLighting();
vec3 getPointLighting();

// The entry point for our vertex shader.
void main()
{
    materialColor = vec3(1.0, 1.0, 1.0); // Will be modified by the texture later.


    // Transform the vertex into eye space.
    v_Position = vec3(u_MVMatrix * a_Position);

    // Pass through the texture coordinate.
    v_TexCoordinate = a_TexCoordinate;

    // Transform the normal's orientation into eye space.
    v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));

    // gl_Position is a special variable used to store the final position.
    // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.

    eyeSpacePosition = u_MVMatrix * a_Position;

        // The model normals need to be adjusted as per the transpose
        // of the inverse of the modelview matrix.
    eyeSpaceNormal = normalize(vec3(u_IT_MVMatrix * vec4(a_Normal, 0.0)));

    gl_Position = u_MVPMatrix * a_Position;

    lighting = getAmbientLighting();
    lighting += getDirectionalLighting();
    lighting += getPointLighting();

}

vec3 getAmbientLighting()
{
    return materialColor * 0.2;
}

vec3 getDirectionalLighting()
{
    return materialColor * max(dot(eyeSpaceNormal, u_VectorToLight), 0.0);
}

vec3 getPointLighting()
{
    vec3 lightingSum = vec3(0.0);

    for (int i = 0; i < 3; i++) {
        vec3 toPointLight = vec3(u_PointLightPositions[i]) - vec3(eyeSpacePosition);
        float distance = length(toPointLight);
        toPointLight = normalize(toPointLight);

        float cosine = max(dot(eyeSpaceNormal, toPointLight), 0.0);
        lightingSum += (materialColor * u_PointLightColors[i] * 5.0 * cosine)
                       / distance;
    }

    return lightingSum;
}

在您的代码中有四个灯光,第四个位于u_LightPos

我建议您删除漫反射变量(第四个灯光)以及对v_颜色的所有引用(因为您也有纹理)。然后你应该开始只看到你的三盏路灯的照明


另外,为了提高性能,我还将灯光计算移到顶点着色器。

尝试了我认为您的建议,请帮助:)现在,对于每个顶点,您需要计算颜色(灯光)的数量。就像你以前在片段着色器中所做的那样。然后通过一个可变的vec3将其带到片段着色器。并与纹理相乘(例如)。目前它只显示纹理。我很快就会尝试,再次感谢您的帮助!如果您感到厌烦,可以将着色器粘贴到您的建议中?禁用getDirectionalLighting()(您的手电筒)一段时间,并增加lightingSum+=行上的5.0,直到您正确使用为止。伟大的我认为照明对地板不起作用,因为我缩放了它?有什么想法吗?这不是缩放。如果有大三角形,则顶点可能会完全错过灯光,并且插值不会显示该三角形中所有片段的灯光。然后(对于那些),你需要在片段着色器中执行此操作。看图片,立方体是否如你所期望的那样?是的,确实非常立方体;)如果您使用立方体作为“光源”,则可能应使其更亮,并忽略照明,否则(即,
gl\u FragColor=v\u color;
),可能使用不同的着色器程序。不管怎样,一堵看起来略带紫色的砖墙似乎将你的灯光组合在一起(红色、深绿色和蓝色)。
    uniform mat4 u_MVPMatrix;       // A constant representing the combined model/view/projection matrix.
uniform mat4 u_MVMatrix;        // A constant representing the combined model/view matrix.

attribute vec4 a_Position;      // Per-vertex position information we will pass in.
attribute vec3 a_Normal;        // Per-vertex normal information we will pass in.
attribute vec2 a_TexCoordinate; // Per-vertex texture coordinate information we will pass in.

varying vec3 v_Position;        // This will be passed into the fragment shader.
varying vec3 v_Normal;          // This will be passed into the fragment shader.
varying vec2 v_TexCoordinate;   // This will be passed into the fragment shader.

uniform vec4 u_PointLightPositions[3];    // In eye space
uniform vec3 u_PointLightColors[3];

uniform vec3 u_VectorToLight;             // In eye space
uniform mat4 u_IT_MVMatrix;
vec4 eyeSpacePosition;
vec3 eyeSpaceNormal;

uniform vec4 v_Color;
varying vec3 lighting;
vec3 materialColor;


vec3 getAmbientLighting();
vec3 getDirectionalLighting();
vec3 getPointLighting();

// The entry point for our vertex shader.
void main()
{
    materialColor = vec3(1.0, 1.0, 1.0); // Will be modified by the texture later.


    // Transform the vertex into eye space.
    v_Position = vec3(u_MVMatrix * a_Position);

    // Pass through the texture coordinate.
    v_TexCoordinate = a_TexCoordinate;

    // Transform the normal's orientation into eye space.
    v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));

    // gl_Position is a special variable used to store the final position.
    // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.

    eyeSpacePosition = u_MVMatrix * a_Position;

        // The model normals need to be adjusted as per the transpose
        // of the inverse of the modelview matrix.
    eyeSpaceNormal = normalize(vec3(u_IT_MVMatrix * vec4(a_Normal, 0.0)));

    gl_Position = u_MVPMatrix * a_Position;

    lighting = getAmbientLighting();
    lighting += getDirectionalLighting();
    lighting += getPointLighting();

}

vec3 getAmbientLighting()
{
    return materialColor * 0.2;
}

vec3 getDirectionalLighting()
{
    return materialColor * max(dot(eyeSpaceNormal, u_VectorToLight), 0.0);
}

vec3 getPointLighting()
{
    vec3 lightingSum = vec3(0.0);

    for (int i = 0; i < 3; i++) {
        vec3 toPointLight = vec3(u_PointLightPositions[i]) - vec3(eyeSpacePosition);
        float distance = length(toPointLight);
        toPointLight = normalize(toPointLight);

        float cosine = max(dot(eyeSpaceNormal, toPointLight), 0.0);
        lightingSum += (materialColor * u_PointLightColors[i] * 5.0 * cosine)
                       / distance;
    }

    return lightingSum;
}
//multiplyMM(mModelMatrix, 0, VMatrix, 0, mModelMatrix, 0);
//invertM(tempMatrix, 0, mModelMatrix, 0);
transposeM(it_modelViewMatrix, 0, VMatrix, 0);