improve lighting and trile editing
This commit is contained in:
parent
9098550523
commit
3a7f19c89d
@ -277,7 +277,11 @@ add_resources_from_pack :: (pack: *Loaded_Pack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
free_resources_from_pack :: (pack: *Loaded_Pack) {
|
free_resources_from_pack :: (pack: *Loaded_Pack) {
|
||||||
|
for pack.textures sg_destroy_image(it);
|
||||||
|
for *pack.audio array_free(it.data);
|
||||||
|
table_reset(*pack.textures);
|
||||||
|
table_reset(*pack.audio);
|
||||||
|
table_reset(*pack.animations);
|
||||||
}
|
}
|
||||||
|
|
||||||
find_pack_by_name :: (name: string) -> (bool, Loaded_Pack) {
|
find_pack_by_name :: (name: string) -> (bool, Loaded_Pack) {
|
||||||
|
|||||||
@ -77,6 +77,8 @@ draw_editor :: () {
|
|||||||
#if OS != .WASM {
|
#if OS != .WASM {
|
||||||
if !in_editor_view then return;
|
if !in_editor_view then return;
|
||||||
|
|
||||||
|
bypass_postprocess = (current_editor_view == .Trile_Editor);
|
||||||
|
|
||||||
if current_editor_view == {
|
if current_editor_view == {
|
||||||
case .Trile_Editor;
|
case .Trile_Editor;
|
||||||
draw_trile_editor();
|
draw_trile_editor();
|
||||||
|
|||||||
@ -540,6 +540,7 @@ gen_rdm :: (quality: s32, include_water: bool, world: World) {
|
|||||||
|
|
||||||
rdm_save_image_to_file :: (path: string, data: *float, width: s32, height: s32) {
|
rdm_save_image_to_file :: (path: string, data: *float, width: s32, height: s32) {
|
||||||
#if OS != .WASM {
|
#if OS != .WASM {
|
||||||
|
file :: #import "File";
|
||||||
builder: String_Builder;
|
builder: String_Builder;
|
||||||
header := RDM_File_Header.{
|
header := RDM_File_Header.{
|
||||||
magic = RDM_FILE_MAGIC,
|
magic = RDM_FILE_MAGIC,
|
||||||
@ -549,7 +550,7 @@ rdm_save_image_to_file :: (path: string, data: *float, width: s32, height: s32)
|
|||||||
write_bytes(*builder, *header, size_of(RDM_File_Header));
|
write_bytes(*builder, *header, size_of(RDM_File_Header));
|
||||||
pixel_bytes := cast(s64) width * cast(s64) height * 4 * size_of(float);
|
pixel_bytes := cast(s64) width * cast(s64) height * 4 * size_of(float);
|
||||||
write_bytes(*builder, data, pixel_bytes);
|
write_bytes(*builder, data, pixel_bytes);
|
||||||
rdm_file.write_entire_file(path, builder_to_string(*builder));
|
file.write_entire_file(path, builder_to_string(*builder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -376,4 +376,33 @@ draw_trile_editor_ui :: (theme: *GR.Overall_Theme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw_picker(theme);
|
draw_picker(theme);
|
||||||
|
|
||||||
|
// View mode buttons — bottom center of the 3D viewport.
|
||||||
|
btn_w := 11.0 * vw;
|
||||||
|
btn_h := cast(float) ui_h(4, 0);
|
||||||
|
bar_w := btn_w * 4.0;
|
||||||
|
bar_x := 100.0 * vw / 2.0 - bar_w / 2.0;
|
||||||
|
bar_y := 100.0 * vh - btn_h - 1.5 * vh;
|
||||||
|
|
||||||
|
bar_r : GR.Rect;
|
||||||
|
bar_r.x = bar_x; bar_r.y = bar_y; bar_r.w = bar_w; bar_r.h = btn_h;
|
||||||
|
ui_add_mouse_occluder(bar_r);
|
||||||
|
|
||||||
|
r2 : GR.Rect;
|
||||||
|
r2.x = bar_x; r2.y = bar_y; r2.w = btn_w; r2.h = btn_h;
|
||||||
|
if GR.button(r2, "Lit", *t_button_selectable(theme, trixel_view_mode == 0)) {
|
||||||
|
trixel_view_mode = 0;
|
||||||
|
}
|
||||||
|
r2.x += btn_w;
|
||||||
|
if GR.button(r2, "Normals", *t_button_selectable(theme, trixel_view_mode == 1)) {
|
||||||
|
trixel_view_mode = 1;
|
||||||
|
}
|
||||||
|
r2.x += btn_w;
|
||||||
|
if GR.button(r2, "Albedo", *t_button_selectable(theme, trixel_view_mode == 2)) {
|
||||||
|
trixel_view_mode = 2;
|
||||||
|
}
|
||||||
|
r2.x += btn_w;
|
||||||
|
if GR.button(r2, "Mixed", *t_button_selectable(theme, trixel_view_mode == 3)) {
|
||||||
|
trixel_view_mode = 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
camera: Camera;
|
camera: Camera;
|
||||||
|
|
||||||
trixel_count : s32 = 0;
|
trixel_count : s32 = 0;
|
||||||
|
trixel_view_mode : s32 = 0;
|
||||||
|
bypass_postprocess : bool = false;
|
||||||
|
|
||||||
trile_offsets : [..]s32;
|
trile_offsets : [..]s32;
|
||||||
current_trile_offset_index : s32 = 0;
|
current_trile_offset_index : s32 = 0;
|
||||||
@ -64,8 +66,11 @@ backend_update_trixels :: (cmd: Render_Command_Update_Trixels) {
|
|||||||
trixels[trixel_count].pos.x = x * (1.0 / 16.0) + TRIXEL_SIZE_HALF;
|
trixels[trixel_count].pos.x = x * (1.0 / 16.0) + TRIXEL_SIZE_HALF;
|
||||||
trixels[trixel_count].pos.y = y * (1.0 / 16.0) + TRIXEL_SIZE_HALF;
|
trixels[trixel_count].pos.y = y * (1.0 / 16.0) + TRIXEL_SIZE_HALF;
|
||||||
trixels[trixel_count].pos.z = z * (1.0 / 16.0) + TRIXEL_SIZE_HALF;
|
trixels[trixel_count].pos.z = z * (1.0 / 16.0) + TRIXEL_SIZE_HALF;
|
||||||
trixels[trixel_count].pos.w = 1.0;
|
cm := (cmd.colMultipliers.*)[x][y][z];
|
||||||
trixel_color := cmd.trile.trixels[x][y][z].material.color * (cmd.colMultipliers.*)[x][y][z];
|
// Encode highlight state in inst.w: non-identity colorMul means highlighted.
|
||||||
|
// 0=normal, 1=hovered, (future: 2=selected, 3=in-brush).
|
||||||
|
trixels[trixel_count].pos.w = ifx (cm.x == 1.0 && cm.y == 1.0 && cm.z == 1.0) then 0.0 else 1.0;
|
||||||
|
trixel_color := cmd.trile.trixels[x][y][z].material.color * cm;
|
||||||
|
|
||||||
trixels[trixel_count].col = .{trixel_color.x, trixel_color.y, trixel_color.z, material_encode_to_float(cmd.trile.trixels[x][y][z].material)};
|
trixels[trixel_count].col = .{trixel_color.x, trixel_color.y, trixel_color.z, material_encode_to_float(cmd.trile.trixels[x][y][z].material)};
|
||||||
trixel_count += 1;
|
trixel_count += 1;
|
||||||
@ -91,10 +96,14 @@ backend_draw_trixels :: () {
|
|||||||
wc : *World_Config = *(World_Config.{});
|
wc : *World_Config = *(World_Config.{});
|
||||||
world_config_to_shader_type(wc, *world_conf);
|
world_config_to_shader_type(wc, *world_conf);
|
||||||
|
|
||||||
|
fs_params : Trixel_Fs_Params;
|
||||||
|
fs_params.view_mode = trixel_view_mode;
|
||||||
|
|
||||||
sg_apply_pipeline(gPipelines.trixel.pipeline);
|
sg_apply_pipeline(gPipelines.trixel.pipeline);
|
||||||
sg_apply_bindings(*gPipelines.trixel.bind);
|
sg_apply_bindings(*gPipelines.trixel.bind);
|
||||||
sg_apply_uniforms(UB_vs_params, *(sg_range.{ ptr = *vs_params, size = size_of(type_of(vs_params)) }));
|
sg_apply_uniforms(UB_vs_params, *(sg_range.{ ptr = *vs_params, size = size_of(type_of(vs_params)) }));
|
||||||
sg_apply_uniforms(UB_trixel_world_config, *(sg_range.{ptr = *world_conf, size = size_of(type_of(world_conf))}));
|
sg_apply_uniforms(UB_trixel_world_config, *(sg_range.{ptr = *world_conf, size = size_of(type_of(world_conf))}));
|
||||||
|
sg_apply_uniforms(UB_trixel_fs_params, *(sg_range.{ ptr = *fs_params, size = size_of(type_of(fs_params)) }));
|
||||||
sg_draw(0, 36, trixel_count);
|
sg_draw(0, 36, trixel_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,6 +219,7 @@ backend_draw_trile_positions_main :: (trile : string, amount : s32, worldConf: *
|
|||||||
fs_params.rdm_diff_scale = lc.rdm_diff_scale;
|
fs_params.rdm_diff_scale = lc.rdm_diff_scale;
|
||||||
fs_params.rdm_spec_scale = lc.rdm_spec_scale;
|
fs_params.rdm_spec_scale = lc.rdm_spec_scale;
|
||||||
fs_params.ambient_color = lc.ambient_color.component;
|
fs_params.ambient_color = lc.ambient_color.component;
|
||||||
|
fs_params.rdm_tint = lc.rdm_tint.component;
|
||||||
|
|
||||||
sg_apply_bindings(*bindings);
|
sg_apply_bindings(*bindings);
|
||||||
sg_apply_uniforms(UB_trile_fs_params, *(sg_range.{ ptr = *fs_params, size = size_of(type_of(fs_params)) }));
|
sg_apply_uniforms(UB_trile_fs_params, *(sg_range.{ ptr = *fs_params, size = size_of(type_of(fs_params)) }));
|
||||||
@ -241,6 +251,7 @@ backend_draw_ground :: (wc: *World_Config) {
|
|||||||
world_conf : Plane_World_Config;
|
world_conf : Plane_World_Config;
|
||||||
plane_data : Plane_Data;
|
plane_data : Plane_Data;
|
||||||
w, h := get_render_size();
|
w, h := get_render_size();
|
||||||
|
plane_data.mvp_shadow = shadow_mvp.floats;
|
||||||
plane_data.screen_w = w;
|
plane_data.screen_w = w;
|
||||||
plane_data.screen_h = h;
|
plane_data.screen_h = h;
|
||||||
plane_data.cameraPosition = camera.position.component;
|
plane_data.cameraPosition = camera.position.component;
|
||||||
@ -249,9 +260,6 @@ backend_draw_ground :: (wc: *World_Config) {
|
|||||||
|
|
||||||
world_config_to_shader_type(wc, *world_conf);
|
world_config_to_shader_type(wc, *world_conf);
|
||||||
|
|
||||||
fs_params : Plane_Fs_Params;
|
|
||||||
fs_params.mvp_shadow = shadow_mvp.floats;
|
|
||||||
fs_params.is_reflection = ifx in_reflection_pass then cast(s32)1 else cast(s32)0;
|
|
||||||
vs_params.mvp = mvp.floats;
|
vs_params.mvp = mvp.floats;
|
||||||
vs_params.planeHeight = wc.planeHeight;
|
vs_params.planeHeight = wc.planeHeight;
|
||||||
sg_apply_pipeline(gPipelines.plane.pipeline);
|
sg_apply_pipeline(gPipelines.plane.pipeline);
|
||||||
@ -259,7 +267,6 @@ backend_draw_ground :: (wc: *World_Config) {
|
|||||||
gPipelines.plane.bind.images[1] = g_shadowmap;
|
gPipelines.plane.bind.images[1] = g_shadowmap;
|
||||||
sg_apply_bindings(*gPipelines.plane.bind);
|
sg_apply_bindings(*gPipelines.plane.bind);
|
||||||
sg_apply_uniforms(UB_plane_vs_params, *(sg_range.{ ptr = *vs_params, size = size_of(type_of(vs_params)) }));
|
sg_apply_uniforms(UB_plane_vs_params, *(sg_range.{ ptr = *vs_params, size = size_of(type_of(vs_params)) }));
|
||||||
sg_apply_uniforms(UB_plane_fs_params, *(sg_range.{ ptr = *fs_params, size = size_of(type_of(fs_params)) }));
|
|
||||||
sg_apply_uniforms(UB_plane_world_config, *(sg_range.{ptr = *world_conf, size = size_of(type_of(world_conf))}));
|
sg_apply_uniforms(UB_plane_world_config, *(sg_range.{ptr = *world_conf, size = size_of(type_of(world_conf))}));
|
||||||
sg_apply_uniforms(UB_plane_data, *(sg_range.{ptr = *plane_data, size = size_of(type_of(plane_data))}));
|
sg_apply_uniforms(UB_plane_data, *(sg_range.{ptr = *plane_data, size = size_of(type_of(plane_data))}));
|
||||||
sg_draw(0, 6, 2);
|
sg_draw(0, 6, 2);
|
||||||
@ -436,8 +443,10 @@ backend_process_command_buckets :: () {
|
|||||||
end_frame_profiling_group("Main pass");
|
end_frame_profiling_group("Main pass");
|
||||||
|
|
||||||
start_frame_profiling_group("Postprocess pass");
|
start_frame_profiling_group("Postprocess pass");
|
||||||
|
if !bypass_postprocess {
|
||||||
bloom_process();
|
bloom_process();
|
||||||
dof_process();
|
dof_process();
|
||||||
|
}
|
||||||
end_frame_profiling_group("Postprocess pass");
|
end_frame_profiling_group("Postprocess pass");
|
||||||
|
|
||||||
start_frame_profiling_group("Final pass");
|
start_frame_profiling_group("Final pass");
|
||||||
@ -446,11 +455,16 @@ backend_process_command_buckets :: () {
|
|||||||
|
|
||||||
// Draw the render texture and do post processing:
|
// Draw the render texture and do post processing:
|
||||||
sg_apply_pipeline(gPipelines.postprocess.pipeline);
|
sg_apply_pipeline(gPipelines.postprocess.pipeline);
|
||||||
gPipelines.postprocess.bind.images[0] = g_postprocess_a;
|
gPipelines.postprocess.bind.images[0] = ifx bypass_postprocess then g_rendertex else g_postprocess_a;
|
||||||
gPipelines.postprocess.bind.images[1] = LUT_list[g_current_lut_texture_index].image;
|
gPipelines.postprocess.bind.images[1] = LUT_list[g_current_lut_texture_index].image;
|
||||||
sg_apply_bindings(*gPipelines.postprocess.bind);
|
sg_apply_bindings(*gPipelines.postprocess.bind);
|
||||||
post_process_config_uniform : Post_Process_Config;
|
post_process_config_uniform : Post_Process_Config;
|
||||||
fill_uniform_with_engine_data(*post_process_config_uniform , *current_post_process);
|
if bypass_postprocess {
|
||||||
|
neutral : Post_Process;
|
||||||
|
fill_uniform_with_engine_data(*post_process_config_uniform, *neutral);
|
||||||
|
} else {
|
||||||
|
fill_uniform_with_engine_data(*post_process_config_uniform, *current_post_process);
|
||||||
|
}
|
||||||
sg_apply_uniforms(UB_post_process_config, *(sg_range.{ ptr = *post_process_config_uniform, size = size_of(type_of(post_process_config_uniform)) }));
|
sg_apply_uniforms(UB_post_process_config, *(sg_range.{ ptr = *post_process_config_uniform, size = size_of(type_of(post_process_config_uniform)) }));
|
||||||
sg_draw(0, 6, 1);
|
sg_draw(0, 6, 1);
|
||||||
|
|
||||||
|
|||||||
@ -1,28 +1,28 @@
|
|||||||
Post_Process :: struct {
|
Post_Process :: struct {
|
||||||
exposure : float = 0.0; @Slider,0,3,0.1;
|
exposure : float = 1.0; @Slider,0,3,0.1;
|
||||||
contrast : float = 1.0; @Slider,0,6,0.1;
|
contrast : float = 1.0; @Slider,0,6,0.1;
|
||||||
saturation : float = 1.0; @Slider,0.0,2.0,0.1;
|
saturation : float = 1.0; @Slider,0.0,2.0,0.1;
|
||||||
gamma : float = 2.2; @Slider,0.3,3.0,0.1;
|
gamma : float = 1.0; @Slider,0.3,3.0,0.1;
|
||||||
tonemap : float = 1.0; @Slider,0,1,1;
|
tonemap : float = 0.0; @Slider,0,1,1;
|
||||||
ssao : float = 1.0; @Slider,0,5,0.1;
|
ssao : float = 0.0; @Slider,0,5,0.1;
|
||||||
ssao_size : s32 = 1; @Slider,0,5,1;
|
ssao_size : s32 = 1; @Slider,0,5,1;
|
||||||
dilate_separation : float = 1.0; @Slider,0,6,0.1;
|
dilate_separation : float = 1.0; @Slider,0,6,0.1;
|
||||||
dilate_size : s32 = 2; @Slider,0,10,1;
|
dilate_size : s32 = 0; @Slider,0,10,1;
|
||||||
dilate_min : float = 0.1; @Slider,0,1,0.1;
|
dilate_min : float = 0.1; @Slider,0,1,0.1;
|
||||||
dilate_max : float = 0.3; @Slider,0,1,0.1;
|
dilate_max : float = 0.3; @Slider,0,1,0.1;
|
||||||
dof_blur_size : s32 = 2; @Slider,0,10,1;
|
dof_blur_size : s32 = 0; @Slider,0,10,1;
|
||||||
dof_min : float = 1.0; @Slider,0,10,1;
|
dof_min : float = 1.0; @Slider,0,10,1;
|
||||||
dof_max : float = 3.0; @Slider,0,50,1;
|
dof_max : float = 3.0; @Slider,0,50,1;
|
||||||
dof_point : float = 5.0; @Slider,0,30,1;
|
dof_point : float = 5.0; @Slider,0,30,1;
|
||||||
bloom_size : s32 = 5; @Slider,0,10,1;
|
bloom_size : s32 = 5; @Slider,0,10,1;
|
||||||
bloom_separation : float = 3.0; @Slider,0,10,1;
|
bloom_separation : float = 3.0; @Slider,0,10,1;
|
||||||
bloom_treshold : float = 0.4; @Slider,0,1,0.1;
|
bloom_treshold : float = 0.4; @Slider,0,1,0.1;
|
||||||
bloom_amount : float = 1.0; @Slider,0,5,0.1;
|
bloom_amount : float = 0.0; @Slider,0,5,0.1;
|
||||||
|
|
||||||
vignette_intensity: float = 0.5; @Slider,0,1,0.1;
|
vignette_intensity: float = 0.0; @Slider,0,1,0.1;
|
||||||
vignette_radius: float = 0.5; @Slider,0,1,0.1;
|
vignette_radius : float = 0.5; @Slider,0,1,0.1;
|
||||||
scanlines_intensity: float = 0.1; @Slider,0,1,0.1;
|
scanlines_intensity: float = 0.0; @Slider,0,1,0.1;
|
||||||
scanlines_density: float = 1; @Slider,0,10,0.1;
|
scanlines_density : float = 1.0; @Slider,0,10,0.1;
|
||||||
chromatic_aberration_intensity: float = 0.0; @Slider,0,0.05,0.001;
|
chromatic_aberration_intensity: float = 0.0; @Slider,0,0.05,0.001;
|
||||||
film_grain_intensity: float = 0.0; @Slider,0,0.5,0.001;
|
film_grain_intensity: float = 0.0; @Slider,0,0.5,0.001;
|
||||||
barrel_distortion_intensity: float = 0.0; @Slider,-2,2,0.1;
|
barrel_distortion_intensity: float = 0.0; @Slider,-2,2,0.1;
|
||||||
@ -40,6 +40,7 @@ Lighting_Config :: struct {
|
|||||||
rdm_diff_scale : float = 1.0; @Slider,0,3,0.1
|
rdm_diff_scale : float = 1.0; @Slider,0,3,0.1
|
||||||
rdm_spec_scale : float = 1.0; @Slider,0,3,0.1
|
rdm_spec_scale : float = 1.0; @Slider,0,3,0.1
|
||||||
ambient_color : Vector3 = .{0.3,0.3,0.4}; @Color
|
ambient_color : Vector3 = .{0.3,0.3,0.4}; @Color
|
||||||
|
rdm_tint : Vector3 = .{1.05,1.0,0.9}; @Color
|
||||||
}
|
}
|
||||||
|
|
||||||
current_lighting_config : Lighting_Config;
|
current_lighting_config : Lighting_Config;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -29,12 +29,6 @@ in flat int idx;
|
|||||||
in float depth;
|
in float depth;
|
||||||
out vec4 frag_color;
|
out vec4 frag_color;
|
||||||
|
|
||||||
// Uniform bindings from the original shader
|
|
||||||
layout(binding=3) uniform plane_fs_params {
|
|
||||||
mat4 mvp_shadow;
|
|
||||||
int is_reflection;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(binding=1) uniform plane_world_config {
|
layout(binding=1) uniform plane_world_config {
|
||||||
vec3 skyBase;
|
vec3 skyBase;
|
||||||
vec3 skyTop;
|
vec3 skyTop;
|
||||||
@ -54,6 +48,7 @@ layout(binding=1) uniform plane_world_config {
|
|||||||
};
|
};
|
||||||
|
|
||||||
layout(binding=2) uniform plane_data {
|
layout(binding=2) uniform plane_data {
|
||||||
|
mat4 mvp_shadow;
|
||||||
int screen_w;
|
int screen_w;
|
||||||
int screen_h;
|
int screen_h;
|
||||||
int is_reflection_pass;
|
int is_reflection_pass;
|
||||||
@ -69,7 +64,7 @@ layout(binding = 2) uniform texture2D normal_map;
|
|||||||
|
|
||||||
// Sampler bindings
|
// Sampler bindings
|
||||||
layout(binding = 0) uniform sampler refsmp;
|
layout(binding = 0) uniform sampler refsmp;
|
||||||
layout(binding = 1) uniform sampler shadowsmp;
|
layout(binding = 1) uniform sampler plane_shadowsmp;
|
||||||
layout(binding = 2) uniform sampler normalsmp;
|
layout(binding = 2) uniform sampler normalsmp;
|
||||||
|
|
||||||
vec3 fresnelSchlick(float cosTheta) {
|
vec3 fresnelSchlick(float cosTheta) {
|
||||||
@ -120,31 +115,33 @@ void main() {
|
|||||||
vec3 normal3 = texture(sampler2D(normal_map, normalsmp), uv3).xzy * 2.0 - 1.0;
|
vec3 normal3 = texture(sampler2D(normal_map, normalsmp), uv3).xzy * 2.0 - 1.0;
|
||||||
vec3 normal4 = texture(sampler2D(normal_map, normalsmp), uv4).xzy * 2.0 - 1.0;
|
vec3 normal4 = texture(sampler2D(normal_map, normalsmp), uv4).xzy * 2.0 - 1.0;
|
||||||
|
|
||||||
// vec3 normal = normalize(vec3(0.0, 1.0, 0.0));
|
|
||||||
vec3 normal = normalize(normal1 + normal2 + normal3 + normal4);
|
vec3 normal = normalize(normal1 + normal2 + normal3 + normal4);
|
||||||
|
|
||||||
vec3 view_dir = normalize(cameraPosition - pos.xyz);
|
vec3 view_dir = normalize(cameraPosition - pos.xyz);
|
||||||
vec3 light_dir = normalize(sunPosition);
|
vec3 light_dir = normalize(sunPosition);
|
||||||
vec3 halfway_dir = normalize(light_dir + view_dir);
|
vec3 halfway_dir = normalize(light_dir + view_dir);
|
||||||
float shadow_factor = 1.0; // shadowmap to be implemented
|
|
||||||
|
|
||||||
vec3 base_water_color = waterColor;
|
float diffuse = max(0.0, dot(normal, light_dir));
|
||||||
float diffuse = (dot(normal, light_dir)) + 0.000001 * is_reflection * shininess;
|
|
||||||
float spec = pow(max(0.0, dot(halfway_dir, normal)), 32);
|
float spec = pow(max(0.0, dot(halfway_dir, normal)), 32);
|
||||||
float fresnel = min(1.0, fresnelSchlick(dot(view_dir, vec3(0.0, 1.0, 0.0))).x + 0.3);
|
float fresnel = min(1.0, fresnelSchlick(dot(view_dir, vec3(0.0, 1.0, 0.0))).x + 0.3);
|
||||||
vec3 refracted_color = base_water_color * diffuse * sunLightColor * sunIntensity;
|
|
||||||
vec3 specular_highlight = sunLightColor * sunIntensity * spec;
|
vec4 shadow_proj_pos = mvp_shadow * vec4(pos.xyz, 1.0);
|
||||||
|
vec3 shadow_pos = shadow_proj_pos.xyz / shadow_proj_pos.w;
|
||||||
|
shadow_pos = shadow_pos * 0.5 + 0.5;
|
||||||
|
shadow_pos.z -= 0.001;
|
||||||
|
float shadowp = texture(sampler2DShadow(shadow, plane_shadowsmp), shadow_pos);
|
||||||
|
|
||||||
|
vec3 refracted_color = waterColor * diffuse * sunLightColor * sunIntensity * shadowp;
|
||||||
|
vec3 specular_highlight = sunLightColor * sunIntensity * spec * shadowp;
|
||||||
|
|
||||||
vec2 screen_uv = gl_FragCoord.xy / vec2(screen_w, screen_h);
|
vec2 screen_uv = gl_FragCoord.xy / vec2(screen_w, screen_h);
|
||||||
screen_uv.y = 1.0 - screen_uv.y;
|
screen_uv.y = 1.0 - screen_uv.y;
|
||||||
vec3 reflected_color = texture(sampler2D(reftex, refsmp), screen_uv).rgb;
|
vec2 distortion = normal.xz * 0.005;
|
||||||
vec3 surface_color = mix(refracted_color, reflected_color, min(1.0, fresnel * 1.0));
|
vec3 reflected_color = texture(sampler2D(reftex, refsmp), screen_uv + distortion).rgb;
|
||||||
vec3 final_color = reflected_color + specular_highlight * 0.2 + diffuse * 0.2 + 0.00001 * surface_color;
|
|
||||||
// vec3 final_color = (surface_color + specular_highlight) * shadow_factor;
|
vec3 surface_color = mix(refracted_color, reflected_color, fresnel);
|
||||||
float refraction_alpha = 0.4;
|
vec3 final_color = surface_color + specular_highlight;
|
||||||
float reflection_alpha = 1.0;
|
float alpha = mix(0.3, 0.5, fresnel);
|
||||||
float alpha = mix(refraction_alpha, reflection_alpha, fresnel);
|
|
||||||
// float alpha = 1.0;
|
|
||||||
|
|
||||||
vec3 fog = skyIntensity * sky(normalize(pos.xyz), sunPosition);
|
vec3 fog = skyIntensity * sky(normalize(pos.xyz), sunPosition);
|
||||||
float fogFactor = smoothstep(750.0, 1000.0, length(pos.xz));
|
float fogFactor = smoothstep(750.0, 1000.0, length(pos.xz));
|
||||||
|
|||||||
@ -74,6 +74,7 @@ layout(binding=3) uniform trile_fs_params {
|
|||||||
float rdm_diff_scale;
|
float rdm_diff_scale;
|
||||||
float rdm_spec_scale;
|
float rdm_spec_scale;
|
||||||
vec3 ambient_color;
|
vec3 ambient_color;
|
||||||
|
vec3 rdm_tint;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(binding = 0) uniform texture2D triletex;
|
layout(binding = 0) uniform texture2D triletex;
|
||||||
@ -518,12 +519,18 @@ void main() {
|
|||||||
|
|
||||||
// Indirect specular
|
// Indirect specular
|
||||||
vec3 indirectSpec = sample_rdm(N, -cv,
|
vec3 indirectSpec = sample_rdm(N, -cv,
|
||||||
hemispherePos, vpos - hemispherePos, roughnessInt, local);
|
hemispherePos, vpos - hemispherePos, roughnessInt, local) * rdm_tint;
|
||||||
|
|
||||||
|
// For metallic surfaces: desaturate the reflection so Frough (which uses albedo
|
||||||
|
// as F0 for metals) applies the metal tint cleanly without double-tinting.
|
||||||
|
float specLum = dot(indirectSpec, vec3(0.2126, 0.7152, 0.0722));
|
||||||
|
indirectSpec = mix(indirectSpec, vec3(specLum), metallic);
|
||||||
|
|
||||||
vec2 envBRDF = texture(sampler2D(brdf_lut, rdmsmp), vec2(max(dot(N, V), 0.0), roughness)).rg;
|
vec2 envBRDF = texture(sampler2D(brdf_lut, rdmsmp), vec2(max(dot(N, V), 0.0), roughness)).rg;
|
||||||
light += indirectSpec * (Frough * envBRDF.x + envBRDF.y) * rdm_spec_scale;
|
light += indirectSpec * (Frough * envBRDF.x + envBRDF.y) * rdm_spec_scale;
|
||||||
|
|
||||||
// Indirect diffuse (interpolated from neighbor probes)
|
// Indirect diffuse (interpolated from neighbor probes)
|
||||||
vec3 indirectDiff = sample_rdm_diff(N, vpos - hemispherePos, local);
|
vec3 indirectDiff = sample_rdm_diff(N, vpos - hemispherePos, local) * rdm_tint;
|
||||||
vec3 kDiff = 1.0 - Frough;
|
vec3 kDiff = 1.0 - Frough;
|
||||||
kDiff *= 1.0 - metallic;
|
kDiff *= 1.0 - metallic;
|
||||||
light += (kDiff * indirectDiff / PI * albedo) * ssao_sample * rdm_diff_scale;
|
light += (kDiff * indirectDiff / PI * albedo) * ssao_sample * rdm_diff_scale;
|
||||||
|
|||||||
@ -14,6 +14,7 @@ out vec4 color;
|
|||||||
out vec4 fnormal;
|
out vec4 fnormal;
|
||||||
out vec4 pos;
|
out vec4 pos;
|
||||||
out vec3 cam;
|
out vec3 cam;
|
||||||
|
out float vtrixel_state;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 instancepos = inst.xyz;
|
vec3 instancepos = inst.xyz;
|
||||||
@ -22,11 +23,16 @@ void main() {
|
|||||||
color = inst_col;
|
color = inst_col;
|
||||||
pos = gl_Position;
|
pos = gl_Position;
|
||||||
cam = camera;
|
cam = camera;
|
||||||
|
vtrixel_state = inst.w;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@fs fs_trixel
|
@fs fs_trixel
|
||||||
|
|
||||||
|
layout(binding=2) uniform trixel_fs_params {
|
||||||
|
int view_mode;
|
||||||
|
};
|
||||||
|
|
||||||
layout(binding=1) uniform trixel_world_config {
|
layout(binding=1) uniform trixel_world_config {
|
||||||
vec3 skyBase;
|
vec3 skyBase;
|
||||||
vec3 skyTop;
|
vec3 skyTop;
|
||||||
@ -52,6 +58,7 @@ in vec4 color;
|
|||||||
in vec4 fnormal;
|
in vec4 fnormal;
|
||||||
in vec4 pos;
|
in vec4 pos;
|
||||||
in vec3 cam;
|
in vec3 cam;
|
||||||
|
in float vtrixel_state;
|
||||||
out vec4 frag_color;
|
out vec4 frag_color;
|
||||||
|
|
||||||
const float PI = 3.1412854;
|
const float PI = 3.1412854;
|
||||||
@ -123,7 +130,28 @@ void main() {
|
|||||||
|
|
||||||
light += (kD * albedo / PI + specular) * NdotL * vec3(1.0, 1.0, 1.0);
|
light += (kD * albedo / PI + specular) * NdotL * vec3(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
if (view_mode == 1) {
|
||||||
|
// Normals: map face normals to RGB so each axis gets a distinct color.
|
||||||
|
frag_color = vec4(N * 0.5 + 0.5, 1.0);
|
||||||
|
} else if (view_mode == 2) {
|
||||||
|
// Albedo: simple diffuse shading, no specular/roughness/metallic eval.
|
||||||
|
float diffuse = max(dot(N, L), 0.0) * 0.6 + 0.4;
|
||||||
|
frag_color = vec4(albedo * diffuse + emissive, 1.0);
|
||||||
|
} else if (view_mode == 3) {
|
||||||
|
// Normal+Albedo: normal color used as a per-face tint on the albedo.
|
||||||
|
// Shows paint color and face orientation simultaneously.
|
||||||
|
vec3 normal_tint = N * 0.5 + 0.5;
|
||||||
|
float diffuse = max(dot(N, L), 0.0) * 0.4 + 0.6;
|
||||||
|
frag_color = vec4(albedo * normal_tint * diffuse + emissive, 1.0);
|
||||||
|
} else {
|
||||||
frag_color = vec4(light + emissive, 1.0);
|
frag_color = vec4(light + emissive, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overlay highlight for hovered / selected / brush-radius trixels in all view modes.
|
||||||
|
// State is encoded per-instance in inst.w: 0=normal, 1=hovered, 2=selected, 3=in-brush.
|
||||||
|
if (vtrixel_state > 0.5) {
|
||||||
|
frag_color.rgb = mix(frag_color.rgb, vec3(1.0, 1.0, 0.5), 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,7 @@ set_trile_gfx :: (name: string, gfx: Trile_GFX, skip_preexist_check: bool = fals
|
|||||||
if success {
|
if success {
|
||||||
sg_destroy_buffer(old_gfx.vertex_buffer);
|
sg_destroy_buffer(old_gfx.vertex_buffer);
|
||||||
sg_destroy_buffer(old_gfx.normal_buffer);
|
sg_destroy_buffer(old_gfx.normal_buffer);
|
||||||
|
sg_destroy_buffer(old_gfx.centre_buffer);
|
||||||
sg_destroy_image(old_gfx.trixel_colors);
|
sg_destroy_image(old_gfx.trixel_colors);
|
||||||
array_reset(*old_gfx.vertices);
|
array_reset(*old_gfx.vertices);
|
||||||
print("Destroyed old GFX buffers for trile: %\n", name);
|
print("Destroyed old GFX buffers for trile: %\n", name);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user