Skip to content

Commit 5f358a4

Browse files
committed
Merge branch 'pbr'
2 parents 12838ee + 92e143b commit 5f358a4

29 files changed

+1888
-1139
lines changed

assets/materials/roof.emt

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,38 @@
11
# roof
22
# auto generated material
33
version = 0.1
4+
type=pbr
45
name=roof
5-
diffuse_colour=0.588 0.588 0.588 1.000
6-
diffuse_map_name=sponza_roof_diff
7-
specular_map_name=sponza_roof_spec
8-
normal_map_name=sponza_roof_ddn
9-
shader=Shader.Material
10-
shininess=1.500000
6+
shader=Shader.PBR
7+
diffuse_colour = 0.5 0 0 1
8+
9+
[map]
10+
name = albedo
11+
filter_min = linear
12+
filter_mag = linear
13+
repeat_u = repeat
14+
repeat_v = repeat
15+
repeat_w = repeat
16+
texture_name = orange_lines_512
17+
[/map]
18+
19+
20+
[map]
21+
name = normal
22+
filter_min = linear
23+
filter_mag = linear
24+
repeat_u = repeat
25+
repeat_v = repeat
26+
repeat_w = repeat
27+
texture_name = sponza_roof_ddn
28+
[/map]
29+
30+
[map]
31+
name = metallic
32+
filter_min = linear
33+
filter_mag = linear
34+
repeat_u = repeat
35+
repeat_v = repeat
36+
repeat_w = repeat
37+
texture_name = sponza_roof_spec
38+
[/map]

