[DEV] tutorial 25 'multiple light' implementation

This commit is contained in:
Edouard DUPIN 2020-04-24 23:37:13 +02:00
parent 58441b9743
commit 6309551af2
9 changed files with 109 additions and 60 deletions

View File

@ -73,7 +73,10 @@ public class MainGameLoop {
fernModel.getTexture().setHasTransparency(true); fernModel.getTexture().setHasTransparency(true);
fernModel.getTexture().setNumberOfRows(2); fernModel.getTexture().setNumberOfRows(2);
Light light = new Light(new Vector3f(3000,2000,2000), new Vector3f(1,1,1)); List<Light> lights = new ArrayList<Light>();
lights.add(new Light(new Vector3f(0,10000,-7000), new Vector3f(1,1,1)));
lights.add(new Light(new Vector3f(-200,10,-200), new Vector3f(10,0,0)));
lights.add(new Light(new Vector3f(200,10,200), new Vector3f(0,0,10)));
TerrainTexture backgroundTexture = new TerrainTexture(loader.loadTexture("grass")); TerrainTexture backgroundTexture = new TerrainTexture(loader.loadTexture("grass"));
TerrainTexture rTexture = new TerrainTexture(loader.loadTexture("dirt")); TerrainTexture rTexture = new TerrainTexture(loader.loadTexture("dirt"));
@ -136,7 +139,7 @@ public class MainGameLoop {
entity.increaseRotation(0, 0.01f, 0.0f); entity.increaseRotation(0, 0.01f, 0.0f);
renderer.processEntity(entity); renderer.processEntity(entity);
} }
renderer.render(light, camera); renderer.render(lights, camera);
guiRenderer.render(guis); guiRenderer.render(guis);
} }
}); });

View File

