Skip to content

Commit 0ff5528

Browse files
committed
add terrain resource and shader
1 parent f6e3254 commit 0ff5528

File tree

15 files changed

+825
-371
lines changed

15 files changed

+825
-371
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
version=1.0
2+
name=Shader.Terrain
3+
stages=vertex,fragment
4+
stagefiles=shaders/TerrainShader.vert.spv,shaders/TerrainShader.frag.spv
5+
depth_test=1
6+
depth_write=1
7+
8+
# Attributes: type,name
9+
attribute=vec3,in_position
10+
attribute=vec3,in_normal
11+
attribute=vec2,in_texcoord
12+
attribute=vec4,in_colour
13+
attribute=vec4,in_tangent
14+
15+
# Uniforms: type,scope,name
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=vec4,1,diffuse_colour
23+
#uniform=samp,1,diffuse_texture
24+
#uniform=samp,1,specular_texture
25+
#uniform=samp,1,normal_texture
26+
uniform=struct32,1,dir_light
27+
uniform=struct480,1,point_lights
28+
uniform=i32,1,num_point_lights
29+
uniform=f32,1,shininess
30+
uniform=mat4,2,model

assets/shaders/TerrainShader.frag

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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+
layout(set = 1, binding = 0) uniform local_uniform_object {
26+
vec4 diffuse_colour;
27+
directional_light dir_light;
28+
point_light point_lights[MAX_POINT_LIGHTS];
29+
int num_point_lights;
30+
float shininess;
31+
} object_ubo;
32+
33+
// // Samplers, diffuse, spec
34+
// const int SAMP_DIFFUSE = 0;
35+
// const int SAMP_SPECULAR = 1;
36+
// const int SAMP_NORMAL = 2;
37+
// layout(set = 1, binding = 1) uniform sampler2D samplers[3];
38+
39+
layout(location = 0) flat in int in_mode;
40+
// Data Transfer Object
41+
layout(location = 1) in struct dto {
42+
vec4 ambient;
43+
vec2 tex_coord;
44+
vec3 normal;
45+
vec3 view_position;
46+
vec3 frag_position;
47+
vec4 colour;
48+
vec4 tangent;
49+
} in_dto;
50+
51+
mat3 TBN;
52+
53+
vec4 calculate_directional_light(directional_light light, vec3 normal, vec3 view_direction);
54+
vec4 calculate_point_light(point_light light, vec3 normal, vec3 frag_position, vec3 view_direction);
55+
56+
void main() {
57+
vec3 normal = in_dto.normal;
58+
vec3 tangent = in_dto.tangent.xyz;
59+
tangent = (tangent - dot(tangent, normal) * normal);
60+
vec3 bitangent = cross(in_dto.normal, in_dto.tangent.xyz) * in_dto.tangent.w;
61+
TBN = mat3(tangent, bitangent, normal);
62+
63+
// Update the normal to use a sample from the normal map.
64+
// vec3 localNormal = 2.0 * texture(samplers[SAMP_NORMAL], in_dto.tex_coord).rgb - 1.0;
65+
// normal = normalize(TBN * localNormal);
66+
67+
if (in_mode == 0 || in_mode == 1) {
68+
vec3 view_direction = normalize(in_dto.view_position - in_dto.frag_position);
69+
70+
out_colour = calculate_directional_light(object_ubo.dir_light, normal, view_direction);
71+
72+
for (int i = 0; i < object_ubo.num_point_lights; i++)
73+
{
74+
out_colour += calculate_point_light(object_ubo.point_lights[i], normal, in_dto.frag_position, view_direction);
75+
}
76+
} else if (in_mode == 2) {
77+
out_colour = vec4(abs(normal), 1.0);
78+
}
79+
}
80+
81+
vec4 calculate_directional_light(directional_light light, vec3 normal, vec3 view_direction) {
82+
float diffuse_factor = max(dot(normal, -light.direction.xyz), 0.0);
83+
84+
vec3 half_direction = normalize(view_direction - light.direction.xyz);
85+
float specular_factor = pow(max(dot(half_direction, normal), 0.0), object_ubo.shininess);
86+
87+
vec4 diff_samp = vec4(1); //texture(samplers[SAMP_DIFFUSE], in_dto.tex_coord);
88+
vec4 ambient = vec4(vec3(in_dto.ambient * object_ubo.diffuse_colour), diff_samp.a);
89+
vec4 diffuse = vec4(vec3(light.colour * diffuse_factor), diff_samp.a);
90+
vec4 specular = vec4(vec3(light.colour * specular_factor), diff_samp.a);
91+
92+
if (in_mode == 0) {
93+
diffuse *= diff_samp;
94+
ambient *= diff_samp;
95+
// specular *= vec4(texture(samplers[SAMP_SPECULAR], in_dto.tex_coord).rgb, diffuse.a);
96+
}
97+
98+
return (ambient + diffuse + specular);
99+
}
100+
101+
vec4 calculate_point_light(point_light light, vec3 normal, vec3 frag_position, vec3 view_direction) {
102+
vec3 light_direction = normalize(light.position.xyz - frag_position);
103+
float diff = max(dot(normal, light_direction), 0.0);
104+
105+
vec3 reflect_direction = reflect(-light_direction, normal);
106+
float spec = pow(max(dot(view_direction, reflect_direction), 0.0), object_ubo.shininess);
107+
108+
// Calculate attenuation, or light falloff over distance.
109+
float distance = length(light.position.xyz - frag_position);
110+
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
111+
112+
vec4 ambient = in_dto.ambient;
113+
vec4 diffuse = light.colour * diff;
114+
vec4 specular = light.colour * spec;
115+
116+
if (in_mode == 0) {
117+
vec4 diff_samp = vec4(1); //texture(samplers[SAMP_DIFFUSE], in_dto.tex_coord);
118+
diffuse *= diff_samp;
119+
ambient *= diff_samp;
120+
// specular *= vec4(texture(samplers[SAMP_SPECULAR], in_dto.tex_coord).rgb, diffuse.a);
121+
}
122+
123+
ambient *= attenuation;
124+
diffuse *= attenuation;
125+
specular *= attenuation;
126+
return (ambient + diffuse + specular);
127+
}

