UPDATE 3 (спасибо за помощь)OpenGL ES 2.0: Несколько источников света: Shader проблема
я снял то, что было предложено. Также u_IT_MVMatrix кажется неправильным (что все это для) Вещи выглядят немного лучше, но пол должен светиться и текстурированные кирпичи должны иметь свет от цветных кирпичей (синий, красный и т.д.)
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);
Отключите getDirectionalLighting() (ваш фонарик) некоторое время и увеличьте 5.0 на строке lightingSum + =, пока не получите правильное решение. Большой! – mikkokoo
Я думаю, что освещение не работает для пола, потому что я его масштабирую? Есть идеи? – Burf2000
Это не масштабирование. Если у вас большие треугольники, вершины могут полностью пропускать огни, а интерполяция не отображает свет для всех фрагментов в этом треугольнике. Затем (для тех) вам нужно будет сделать это в шейдере фрагмента. – mikkokoo