@ -54,18 +54,18 @@ public class MasterRenderer {
GL11.glDisable(GL11.GL_BACK); GL11.glDisable(GL11.GL_BACK);
} }
public void render(Light sun, Camera camera) { public void render(List<Light> lights, Camera camera) {
prepare(); prepare();
shader.start(); shader.start();
shader.loadSkyColour(SKY_COLOUR); shader.loadSkyColour(SKY_COLOUR);
shader.loadLight(sun); shader.loadLights(lights);
shader.loadViewMatrix(camera); shader.loadViewMatrix(camera);
renderer.render(entities); renderer.render(entities);
shader.stop(); shader.stop();
entities.clear(); entities.clear();
terrainShader.start(); terrainShader.start();
terrainShader.loadSkyColour(SKY_COLOUR); terrainShader.loadSkyColour(SKY_COLOUR);
terrainShader.loadLight(sun); terrainShader.loadLights(lights);
terrainShader.loadViewMatrix(camera); terrainShader.loadViewMatrix(camera);
terrainRenderer.render(terrains); terrainRenderer.render(terrains);
terrainShader.stop(); terrainShader.stop();

View File

@ -90,6 +90,7 @@ public abstract class ShaderProgram {
} }
private static int loadShader(String file, int type) { private static int loadShader(String file, int type) {
System.out.println("Load shader: '" + file + "'");
StringBuilder shaderSource = new StringBuilder(); StringBuilder shaderSource = new StringBuilder();
try { try {
BufferedReader reader = new BufferedReader(new FileReader(file)); BufferedReader reader = new BufferedReader(new FileReader(file));

View File

@ -1,5 +1,7 @@
package shaders; package shaders;
import java.util.List;
import org.atriaSoft.etk.math.Matrix4f; import org.atriaSoft.etk.math.Matrix4f;
import org.atriaSoft.etk.math.Vector2f; import org.atriaSoft.etk.math.Vector2f;
import org.atriaSoft.etk.math.Vector3f; import org.atriaSoft.etk.math.Vector3f;
@ -9,14 +11,15 @@ import entities.Light;
import toolbox.Maths; import toolbox.Maths;
public class StaticShader extends ShaderProgram { public class StaticShader extends ShaderProgram {
private static final int MAX_LIGHTS = 4;
private static final String VERTEX_FILE = "src/shaders/vertexShader.txt"; private static final String VERTEX_FILE = "src/shaders/vertexShader.txt";
private static final String FRAGMENT_FILE = "src/shaders/fragmentShader.txt"; private static final String FRAGMENT_FILE = "src/shaders/fragmentShader.txt";
private int location_transformationMatrix; private int location_transformationMatrix;
private int location_projectionMatrix; private int location_projectionMatrix;
private int location_viewMatrix; private int location_viewMatrix;
private int location_lightPosition; private int location_lightPosition[];
private int location_lightColour; private int location_lightColour[];
private int location_reflectivity; private int location_reflectivity;
private int location_shineDamper; private int location_shineDamper;
private int location_useFakeLighting; private int location_useFakeLighting;
@ -40,14 +43,19 @@ public class StaticShader extends ShaderProgram {
location_transformationMatrix = super.getUniformLocation("transformationMatrix"); location_transformationMatrix = super.getUniformLocation("transformationMatrix");
location_projectionMatrix = super.getUniformLocation("projectionMatrix"); location_projectionMatrix = super.getUniformLocation("projectionMatrix");
location_viewMatrix = super.getUniformLocation("viewMatrix"); location_viewMatrix = super.getUniformLocation("viewMatrix");
location_lightPosition = super.getUniformLocation("lightPosition");
location_lightColour = super.getUniformLocation("lightColour");
location_reflectivity = super.getUniformLocation("reflectivity"); location_reflectivity = super.getUniformLocation("reflectivity");
location_shineDamper = super.getUniformLocation("shineDamper"); location_shineDamper = super.getUniformLocation("shineDamper");
location_useFakeLighting = super.getUniformLocation("useFakeLighting"); location_useFakeLighting = super.getUniformLocation("useFakeLighting");
location_skyColor = super.getUniformLocation("skyColor"); location_skyColor = super.getUniformLocation("skyColor");
location_numberOfRows = super.getUniformLocation("numberOfRows"); location_numberOfRows = super.getUniformLocation("numberOfRows");
location_offset = super.getUniformLocation("offset"); location_offset = super.getUniformLocation("offset");
location_lightPosition = new int[MAX_LIGHTS];
location_lightColour = new int[MAX_LIGHTS];
for (int iii=0; iii<MAX_LIGHTS; iii++) {
location_lightPosition[iii] = super.getUniformLocation("lightPosition[" + iii+ "]");
location_lightColour[iii] = super.getUniformLocation("lightColour[" + iii+ "]");
}
} }
@ -75,9 +83,16 @@ public class StaticShader extends ShaderProgram {
public void loadTransformationMatrix(Matrix4f matrix) { public void loadTransformationMatrix(Matrix4f matrix) {
super.loadMatrix(location_transformationMatrix, matrix); super.loadMatrix(location_transformationMatrix, matrix);
} }
public void loadLight(Light light) { public void loadLights(List<Light> lights) {
super.loadVector(location_lightPosition, light.getPosition()); for (int iii=0; iii<MAX_LIGHTS; iii++) {
super.loadVector(location_lightColour, light.getColour()); if (iii<lights.size()) {
super.loadVector(location_lightPosition[iii], lights.get(iii).getPosition());
super.loadVector(location_lightColour[iii], lights.get(iii).getColour());
} else {
super.loadVector(location_lightPosition[iii], new Vector3f(0,0,0));
super.loadVector(location_lightColour[iii], new Vector3f(0,0,0));
}
}
} }
public void loadProjectionMatrix(Matrix4f projection) { public void loadProjectionMatrix(Matrix4f projection) {
super.loadMatrix(location_projectionMatrix, projection); super.loadMatrix(location_projectionMatrix, projection);

View File

@ -1,5 +1,7 @@
package shaders; package shaders;
import java.util.List;
import org.atriaSoft.etk.math.Matrix4f; import org.atriaSoft.etk.math.Matrix4f;
import org.atriaSoft.etk.math.Vector3f; import org.atriaSoft.etk.math.Vector3f;
@ -8,14 +10,15 @@ import entities.Light;
import toolbox.Maths; import toolbox.Maths;
public class TerrainShader extends ShaderProgram { public class TerrainShader extends ShaderProgram {
private static final int MAX_LIGHTS = 4;
private static final String VERTEX_FILE = "src/shaders/terrainVertexShader.txt"; private static final String VERTEX_FILE = "src/shaders/terrainVertexShader.txt";
private static final String FRAGMENT_FILE = "src/shaders/terrainFragmentShader.txt"; private static final String FRAGMENT_FILE = "src/shaders/terrainFragmentShader.txt";
private int location_transformationMatrix; private int location_transformationMatrix;
private int location_projectionMatrix; private int location_projectionMatrix;
private int location_viewMatrix; private int location_viewMatrix;
private int location_lightPosition; private int location_lightPosition[];
private int location_lightColour; private int location_lightColour[];
private int location_reflectivity; private int location_reflectivity;
private int location_shineDamper; private int location_shineDamper;
private int location_skyColor; private int location_skyColor;
@ -41,8 +44,6 @@ public class TerrainShader extends ShaderProgram {
location_transformationMatrix = super.getUniformLocation("transformationMatrix"); location_transformationMatrix = super.getUniformLocation("transformationMatrix");
location_projectionMatrix = super.getUniformLocation("projectionMatrix"); location_projectionMatrix = super.getUniformLocation("projectionMatrix");
location_viewMatrix = super.getUniformLocation("viewMatrix"); location_viewMatrix = super.getUniformLocation("viewMatrix");
location_lightPosition = super.getUniformLocation("lightPosition");
location_lightColour = super.getUniformLocation("lightColour");
location_reflectivity = super.getUniformLocation("reflectivity"); location_reflectivity = super.getUniformLocation("reflectivity");
location_shineDamper = super.getUniformLocation("shineDamper"); location_shineDamper = super.getUniformLocation("shineDamper");
location_skyColor = super.getUniformLocation("skyColor"); location_skyColor = super.getUniformLocation("skyColor");
@ -51,6 +52,12 @@ public class TerrainShader extends ShaderProgram {
location_gTexture = super.getUniformLocation("gTexture"); location_gTexture = super.getUniformLocation("gTexture");
location_bTexture = super.getUniformLocation("bTexture"); location_bTexture = super.getUniformLocation("bTexture");
location_blendMap = super.getUniformLocation("blendMap"); location_blendMap = super.getUniformLocation("blendMap");
location_lightPosition = new int[MAX_LIGHTS];
location_lightColour = new int[MAX_LIGHTS];
for (int iii=0; iii<MAX_LIGHTS; iii++) {
location_lightPosition[iii] = super.getUniformLocation("lightPosition[" + iii+ "]");
location_lightColour[iii] = super.getUniformLocation("lightColour[" + iii+ "]");
}
} }
public void connectTextureUnits() { public void connectTextureUnits() {
@ -73,10 +80,17 @@ public class TerrainShader extends ShaderProgram {
public void loadTransformationMatrix(Matrix4f matrix) { public void loadTransformationMatrix(Matrix4f matrix) {
super.loadMatrix(location_transformationMatrix, matrix); super.loadMatrix(location_transformationMatrix, matrix);
} }
public void loadLight(Light light) { public void loadLights(List<Light> lights) {
super.loadVector(location_lightPosition, light.getPosition()); for (int iii=0; iii<MAX_LIGHTS; iii++) {
super.loadVector(location_lightColour, light.getColour()); if (iii<lights.size()) {
super.loadVector(location_lightPosition[iii], lights.get(iii).getPosition());
super.loadVector(location_lightColour[iii], lights.get(iii).getColour());
} else {
super.loadVector(location_lightPosition[iii], new Vector3f(0,0,0));
super.loadVector(location_lightColour[iii], new Vector3f(0,0,0));
}
}
} }
public void loadProjectionMatrix(Matrix4f projection) { public void loadProjectionMatrix(Matrix4f projection) {

View File

@ -2,7 +2,7 @@
in vec2 pass_textureCoordinates; in vec2 pass_textureCoordinates;
in vec3 surfaceNormal; in vec3 surfaceNormal;
in vec3 toLightVector; in vec3 toLightVector[4];
in vec3 toCameraVector; in vec3 toCameraVector;
// FOW: Fog Of War result calculation // FOW: Fog Of War result calculation
in float visibility; in float visibility;
@ -10,7 +10,7 @@ in float visibility;
out vec4 out_Color; out vec4 out_Color;
uniform sampler2D textureSampler; uniform sampler2D textureSampler;
uniform vec3 lightColour; uniform vec3 lightColour[4];
uniform float reflectivity; uniform float reflectivity;
uniform float shineDamper; uniform float shineDamper;
uniform vec3 skyColor; uniform vec3 skyColor;
@ -19,21 +19,25 @@ uniform vec3 skyColor;
void main(void) { void main(void) {
vec3 unitNormal = normalize(surfaceNormal); vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDot1 = dot(unitNormal, unitLightVector);
// the 0.2 represent the anbiant lightning ==> maybe set an uniform for this
float brightness = max(nDot1, 0.2);
vec3 diffuse = brightness * lightColour;
vec3 unitVectorToCamera = normalize(toCameraVector); vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector; vec3 totalDiffuse = vec3(0.0);
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal); vec3 totalSpecular = vec3(0.0);
for(int i=0;i<4;i++) {
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera); vec3 unitLightVector = normalize(toLightVector[i]);
specularFactor = max(specularFactor, 0.0); float nDot1 = dot(unitNormal, unitLightVector);
float damperFactor = pow(specularFactor, shineDamper); float brightness = max(nDot1, 0.0);
vec3 finalSpecular = damperFactor * reflectivity * lightColour; vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor, 0.0);
float damperFactor = pow(specularFactor, shineDamper);
vec3 diffuse = brightness * lightColour[i];
vec3 finalSpecular = damperFactor * reflectivity * lightColour[i];
totalDiffuse = totalDiffuse + diffuse;
totalSpecular = totalSpecular + finalSpecular;
}
// the 0.2 represent the ambiant lightning ==> maybe set an uniform for this
totalDiffuse = max (totalDiffuse, 0.2);
// disable transparency elements in the texture ... // disable transparency elements in the texture ...
// Can be set at the start of the shader ... // Can be set at the start of the shader ...
@ -42,7 +46,7 @@ void main(void) {
discard; discard;
} }
out_Color = vec4(diffuse,1.0) * textureColour + vec4(finalSpecular, 1.0); out_Color = vec4(totalDiffuse,1.0) * textureColour + vec4(totalSpecular, 1.0);
out_Color = mix(vec4(skyColor,1.0), out_Color, visibility); out_Color = mix(vec4(skyColor,1.0), out_Color, visibility);
} }

View File

@ -2,7 +2,7 @@
in vec2 pass_textureCoordinates; in vec2 pass_textureCoordinates;
in vec3 surfaceNormal; in vec3 surfaceNormal;
in vec3 toLightVector; in vec3 toLightVector[4];
in vec3 toCameraVector; in vec3 toCameraVector;
// FOW: Fog Of War result calculation // FOW: Fog Of War result calculation
in float visibility; in float visibility;
@ -15,7 +15,7 @@ uniform sampler2D gTexture;
uniform sampler2D bTexture; uniform sampler2D bTexture;
uniform sampler2D blendMap; uniform sampler2D blendMap;
uniform vec3 lightColour; uniform vec3 lightColour[4];
uniform float reflectivity; uniform float reflectivity;
uniform float shineDamper; uniform float shineDamper;
uniform vec3 skyColor; uniform vec3 skyColor;
@ -35,23 +35,31 @@ void main(void) {
vec4 totalColour = backgroundTextureColour + rTextureColour + gTextureColour + bTextureColour; vec4 totalColour = backgroundTextureColour + rTextureColour + gTextureColour + bTextureColour;
vec3 unitNormal = normalize(surfaceNormal); vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDot1 = dot(unitNormal, unitLightVector); vec3 totalDiffuse = vec3(0.0);
// the 0.2 represent the anbiant lightning ==> maybe set an uniform for this vec3 totalSpecular = vec3(0.0);
float brightness = max(nDot1, 0.2); for(int i=0;i<4;i++) {
vec3 diffuse = brightness * lightColour; vec3 unitLightVector = normalize(toLightVector[i]);
float nDot1 = dot(unitNormal, unitLightVector);
float brightness = max(nDot1, 0.0);
vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor, 0.0);
float damperFactor = pow(specularFactor, shineDamper);
vec3 diffuse = brightness * lightColour[i];
vec3 finalSpecular = damperFactor * reflectivity * lightColour[i];
totalDiffuse = totalDiffuse + diffuse;
totalSpecular = totalSpecular + finalSpecular;
}
// the 0.2 represent the ambiant lightning ==> maybe set an uniform for this
totalDiffuse = max (totalDiffuse, 0.2);
vec3 unitVectorToCamera = normalize(toCameraVector); out_Color = vec4(totalDiffuse,1.0) * totalColour + vec4(totalSpecular, 1.0);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor, 0.0);
float damperFactor = pow(specularFactor, shineDamper);
vec3 finalSpecular = damperFactor * reflectivity * lightColour;
out_Color = vec4(diffuse,1.0) * totalColour + vec4(finalSpecular, 1.0);
out_Color = mix(vec4(skyColor,1.0), out_Color, visibility); out_Color = mix(vec4(skyColor,1.0), out_Color, visibility);
} }

View File

@ -6,7 +6,7 @@ in vec3 normal;
out vec2 pass_textureCoordinates; out vec2 pass_textureCoordinates;
out vec3 surfaceNormal; out vec3 surfaceNormal;
out vec3 toLightVector; out vec3 toLightVector[4];
out vec3 toCameraVector; out vec3 toCameraVector;
// FOW: Fog Of War result calculation // FOW: Fog Of War result calculation
out float visibility; out float visibility;
@ -14,7 +14,7 @@ out float visibility;
uniform mat4 transformationMatrix; uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix; uniform mat4 projectionMatrix;
uniform mat4 viewMatrix; uniform mat4 viewMatrix;
uniform vec3 lightPosition; uniform vec3 lightPosition[4];
const float density = 0.007; const float density = 0.007;
const float gradient = 2.5; const float gradient = 2.5;
@ -26,7 +26,9 @@ void main(void) {
pass_textureCoordinates = textureCoords; pass_textureCoordinates = textureCoords;
surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz; surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz;
toLightVector = lightPosition - worldPosition.xyz; for(int i=0;i<4;i++) {
toLightVector[i] = lightPosition[i] - worldPosition.xyz;
}
toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz; toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;
float distance = length(positionRelativeToCam.xyz); float distance = length(positionRelativeToCam.xyz);

View File

@ -6,7 +6,7 @@ in vec3 normal;
out vec2 pass_textureCoordinates; out vec2 pass_textureCoordinates;
out vec3 surfaceNormal; out vec3 surfaceNormal;
out vec3 toLightVector; out vec3 toLightVector[4];
out vec3 toCameraVector; out vec3 toCameraVector;
// FOW: Fog Of War result calculation // FOW: Fog Of War result calculation
out float visibility; out float visibility;
@ -14,7 +14,7 @@ out float visibility;
uniform mat4 transformationMatrix; uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix; uniform mat4 projectionMatrix;
uniform mat4 viewMatrix; uniform mat4 viewMatrix;
uniform vec3 lightPosition; uniform vec3 lightPosition[4];
uniform float useFakeLighting; uniform float useFakeLighting;
@ -36,7 +36,9 @@ void main(void) {
actualNormal = vec3(0.0, 1.0, 0.0); actualNormal = vec3(0.0, 1.0, 0.0);
} }
surfaceNormal = (transformationMatrix * vec4(actualNormal, 0.0)).xyz; surfaceNormal = (transformationMatrix * vec4(actualNormal, 0.0)).xyz;
toLightVector = lightPosition - worldPosition.xyz; for(int i=0;i<4;i++) {
toLightVector[i] = lightPosition[i] - worldPosition.xyz;
}
toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz; toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;
float distance = length(positionRelativeToCam.xyz); float distance = length(positionRelativeToCam.xyz);