assets/shaders/PBRShader.frag

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
#version 450
2+
3+
layout(location = 0) out vec4 out_colour;
4+
5+
struct directional_light {
6+
vec4 direction;
7+
vec4 colour;
8+
};
9+
10+
const int MAX_POINT_LIGHTS = 10;
11+
12+
struct point_light {
13+
vec4 position;
14+
vec4 colour;
15+
// Usually 1, make sure denominator never gets smaller than 1
16+
float constant;
17+
// Reduces light intensity linearly
18+
float linear;
19+
// Makes the light fall off slower at longer distances.
20+
float quadratic;
21+
22+
float pad;
23+
};
24+
25+
struct pbr_properties {
26+
vec4 diffuse;
27+
vec3 pad;
28+
float shininess;
29+
};
30+
31+
layout(set = 1, binding = 0) uniform local_uniform_object {
32+
directional_light dir_light;
33+
point_light point_lights[MAX_POINT_LIGHTS];
34+
int num_point_lights;
35+
pbr_properties props;
36+
} object_ubo;
37+
38+
// Samplers, diffuse, spec
39+
const int SAMP_ALBEDO = 0;
40+
const int SAMP_NORMAL = 1;
41+
const int SAMP_METALLIC = 2;
42+
const int SAMP_ROUGHNESS = 3;
43+
const int SAMP_AO = 4;
44+
const int SAMP_IBL = 5;
45+
46+
layout(set = 1, binding = 1) uniform sampler2D samplers[6];
47+
layout(set = 1, binding = 1) uniform samplerCube samplersCube[6];
48+
49+
const float PI = 3.14159265359;
50+
51+
layout(location = 0) flat in int in_mode;
52+
layout(location = 1) in struct dto {
53+
vec4 ambient;
54+
vec2 tex_coord;
55+
vec3 normal;
56+
vec3 view_position;
57+
vec3 frag_position;
58+
vec4 colour;
59+
vec4 tangent;
60+
} in_dto;
61+
62+
mat3 TBN;
63+
64+
float geometry_ggx(float normal_dot_direction, float roughness)
65+
{
66+
roughness += 1;
67+
float k = (roughness * roughness) / 8;
68+
return normal_dot_direction / (normal_dot_direction * (1 - k) + k);
69+
}
70+
71+
vec3 calculate_point_light_radiance(point_light light, vec3 view_direction, vec3 frag_position)
72+
{
73+
float distance = length(light.position.xyz - frag_position);
74+
float attenuation = 1 / (light.constant + light.linear * distance + light.quadratic * distance * distance);
75+
76+
return light.colour.rgb * attenuation;
77+
}
78+
79+
vec3 calculate_directional_light_radiance(directional_light light)
80+
{
81+
return light.colour.rgb;
82+
}
83+
84+
vec3 calculate_reflectance(vec3 albedo, vec3 normal, vec3 view_direction, vec3 light_direction, float metallic, float roughness, vec3 base_reflectivity, vec3 radiance)
85+
{
86+
vec3 halfway = normalize(view_direction + light_direction);
87+
float rough_sq = roughness * roughness;
88+
float rough_sq_sq = rough_sq * rough_sq;
89+
90+
float normal_dot_halfway = max(dot(normal, halfway), 0);
91+
float normal_dot_halfway_sq = normal_dot_halfway * normal_dot_halfway;
92+
93+
float denom = normal_dot_halfway_sq * (rough_sq_sq - 1) + 1;
94+
denom = PI * denom * denom;
95+
96+
float normal_distribution = (rough_sq_sq / denom);
97+
98+
float normal_dot_view_dir = max(dot(normal, view_direction), 0);
99+
float normal_dot_light_dir = max(dot(normal, light_direction), 0);
100+
101+
float ggx_0 = geometry_ggx(normal_dot_view_dir, roughness);
102+
float ggx_1 = geometry_ggx(normal_dot_light_dir, roughness);
103+
104+
float geo = ggx_0 * ggx_1;
105+
106+
float cos_theta = max(dot(halfway, view_direction), 0);
107+
vec3 fresnel = base_reflectivity + (1 - base_reflectivity) * pow(clamp(1 - cos_theta, 0, 1), 5);
108+
109+
vec3 numerator = normal_distribution * geo * fresnel;
110+
float denominator = 4 * max(dot(normal, view_direction), 0) + 0.0001;
111+
112+
vec3 specular = numerator / denominator;
113+
vec3 refraction_diffuse = vec3(1) - fresnel;
114+
refraction_diffuse *= 1 - metallic;
115+
116+
return (refraction_diffuse * albedo / PI + specular) * radiance * normal_distribution;
117+
}
118+
119+
void main() {
120+
vec3 normal = in_dto.normal;
121+
vec3 tangent = in_dto.tangent.xyz;
122+
tangent = (tangent - dot(tangent, normal) * normal);
123+
124+
vec3 bitangent = cross(in_dto.normal, in_dto.tangent.xyz);
125+
TBN = mat3(tangent, bitangent, normal);
126+
127+
vec3 local_normal = 2 * texture(samplers[SAMP_NORMAL], in_dto.tex_coord).rgb - 1;
128+
normal = normalize(TBN * local_normal);
129+
130+
vec4 albedo_samp = texture(samplers[SAMP_ALBEDO], in_dto.tex_coord);
131+
132+
//Gamma correction
133+
vec3 albedo = pow(albedo_samp.rgb, vec3(2.2));
134+
135+
float metallic = texture(samplers[SAMP_METALLIC], in_dto.tex_coord).r;
136+
float roughness = texture(samplers[SAMP_ROUGHNESS], in_dto.tex_coord).r;
137+
float ao = texture(samplers[SAMP_AO], in_dto.tex_coord).r;
138+
139+
vec3 base_reflectivity = vec3(0.04);
140+
base_reflectivity = mix(base_reflectivity, albedo, metallic);
141+
142+
if (in_mode == 0 || in_mode == 1)
143+
{
144+
vec3 view_direction = in_dto.view_position - in_dto.frag_position;
145+
albedo += vec3(1) * in_mode;
146+
147+
albedo = clamp(albedo, vec3(0), vec3(1));
148+
149+
vec3 total_reflectance = vec3(0);
150+
151+
{
152+
directional_light light = object_ubo.dir_light;
153+
vec3 light_dir = normalize(-light.direction.xyz);
154+
vec3 radiance = calculate_directional_light_radiance(light);
155+
156+
total_reflectance += calculate_reflectance(albedo, normal, view_direction, light_dir, metallic, roughness, base_reflectivity, radiance);
157+
}
158+
159+
for (int i = 0; i < object_ubo.num_point_lights; i++)
160+
{
161+
point_light light = object_ubo.point_lights[i];
162+
163+
vec3 light_dir = normalize(light.position.xyz - in_dto.frag_position.xyz);
164+
165+
vec3 radiance = calculate_point_light_radiance(light, in_dto.view_position, in_dto.frag_position);
166+
167+
total_reflectance += calculate_reflectance(albedo, normal, view_direction, light_dir, metallic, roughness, base_reflectivity, radiance);
168+
}
169+
170+
vec3 irradiance = texture(samplersCube[SAMP_IBL], normal).rgb;
171+
172+
vec3 ambient = irradiance * albedo * ao;
173+
vec3 colour = ambient + total_reflectance;
174+
colour = colour / (colour + vec3(1));
175+
colour = pow(colour, vec3(1 / 2.2));
176+
177+
out_colour = vec4(colour, albedo_samp.a);
178+
}
179+
else if (in_mode == 2)
180+
{
181+
out_colour = vec4(abs(normal), 1);
182+
}
183+
}
184+

