lights
This commit is contained in:
parent
17f8d58a67
commit
29e8eff82a
4
.gitignore
vendored
4
.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
opengl-deferred
|
opengl-deferred
|
||||||
|
assets/textures
|
||||||
|
assets/geometries
|
@ -5,7 +5,7 @@ layout (location = 1) in vec2 _tex;
|
|||||||
layout (location = 2) in vec3 _norm;
|
layout (location = 2) in vec3 _norm;
|
||||||
|
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
uniform mat4 camera;
|
uniform mat4 view;
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
|
|
||||||
out vec3 pos;
|
out vec3 pos;
|
||||||
@ -13,7 +13,7 @@ out vec3 norm;
|
|||||||
out vec2 tex;
|
out vec2 tex;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = projection * camera * model * vec4(_pos, 1.0);
|
gl_Position = projection * view * model * vec4(_pos, 1.0);
|
||||||
pos = vec3(model * vec4(_pos, 1.0));
|
pos = vec3(model * vec4(_pos, 1.0));
|
||||||
norm = _norm;
|
norm = _norm;
|
||||||
tex = _tex;
|
tex = _tex;
|
||||||
|
@ -1,20 +1,65 @@
|
|||||||
#version 460 core
|
#version 460 core
|
||||||
|
|
||||||
uniform sampler2D albedo;
|
// gbuffer textures
|
||||||
uniform sampler2D depth;
|
uniform sampler2D s_albedo;
|
||||||
uniform sampler2D normal;
|
uniform sampler2D s_depth;
|
||||||
uniform sampler2D material;
|
uniform sampler2D s_normal;
|
||||||
uniform sampler2D position;
|
uniform sampler2D s_material;
|
||||||
|
uniform sampler2D s_position;
|
||||||
|
|
||||||
|
// lights
|
||||||
|
#define MAX_LIGHT_COUNT 100
|
||||||
|
#define POINT 0
|
||||||
|
#define SPOT 1
|
||||||
|
#define DIRECTIONAL 2
|
||||||
|
#define AMBIENT 3
|
||||||
|
|
||||||
|
struct light_t {
|
||||||
|
vec3 color;
|
||||||
|
vec3 position;
|
||||||
|
vec3 direction;
|
||||||
|
float intensity;
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform light_t lights[MAX_LIGHT_COUNT];
|
||||||
|
uniform int light_count;
|
||||||
|
|
||||||
|
uniform vec3 view_pos;
|
||||||
|
|
||||||
|
// from vertex shader
|
||||||
in vec3 pos;
|
in vec3 pos;
|
||||||
in vec2 tex;
|
in vec2 tex;
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
float map(float value, float min1, float max1, float min2, float max2) {
|
vec3 albedo;
|
||||||
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
|
float depth;
|
||||||
|
vec3 normal;
|
||||||
|
vec3 material; // specular, roughness, metalic
|
||||||
|
vec3 position;
|
||||||
|
|
||||||
|
vec3 calc_light(light_t light) {
|
||||||
|
vec3 light_dir = normalize(light.position - position);
|
||||||
|
vec3 view_dir = normalize(view_pos - position);
|
||||||
|
vec3 reflect_dir = reflect(-light_dir, normal);
|
||||||
|
|
||||||
|
float diffuse = max(dot(normal, light_dir), 0.0);
|
||||||
|
float specular = pow(max(dot(view_dir, reflect_dir), 0.0), 1 - material.y) * material.x;
|
||||||
|
|
||||||
|
return (diffuse + specular) * light.intensity * light.color / max(pow(length(light.position - position), 2), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
FragColor = texture(position, tex);
|
albedo = texture(s_albedo, tex).rgb;
|
||||||
|
depth = texture(s_depth, tex).x;
|
||||||
|
normal = (texture(s_normal, tex).rgb * 2) - 1;
|
||||||
|
material = texture(s_material, tex).xyz;
|
||||||
|
position = texture(s_position, tex).xyz;
|
||||||
|
|
||||||
|
vec3 light_result;
|
||||||
|
for (int i = 0; i < light_count; i++) {
|
||||||
|
light_result += calc_light(lights[i]);
|
||||||
|
}
|
||||||
|
FragColor = vec4(albedo * light_result, 1);
|
||||||
}
|
}
|
42
main.go
42
main.go
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"git.tek.govt.hu/dowerx/opengl-deferred/types/gbuffer"
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/gbuffer"
|
||||||
"git.tek.govt.hu/dowerx/opengl-deferred/types/geometry"
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/geometry"
|
||||||
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/light"
|
||||||
"git.tek.govt.hu/dowerx/opengl-deferred/types/shader"
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/shader"
|
||||||
"git.tek.govt.hu/dowerx/opengl-deferred/types/texture"
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/texture"
|
||||||
"github.com/go-gl/gl/v4.6-core/gl"
|
"github.com/go-gl/gl/v4.6-core/gl"
|
||||||
@ -15,8 +16,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
WIDTH = 640
|
WIDTH = 800
|
||||||
HEIGHT = 480
|
HEIGHT = 600
|
||||||
TITLE = "opengl-deferred"
|
TITLE = "opengl-deferred"
|
||||||
FOV = 45.0
|
FOV = 45.0
|
||||||
)
|
)
|
||||||
@ -48,7 +49,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gl.Enable(gl.DEPTH_TEST)
|
gl.Enable(gl.DEPTH_TEST)
|
||||||
// gl.Enable(gl.CULL_FACE)
|
gl.Enable(gl.CULL_FACE)
|
||||||
gl.DepthFunc(gl.LESS)
|
gl.DepthFunc(gl.LESS)
|
||||||
gl.ClearColor(0, 0, 0, 0)
|
gl.ClearColor(0, 0, 0, 0)
|
||||||
|
|
||||||
@ -87,7 +88,7 @@ func main() {
|
|||||||
defer screenShader.Delete()
|
defer screenShader.Delete()
|
||||||
|
|
||||||
// geometry
|
// geometry
|
||||||
cube, err := geometry.LoadOBJ("assets/geometries/suzanne.obj")
|
cube, err := geometry.LoadOBJ("assets/geometries/cube.obj")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -130,6 +131,11 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer metalic.Delete()
|
defer metalic.Delete()
|
||||||
|
|
||||||
|
// lights
|
||||||
|
lights := []light.Light{
|
||||||
|
{Color: [3]float32{1, 1, 1}, Position: mgl32.Vec3{3, 3, 3}, Intensity: 10, Type: light.POINT},
|
||||||
|
}
|
||||||
|
|
||||||
// gbuffer
|
// gbuffer
|
||||||
gbuff, err := gbuffer.New(WIDTH, HEIGHT)
|
gbuff, err := gbuffer.New(WIDTH, HEIGHT)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -140,8 +146,8 @@ func main() {
|
|||||||
|
|
||||||
// transformations
|
// transformations
|
||||||
projection := mgl32.Perspective(mgl32.DegToRad(FOV), float32(WIDTH)/HEIGHT, 0.1, 10)
|
projection := mgl32.Perspective(mgl32.DegToRad(FOV), float32(WIDTH)/HEIGHT, 0.1, 10)
|
||||||
camera := mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0})
|
viewPositon := mgl32.Vec3{3, 3, 3}
|
||||||
model := mgl32.Ident4()
|
view := mgl32.LookAtV(viewPositon, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0})
|
||||||
|
|
||||||
angle := 0.0
|
angle := 0.0
|
||||||
previousTime := glfw.GetTime()
|
previousTime := glfw.GetTime()
|
||||||
@ -152,10 +158,12 @@ func main() {
|
|||||||
previousTime = time
|
previousTime = time
|
||||||
|
|
||||||
angle += elapsed
|
angle += elapsed
|
||||||
model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0})
|
model := mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0})
|
||||||
|
|
||||||
// first pass
|
// first pass
|
||||||
// bind textures
|
// bind textures
|
||||||
|
gl.Enable(gl.DEPTH_TEST)
|
||||||
|
|
||||||
gbuff.Bind()
|
gbuff.Bind()
|
||||||
|
|
||||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||||
@ -169,7 +177,7 @@ func main() {
|
|||||||
// transfer uniforms
|
// transfer uniforms
|
||||||
deferredShader.Use()
|
deferredShader.Use()
|
||||||
deferredShader.Mat4("projection", projection)
|
deferredShader.Mat4("projection", projection)
|
||||||
deferredShader.Mat4("camera", camera)
|
deferredShader.Mat4("view", view)
|
||||||
deferredShader.Mat4("model", model)
|
deferredShader.Mat4("model", model)
|
||||||
|
|
||||||
deferredShader.Int("s_albedo", 0)
|
deferredShader.Int("s_albedo", 0)
|
||||||
@ -180,17 +188,23 @@ func main() {
|
|||||||
cube.Draw()
|
cube.Draw()
|
||||||
|
|
||||||
// second pass
|
// second pass
|
||||||
|
gl.Disable(gl.DEPTH_TEST)
|
||||||
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
|
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
|
||||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
gbuff.BindTextures()
|
gbuff.BindTextures()
|
||||||
|
|
||||||
screenShader.Use()
|
screenShader.Use()
|
||||||
screenShader.Int("albedo", 0)
|
screenShader.Int("s_albedo", 0)
|
||||||
screenShader.Int("depth", 1)
|
screenShader.Int("s_depth", 1)
|
||||||
screenShader.Int("normal", 2)
|
screenShader.Int("s_normal", 2)
|
||||||
screenShader.Int("material", 3)
|
screenShader.Int("s_material", 3)
|
||||||
screenShader.Int("position", 4)
|
screenShader.Int("s_position", 4)
|
||||||
|
screenShader.Vec3("view_pos", &viewPositon[0])
|
||||||
|
|
||||||
|
for _, light := range lights {
|
||||||
|
screenShader.Light(&light)
|
||||||
|
}
|
||||||
|
|
||||||
screen.Draw()
|
screen.Draw()
|
||||||
|
|
||||||
|
20
types/light/light.go
Normal file
20
types/light/light.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package light
|
||||||
|
|
||||||
|
import "github.com/go-gl/mathgl/mgl32"
|
||||||
|
|
||||||
|
const MAX_LIGHT_COUNT = 100
|
||||||
|
|
||||||
|
const (
|
||||||
|
POINT int32 = iota
|
||||||
|
SPOT int32 = iota
|
||||||
|
DIRECTIONAL int32 = iota
|
||||||
|
AMBIENT int32 = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
type Light struct {
|
||||||
|
Color mgl32.Vec3
|
||||||
|
Position mgl32.Vec3
|
||||||
|
Direction mgl32.Vec3
|
||||||
|
Intensity float32
|
||||||
|
Type int32
|
||||||
|
}
|
@ -2,19 +2,23 @@ package shader
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/light"
|
||||||
"github.com/go-gl/gl/v4.6-core/gl"
|
"github.com/go-gl/gl/v4.6-core/gl"
|
||||||
"github.com/go-gl/mathgl/mgl32"
|
"github.com/go-gl/mathgl/mgl32"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Shader struct {
|
type Shader struct {
|
||||||
program uint32
|
program uint32
|
||||||
uniforms map[string]int32
|
uniforms map[string]int32
|
||||||
|
lightCount int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Shader) Use() {
|
func (s *Shader) Use() {
|
||||||
gl.UseProgram(s.program)
|
gl.UseProgram(s.program)
|
||||||
|
s.lightCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Shader) Delete() {
|
func (s *Shader) Delete() {
|
||||||
@ -40,6 +44,30 @@ func (s *Shader) Int(name string, val int32) {
|
|||||||
gl.Uniform1i(s.getUniformLocation(name), val)
|
gl.Uniform1i(s.getUniformLocation(name), val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Shader) Float(name string, val float32) {
|
||||||
|
gl.Uniform1f(s.getUniformLocation(name), val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Shader) Vec3(name string, val *float32) {
|
||||||
|
gl.Uniform3fv(s.getUniformLocation(name), 1, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Shader) Light(l *light.Light) error {
|
||||||
|
if s.lightCount >= light.MAX_LIGHT_COUNT {
|
||||||
|
return errors.New("too many lights")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Vec3(fmt.Sprintf("lights[%d].color", s.lightCount), &l.Color[0])
|
||||||
|
s.Vec3(fmt.Sprintf("lights[%d].position", s.lightCount), &l.Position[0])
|
||||||
|
s.Vec3(fmt.Sprintf("lights[%d].direction", s.lightCount), &l.Direction[0])
|
||||||
|
s.Float(fmt.Sprintf("lights[%d].intensity", s.lightCount), l.Intensity)
|
||||||
|
s.Int(fmt.Sprintf("lights[%d].type", s.lightCount), l.Type)
|
||||||
|
s.lightCount++
|
||||||
|
s.Int("light_count", s.lightCount)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func compileShader(source string, shaderType uint32) (uint32, error) {
|
func compileShader(source string, shaderType uint32) (uint32, error) {
|
||||||
shader := gl.CreateShader(shaderType)
|
shader := gl.CreateShader(shaderType)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user