Restructured deferred lighting/rendering

This commit is contained in:
2020-05-12 15:19:05 -05:00
parent 7c81dd93e3
commit dae950c72a
14 changed files with 152 additions and 225 deletions

View File

@@ -2,9 +2,10 @@ class IMICFPS
class Light
DIRECTIONAL = 0
POINT = 1
SPOT = 2
attr_reader :light_id
attr_accessor :type, :ambient, :diffuse, :specular, :position, :intensity
attr_accessor :type, :ambient, :diffuse, :specular, :position, :direction, :intensity
def initialize(
id:,
type: Light::POINT,
@@ -12,6 +13,7 @@ class IMICFPS
diffuse: Vector.new(1, 1, 1),
specular: Vector.new(0.2, 0.2, 0.2),
position: Vector.new(0, 0, 0),
direction: Vector.new(0, 0, 0),
intensity: 1
)
@light_id = id
@@ -21,6 +23,7 @@ class IMICFPS
@diffuse = diffuse
@specular = specular
@position = position
@direction = direction
@intensity = intensity
end

View File

@@ -119,11 +119,6 @@ class IMICFPS
buffer = " " * 4
glGenBuffers(1, buffer)
@uvs_buffer_id = buffer.unpack('L2').first
@textures_buffer_id = nil
buffer = " " * 4
glGenBuffers(1, buffer)
@textures_buffer_id = buffer.unpack('L2').first
end
def populate_vertex_buffer
@@ -131,7 +126,6 @@ class IMICFPS
colors = []
norms = []
uvs = []
tex_ids = []
@faces.each do |face|
pos << face.vertices.map { |vert| [vert.x, vert.y, vert.z] }
@@ -140,7 +134,6 @@ class IMICFPS
if has_texture?
uvs << face.uvs.map { |vert| [vert.x, vert.y, vert.z] }
tex_ids << face.material.texture_id ? face.material.texture_id.to_f : -1.0
end
end
@@ -156,9 +149,6 @@ class IMICFPS
if has_texture?
glBindBuffer(GL_ARRAY_BUFFER, @uvs_buffer_id)
glBufferData(GL_ARRAY_BUFFER, uvs.flatten.size * Fiddle::SIZEOF_FLOAT, uvs.flatten.pack("f*"), GL_STATIC_DRAW)
# glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id)
# glBufferData(GL_ARRAY_BUFFER, tex_ids.flatten.size * Fiddle::SIZEOF_FLOAT, tex_ids.flatten.pack("f*"), GL_STATIC_DRAW)
end
glBindBuffer(GL_ARRAY_BUFFER, 0)
@@ -193,11 +183,6 @@ class IMICFPS
# inUV
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, nil)
gl_error?
# texture ids
glBindBuffer(GL_ARRAY_BUFFER, @textures_buffer_id)
# inTextureID
glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, 0, nil)
gl_error?
end
glBindBuffer(GL_ARRAY_BUFFER, 0)

View File

@@ -127,6 +127,9 @@ class IMICFPS
glBufferData(GL_ARRAY_BUFFER, @uvs.size * Fiddle::SIZEOF_FLOAT, @uvs.pack("f*"), GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nil)
glEnableVertexAttribArray(0)
glEnableVertexAttribArray(1)
glBindVertexArray(0)
end

View File