assets/shaders/TerrainShader.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+
}

engine/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ set(SOURCES
5353
resources/skybox.cpp
5454
resources/texture.cpp
5555
resources/transform.cpp
56+
resources/terrain.cpp
5657
resources/ui_text.cpp
58+
5759
scenes/simple_scene.cpp
5860
systems/audio_system.cpp
5961
systems/camera_system.cpp

engine/plugins/renderer/vulkan/vulkan_shader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ namespace egkr
249249
binding_desc.setBinding(0).setStride(get_attribute_stride()).setInputRate(vk::VertexInputRate::eVertex);
250250

251251
pipeline_properties pipeline_properties{};
252-
pipeline_properties.renderpass = (renderpass::vulkan_renderpass*)renderpass;
252+
pipeline_properties.renderpass = renderpass;
253253
pipeline_properties.descriptor_set_layout = descriptor_set_layout;
254254
pipeline_properties.shader_stage_info = stage_create_infos;
255255
pipeline_properties.is_wireframe = false;
@@ -329,7 +329,7 @@ namespace egkr
329329
}
330330

331331
const auto image_index = context_->image_index;
332-
auto& command_buffer = context_->graphics_command_buffers[image_index].get_handle();
332+
const auto& command_buffer = context_->graphics_command_buffers[image_index].get_handle();
333333

334334
auto& object_state = instance_states[get_bound_instance_id()];
335335
auto& object_descriptor_set = object_state.descriptor_set_state.descriptor_sets[image_index];

engine/renderer/passes/scene_pass.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <systems/material_system.h>
66

77
#include "engine/engine.h"
8+
#include "systems/light_system.h"
89

910
namespace egkr::pass
1011
{
@@ -63,6 +64,31 @@ namespace egkr::pass
6364
debug_shader_locations.view = debug_colour_shader->get_uniform_index("view");
6465
debug_shader_locations.model = debug_colour_shader->get_uniform_index("model");
6566
}
67+
{
68+
std::string terrain_shader_name = "Shader.Terrain";
69+
auto shader = resource_system::load(terrain_shader_name, egkr::resource::type::shader, nullptr);
70+
auto* properties = (shader::properties*)shader->data;
71+
shader_system::create_shader(*properties, renderpass.get());
72+
resource_system::unload(shader);
73+
74+
terrain_shader = shader_system::get_shader(terrain_shader_name);
75+
terrain_shader->acquire_instance_resources({});
76+
77+
terrain_shader_locations.projection = terrain_shader->get_uniform_index("projection");
78+
terrain_shader_locations.view = terrain_shader->get_uniform_index("view");
79+
terrain_shader_locations.shininess = terrain_shader->get_uniform_index("shininess");
80+
terrain_shader_locations.ambient_colour = terrain_shader->get_uniform_index("ambient_colour");
81+
terrain_shader_locations.diffuse_colour = terrain_shader->get_uniform_index("diffuse_colour");
82+
// terrain_shader_locations.diffuse_texture = terrain_shader->get_uniform_index("diffuse_texture");
83+
// terrain_shader_locations.specular_texture = terrain_shader->get_uniform_index("specular_texture");
84+
// terrain_shader_locations.normal_texture = terrain_shader->get_uniform_index("normal_texture");
85+
terrain_shader_locations.view_position = terrain_shader->get_uniform_index("view_position");
86+
terrain_shader_locations.model = terrain_shader->get_uniform_index("model");
87+
terrain_shader_locations.mode = terrain_shader->get_uniform_index("mode");
88+
terrain_shader_locations.point_light = terrain_shader->get_uniform_index("point_lights");
89+
terrain_shader_locations.directional_light = terrain_shader->get_uniform_index("dir_light");
90+
terrain_shader_locations.num_point_lights = terrain_shader->get_uniform_index("num_point_lights");
91+
}
6692

