1

UPDATE 3 (спасибо за помощь)OpenGL ES 2.0: Несколько источников света: Shader проблема

я снял то, что было предложено. Также u_IT_MVMatrix кажется неправильным (что все это для) Вещи выглядят немного лучше, но пол должен светиться и текстурированные кирпичи должны иметь свет от цветных кирпичей (синий, красный и т.д.)

enter image description here

Vertex (фрагмент остался прежним) для текстурированных объектов

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; 
} 

Я всегда боролся с использованием нескольких источников света в шейдере, но я нашел пример в моей Android OpenGL 2.0 быстрого запуска книги.

Думаю, что я отдал его назад, к сожалению, что бы я ни делал, я, кажется, был светом, поэтому, когда я приближаюсь к объекту, он становится легче, что я хочу сделать 3 разных места (например, уличные фонари) источники света.

Я определяю мои легкие места и цвет в моей визуализации

// new lighting 
    public final float[] pointLightPositions = new float[] 
      {0f, 1f, 0f, 1f, 
       100f, 1f, 0f, 1f, 
       50f, 1f, 0f, 1f}; 

    public final float[] pointLightColors = new float[] 
      {1.00f, 0.20f, 0.20f, 
        0.02f, 0.25f, 0.02f, 
        0.02f, 0.20f, 1.00f}; 

Об оказании

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); 

шейдеры (вершина)

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;        
} 

Фрагмент

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; 
    } 

Я был бы очень рад, если кто-то может помочь :)

UPDATE 2

У меня есть освещение, разные цвета, но они светятся только тогда, когда я действительно близко? Я уверен, что его что-то делать с матрицей u_IT_MVMatrix

Фрагмент

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); 
} 

Vertex

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); 
+1

Отключите getDirectionalLighting() (ваш фонарик) некоторое время и увеличьте 5.0 на строке lightingSum + =, пока не получите правильное решение. Большой! – mikkokoo

+0

Я думаю, что освещение не работает для пола, потому что я его масштабирую? Есть идеи? – Burf2000

+1

Это не масштабирование. Если у вас большие треугольники, вершины могут полностью пропускать огни, а интерполяция не отображает свет для всех фрагментов в этом треугольнике. Затем (для тех) вам нужно будет сделать это в шейдере фрагмента. – mikkokoo

ответ

1

В вашем коде у вас есть четыре огня, четвертый - в u_LightPos.

Я предлагаю вам удалить диффузную переменную (четвертый свет) в целом, а также все ссылки на v_Color (так как у вас также есть текстура). Тогда вы должны начать видеть только освещение ваших трех уличных фонарей.

пс. Я бы также перевел вычисления света в вершинный шейдер ради производительности.

+0

Пробовал, что я думаю, вы предложили, пожалуйста, помогите :) – Burf2000

+1

Теперь для каждой вершины вам нужно рассчитать количество цветов (свет). Как раньше вы делали фрагментарный шейдер. Затем переносите это в шейдер фрагмента через переменный vec3. И умножьте (например) на текстуру. В настоящее время он показывает только текстуру. – mikkokoo

+0

Я даю это очень скоро, снова спасибо за вашу помощь! Если вам скучно, можете вставить шейдеры в том, что вы предлагаете? – Burf2000

Смежные вопросы