@@ -16,27 +16,16 @@ class IMICFPS
end
def render(camera, lights, entities)
if window.config.get(:debug_options, :use_shaders) && Shader.available?("default") && Shader.available?("render_screen")
if window.config.get(:debug_options, :use_shaders) && Shader.available?("g_buffer") && Shader.available?("deferred_lighting")
@g_buffer.bind_for_writing
gl_error?
glClearColor(0.0, 0.0, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
Shader.use("default") do |shader|
lights.each_with_index do |light, i|
shader.uniform_float("lights[#{i}.end", -1.0);
shader.uniform_float("lights[#{i}.type", light.type);
shader.uniform_vec3("lights[#{i}].position", light.position)
shader.uniform_vec3("lights[#{i}].ambient", light.ambient)
shader.uniform_vec3("lights[#{i}].diffuse", light.diffuse)
shader.uniform_vec3("lights[#{i}].specular", light.specular)
end
Shader.use("g_buffer") do |shader|
gl_error?
shader.uniform_integer("totalLights", lights.size)
entities.each do |entity|
next unless entity.visible && entity.renderable
@@ -54,7 +43,6 @@ class IMICFPS
@g_buffer.unbind_framebuffer
gl_error?
@g_buffer.bind_for_reading
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)
@@ -65,7 +53,7 @@ class IMICFPS
@g_buffer.unbind_framebuffer
gl_error?
else
puts "Shader 'default' failed to compile, using immediate mode for rendering..." unless @@immediate_mode_warning
puts "Shaders are disabled or failed to compile, using immediate mode for rendering..." unless @@immediate_mode_warning
@@immediate_mode_warning = true
gl_error?
@@ -94,7 +82,7 @@ class IMICFPS
gl_error?
end
def lighting(lights)
def copy_g_buffer_to_screen
@g_buffer.set_read_buffer(:position)
glBlitFramebuffer(0, 0, @g_buffer.width, @g_buffer.height,
0, 0, @g_buffer.width / 2, @g_buffer.height / 2,
@@ -116,15 +104,50 @@ class IMICFPS
GL_COLOR_BUFFER_BIT, GL_LINEAR)
end
def lighting(lights)
Shader.use("deferred_lighting") do |shader|
lights.each_with_index do |light, i|
shader.uniform_float("light.type", light.type);
shader.uniform_vec3("light.direction", light.direction)
shader.uniform_vec3("light.position", light.position)
shader.uniform_vec3("light.ambient", light.ambient)
shader.uniform_vec3("light.diffuse", light.diffuse)
shader.uniform_vec3("light.specular", light.specular)
glBindVertexArray(@g_buffer.screen_vbo)
glDisable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:diffuse))
glActiveTexture(GL_TEXTURE1)
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:position))
glActiveTexture(GL_TEXTURE2)
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:texcoord))
glActiveTexture(GL_TEXTURE3)
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:normal))
glActiveTexture(GL_TEXTURE4)
glBindTexture(GL_TEXTURE_2D, @g_buffer.texture(:depth))
glDrawArrays(GL_TRIANGLES, 0, @g_buffer.vertices.size)
glBindVertexArray(0)
end
end
end
def post_processing
end
def render_framebuffer
if Shader.available?("render_screen")
Shader.use("render_screen") do |shader|
if Shader.available?("deferred_lighting")
Shader.use("deferred_lighting") do |shader|
glBindVertexArray(@g_buffer.screen_vbo)
glEnableVertexAttribArray(0)
glEnableVertexAttribArray(1)
glDisable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
@@ -134,8 +157,6 @@ class IMICFPS
glDrawArrays(GL_TRIANGLES, 0, @g_buffer.vertices.size)
glDisableVertexAttribArray(1)
glDisableVertexAttribArray(0)
glBindVertexArray(0)
end
end

View File