assets/shaders/PBRShader.vert

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#version 450
2+
3+
layout(location = 0) in vec3 in_position;
4+
layout(location = 1) in vec3 in_normal;
5+
layout(location = 2) in vec2 in_texcoord;
6+
layout(location = 3) in vec4 in_colour;
7+
layout(location = 4) in vec4 in_tangent;
8+
9+
layout(set = 0, binding = 0) uniform global_uniform_object {
10+
mat4 projection;
11+
mat4 view;
12+
vec4 ambient_colour;
13+
vec3 view_position;
14+
int mode;
15+
} global_ubo;
16+
17+
layout(push_constant) uniform push_constants {
18+
19+
// Only guaranteed a total of 128 bytes.
20+
mat4 model; // 64 bytes
21+
} u_push_constants;
22+
23+
layout(location = 0) out int out_mode;
24+
25+
// Data Transfer Object
26+
layout(location = 1) out struct dto {
27+
vec4 ambient;
28+
vec2 tex_coord;
29+
vec3 normal;
30+
vec3 view_position;
31+
vec3 frag_position;
32+
vec4 colour;
33+
vec4 tangent;
34+
} out_dto;
35+
36+
void main() {
37+
out_dto.tex_coord = in_texcoord;
38+
out_dto.colour = in_colour;
39+
// Fragment position in world space.
40+
out_dto.frag_position = vec3(u_push_constants.model * vec4(in_position, 1.0));
41+
// Copy the normal over.
42+
mat3 m3_model = mat3(u_push_constants.model);
43+
out_dto.normal = normalize(m3_model * in_normal);
44+
out_dto.tangent = vec4(normalize(m3_model * in_tangent.xyz), in_tangent.w);
45+
out_dto.ambient = global_ubo.ambient_colour;
46+
out_dto.view_position = global_ubo.view_position;
47+
gl_Position = global_ubo.projection * global_ubo.view * u_push_constants.model * vec4(in_position, 1.0);
48+
49+
out_mode = global_ubo.mode;
50+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#Physically Based Rendering
2+
version=1.0
3+
4+
name = Shader.PBR
5+
stages = vertex,fragment
6+
stagefiles = shaders/PBRShader.vert.spv,shaders/PBRShader.frag.spv
7+
depth_test = 1
8+
depth_write = 1
9+
10+
attribute=vec3,in_position
11+
attribute=vec3,in_normal
12+
attribute=vec2,in_texcoord
13+
attribute=vec4,in_colour
14+
attribute=vec4,in_tangent
15+
16+
# NOTE: For scope: 0=global, 1=instance, 2=local
17+
uniform=mat4,0,projection
18+
uniform=mat4,0,view
19+
uniform=vec4,0,ambient_colour
20+
uniform=vec3,0,view_position
21+
uniform=u32,0,mode
22+
uniform=samp,1,albedo_texture
23+
uniform=samp,1,normal_texture
24+
uniform=samp,1,metallic_texture
25+
uniform=samp,1,roughness_texture
26+
uniform=samp,1,ao_texture
27+
uniform=samp,1,cube_texture
28+
uniform=struct32,1,dir_light
29+
uniform=struct480,1,point_lights
30+
uniform=struct32,1,properties
31+
uniform=i32,1,num_point_lights
32+
uniform=mat4,2,model

0 commit comments

Comments
 (0)