Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Johannes Braun
glare
Commits
a60c43e1
Commit
a60c43e1
authored
Aug 07, 2017
by
Johannes Braun
Browse files
Improved Light structs and fixed advanced phong shading
parent
0d85c7ca
Changes
18
Hide whitespace changes
Inline
Side-by-side
assets/preferences/default.xml
View file @
a60c43e1
...
...
@@ -4,7 +4,7 @@
<item
name=
"window_size_x"
value=
"1440"
/>
<item
name=
"window_size_y"
value=
"900"
/>
<item
name=
"vsync"
value=
"0"
/>
<item
name=
"msaa"
value=
"
2
"
/>
<item
name=
"msaa"
value=
"
4
"
/>
</group>
<item
name=
"splash_screen"
value=
"/preferences/splash_01.xml"
/>
...
...
assets/shaders/pathtracer/bsdf.glsl
View file @
a60c43e1
...
...
@@ -146,7 +146,7 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i
// Compute the microsurface normal probability and with that the final probability density function
// Clamp up denominator to not divide by zero.
float
jacobian_reflect
=
1
/
clamp
(
4
*
m_dot_out
,
0
.
000
0
1
f
,
1
);
float
jacobian_reflect
=
1
/
clamp
(
4
*
m_dot_out
,
0
.
0001
f
,
1
);
float
probability_m
=
hemisphere_sample
.
distribution
*
cos_theta
;
float
pdf
=
probability_m
*
jacobian_reflect
;
...
...
@@ -154,14 +154,14 @@ BSDFResult computeBSDF(const in Material material, const in vec2 random, const i
float
ior_out_2
=
ior_out
*
ior_out
;
float
jacobian_refract_denominator
=
ior_in
*
m_dot_in
+
ior_out
*
m_dot_out_refract
;
jacobian_refract_denominator
*=
jacobian_refract_denominator
;
jacobian_refract_denominator
=
clamp
(
jacobian_refract_denominator
,
0
.
000
0
1
f
,
1
.
f
);
jacobian_refract_denominator
=
clamp
(
jacobian_refract_denominator
,
0
.
0001
f
,
1
.
f
);
//Take the absolute value as m_dot_out_refract is negative
float
jacobian_refract
=
abs
(
ior_out_2
*
m_dot_out_refract
/
jacobian_refract_denominator
);
float
pdf_refract
=
probability_m
*
jacobian_refract
;
// Same here... clamp up denominator to not divide by zero
float
brdf_denominator
=
clamp
((
4
*
n_dot_in
*
n_dot_out
),
0
.
000
0001
f
,
1
.
f
);
float
brdf_denominator
=
clamp
((
4
*
n_dot_in
*
n_dot_out
),
0
.
0001
f
,
1
.
f
);
float
btdf_denominator
=
jacobian_refract_denominator
;
// Finally, build the brdf. As we do russian roulette, we can just tint the brdf instead of multiplying with the fresnel value.
...
...
assets/shaders/pathtracer/pathtracer.comp
View file @
a60c43e1
...
...
@@ -87,7 +87,7 @@ vec4 loadColorStore(int id)
bool sampleLight(const in Light light, const in vec3 position, out vec3 point_on_light, out vec3 color, const in vec2 random_sample)
{
return u_light_sample[light.
data.light_
type % 4](light, position, point_on_light, color, random_sample);
return u_light_sample[light.type % 4](light, position, point_on_light, color, random_sample);
}
//////////////////////////////////////////////////////////////////////////
...
...
@@ -145,15 +145,9 @@ bool shade(int id, inout vec3 radiance, uint bounce, out uint bsdf_id)
&& traces_data[id].properties.travelled_distance < u_linespace_properties.distance_threshold;
if (lights_data.length() > 0) {
//Select random light.
.. well... at least if there are any.
//Select random light.
Light light = lights_data[int(floor(random_sample.x * lights_data.length()))];
//Shadow test
//float light_distance;
// vec3 light_color;
// float light_distance;
// bool success = sampleLight(light, vertex, random_sample, shadow_test, light_distance, light_color);
vec3 point_on_light;
vec3 light_color;
bool success = sampleLight(light, vertex.position.xyz, point_on_light, light_color, random_sample);
...
...
assets/shaders/screenshader/gbuffer/gbuffer_lights.glsl
View file @
a60c43e1
...
...
@@ -3,6 +3,7 @@
#include
<util/scene/light.glsl>
#include
<util/scene/material.glsl>
#include
<util/math/ggx.glsl>
layout
(
std430
)
restrict
readonly
buffer
lightsBuffer
{
...
...
@@ -13,7 +14,7 @@ subroutine uniform lightSample u_light_sample[4];
bool
sampleLight
(
const
in
Light
light
,
const
in
vec3
position
,
out
vec3
point_on_light
,
out
vec3
color
,
const
in
vec2
random_sample
)
{
return
u_light_sample
[
light
.
data
.
light_
type
%
4
](
light
,
position
,
point_on_light
,
color
,
random_sample
);
return
u_light_sample
[
light
.
type
%
4
](
light
,
position
,
point_on_light
,
color
,
random_sample
);
}
vec4
phong
(
const
in
Material
material
,
const
in
LightShadow
light_and_map
,
samplerCube
environment
,
const
in
vec3
position
,
const
in
vec3
normal
,
const
in
vec3
camera
)
...
...
@@ -21,58 +22,66 @@ vec4 phong(const in Material material, const in LightShadow light_and_map, sampl
vec3
color
=
vec3
(
0
);
vec3
point_on_light
;
vec3
phong_diffuse
=
vec3
(
0
);
vec3
phong_specular
=
vec3
(
0
);
vec3
eye
=
normalize
(
camera
-
position
.
xyz
);
vec3
reflection_vector
=
reflect
(
-
eye
,
normal
.
xyz
);
vec3
environment_reflect
=
textureLod
(
environment
,
reflection_vector
,
material
.
roughness
.
value
*
8
).
rgb
;
float
cos_phi_n_reflect
=
1
;
//pow(max(dot(reflection_vector, eye), 0.0f), phong_shininess);//20+1-(1+99*material.roughness.value));
vec3
environment_refract
=
vec3
(
0
);
//Tinting.
vec3
reflective_tint
=
mix
(
vec3
(
1
),
material
.
base
.
value
,
material
.
metallic
.
value
);
environment_reflect
*=
reflective_tint
*
cos_phi_n_reflect
;
vec3
refraction
=
vec3
(
0
);
if
(
material
.
transmission
.
value
>
0
)
{
vec3
refraction_vector
=
refract
(
-
eye
,
normal
.
xyz
,
1
/
material
.
ior
);
environment_refract
=
material
.
base
.
value
*
mix
(
vec3
(
0
),
textureLod
(
environment
,
refraction_vector
,
material
.
roughness
.
value
*
8
).
rgb
,
material
.
transmission
.
value
);
}
float
shadowing
=
1
;
if
(
light_and_map
.
light
.
sampleLight
(
position
,
point_on_light
,
color
.
rgb
,
vec2
(
-
1
)))
{
vec3
point_to_light
=
normalize
(
point_on_light
-
position
);
float
shadowing
=
1
.
f
;
//
sampleShadowMap(light_and_map, position, point_to_light, normal, camera);
shadowing
=
sampleShadowMap
(
light_and_map
,
position
,
point_to_light
,
normal
,
camera
);
if
(
shadowing
<=
0
)
{
return
vec4
(
0
,
0
,
0
,
1
);
}
vec3
eye
=
normalize
(
camera
-
position
.
xyz
);
vec3
half_vector
=
normalize
(
eye
+
point_to_light
);
//DIFFUSE
float
cos_phi
=
max
(
dot
(
normalize
(
normal
.
xyz
),
normalize
(
point_to_light
)),
0
.
0
f
);
vec3
light_reflection_vector
=
reflect
(
-
point_to_light
,
normal
.
xyz
);
vec3
light_reflection_vector
=
normalize
(
reflect
(
-
point_to_light
,
normal
.
xyz
)
)
;
float
phong_shininess
=
20
+
100
-
(
1
+
99
*
material
.
roughness
.
value
);
//SPECULAR
float
cos_phi_n
=
pow
(
max
(
dot
(
light_reflection_vector
,
eye
),
0
.
0
f
),
1
-
(
1
+
99
*
material
.
roughness
.
value
));
vec3
reflection_vector
=
reflect
(
-
eye
,
normal
.
xyz
);
vec3
environment_reflect
=
textureLod
(
environment
,
reflection_vector
,
material
.
roughness
.
value
*
8
).
rgb
;
vec3
environment_refract
=
vec3
(
0
);
//Tinting.
vec3
reflective_tint
=
mix
(
vec3
(
1
),
material
.
base
.
value
,
material
.
metallic
.
value
);
environment_reflect
*=
reflective_tint
;
float
cos_phi_n
=
pow
(
max
(
dot
(
light_reflection_vector
,
eye
),
0
.
0
f
),
phong_shininess
);
vec3
refraction
=
vec3
(
0
);
if
(
material
.
transmission
.
value
>
0
)
{
vec3
refraction_vector
=
refract
(
-
eye
,
normal
.
xyz
,
1
/
material
.
ior
);
environment_refract
=
material
.
base
.
value
*
mix
(
vec3
(
0
),
textureLod
(
environment
,
refraction_vector
,
material
.
roughness
.
value
*
8
).
rgb
,
max
(
material
.
transmission
.
value
,
material
.
metallic
.
value
));
}
float
k_s
=
material
.
roughness
.
value
;
float
k_rest
=
1
-
k_s
;
float
k_t
=
k_rest
*
material
.
transmission
.
value
;
float
k_d
=
1
-
k_s
-
k_t
;
vec3
phong_diffuse
=
material
.
base
.
value
*
cos_phi
*
color
;
vec3
phong_specular
=
(
reflective_tint
*
cos_phi_n
*
color
);
return
vec4
(
shadowing
*
(
phong_diffuse
+
phong_specular
),
1
);
phong_diffuse
=
shadowing
*
material
.
base
.
value
*
color
.
rgb
*
cos_phi
;
phong_specular
=
shadowing
*
reflective_tint
*
cos_phi_n
*
color
;
//(environment_reflect + reflective_tint * cos_phi_n * color) / 2;
}
else
{
//color may still be set e.g. by ambient
//if this else is triggered by a low attenuation (example), it shall be assured that the color will be set to a near-zero value.
return
vec4
(
color
,
1
)
;
phong_diffuse
=
color
;
}
// called F0 in several papers, it helps computing the fresnel via Schlick's approximation
float
fresnel
=
fresnelSchlick
(
max
(
0
,
dot
(
eye
,
normal
)),
normalResponse
(
material
.
ior
,
material
.
metallic
.
value
));
float
k_s
=
fresnel
;
float
k_t
=
(
1
-
k_s
)
*
material
.
transmission
.
value
;
float
k_d
=
1
-
k_s
-
k_t
;
return
vec4
(
k_d
*
(
phong_diffuse
+
material
.
base
.
value
*
textureLod
(
environment
,
normal
,
8
).
rgb
)
+
k_t
*
environment_refract
+
k_s
*
(
environment_reflect
+
phong_specular
),
1
);
}
#endif // !__GBUFFER_LIGHTS_GLH
assets/shaders/simple/simple.frag
View file @
a60c43e1
...
...
@@ -48,23 +48,18 @@ void main()
parallax_texcoord
=
out_texcoord
+
(
to_eye
.
xy
*
v
);
}
output_base_ior
.
rgb
=
u_material
.
getBase
(
parallax_texcoord
);
output_base_ior
.
a
=
u_material
.
ior
;
output_modelview_position
=
out_view_position
;
output_world_position
=
out_world_position
;
output_rough_metallic_transmit_emit
.
b
=
u_material
.
getTransmission
(
parallax_texcoord
);
// discard fragments via the transparency map.
if
(
output_rough_metallic_transmit_emit
.
b
>
0
.
2
){
discard
;
}
output_rough_metallic_transmit_emit
.
r
=
u_material
.
getRoughness
(
parallax_texcoord
);
output_rough_metallic_transmit_emit
.
g
=
u_material
.
getMetallic
(
parallax_texcoord
);
output_rough_metallic_transmit_emit
.
a
=
u_material
.
getEmission
(
parallax_texcoord
);
output_base_ior
.
rgb
=
u_material
.
getBase
(
parallax_texcoord
);
output_base_ior
.
a
=
u_material
.
ior
;
output_normal
=
u_material
.
has_normal_map
?
vec4
(
out_tangent_space
*
normalize
((
texture
(
u_material
.
normal_map
,
parallax_texcoord
).
xyz
)
*
2
.
0
-
1
.
0
),
0
)
:
vec4
(
out_normal
.
rgb
,
0
);
...
...
assets/shaders/util/math/random.glsl
View file @
a60c43e1
...
...
@@ -3,7 +3,7 @@
#include
<util/math/constants.glsl>
const
float
RANDOM_SAMPLING_FACTOR
=
1000000
.
0
;
const
float
RANDOM_SAMPLING_FACTOR
=
1000000
00
.
0
;
const
float
INV_RANDOM_SAMPLING_FACTOR
=
1
.
0
/
RANDOM_SAMPLING_FACTOR
;
//Method to generate a pseudo-random seed.
...
...
assets/shaders/util/scene/camera.glsl
View file @
a60c43e1
...
...
@@ -30,13 +30,13 @@ struct Camera
void
depthOfField
(
const
in
Camera
camera
,
inout
Ray
ray
,
const
in
vec2
random
)
{
// Sample a point on a unit disk
float
r
=
sqrt
(
random
.
x
)
;
float
r
=
random
.
x
;
float
theta
=
2
*
PI
*
random
.
y
;
float
x
=
r
*
cos
(
theta
);
float
y
=
r
*
sin
(
theta
);
// multiply radius
vec3
offset
=
camera
.
dof_size
*
(
x
*
camera
.
axis_x_scaled
+
y
*
camera
.
axis_y_scaled
);
vec3
offset
=
camera
.
dof_size
*
(
x
*
camera
.
axis_x_scaled
+
y
*
camera
.
axis_y_scaled
);
vec3
focus
=
ray
.
origin
+
camera
.
focus_distance
*
ray
.
direction
;
ray
.
origin
+=
offset
;
ray
.
direction
=
normalize
(
focus
-
ray
.
origin
);
...
...
@@ -44,17 +44,22 @@ void depthOfField(const in Camera camera, inout Ray ray, const in vec2 random)
Ray
getRayFromPixel
(
const
in
Camera
camera
,
const
in
vec2
pixel
,
const
in
vec2
sub_pixel
)
{
// Correct subpixel offset for an overall smoother image.
const
float
sub_pixel_correction
=
sqrt
(
2
);
const
vec2
sub_pixel_offset
=
2
*
sub_pixel
-
1
;
Ray
ray
;
ray
.
origin
=
camera
.
position
;
ray
.
direction
=
camera
.
bottom_left
+
(
pixel
.
x
+
sub_pixel
.
x
)
*
camera
.
axis_x_scaled
+
(
pixel
.
y
+
sub_pixel
.
y
)
*
camera
.
axis_y_scaled
-
(
pixel
.
x
+
sub_pixel
_offset
.
x
)
*
camera
.
axis_x_scaled
+
(
pixel
.
y
+
sub_pixel
_offset
.
y
)
*
camera
.
axis_y_scaled
-
camera
.
position
;
vec2
final_pixel
=
pixel
+
sub_pixel
;
ray
.
px
=
final_pixel
.
x
;
ray
.
py
=
final_pixel
.
y
;
camera
.
depthOfField
(
ray
,
sub_pixel
);
camera
.
depthOfField
(
ray
,
sub_pixel
_offset
);
return
ray
;
}
...
...
assets/shaders/util/scene/light.glsl
View file @
a60c43e1
...
...
@@ -4,7 +4,7 @@
#include
<util/math/random.glsl>
const
float
DIRECTIONAL_DISTANCE
=
1000000
.
f
;
const
float
DIRECTIONAL_SMOOTH_DISTANCE
=
1
0
.
f
;
const
float
DIRECTIONAL_SMOOTH_DISTANCE
=
1
.
f
;
////////////////////////////////////////////////////////////////////
////
...
...
@@ -17,23 +17,63 @@ struct Attenuation
float
constant
;
float
linear
;
float
quadratic
;
int
p
;
};
struct
LightParameters
const
uint
ePoint
=
0
;
const
uint
eSpot
=
1
;
const
uint
eDirectional
=
2
;
const
uint
eAmbient
=
3
;
const
uint
eQuad
=
4
;
struct
PointLight
{
int
light_type
;
float
params
[
2
];
int
p
;
vec3
position
;
float
radius
;
vec3
color
;
float
pd_01
;
Attenuation
attenuation
;
};
struct
Light
struct
DirectionalLight
{
vec3
direction
;
float
radius
;
vec3
color
;
};
struct
SpotLight
{
vec4
position
;
vec4
direction
;
vec4
color
;
vec3
position
;
float
radius
;
vec3
direction
;
float
angle
;
vec3
color
;
float
falloff
;
Attenuation
attenuation
;
LightParameters
data
;
};
struct
AmbientLight
{
vec3
color
;
};
struct
QuadLight
{
vec3
position
;
float
scale_x
;
vec3
direction
;
float
scale_y
;
vec3
color
;
float
pd_01
;
Attenuation
attenuation
;
};
struct
Light
{
vec4
dataset_01
[
3
];
vec3
dataset_02
;
uint
type
;
};
struct
ShadowMap
...
...
@@ -77,9 +117,74 @@ const vec2 poissonDisk[16] = vec2[](
subroutine
bool
lightSample
(
const
in
Light
light
,
const
in
vec3
position
,
out
vec3
point_on_light
,
out
vec3
color
,
const
in
vec2
random_sample
);
float
attenuation
(
const
in
Light
light
,
float
distance
)
PointLight
asPoint
(
const
in
Light
light
)
{
PointLight
point_light
;
point_light
.
position
=
light
.
dataset_01
[
0
].
xyz
;
point_light
.
radius
=
light
.
dataset_01
[
0
].
w
;
point_light
.
color
=
light
.
dataset_01
[
1
].
rgb
;
point_light
.
attenuation
.
constant
=
light
.
dataset_01
[
2
].
x
;
point_light
.
attenuation
.
linear
=
light
.
dataset_01
[
2
].
y
;
point_light
.
attenuation
.
quadratic
=
light
.
dataset_01
[
2
].
z
;
return
point_light
;
}
DirectionalLight
asDirectional
(
const
in
Light
light
)
{
return
1
/
(
light
.
attenuation
.
constant
+
distance
*
light
.
attenuation
.
linear
+
pow
(
distance
,
2
)
*
light
.
attenuation
.
quadratic
);
DirectionalLight
directional_light
;
directional_light
.
direction
=
light
.
dataset_01
[
0
].
xyz
;
directional_light
.
radius
=
light
.
dataset_01
[
0
].
w
;
directional_light
.
color
=
light
.
dataset_01
[
1
].
rgb
;
return
directional_light
;
}
SpotLight
asSpot
(
const
in
Light
light
)
{
SpotLight
spot_light
;
spot_light
.
position
=
light
.
dataset_01
[
0
].
xyz
;
spot_light
.
radius
=
light
.
dataset_01
[
0
].
w
;
spot_light
.
direction
=
light
.
dataset_01
[
1
].
xyz
;
spot_light
.
angle
=
light
.
dataset_01
[
1
].
w
;
spot_light
.
color
=
light
.
dataset_01
[
2
].
rgb
;
spot_light
.
falloff
=
light
.
dataset_01
[
2
].
w
;
spot_light
.
attenuation
.
constant
=
light
.
dataset_02
.
x
;
spot_light
.
attenuation
.
linear
=
light
.
dataset_02
.
y
;
spot_light
.
attenuation
.
quadratic
=
light
.
dataset_02
.
z
;
return
spot_light
;
}
AmbientLight
asAmbient
(
const
in
Light
light
)
{
AmbientLight
ambient_light
;
ambient_light
.
color
=
light
.
dataset_01
[
0
].
rgb
;
return
ambient_light
;
}
QuadLight
asQuad
(
const
in
Light
light
)
{
QuadLight
quad_light
;
quad_light
.
position
=
light
.
dataset_01
[
0
].
xyz
;
quad_light
.
scale_x
=
light
.
dataset_01
[
0
].
w
;
quad_light
.
direction
=
light
.
dataset_01
[
1
].
xyz
;
quad_light
.
scale_y
=
light
.
dataset_01
[
1
].
w
;
quad_light
.
color
=
light
.
dataset_01
[
2
].
rgb
;
quad_light
.
attenuation
.
constant
=
light
.
dataset_02
.
x
;
quad_light
.
attenuation
.
linear
=
light
.
dataset_02
.
y
;
quad_light
.
attenuation
.
quadratic
=
light
.
dataset_02
.
z
;
return
quad_light
;
}
float
attenuate
(
const
in
Attenuation
attenuation
,
float
distance
)
{
return
1
/
(
attenuation
.
constant
+
distance
*
attenuation
.
linear
+
pow
(
distance
,
2
)
*
attenuation
.
quadratic
);
}
float
sampleShadowMap
(
const
in
LightShadow
light
,
const
in
vec3
position
,
const
in
vec3
to_light
,
const
in
vec3
normal
,
const
in
vec3
camera
)
{
...
...
@@ -89,21 +194,20 @@ float sampleShadowMap(const in LightShadow light, const in vec3 position, const
vec4
shadow_coord
=
light
.
shadow_map
.
matrix
*
vec4
(
position
.
xyz
,
1
);
// clip coordinates, light space
vec3
shadow_coord_normalized
=
shadow_coord
.
xyz
/
shadow_coord
.
w
;
// normalized device coordinates, light space
//shadow_coord_normalized.xy = clamp(shadow_coord_normalized.xy, 0, 1);
float
dst
=
pow
(
clamp
(
distance
(
camera
,
position
.
xyz
)
/
175
.
f
,
0
,
1
),
3
);
float
cos_theta
=
dot
(
normal
.
xyz
,
to_light
);
if
(
dst
==
0
||
!
(
shadow_coord_normalized
.
x
<=
1
.
f
&&
shadow_coord_normalized
.
x
>
0
.
f
&&
shadow_coord_normalized
.
y
<=
1
.
f
&&
shadow_coord_normalized
.
y
>
0
.
f
))
{
return
1
;
}
float
bias
=
0
.
00
5
*
tan
(
acos
(
cos_theta
));
bias
=
clamp
(
bias
,
0
,
0
.
001
f
);
float
bias
=
0
.
00
05
f
*
tan
(
acos
(
cos_theta
));
bias
=
clamp
(
bias
,
0
,
0
.
00
0
1
f
);
const
vec2
size
=
vec2
(
light
.
shadow_map
.
map
.
textureSize
(
0
));
const
int
num_samples
=
16
;
float
shadow_value
=
0
.
f
;
for
(
int
i
=
0
;
i
<
num_samples
;
i
++
)
{
shadow_value
+=
texture
(
light
.
shadow_map
.
map
,
vec3
(
shadow_coord_normalized
.
xy
+
(
3
*
poissonDisk
[
i
]
/
size
.
x
),
shadow_coord_normalized
.
z
-
bias
));
shadow_value
+=
texture
(
light
.
shadow_map
.
map
,
vec3
(
shadow_coord_normalized
.
xy
+
(
2
*
poissonDisk
[
i
]
/
size
.
x
),
shadow_coord_normalized
.
z
-
bias
));
}
darkening
=
mix
(
shadow_value
/
num_samples
,
1
,
dst
);
...
...
@@ -114,22 +218,24 @@ float sampleShadowMap(const in LightShadow light, const in vec3 position, const
bool
isColorSignificant
(
const
in
vec3
color
)
{
return
length
(
color
.
rgb
)
>
0
.
0001
f
;
return
length
(
color
)
>
0
.
0001
f
;
}
subroutine
(
lightSample
)
bool
samplePoint
(
const
in
Light
light
,
const
in
vec3
position
,
out
vec3
point_on_light
,
out
vec3
color
,
const
in
vec2
random_sample
)
{
PointLight
point_light
=
light
.
asPoint
();
if
(
random_sample
==
vec2
(
-
1
))
{
point_on_light
=
light
.
position
.
xyz
;
point_on_light
=
point_
light
.
position
;
}
else
{
point_on_light
=
(
light
.
position
.
xyz
+
randUniformSphere
(
random_sample
)
*
light
.
data
.
params
[
0
]
);
point_on_light
=
(
point_
light
.
position
+
randUniformSphere
(
random_sample
)
*
point_light
.
radius
);
}
color
=
light
.
color
.
rgb
*
light
.
attenuation
(
distance
(
position
,
point_on_light
));
color
=
point_
light
.
color
*
point_
light
.
attenuation
.
attenuate
(
distance
(
position
,
point_on_light
));
return
isColorSignificant
(
color
);
}
...
...
@@ -137,38 +243,41 @@ bool samplePoint(const in Light light, const in vec3 position, out vec3 point_on
subroutine
(
lightSample
)
bool
sampleSpot
(
const
in
Light
light
,
const
in
vec3
position
,
out
vec3
point_on_light
,
out
vec3
color
,
const
in
vec2
random_sample
)
{
SpotLight
spot_light
=
light
.
asSpot
();
if
(
random_sample
==
vec2
(
-
1
))
{
point_on_light
=
light
.
position
.
xyz
;
point_on_light
=
spot_
light
.
position
;
}
else
{
//TODO: Add proper spot light source radius
point_on_light
=
(
light
.
position
.
xyz
+
randUniformSphere
(
random_sample
)
*
0
.
1
f
);
point_on_light
=
(
spot_light
.
position
+
randUniformSphere
(
random_sample
)
*
spot_light
.
radius
);
}
float
angle_dot
=
max
(
dot
(
normalize
(
position
-
point_on_light
),
normalize
(
light
.
direction
.
xyz
)),
0
.
0
);
float
att
=
(
1
-
smoothstep
(
cos
(
light
.
data
.
params
[
0
]),
cos
(
light
.
data
.
params
[
1
]),
angle_dot
))
*
light
.
attenuation
(
distance
(
position
,
point_on_light
));
color
=
att
*
light
.
color
.
rgb
;
float
angle_dot
=
max
(
dot
(
normalize
(
position
-
point_on_light
),
normalize
(
spot_light
.
direction
.
xyz
)),
0
.
0
);
float
att
=
(
smoothstep
(
cos
(
spot_light
.
angle
*
(
1
-
spot_light
.
falloff
)),
cos
(
spot_light
.
angle
),
angle_dot
))
*
spot_light
.
attenuation
.
attenuate
(
distance
(
position
,
point_on_light
));
color
=
att
*
spot_light
.
color
;
return
isColorSignificant
(
color
);
}
subroutine
(
lightSample
)
bool
sampleDirectional
(
const
in
Light
light
,
const
in
vec3
position
,
out
vec3
point_on_light
,
out
vec3
color
,
const
in
vec2
random_sample
)
{
DirectionalLight
directional_light
=
light
.
asDirectional
();
if
(
random_sample
==
vec2
(
-
1
))
{
point_on_light
=
position
-
DIRECTIONAL_DISTANCE
*
light
.
direction
.
xyz
;
point_on_light
=
position
-
DIRECTIONAL_DISTANCE
*
directional_
light
.
direction
;
}
else
{
//TODO: Add proper directional light source radius
point_on_light
=
position
-
DIRECTIONAL_SMOOTH_DISTANCE
*
light
.
direction
.
xyz
;
//(light.position.xyz + randUniformSphere(random_sample)*0.1f);
point_on_light
+=
randUniformSphere
(
random_sample
)
*
0
.
1
f
;
point_on_light
=
position
-
DIRECTIONAL_SMOOTH_DISTANCE
*
directional_light
.
direction
;
point_on_light
+=
randUniformSphere
(
random_sample
)
*
directional_light
.
radius
;
point_on_light
=
position
-
DIRECTIONAL_DISTANCE
*
normalize
(
position
-
point_on_light
);
}
color
=
light
.
color
.
rgb
;
color
=
directional_
light
.
color
;
//Sadly the color still has to be evaluated because there might be a directional light with black color.
return
isColorSignificant
(
color
);
...
...
@@ -177,6 +286,8 @@ bool sampleDirectional(const in Light light, const in vec3 position, out vec3 po
subroutine
(
lightSample
)
bool
sampleAmbient
(
const
in
Light
light
,
const
in
vec3
position
,
out
vec3
point_on_light
,
out
vec3
color
,
const
in
vec2
random_sample
)
{
AmbientLight
ambient_light
=
light
.
asAmbient
();
if
(
random_sample
==
vec2
(
-
1
))
{
// Just to not have to bother with accidental normalization NaNs
...
...
@@ -189,7 +300,7 @@ bool sampleAmbient(const in Light light, const in vec3 position, out vec3 point_
point_on_light
=
position
+
randUniformSphere
(
random_sample
);
}
color
=
light
.
color
.
rgb
;
color
=
ambient_
light
.
color
;
// If needed, ambient color can be calculated in, but in general, better leave it out.
return
false
;
...
...
src/executables/pathtracing/main.cpp
View file @
a60c43e1
...
...
@@ -28,7 +28,7 @@ const fs::path engine_settings_path = files::asset("/preferences/default.xml");
const
fs
::
path
pathtracer_settings_path
=
files
::
asset
(
"/preferences/pathtracer_default.xml"
);
const
fs
::
path
skybox_files_path
=
files
::
asset
(
"/textures/ryfjallet/"
);
const
fs
::
path
env_audio_path
=
files
::
asset
(
"/audio/env.wav"
);
const
fs
::
path
startup_scene_path
=
files
::
asset
(
"/meshes/scenery/
glassplane
.dae"
);
const
fs
::
path
startup_scene_path
=
files
::
asset
(
"/meshes/scenery/
floating_island_lowpoly
.dae"
);
// My little all-enclosing pathtracer pointer
std
::
unique_ptr
<
raytrace
::
Pathtracer
>
pathtracer
=
nullptr
;
...
...
src/libraries/core/objects/light.cpp
View file @
a60c43e1
...
...
@@ -7,7 +7,7 @@ namespace glare
{
namespace
core
{
LightComponent
::
LightComponent
(
color
::
rgba32f
color
,
Attenuation
attenuation
,
LightParameters
data
)
:
m_color
(
color
),
m_attenuation
(
attenuation
),
m_data
(
data
)
LightComponent
::
LightComponent
(
color
::
rgba32f
color
,
LightParameters
data
)
:
m_color
(
color
),
m_data
(
data
)
{
}
...
...
@@ -31,8 +31,74 @@ namespace glare
void
LightComponent
::
update
()
{
if
(
!
m_shadow_map_renderer
&&
getOwner
()
&&
m_data
.
light_type
==
LightType
::
eDirectional
)
{
m_shadow_map_renderer
=
std
::
make_unique
<
ShadowMap
>
(
4096
,
350
,
getOwner
());
m_shadow_map_renderer
=
std
::
make_unique
<
ShadowMap
>
(
4096
,
8
,
getOwner
());
}
}
Light
LightComponent
::
buildLight
()
const
{
const
auto
transform
=
getOwner
()
->
absoluteTransform
();
Light
light
;
switch
(
m_data
.
light_type
)
{
default:
case
LightType
::
ePoint
:
{
light
.
point
.
attenuation
=
m_data
.
data
.
point
.
attenuation
;
light
.
point
.
color
=
m_color
.
rgb
;
light
.
point
.
radius
=
m_data
.
data
.
point
.
radius
;
light
.
point
.
position
=
glm
::
vec3
(
transform
*
glm
::
vec4
(
0
,
0
,
0
,
1
));
light
.
point
.
type
=
LightType
::
ePoint
;
}
break
;
case
LightType
::
eDirectional
:
{
light
.
directional
.
direction
=
glm
::
vec3
(
transform
*
glm
::
vec4
(
0
,
0
,
-
1
,
0
));
light
.
directional
.
color
=
m_color
.
rgb
;
light
.
directional
.
radius
=
m_data
.
data
.
directional
.
radius
;
light
.
point
.
type
=
LightType
::
eDirectional
;
}
break
;