Split vertex shader for terrain and tests.
This commit is contained in:
parent
a331721dd8
commit
1abfdfadf8
57
game/game.py
57
game/game.py
@ -30,18 +30,21 @@ def main():
|
|||||||
|
|
||||||
print("Initializing...")
|
print("Initializing...")
|
||||||
window = initialize(b'RK Island', 1600, 900)
|
window = initialize(b'RK Island', 1600, 900)
|
||||||
terrain_shader = shader.load('terrain')
|
terrain_shader = shader.load('terrain', 'common')
|
||||||
|
tests_shader = shader.load('tests', 'common')
|
||||||
sky_shader = shader.load('sky')
|
sky_shader = shader.load('sky')
|
||||||
|
|
||||||
heightmap = create_texture(
|
heightmap = create_texture(
|
||||||
1, TEXTURE_FORMAT_32F, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR,
|
1, TEXTURE_FORMAT_32F, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR,
|
||||||
generated.packed_heights)
|
generated.packed_heights)
|
||||||
heightmap_sampler = resolve_input(terrain_shader, b'u_height_sampler')
|
terrain_heightmap_sampler = resolve_input(terrain_shader, b'u_height_sampler')
|
||||||
|
tests_heightmap_sampler = resolve_input(tests_shader, b'u_height_sampler')
|
||||||
|
|
||||||
normalmap = create_texture(
|
normalmap = create_texture(
|
||||||
2, TEXTURE_FORMAT_RGB10_A2, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR,
|
2, TEXTURE_FORMAT_RGB10_A2, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR,
|
||||||
generated.packed_normals)
|
generated.packed_normals)
|
||||||
normalmap_sampler = resolve_input(terrain_shader, b'u_normal_sampler')
|
terrain_normalmap_sampler = resolve_input(terrain_shader, b'u_normal_sampler')
|
||||||
|
tests_normalmap_sampler = resolve_input(tests_shader, b'u_normal_sampler')
|
||||||
|
|
||||||
print("Loading resources...")
|
print("Loading resources...")
|
||||||
archive = resources.RuntimeArchive.load('data/rk_island.rkar')
|
archive = resources.RuntimeArchive.load('data/rk_island.rkar')
|
||||||
@ -90,7 +93,7 @@ def main():
|
|||||||
model.spawn(terrain_batch, (float(((mx - 128) * 8) + 4), float(((127 - my) * 8) + 4), 0.0))
|
model.spawn(terrain_batch, (float(((mx - 128) * 8) + 4), float(((127 - my) * 8) + 4), 0.0))
|
||||||
|
|
||||||
tests_texture = archive.get_texture('tests')
|
tests_texture = archive.get_texture('tests')
|
||||||
tests_sampler = resolve_input(terrain_shader, b'u_texture_sampler')
|
tests_sampler = resolve_input(tests_shader, b'u_texture_sampler')
|
||||||
tests_vertices = archive.get_vertices('tests')
|
tests_vertices = archive.get_vertices('tests')
|
||||||
blob = archive.get_model('blob')
|
blob = archive.get_model('blob')
|
||||||
cube = archive.get_model('cube')
|
cube = archive.get_model('cube')
|
||||||
@ -111,11 +114,15 @@ def main():
|
|||||||
proj_far_z = 3000.0
|
proj_far_z = 3000.0
|
||||||
|
|
||||||
terrain_environment_inputs = environment.resolve_inputs(terrain_shader)
|
terrain_environment_inputs = environment.resolve_inputs(terrain_shader)
|
||||||
terrain_orientation = resolve_param(terrain_shader, b'i_orientation')
|
|
||||||
terrain_camera = camera.Camera()
|
terrain_camera = camera.Camera()
|
||||||
terrain_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z)
|
terrain_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z)
|
||||||
terrain_camera.resolve_inputs(terrain_shader)
|
terrain_camera.resolve_inputs(terrain_shader)
|
||||||
|
|
||||||
|
tests_environment_inputs = environment.resolve_inputs(tests_shader)
|
||||||
|
tests_camera = camera.Camera()
|
||||||
|
tests_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z)
|
||||||
|
tests_camera.resolve_inputs(tests_shader)
|
||||||
|
|
||||||
sky_environment_inputs = environment.resolve_inputs(sky_shader)
|
sky_environment_inputs = environment.resolve_inputs(sky_shader)
|
||||||
sea_phase = resolve_input(sky_shader, b'u_sea_phase')
|
sea_phase = resolve_input(sky_shader, b'u_sea_phase')
|
||||||
sea_polar_textures = sea.load_polar_textures(('data/sea_bump1.png', 'data/sea_bump2.png'))
|
sea_polar_textures = sea.load_polar_textures(('data/sea_bump1.png', 'data/sea_bump2.png'))
|
||||||
@ -162,6 +169,11 @@ def main():
|
|||||||
mat3_mul_vec3(_origin, _rotation, origin)
|
mat3_mul_vec3(_origin, _rotation, origin)
|
||||||
mat3_mul_vec3(_lookat, _rotation, lookat)
|
mat3_mul_vec3(_lookat, _rotation, lookat)
|
||||||
|
|
||||||
|
terrain_camera.set_view(_origin, _lookat)
|
||||||
|
tests_camera.set_view(_origin, _lookat)
|
||||||
|
sky_camera.set_view(vec3(math.vec3_scale(_origin, 0.001)), vec3(math.vec3_scale(_lookat, 0.001)))
|
||||||
|
environment_values = environment.from_sun(terrain_camera.view, sun_direction, sun_power)
|
||||||
|
|
||||||
mat3_rotation(_rotation, up, (current_time * 0.21) % tau)
|
mat3_rotation(_rotation, up, (current_time * 0.21) % tau)
|
||||||
mat3_mul_vec3(_blob_translation, _rotation, blob_translation)
|
mat3_mul_vec3(_blob_translation, _rotation, blob_translation)
|
||||||
tests_batch.set_param(0, blob_id, _blob_translation)
|
tests_batch.set_param(0, blob_id, _blob_translation)
|
||||||
@ -176,39 +188,37 @@ def main():
|
|||||||
tests_batch.set_param(1, clouds_id, _clouds_orientation)
|
tests_batch.set_param(1, clouds_id, _clouds_orientation)
|
||||||
|
|
||||||
select_shader(terrain_shader)
|
select_shader(terrain_shader)
|
||||||
select_texture(heightmap, heightmap_sampler)
|
|
||||||
select_texture(normalmap, normalmap_sampler)
|
|
||||||
|
|
||||||
terrain_camera.set_view(_origin, _lookat)
|
|
||||||
terrain_camera.update_inputs()
|
terrain_camera.update_inputs()
|
||||||
environment_values = environment.from_sun(terrain_camera.view, sun_direction, sun_power)
|
|
||||||
environment.update_inputs(terrain_environment_inputs, environment_values)
|
environment.update_inputs(terrain_environment_inputs, environment_values)
|
||||||
|
|
||||||
select_texture(tiles_texture, tiles_sampler)
|
select_texture(tiles_texture, tiles_sampler)
|
||||||
|
select_texture(heightmap, terrain_heightmap_sampler)
|
||||||
|
select_texture(normalmap, terrain_normalmap_sampler)
|
||||||
select_vertices(tiles_vertices)
|
select_vertices(tiles_vertices)
|
||||||
set_param_vec3(terrain_orientation, vec3(vec3_forward))
|
|
||||||
draw_begin = time.thread_time()
|
draw_begin = time.thread_time()
|
||||||
terrain_batch.draw()
|
terrain_batch.draw()
|
||||||
draw_end = time.thread_time()
|
draw_end = time.thread_time()
|
||||||
unselect_vertices(tiles_vertices)
|
unselect_vertices(tiles_vertices)
|
||||||
unselect_texture(tiles_texture)
|
unselect_texture(tiles_texture)
|
||||||
|
|
||||||
select_texture(tests_texture, tests_sampler)
|
|
||||||
select_vertices(tests_vertices)
|
|
||||||
tests_batch.draw()
|
|
||||||
unselect_vertices(tests_vertices)
|
|
||||||
unselect_texture(tests_texture)
|
|
||||||
|
|
||||||
unselect_texture(normalmap)
|
unselect_texture(normalmap)
|
||||||
unselect_texture(heightmap)
|
unselect_texture(heightmap)
|
||||||
unselect_shader(terrain_shader)
|
unselect_shader(terrain_shader)
|
||||||
|
|
||||||
|
select_shader(tests_shader)
|
||||||
|
tests_camera.update_inputs()
|
||||||
|
environment.update_inputs(tests_environment_inputs, environment_values)
|
||||||
|
select_texture(tests_texture, tests_sampler)
|
||||||
|
select_texture(heightmap, tests_heightmap_sampler)
|
||||||
|
select_texture(normalmap, tests_normalmap_sampler)
|
||||||
|
select_vertices(tests_vertices)
|
||||||
|
tests_batch.draw()
|
||||||
|
unselect_vertices(tests_vertices)
|
||||||
|
unselect_texture(tests_texture)
|
||||||
|
unselect_texture(normalmap)
|
||||||
|
unselect_texture(heightmap)
|
||||||
|
unselect_shader(tests_shader)
|
||||||
|
|
||||||
select_shader(sky_shader)
|
select_shader(sky_shader)
|
||||||
sky_camera.set_view(
|
|
||||||
vec3(math.vec3_scale(_origin, 0.001)),
|
|
||||||
vec3(math.vec3_scale(_lookat, 0.001)))
|
|
||||||
sky_camera.update_inputs()
|
sky_camera.update_inputs()
|
||||||
environment_values = environment.from_sun(sky_camera.view, sun_direction, sun_power)
|
|
||||||
environment.update_inputs(sky_environment_inputs, environment_values)
|
environment.update_inputs(sky_environment_inputs, environment_values)
|
||||||
set_input_float(sea_phase, (current_time * 0.023) % 1.0)
|
set_input_float(sea_phase, (current_time * 0.023) % 1.0)
|
||||||
select_texture(sea_polar_textures, sea_polar_sampler)
|
select_texture(sea_polar_textures, sea_polar_sampler)
|
||||||
@ -262,5 +272,6 @@ def main():
|
|||||||
destroy_triangles(sky_triangles)
|
destroy_triangles(sky_triangles)
|
||||||
archive.destroy()
|
archive.destroy()
|
||||||
destroy_shader(terrain_shader)
|
destroy_shader(terrain_shader)
|
||||||
|
destroy_shader(tests_shader)
|
||||||
destroy_shader(sky_shader)
|
destroy_shader(sky_shader)
|
||||||
terminate()
|
terminate()
|
||||||
|
@ -19,7 +19,10 @@ from engine import load_shader
|
|||||||
|
|
||||||
#TODO: preprocessing (at least includes)
|
#TODO: preprocessing (at least includes)
|
||||||
|
|
||||||
def load(name):
|
def load(vert_name, frag_name = ''):
|
||||||
|
path = Path('.') / 'game' / 'shaders'
|
||||||
|
if not frag_name:
|
||||||
|
frag_name = vert_name
|
||||||
def _cleanup(_line):
|
def _cleanup(_line):
|
||||||
return _line.partition('//')[0].strip()
|
return _line.partition('//')[0].strip()
|
||||||
def _filter(_line):
|
def _filter(_line):
|
||||||
@ -31,13 +34,13 @@ def load(name):
|
|||||||
print("Cannot find", _path)
|
print("Cannot find", _path)
|
||||||
return None
|
return None
|
||||||
return list(map(_convert, filter(_filter, map(_cleanup, open(_path, 'rt')))))
|
return list(map(_convert, filter(_filter, map(_cleanup, open(_path, 'rt')))))
|
||||||
print("Loading shader", name)
|
print("Loading vertex shader", vert_name)
|
||||||
path = Path('.') / 'game' / 'shaders'
|
vert_lines = load_source(path / (vert_name + '_opengles.vert'))
|
||||||
vert_lines = load_source(path / (name + '_opengles.vert'))
|
|
||||||
if not vert_lines:
|
if not vert_lines:
|
||||||
print("Error: Vertex shader is empty.")
|
print("Error: Vertex shader is empty.")
|
||||||
return None
|
return None
|
||||||
frag_lines = load_source(path / (name + '_opengles.frag'))
|
print("Loading fragment shader", frag_name)
|
||||||
|
frag_lines = load_source(path / (frag_name + '_opengles.frag'))
|
||||||
if not frag_lines:
|
if not frag_lines:
|
||||||
print("Error: Fragment shader is empty.")
|
print("Error: Fragment shader is empty.")
|
||||||
return None
|
return None
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
#version 320 es
|
#version 320 es
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
in vec3 v_position; // view space
|
in vec4 v_position; // view space
|
||||||
in vec3 v_normal; // view space
|
in vec4 v_normal; // view space
|
||||||
in vec4 v_terrain_normal; // view space (x, y, z, weight)
|
in vec4 v_terrain_normal; // view space (x, y, z, weight)
|
||||||
in vec4 v_texcoord; // texture space (s, t, pixel_level, material_level)
|
in vec4 v_texcoord; // texture space (s, t, pixel_level, material_level)
|
||||||
|
|
||||||
@ -36,8 +36,8 @@ void main(void) {
|
|||||||
#define m_metallic material.x
|
#define m_metallic material.x
|
||||||
#define m_specular material.y
|
#define m_specular material.y
|
||||||
#define m_roughness material.z
|
#define m_roughness material.z
|
||||||
vec3 normal = normalize(v_normal);
|
vec3 normal = normalize(v_normal.xyz);
|
||||||
vec3 eye_dir = -normalize(v_position);
|
vec3 eye_dir = -normalize(v_position.xyz);
|
||||||
float d = dot(normal, u_light_direction);
|
float d = dot(normal, u_light_direction);
|
||||||
float halfd = 0.5 + d * 0.5;
|
float halfd = 0.5 + d * 0.5;
|
||||||
float td = dot(normalize(v_terrain_normal.xyz), u_light_direction);
|
float td = dot(normalize(v_terrain_normal.xyz), u_light_direction);
|
@ -21,7 +21,6 @@ layout(location = 1) in vec3 a_normal; // model space
|
|||||||
layout(location = 2) in vec3 a_texcoord; // texture space
|
layout(location = 2) in vec3 a_texcoord; // texture space
|
||||||
|
|
||||||
layout(location = 3) in vec3 i_translation; // per mesh, model space -> world space
|
layout(location = 3) in vec3 i_translation; // per mesh, model space -> world space
|
||||||
layout(location = 4) in vec3 i_orientation; // per mesh, model space -> world space
|
|
||||||
|
|
||||||
uniform mat4 u_view; // world space -> view space
|
uniform mat4 u_view; // world space -> view space
|
||||||
uniform mat4 u_projection; // view space -> screen space
|
uniform mat4 u_projection; // view space -> screen space
|
||||||
@ -38,25 +37,21 @@ const float c_weight_scale = 1.0 / 64.f;
|
|||||||
const vec3 c_world_forward = vec3(0.0, 1.0, 0.0);
|
const vec3 c_world_forward = vec3(0.0, 1.0, 0.0);
|
||||||
const vec3 c_world_up = vec3(0.0, 0.0, 1.0);
|
const vec3 c_world_up = vec3(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
out vec3 v_position; // view space
|
out vec4 v_position; // view space
|
||||||
out vec3 v_normal; // view space
|
out vec4 v_normal; // view space
|
||||||
out vec4 v_terrain_normal; // view space (x, y, z, weigth)
|
out vec4 v_terrain_normal; // view space (x, y, z, weigth)
|
||||||
out vec4 v_texcoord; // texture space (s, t, pixel_level, material_level)
|
out vec4 v_texcoord; // texture space (s, t, pixel_level, material_level)
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec3 orientation = normalize(i_orientation);
|
vec4 world_position = vec4(i_translation + a_position, 1.0);
|
||||||
mat3 rotation = mat3(cross(orientation, c_world_up), orientation, c_world_up);
|
|
||||||
vec4 world_position = vec4(i_translation.xyz + rotation * a_position, 1.0);
|
|
||||||
float weight = max(0.0, 1.0 - world_position.z * c_weight_scale);
|
|
||||||
vec3 world_normal = rotation * normalize(a_normal);
|
|
||||||
vec2 terrain_coords = c_terrain_shift + world_position.xy * c_terrain_scale;
|
vec2 terrain_coords = c_terrain_shift + world_position.xy * c_terrain_scale;
|
||||||
world_position.z += texture(u_height_sampler, terrain_coords).r;
|
world_position.z += texture(u_height_sampler, terrain_coords).r;
|
||||||
vec4 view_position = u_view * world_position;
|
vec4 view_position = u_view * world_position;
|
||||||
vec3 terrain_normal = normalize(c_normal_shift + texture(u_normal_sampler, terrain_coords).rgb * c_normal_scale);
|
vec3 terrain_normal = normalize(c_normal_shift + texture(u_normal_sampler, terrain_coords).rgb * c_normal_scale);
|
||||||
world_normal = mat3(cross(c_world_forward, terrain_normal), c_world_forward, terrain_normal) * world_normal;
|
vec3 world_normal = mat3(cross(c_world_forward, terrain_normal), c_world_forward, terrain_normal) * normalize(a_normal);
|
||||||
v_position = view_position.xyz;
|
v_position = view_position;
|
||||||
v_normal = (u_view * vec4(world_normal, 0.0)).xyz;
|
v_normal = u_view * vec4(world_normal, 0.0);
|
||||||
v_terrain_normal = vec4((u_view * vec4(terrain_normal, 0.0)).xyz, weight);
|
v_terrain_normal = vec4((u_view * vec4(terrain_normal, 0.0)).xyz, 1.0);
|
||||||
v_texcoord = vec4(a_texcoord.st * c_st_scale, a_texcoord.p, a_texcoord.p + 1.0);
|
v_texcoord = vec4(a_texcoord.st * c_st_scale, a_texcoord.p, a_texcoord.p + 1.0);
|
||||||
gl_Position = u_projection * view_position;
|
gl_Position = u_projection * view_position;
|
||||||
}
|
}
|
||||||
|
62
game/shaders/tests_opengles.vert
Normal file
62
game/shaders/tests_opengles.vert
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Copyright (C) 2022 RozK
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#version 320 es
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 a_position; // model space
|
||||||
|
layout(location = 1) in vec3 a_normal; // model space
|
||||||
|
layout(location = 2) in vec3 a_texcoord; // texture space
|
||||||
|
|
||||||
|
layout(location = 3) in vec3 i_translation; // per mesh, model space -> world space
|
||||||
|
layout(location = 4) in vec3 i_orientation; // per mesh, model space -> world space
|
||||||
|
|
||||||
|
uniform mat4 u_view; // world space -> view space
|
||||||
|
uniform mat4 u_projection; // view space -> screen space
|
||||||
|
|
||||||
|
uniform highp sampler2D u_height_sampler;
|
||||||
|
uniform highp sampler2D u_normal_sampler;
|
||||||
|
|
||||||
|
const vec3 c_normal_scale = vec3(2.0, 2.0, 1.0);
|
||||||
|
const vec3 c_normal_shift = vec3(-1.0, -1.0, 0.0);
|
||||||
|
const vec2 c_st_scale = vec2(1.0 / 1023.0, 1.0 / 1023.0);
|
||||||
|
const vec2 c_terrain_scale = vec2(1.0 / 2048.0, -1.0 / 2048.0);
|
||||||
|
const vec2 c_terrain_shift = vec2(0.5, 0.5);
|
||||||
|
const float c_weight_scale = 1.0 / 64.f;
|
||||||
|
const vec3 c_world_forward = vec3(0.0, 1.0, 0.0);
|
||||||
|
const vec3 c_world_up = vec3(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
out vec4 v_position; // view space
|
||||||
|
out vec4 v_normal; // view space
|
||||||
|
out vec4 v_terrain_normal; // view space (x, y, z, weigth)
|
||||||
|
out vec4 v_texcoord; // texture space (s, t, pixel_level, material_level)
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec3 orientation = normalize(i_orientation);
|
||||||
|
mat3 rotation = mat3(cross(orientation, c_world_up), orientation, c_world_up);
|
||||||
|
vec4 world_position = vec4(i_translation + rotation * a_position, 1.0);
|
||||||
|
float weight = max(0.0, 1.0 - world_position.z * c_weight_scale);
|
||||||
|
vec3 world_normal = rotation * normalize(a_normal);
|
||||||
|
vec2 terrain_coords = c_terrain_shift + world_position.xy * c_terrain_scale;
|
||||||
|
world_position.z += texture(u_height_sampler, terrain_coords).r;
|
||||||
|
vec4 view_position = u_view * world_position;
|
||||||
|
vec3 terrain_normal = normalize(c_normal_shift + texture(u_normal_sampler, terrain_coords).rgb * c_normal_scale);
|
||||||
|
world_normal = mat3(cross(c_world_forward, terrain_normal), c_world_forward, terrain_normal) * world_normal;
|
||||||
|
v_position = view_position;
|
||||||
|
v_normal = u_view * vec4(world_normal, 0.0);
|
||||||
|
v_terrain_normal = vec4((u_view * vec4(terrain_normal, 0.0)).xyz, weight);
|
||||||
|
v_texcoord = vec4(a_texcoord.st * c_st_scale, a_texcoord.p, a_texcoord.p + 1.0);
|
||||||
|
gl_Position = u_projection * view_position;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user