lights
This commit is contained in:
parent
17f8d58a67
commit
29e8eff82a
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
||||
opengl-deferred
|
||||
assets/textures
|
||||
assets/geometries
|
@ -5,7 +5,7 @@ layout (location = 1) in vec2 _tex;
|
||||
layout (location = 2) in vec3 _norm;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 camera;
|
||||
uniform mat4 view;
|
||||
uniform mat4 model;
|
||||
|
||||
out vec3 pos;
|
||||
@ -13,7 +13,7 @@ out vec3 norm;
|
||||
out vec2 tex;
|
||||
|
||||
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));
|
||||
norm = _norm;
|
||||
tex = _tex;
|
||||
|
@ -1,20 +1,65 @@
|
||||
#version 460 core
|
||||
|
||||
uniform sampler2D albedo;
|
||||
uniform sampler2D depth;
|
||||
uniform sampler2D normal;
|
||||
uniform sampler2D material;
|
||||
uniform sampler2D position;
|
||||
// gbuffer textures
|
||||
uniform sampler2D s_albedo;
|
||||
uniform sampler2D s_depth;
|
||||
uniform sampler2D s_normal;
|
||||
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 vec2 tex;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
float map(float value, float min1, float max1, float min2, float max2) {
|
||||
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
|
||||
vec3 albedo;
|
||||
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() {
|
||||
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/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/texture"
|
||||
"github.com/go-gl/gl/v4.6-core/gl"
|
||||
@ -15,8 +16,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
WIDTH = 640
|
||||
HEIGHT = 480
|
||||
WIDTH = 800
|
||||
HEIGHT = 600
|
||||
TITLE = "opengl-deferred"
|
||||
FOV = 45.0
|
||||
)
|
||||
@ -48,7 +49,7 @@ func main() {
|
||||
}
|
||||
|
||||
gl.Enable(gl.DEPTH_TEST)
|
||||
// gl.Enable(gl.CULL_FACE)
|
||||
gl.Enable(gl.CULL_FACE)
|
||||
gl.DepthFunc(gl.LESS)
|
||||
gl.ClearColor(0, 0, 0, 0)
|
||||
|
||||
@ -87,7 +88,7 @@ func main() {
|
||||
defer screenShader.Delete()
|
||||
|
||||
// geometry
|
||||
cube, err := geometry.LoadOBJ("assets/geometries/suzanne.obj")
|
||||
cube, err := geometry.LoadOBJ("assets/geometries/cube.obj")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -130,6 +131,11 @@ func main() {
|
||||
}
|
||||
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
|
||||
gbuff, err := gbuffer.New(WIDTH, HEIGHT)
|
||||
if err != nil {
|
||||
@ -140,8 +146,8 @@ func main() {
|
||||
|
||||
// transformations
|
||||
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})
|
||||
model := mgl32.Ident4()
|
||||
viewPositon := mgl32.Vec3{3, 3, 3}
|
||||
view := mgl32.LookAtV(viewPositon, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0})
|
||||
|
||||
angle := 0.0
|
||||
previousTime := glfw.GetTime()
|
||||
@ -152,10 +158,12 @@ func main() {
|
||||
previousTime = time
|
||||
|
||||
angle += elapsed
|
||||
model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0})
|
||||
model := mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0})
|
||||
|
||||
// first pass
|
||||
// bind textures
|
||||
gl.Enable(gl.DEPTH_TEST)
|
||||
|
||||
gbuff.Bind()
|
||||
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||
@ -169,7 +177,7 @@ func main() {
|
||||
// transfer uniforms
|
||||
deferredShader.Use()
|
||||
deferredShader.Mat4("projection", projection)
|
||||
deferredShader.Mat4("camera", camera)
|
||||
deferredShader.Mat4("view", view)
|
||||
deferredShader.Mat4("model", model)
|
||||
|
||||
deferredShader.Int("s_albedo", 0)
|
||||
@ -180,17 +188,23 @@ func main() {
|
||||
cube.Draw()
|
||||
|
||||
// second pass
|
||||
gl.Disable(gl.DEPTH_TEST)
|
||||
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||
|
||||
gbuff.BindTextures()
|
||||
|
||||
screenShader.Use()
|
||||
screenShader.Int("albedo", 0)
|
||||
screenShader.Int("depth", 1)
|
||||
screenShader.Int("normal", 2)
|
||||
screenShader.Int("material", 3)
|
||||
screenShader.Int("position", 4)
|
||||
screenShader.Int("s_albedo", 0)
|
||||
screenShader.Int("s_depth", 1)
|
||||
screenShader.Int("s_normal", 2)
|
||||
screenShader.Int("s_material", 3)
|
||||
screenShader.Int("s_position", 4)
|
||||
screenShader.Vec3("view_pos", &viewPositon[0])
|
||||
|
||||
for _, light := range lights {
|
||||
screenShader.Light(&light)
|
||||
}
|
||||
|
||||
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,8 +2,10 @@ package shader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.tek.govt.hu/dowerx/opengl-deferred/types/light"
|
||||
"github.com/go-gl/gl/v4.6-core/gl"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
@ -11,10 +13,12 @@ import (
|
||||
type Shader struct {
|
||||
program uint32
|
||||
uniforms map[string]int32
|
||||
lightCount int32
|
||||
}
|
||||
|
||||
func (s *Shader) Use() {
|
||||
gl.UseProgram(s.program)
|
||||
s.lightCount = 0
|
||||
}
|
||||
|
||||
func (s *Shader) Delete() {
|
||||
@ -40,6 +44,30 @@ func (s *Shader) Int(name string, val int32) {
|
||||
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) {
|
||||
shader := gl.CreateShader(shaderType)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user