From 6309551af2f90823a7477ca305beb046bd43b562 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Fri, 24 Apr 2020 23:37:13 +0200 Subject: [PATCH] [DEV] tutorial 25 'multiple light' implementation --- src/engineTester/MainGameLoop.java | 7 +++-- src/renderEngine/MasterRenderer.java | 6 ++-- src/shaders/ShaderProgram.java | 1 + src/shaders/StaticShader.java | 29 +++++++++++++----- src/shaders/TerrainShader.java | 30 ++++++++++++++----- src/shaders/fragmentShader.txt | 38 +++++++++++++----------- src/shaders/terrainFragmentShader.txt | 42 ++++++++++++++++----------- src/shaders/terrainVertexShader.txt | 8 +++-- src/shaders/vertexShader.txt | 8 +++-- 9 files changed, 109 insertions(+), 60 deletions(-) diff --git a/src/engineTester/MainGameLoop.java b/src/engineTester/MainGameLoop.java index 6fd6bfe..c16d969 100644 --- a/src/engineTester/MainGameLoop.java +++ b/src/engineTester/MainGameLoop.java @@ -73,7 +73,10 @@ public class MainGameLoop { fernModel.getTexture().setHasTransparency(true); fernModel.getTexture().setNumberOfRows(2); - Light light = new Light(new Vector3f(3000,2000,2000), new Vector3f(1,1,1)); + List lights = new ArrayList(); + 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 rTexture = new TerrainTexture(loader.loadTexture("dirt")); @@ -136,7 +139,7 @@ public class MainGameLoop { entity.increaseRotation(0, 0.01f, 0.0f); renderer.processEntity(entity); } - renderer.render(light, camera); + renderer.render(lights, camera); guiRenderer.render(guis); } }); diff --git a/src/renderEngine/MasterRenderer.java b/src/renderEngine/MasterRenderer.java index e36d884..1dfb131 100644 --- a/src/renderEngine/MasterRenderer.java +++ b/src/renderEngine/MasterRenderer.java @@ -54,18 +54,18 @@ public class MasterRenderer { GL11.glDisable(GL11.GL_BACK); } - public void render(Light sun, Camera camera) { + public void render(List lights, Camera camera) { prepare(); shader.start(); shader.loadSkyColour(SKY_COLOUR); - shader.loadLight(sun); + shader.loadLights(lights); shader.loadViewMatrix(camera); renderer.render(entities); shader.stop(); entities.clear(); terrainShader.start(); terrainShader.loadSkyColour(SKY_COLOUR); - terrainShader.loadLight(sun); + terrainShader.loadLights(lights); terrainShader.loadViewMatrix(camera); terrainRenderer.render(terrains); terrainShader.stop(); diff --git a/src/shaders/ShaderProgram.java b/src/shaders/ShaderProgram.java index d7a3abb..43bd3dd 100644 --- a/src/shaders/ShaderProgram.java +++ b/src/shaders/ShaderProgram.java @@ -90,6 +90,7 @@ public abstract class ShaderProgram { } private static int loadShader(String file, int type) { + System.out.println("Load shader: '" + file + "'"); StringBuilder shaderSource = new StringBuilder(); try { BufferedReader reader = new BufferedReader(new FileReader(file)); diff --git a/src/shaders/StaticShader.java b/src/shaders/StaticShader.java index 70985bd..a781277 100644 --- a/src/shaders/StaticShader.java +++ b/src/shaders/StaticShader.java @@ -1,5 +1,7 @@ package shaders; +import java.util.List; + import org.atriaSoft.etk.math.Matrix4f; import org.atriaSoft.etk.math.Vector2f; import org.atriaSoft.etk.math.Vector3f; @@ -9,14 +11,15 @@ import entities.Light; import toolbox.Maths; 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 FRAGMENT_FILE = "src/shaders/fragmentShader.txt"; private int location_transformationMatrix; private int location_projectionMatrix; private int location_viewMatrix; - private int location_lightPosition; - private int location_lightColour; + private int location_lightPosition[]; + private int location_lightColour[]; private int location_reflectivity; private int location_shineDamper; private int location_useFakeLighting; @@ -40,14 +43,19 @@ public class StaticShader extends ShaderProgram { location_transformationMatrix = super.getUniformLocation("transformationMatrix"); location_projectionMatrix = super.getUniformLocation("projectionMatrix"); location_viewMatrix = super.getUniformLocation("viewMatrix"); - location_lightPosition = super.getUniformLocation("lightPosition"); - location_lightColour = super.getUniformLocation("lightColour"); location_reflectivity = super.getUniformLocation("reflectivity"); location_shineDamper = super.getUniformLocation("shineDamper"); location_useFakeLighting = super.getUniformLocation("useFakeLighting"); location_skyColor = super.getUniformLocation("skyColor"); location_numberOfRows = super.getUniformLocation("numberOfRows"); location_offset = super.getUniformLocation("offset"); + + location_lightPosition = new int[MAX_LIGHTS]; + location_lightColour = new int[MAX_LIGHTS]; + for (int iii=0; iii lights) { + for (int iii=0; iii lights) { + for (int iii=0; iii maybe set an uniform for this - float brightness = max(nDot1, 0.2); - vec3 diffuse = brightness * lightColour; - 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 finalSpecular = damperFactor * reflectivity * lightColour; + vec3 totalDiffuse = vec3(0.0); + vec3 totalSpecular = vec3(0.0); + for(int i=0;i<4;i++) { + vec3 unitLightVector = normalize(toLightVector[i]); + float nDot1 = dot(unitNormal, unitLightVector); + float brightness = max(nDot1, 0.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 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 ... // Can be set at the start of the shader ... @@ -42,7 +46,7 @@ void main(void) { 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); } diff --git a/src/shaders/terrainFragmentShader.txt b/src/shaders/terrainFragmentShader.txt index 5f863f2..6688884 100644 --- a/src/shaders/terrainFragmentShader.txt +++ b/src/shaders/terrainFragmentShader.txt @@ -2,7 +2,7 @@ in vec2 pass_textureCoordinates; in vec3 surfaceNormal; -in vec3 toLightVector; +in vec3 toLightVector[4]; in vec3 toCameraVector; // FOW: Fog Of War result calculation in float visibility; @@ -15,7 +15,7 @@ uniform sampler2D gTexture; uniform sampler2D bTexture; uniform sampler2D blendMap; -uniform vec3 lightColour; +uniform vec3 lightColour[4]; uniform float reflectivity; uniform float shineDamper; uniform vec3 skyColor; @@ -35,23 +35,31 @@ void main(void) { vec4 totalColour = backgroundTextureColour + rTextureColour + gTextureColour + bTextureColour; 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 totalDiffuse = vec3(0.0); + vec3 totalSpecular = vec3(0.0); + for(int i=0;i<4;i++) { + 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); - 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 = vec4(totalDiffuse,1.0) * totalColour + vec4(totalSpecular, 1.0); out_Color = mix(vec4(skyColor,1.0), out_Color, visibility); } diff --git a/src/shaders/terrainVertexShader.txt b/src/shaders/terrainVertexShader.txt index 8db3b01..149182e 100644 --- a/src/shaders/terrainVertexShader.txt +++ b/src/shaders/terrainVertexShader.txt @@ -6,7 +6,7 @@ in vec3 normal; out vec2 pass_textureCoordinates; out vec3 surfaceNormal; -out vec3 toLightVector; +out vec3 toLightVector[4]; out vec3 toCameraVector; // FOW: Fog Of War result calculation out float visibility; @@ -14,7 +14,7 @@ out float visibility; uniform mat4 transformationMatrix; uniform mat4 projectionMatrix; uniform mat4 viewMatrix; -uniform vec3 lightPosition; +uniform vec3 lightPosition[4]; const float density = 0.007; const float gradient = 2.5; @@ -26,7 +26,9 @@ void main(void) { pass_textureCoordinates = textureCoords; 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; float distance = length(positionRelativeToCam.xyz); diff --git a/src/shaders/vertexShader.txt b/src/shaders/vertexShader.txt index b853fe1..233f1a9 100644 --- a/src/shaders/vertexShader.txt +++ b/src/shaders/vertexShader.txt @@ -6,7 +6,7 @@ in vec3 normal; out vec2 pass_textureCoordinates; out vec3 surfaceNormal; -out vec3 toLightVector; +out vec3 toLightVector[4]; out vec3 toCameraVector; // FOW: Fog Of War result calculation out float visibility; @@ -14,7 +14,7 @@ out float visibility; uniform mat4 transformationMatrix; uniform mat4 projectionMatrix; uniform mat4 viewMatrix; -uniform vec3 lightPosition; +uniform vec3 lightPosition[4]; uniform float useFakeLighting; @@ -36,7 +36,9 @@ void main(void) { actualNormal = vec3(0.0, 1.0, 0.0); } 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; float distance = length(positionRelativeToCam.xyz);