@@ -10,7 +10,7 @@ class IMICFPS
end
def preload_default_shaders
shaders = ["default", "render_screen"]
shaders = ["g_buffer", "deferred_lighting"]
shaders.each do |shader|
Shader.new(
name: shader,

View File

@@ -8,15 +8,6 @@ class IMICFPS
window.needs_cursor = false
@manifest = @options[:manifest]
if window.config.get(:debug_options, :use_shaders) && !Shader.available?("default")
Shader.new(
name: "default",
includes_dir: "shaders/include",
vertex: "shaders/vertex/default.glsl",
fragment: "shaders/fragment/default.glsl"
)
end
@map = ProtoMap.new
Publisher.new
@@ -27,7 +18,7 @@ class IMICFPS
@crosshair = Crosshair.new(color: Gosu::Color.rgba(100, 200, 255, 100))
@lights = []
@light = Light.new(id: available_light, position: Vector.new, diffuse: Vector.new(1, 1, 1, 1))
@light = Light.new(type: Light::DIRECTIONAL, id: available_light, position: Vector.new, diffuse: Vector.new(1, 1, 1, 1))
@lights << @light
@camera = Camera.new(position: Vector.new(0, 1.5, 5), orientation: Vector.forward)

View File

@@ -1,108 +0,0 @@
# version 330 core
@include "light_struct"
layout(location = 0) out vec3 fragPosition;
layout (location = 1) out vec4 fragColor;
layout (location = 2) out vec3 fragNormal;
layout (location = 3) out vec3 fragUV;
in vec3 outPosition;
in vec3 outColor;
in vec3 outNormal;
in vec3 outUV;
in float outTextureID;
in Light outLights[MAX_LIGHTS];
flat in int outTotalLights;
in vec3 outFragPos;
in vec3 outCameraPos;
flat in int outHasTexture;
flat in int outDisableLighting;
uniform sampler2D diffuse_texture;
// optimizing compilers are annoying at this stage of my understanding of GLSL
vec4 lokiVar;
// https://learnopengl.com/Lighting/Multiple-lights
vec3 calculatePointLight(Light light) {
vec3 viewDir = normalize(outCameraPos - outFragPos);
vec3 lightDir = normalize(light.position - outFragPos);
float diff = max(dot(vec3(outNormal), lightDir), 0.0);
vec3 reflectDir = reflect(-lightDir, vec3(outNormal));
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16.0);
float distance = length(light.position - outFragPos);
float attenuation = 1.0 / (1.0 + 0.09 * distance +
0.032 * (distance * distance));
vec3 ambient = light.ambient * outColor;
vec3 diffuse = light.diffuse * outColor;
vec3 specular = light.specular * spec * vec3(1.0, 1.0, 1.0);
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return (ambient + diffuse + specular);
}
// https://learnopengl.com/Lighting/Basic-Lighting
vec3 calculateBasicLight(Light light) {
vec3 lightDir = normalize(light.position - outFragPos);
float ambientStrength = 0.25;
vec3 ambient = ambientStrength * light.ambient;
float diff = max(dot(normalize(vec3(outNormal)), lightDir), 0.0);
vec3 diffuse = diff * light.diffuse;
float specularStrength = 0.5;
vec3 viewDir = normalize(outCameraPos - outFragPos);
vec3 reflectDir = reflect(-lightDir, outNormal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * light.specular;
return vec3(ambient + diffuse + specular);
}
vec3 calculateLighting() {
vec3 result = vec3(0.0, 0.0, 0.0);
for (int i = 0; i < min(outTotalLights, MAX_LIGHTS); i++) {
if (int(outLights[i].type) == 0) {
result += calculateBasicLight(outLights[i]);
} else if (int(outLights[i].type) == 1) {
result += calculateBasicLight(outLights[i]);
}
}
return result;
}
void main() {
lokiVar = vec4(outColor, 1.0) + vec4(outNormal, 1.0) + vec4(outUV, 1.0) + vec4(outTextureID, 1.0, 1.0, 1.0);
lokiVar = normalize(lokiVar);
vec3 result;
if (outHasTexture == 0) {
if (outDisableLighting == 1.0) {
result = outColor + 0.25;
} else {
result = calculateLighting() * outColor;
}
} else {
if (outDisableLighting == 1.0) {
result = texture(diffuse_texture, outUV.xy).xyz + 0.25;
} else {
result = calculateLighting() * texture(diffuse_texture, outUV.xy).xyz;
}
}
fragPosition = outPosition;
fragColor = vec4(result, 1.0);
fragNormal = outNormal;
fragUV = outUV;
}

View File

@@ -0,0 +1,35 @@
#version 330 core
out vec4 FragColor;
@include "light_struct"
const int DIRECTIONAL = 0;
const int POINT = 1;
const int SPOT = 2;
in vec2 outTexCoords;
flat in Light outLight;
uniform sampler2D diffuse, position, texcoord, normal, depth;
vec4 directionalLight(Light light) {
return vec4(0,0,0,0);
}
vec4 calculateLighting(Light light) {
vec4 result = vec4(0,0,0,0);
switch(light.type) {
case DIRECTIONAL: {
result = directionalLight(light);
}
default: {
result = vec4(1,1,1,1);
}
}
return result;
}
void main() {
FragColor = texture(diffuse, outTexCoords) * calculateLighting(outLight);
}

View File

@@ -0,0 +1,26 @@
# version 330 core
layout(location = 0) out vec3 fragPosition;
layout (location = 1) out vec4 fragColor;
layout (location = 2) out vec3 fragNormal;
layout (location = 3) out vec3 fragUV;
in vec3 outPosition, outColor, outNormal, outUV, outFragPos, outCameraPos;
flat in int outHasTexture;
uniform sampler2D diffuse_texture;
void main() {
vec3 result;
if (outHasTexture == 0) {
result = outColor;
} else {
result = texture(diffuse_texture, outUV.xy).xyz + 0.25;
}
fragPosition = outPosition;
fragColor = vec4(result, 1.0);
fragNormal = outNormal;
fragUV = outUV;
}

View File

@@ -1,10 +0,0 @@
#version 330 core
out vec4 FragColor;
in vec2 outTexCoords;
uniform sampler2D screenTexture;
void main() {
FragColor = texture(screenTexture, outTexCoords);
}

View File

@@ -1,15 +1,11 @@
const int MAX_LIGHTS = 2;
struct Light {
float end;
float type;
int type;
vec3 direction;
vec3 position;
vec3 diffuse;
vec3 ambient;
vec3 specular;
vec3 direction;
float intensity;
};

View File

@@ -1,50 +0,0 @@
# version 330 core
@include "light_struct"
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec3 inNormal;
layout(location = 3) in vec3 inUV;
layout(location = 4) in float inTextureID;
out vec3 outPosition;
out vec3 outColor;
out vec3 outNormal;
out vec3 outUV;
out float outTextureID;
out Light outLights[MAX_LIGHTS];
flat out int outTotalLights;
out vec3 outFragPos;
out vec3 outViewPos;
out vec3 outCameraPos;
flat out int outHasTexture;
flat out int outDisableLighting;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform int hasTexture;
uniform int totalLights;
uniform Light lights[MAX_LIGHTS];
uniform vec3 cameraPos;
uniform int disableLighting;
void main() {
// projection * view * model * position
outPosition = inPosition;
outColor = inColor;
outNormal= normalize(transpose(inverse(mat3(model))) * inNormal);
outUV = inUV;
outTextureID = inTextureID;
outHasTexture = hasTexture;
outLights = lights;
outTotalLights = totalLights;
outCameraPos = cameraPos;
outDisableLighting = disableLighting;
outFragPos = vec3(model * vec4(inPosition, 1.0));
gl_Position = projection * view * model * vec4(inPosition, 1.0);
}

View File

@@ -1,10 +1,17 @@
#version 330 core
@include "light_struct"
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 inTexCoords;
uniform sampler2D diffuse, position, texcoord, normal, depth;
uniform Light light;
out vec2 outTexCoords;
flat out Light outLight;
void main() {
gl_Position = vec4(inPosition.x, inPosition.y, inPosition.z, 1.0);
gl_Position = vec4(inPosition.x, inPosition.y, inPosition.z, 1.0);
outTexCoords = inTexCoords;
}
outLight = light;
}

View File

@@ -0,0 +1,28 @@
# version 330 core
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec3 inNormal;
layout(location = 3) in vec3 inUV;
uniform mat4 projection, view, model;
uniform int hasTexture;
uniform vec3 cameraPos;
out vec3 outPosition, outColor, outNormal, outUV;
out vec3 outFragPos, outViewPos, outCameraPos;
flat out int outHasTexture;
void main() {
// projection * view * model * position
outPosition = inPosition;
outColor = inColor;
outNormal= normalize(transpose(inverse(mat3(model))) * inNormal);
outUV = inUV;
outHasTexture = hasTexture;
outCameraPos = cameraPos;
outFragPos = vec3(model * vec4(inPosition, 1.0));
gl_Position = projection * view * model * vec4(inPosition, 1.0);
}