6793
event::register_event(event::code::render_mode, this, on_event);
6894
return true;
@@ -73,6 +99,47 @@ namespace egkr::pass
7399
engine::get()->get_renderer()->set_active_viewport(viewport);
74100
renderpass->begin(frame_data.render_target_index);
75101

102+
if (!data.terrain.empty())
103+
{
104+
const float shininess{32};
105+
const float4 diffuse_colour{0.5, 0.5, 0.5, 1.0};
106+
shader_system::use(terrain_shader->get_id());
107+
shader_system::set_uniform(terrain_shader_locations.projection, &projection);
108+
shader_system::set_uniform(terrain_shader_locations.view, &view);
109+
shader_system::set_uniform(terrain_shader_locations.ambient_colour, &data.ambient_colour);
110+
shader_system::set_uniform(terrain_shader_locations.view_position, &view_position);
111+
shader_system::set_uniform(terrain_shader_locations.mode, &data.render_mode);
112+
113+
shader_system::apply_global(true);
114+
115+
shader_system::bind_instance(0);
116+
shader_system::set_uniform(terrain_shader_locations.diffuse_colour, &diffuse_colour);
117+
shader_system::set_uniform(terrain_shader_locations.directional_light, light_system::get_directional_light());
118+
shader_system::set_uniform(terrain_shader_locations.point_light, light_system::get_point_lights().data());
119+
auto num_point_lights = light_system::point_light_count();
120+
shader_system::set_uniform(terrain_shader_locations.num_point_lights, &num_point_lights);
121+
shader_system::set_uniform(terrain_shader_locations.shininess, &shininess);
122+
shader_system::apply_instance(true);
123+
124+
for (const auto& terrain : data.terrain)
125+
{
126+
const auto& world = terrain.transform.lock()->get_world();
127+
shader_system::set_uniform(terrain_shader_locations.model, &world);
128+
}
129+
130+
if (data.terrain.front().is_winding_reversed)
131+
{
132+
engine::get()->get_renderer()->set_winding(winding::clockwise);
133+
}
134+
135+
data.terrain.front().render_geometry->draw();
136+
137+
if (data.terrain.front().is_winding_reversed)
138+
{
139+
engine::get()->get_renderer()->set_winding(winding::counter_clockwise);
140+
}
141+
}
142+
76143
shader_system::use(material_shader->get_id());
77144
material_system::apply_global(material_shader->get_id(), frame_data, projection, view, data.ambient_colour, view_position, data.render_mode);
78145

engine/renderer/passes/scene_pass.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace egkr::pass
1515
uint32_t render_mode;
1616
float4 ambient_colour;
1717
egkr::vector<egkr::render_data> geometries;
18-
// egkr::vector<egkr::render_data> terrain;
18+
egkr::vector<egkr::render_data> terrain;
1919
egkr::vector<egkr::render_data> debug_geometries;
2020
} data;
2121

@@ -26,8 +26,27 @@ namespace egkr::pass
2626
uint32_t model{};
2727
} debug_shader_locations;
2828

29+
struct terrain_shader_locations
30+
{
31+
uint32_t projection{};
32+
uint32_t view{};
33+
uint32_t ambient_colour{};
34+
uint32_t view_position{};
35+
uint32_t diffuse_colour{};
36+
uint32_t diffuse_texture{};
37+
uint32_t specular_texture{};
38+
uint32_t normal_texture{};
39+
uint32_t shininess{};
40+
uint32_t model{};
41+
uint32_t mode{};
42+
uint32_t directional_light{};
43+
uint32_t point_light{};
44+
uint32_t num_point_lights{};
45+
} terrain_shader_locations;
46+
2947
shader::shared_ptr material_shader;
3048
shader::shared_ptr debug_colour_shader;
49+
shader::shared_ptr terrain_shader;
3150

3251
static scene* create();
3352
bool init() override;

0 commit comments

Comments
 (0)