Rendering fixes
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -28,9 +28,6 @@ const gbuffer0: tex2d;
|
||||
#[set(everything)]
|
||||
const gbuffer1: tex2d;
|
||||
|
||||
#[set(everything)]
|
||||
const senvmap_brdf: tex2d;
|
||||
|
||||
#[set(everything)]
|
||||
const senvmap_radiance: tex2d;
|
||||
|
||||
@@ -178,7 +175,7 @@ fun mip_from_roughness(roughness: float, num_mipmaps: float): float {
|
||||
|
||||
fun envmap_equirect(normal: float3, angle: float): float2 {
|
||||
var phi: float = acos(normal.z);
|
||||
var theta: float = atan2(normal.x, -normal.y) + PI + angle;
|
||||
var theta: float = atan2(-normal.y, normal.x) + PI + angle;
|
||||
return float2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
@@ -201,6 +198,16 @@ fun envmap_sample(lod: float, coord: float2): float3 {
|
||||
return sample_lod(senvmap_radiance4, sampler_linear, coord, 0.0).rgb;
|
||||
}
|
||||
|
||||
// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
|
||||
fun env_brdf_approx(specular: float3, roughness: float, dotnv: float): float3 {
|
||||
var c0: float4 = float4(-1.0, -0.0275, -0.572, 0.022);
|
||||
var c1: float4 = float4(1.0, 0.0425, 1.04, -0.04);
|
||||
var r: float4 = c0 * roughness + c1;
|
||||
var a004: float = min(r.x * r.x, exp((-9.28 * dotnv) * log(2.0))) * r.x + r.y;
|
||||
var ab: float2 = float2(-1.04, 1.04) * a004 + r.zw;
|
||||
return specular * ab.x + ab.y;
|
||||
}
|
||||
|
||||
fun deferred_light_frag(input: vert_out): float4 {
|
||||
// normal.xy, roughness, metallic/matid
|
||||
var g0: float4 = sample_lod(gbuffer0, sampler_linear, input.tex, 0.0);
|
||||
@@ -236,7 +243,6 @@ fun deferred_light_frag(input: vert_out): float4 {
|
||||
var p: float3 = get_pos(constants.eye, constants.eye_look, normalize(input.view_ray), depth, constants.camera_proj);
|
||||
var v: float3 = normalize(constants.eye - p);
|
||||
var dotnv: float = max(0.0, dot(n, v));
|
||||
|
||||
occ = lerp(1.0, occ, dotnv); // ao fresnel
|
||||
|
||||
// Envmap
|
||||
@@ -251,10 +257,8 @@ fun deferred_light_frag(input: vert_out): float4 {
|
||||
envl = envl / PI;
|
||||
|
||||
var reflection_world: float3 = reflect(-v, n);
|
||||
|
||||
// var lod: float = mip_from_roughness(roughness, float(constants.envmap_num_mipmaps));
|
||||
// var prefiltered_color: float3 = sample_lod(senvmap_radiance, sampler_linear, envmap_equirect(reflection_world, constants.envmap_data.x), lod).rgb;
|
||||
|
||||
var lod: float = mip_from_roughness(roughness, 5.0);
|
||||
var lod0: float = floor(lod);
|
||||
var lod1: float = ceil(lod);
|
||||
@@ -266,11 +270,11 @@ fun deferred_light_frag(input: vert_out): float4 {
|
||||
|
||||
envl.rgb = envl.rgb * albedo;
|
||||
// Indirect specular
|
||||
// var env_brdf: float2 = senvmap_brdf[uint2(roughness * 255.0, (1.0 - dotnv) * 255.0)].xy;
|
||||
var env_brdf: float4 = senvmap_brdf[uint2(uint(roughness * 255.0), uint((1.0 - dotnv) * 255.0))];
|
||||
// var env_brdf: float4 = senvmap_brdf[uint2(uint(dotnv * 255.0), uint(roughness * 255.0))];
|
||||
// envl.rgb += prefiltered_color * (f0 * env_brdf.x + env_brdf.y);
|
||||
// envl.rgb = envl.rgb + (prefiltered_color * (f0 * env_brdf.x + env_brdf.y));
|
||||
envl.rgb = envl.rgb + prefiltered_color * env_brdf_approx(f0, roughness, dotnv) * 0.5;
|
||||
|
||||
//envl.rgb += prefiltered_color * (f0 * env_brdf.x + env_brdf.y) * 1.5;
|
||||
envl.rgb = envl.rgb + (prefiltered_color * (f0 * env_brdf.x + env_brdf.y) * 1.5);
|
||||
envl.rgb = envl.rgb * constants.envmap_data.w * occ;
|
||||
|
||||
var color: float4;
|
||||
@@ -282,9 +286,9 @@ fun deferred_light_frag(input: vert_out): float4 {
|
||||
color.rgb = color.rgb + g1.rgb; // materialid
|
||||
//albedo = float3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
color.rgb = max3(color.rgb, float3(0.0, 0.0, 0.0));
|
||||
color.a = 1.0; // Mark as opaque
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ const sampler_linear: sampler;
|
||||
#[set(everything)]
|
||||
const radiance: tex2d;
|
||||
|
||||
#[set(everything)]
|
||||
const noise: tex2d;
|
||||
|
||||
const PI: float = 3.14159265358979;
|
||||
const PI2: float = 6.28318530718;
|
||||
|
||||
@@ -31,12 +34,14 @@ fun prefilter_envmap_vert(input: vert_in): vert_out {
|
||||
}
|
||||
|
||||
fun rand(co: float2): float {
|
||||
return frac(sin(dot(co.xy, float2(12.9898, 78.233)) % 3.14) * 43758.5453);
|
||||
// return frac(sin(dot(co.xy, float2(12.9898, 78.233)) % 3.14) * 43758.5453);
|
||||
var uv: float2 = frac(co * 12.34);
|
||||
return sample(noise, sampler_linear, uv).r;
|
||||
}
|
||||
|
||||
fun equirect(normal: float3): float2 {
|
||||
var phi: float = acos(normal.z);
|
||||
var theta: float = atan2(normal.x, -normal.y) + PI;
|
||||
var theta: float = atan2(-normal.y, normal.x) + PI;
|
||||
return float2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
@@ -67,17 +72,15 @@ fun prefilter_envmap_frag(input: vert_out): float4 {
|
||||
var i: int = 0;
|
||||
while (i < int(constants.params.y)) {
|
||||
var dir: float3 = normalize(lerp3(n, cos_weighted_hemisphere_direction(n, input.tex, float(i)), constants.params.x));
|
||||
color.rgb = color.rgb + sample(radiance, sampler_linear, equirect(dir)).rgb;
|
||||
var sampled: float3 = sample(radiance, sampler_linear, equirect(dir)).rgb;
|
||||
sampled = min3(sampled, float3(10.0, 10.0, 10.0));
|
||||
color.rgb = color.rgb + sampled;
|
||||
|
||||
//
|
||||
i += 1;
|
||||
//
|
||||
}
|
||||
color.rgb = color.rgb / constants.params.y;
|
||||
// color.rgb = pow(color.rgb, float3(1.0 / 2.2, 1.0 / 2.2, 1.0 / 2.2));
|
||||
color.r = pow(color.r, 1.0 / 2.2);
|
||||
color.g = pow(color.g, 1.0 / 2.2);
|
||||
color.b = pow(color.b, 1.0 / 2.2);
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ fun world_pass_vert(input: vert_in): vert_out {
|
||||
|
||||
fun envmap_equirect(normal: float3, angle: float): float2 {
|
||||
var phi: float = acos(normal.z);
|
||||
var theta: float = atan2(normal.x, -normal.y) + PI + angle;
|
||||
var theta: float = atan2(-normal.y, normal.x) + PI + angle;
|
||||
return float2(theta / PI2, phi / PI);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ let import_envmap_params: vec4_t = vec4_create();
|
||||
let import_envmap_n: vec4_t = vec4_create();
|
||||
let import_envmap_radiance_loc: i32;
|
||||
let import_envmap_radiance: gpu_texture_t = null;
|
||||
let import_envmap_noise_loc: i32;
|
||||
let import_envmap_mips: gpu_texture_t[] = null;
|
||||
|
||||
function import_envmap_run(path: string, image: gpu_texture_t) {
|
||||
@@ -22,6 +23,7 @@ function import_envmap_run(path: string, image: gpu_texture_t) {
|
||||
gpu_pipeline_compile(import_envmap_pipeline);
|
||||
import_envmap_params_loc = 0;
|
||||
import_envmap_radiance_loc = 0;
|
||||
import_envmap_noise_loc = 1;
|
||||
|
||||
import_envmap_radiance = gpu_create_render_target(1024, 512, tex_format_t.RGBA128);
|
||||
|
||||
@@ -70,7 +72,7 @@ function import_envmap_get_radiance_mip(mip: gpu_texture_t, level: i32, radiance
|
||||
gpu_set_vertex_buffer(const_data_screen_aligned_vb);
|
||||
gpu_set_index_buffer(const_data_screen_aligned_ib);
|
||||
gpu_set_pipeline(import_envmap_pipeline);
|
||||
import_envmap_params.x = 0.1 + level / 8;
|
||||
import_envmap_params.x = (level + 1) / 10;
|
||||
/// if (arm_macos || arm_ios)
|
||||
import_envmap_params.y = 1024 * 2; // Prevent gpu hang
|
||||
/// else
|
||||
@@ -78,6 +80,8 @@ function import_envmap_get_radiance_mip(mip: gpu_texture_t, level: i32, radiance
|
||||
/// end
|
||||
gpu_set_float4(import_envmap_params_loc, import_envmap_params.x, import_envmap_params.y, import_envmap_params.z, import_envmap_params.w);
|
||||
gpu_set_texture(import_envmap_radiance_loc, radiance);
|
||||
let noise: gpu_texture_t = data_get_image("bnoise256.k");
|
||||
gpu_set_texture(import_envmap_noise_loc, noise);
|
||||
gpu_draw();
|
||||
gpu_end();
|
||||
}
|
||||
|
||||
@@ -140,8 +140,7 @@ function make_mesh_run(data: material_t, layer_pass: i32 = 0): node_shader_conte
|
||||
}
|
||||
|
||||
if (context_raw.viewport_mode == viewport_mode_t.LIT && context_raw.render_mode == render_mode_t.FORWARD) {
|
||||
texture_count += 7;
|
||||
node_shader_add_texture(kong, "senvmap_brdf", "$brdf.k");
|
||||
texture_count += 6;
|
||||
node_shader_add_texture(kong, "senvmap_radiance", "_envmap_radiance");
|
||||
node_shader_add_texture(kong, "senvmap_radiance0", "_envmap_radiance0");
|
||||
node_shader_add_texture(kong, "senvmap_radiance1", "_envmap_radiance1");
|
||||
@@ -391,9 +390,6 @@ function make_mesh_run(data: material_t, layer_pass: i32 = 0): node_shader_conte
|
||||
node_shader_write_frag(kong, "var f0: float3 = lerp3(float3(0.04, 0.04, 0.04), basecol, metallic);");
|
||||
kong.frag_vvec = true;
|
||||
node_shader_write_frag(kong, "var dotnv: float = max(0.0, dot(n, vvec));");
|
||||
// node_shader_write_frag(kong, "var env_brdf: float2 = senvmap_brdf[uint2(float2(roughness, 1.0 - dotnv) * 255.0)].xy;");
|
||||
node_shader_write_frag(kong, "var brdf_coord: float2 = float2(roughness, 1.0 - dotnv) * 255.0;");
|
||||
node_shader_write_frag(kong, "var env_brdf: float4 = senvmap_brdf[uint2(uint(brdf_coord.x), uint(brdf_coord.y))];");
|
||||
// node_shader_add_constant(kong, "envmap_num_mipmaps: int", "_envmap_num_mipmaps");
|
||||
node_shader_add_constant(kong, "envmap_data: float4", "_envmap_data"); // angle, sin(angle), cos(angle), strength
|
||||
node_shader_write_frag(kong, "var wreflect: float3 = reflect(-vvec, n);");
|
||||
@@ -425,7 +421,8 @@ function make_mesh_run(data: material_t, layer_pass: i32 = 0): node_shader_conte
|
||||
node_shader_write_frag(
|
||||
kong,
|
||||
"var indirect: float3 = albedo * (sh_irradiance(float3(n.x * constants.envmap_data.z - n.y * constants.envmap_data.y, n.x * constants.envmap_data.y + n.y * constants.envmap_data.z, n.z)) / 3.14159265);");
|
||||
node_shader_write_frag(kong, "indirect = indirect + (prefiltered_color * (f0 * env_brdf.x + env_brdf.y) * 1.5);");
|
||||
node_shader_add_function(kong, str_env_brdf_approx);
|
||||
node_shader_write_frag(kong, "indirect = indirect + prefiltered_color * env_brdf_approx(f0, roughness, dotnv) * 0.5;");
|
||||
node_shader_write_frag(kong, "indirect = indirect * constants.envmap_data.w * occlusion;");
|
||||
node_shader_write_frag(kong, "output[1] = float4(indirect, 1.0);");
|
||||
}
|
||||
@@ -654,3 +651,15 @@ fun envmap_sample(lod: float, coord: float2): float3 { \
|
||||
return sample_lod(senvmap_radiance4, sampler_linear, coord, 0.0).rgb; \
|
||||
} \
|
||||
";
|
||||
|
||||
// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
|
||||
let str_env_brdf_approx: string = "\
|
||||
fun env_brdf_approx(specular: float3, roughness: float, dotnv: float): float3 { \
|
||||
var c0: float4 = float4(-1.0, -0.0275, -0.572, 0.022); \
|
||||
var c1: float4 = float4(1.0, 0.0425, 1.04, -0.04); \
|
||||
var r: float4 = c0 * roughness + c1; \
|
||||
var a004: float = min(r.x * r.x, exp((-9.28 * dotnv) * log(2.0))) * r.x + r.y; \
|
||||
var ab: float2 = float2(-1.04, 1.04) * a004 + r.zw; \
|
||||
return specular * ab.x + ab.y; \
|
||||
} \
|
||||
";
|
||||
|
||||
@@ -293,6 +293,7 @@ function project_new(reset_layers: bool = true) {
|
||||
sys_notify_on_next_frame(function() {
|
||||
// Once layers and meshes are populated on project open
|
||||
util_render_make_material_preview();
|
||||
context_raw.ddirty = 4;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -305,7 +306,7 @@ function project_set_default_envmap() {
|
||||
scene_world._.radiance = context_raw.default_radiance;
|
||||
scene_world._.radiance_mipmaps = context_raw.default_radiance_mipmaps;
|
||||
scene_world._.irradiance = context_raw.default_irradiance;
|
||||
scene_world.strength = 4.0;
|
||||
scene_world.strength = 2.0;
|
||||
context_raw.envmap_angle = 0.0;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ let render_path_base_last_y: f32 = -1.0;
|
||||
let render_path_base_bloom_mipmaps: render_target_t[];
|
||||
let render_path_base_bloom_current_mip: i32 = 0;
|
||||
let render_path_base_bloom_sample_scale: f32;
|
||||
let render_path_base_buf_swapped: bool = false;
|
||||
|
||||
function render_path_base_init() {
|
||||
pipes_init();
|
||||
@@ -335,6 +336,10 @@ function render_path_base_draw_taa(bufa: string, bufb: string) {
|
||||
render_path_draw_shader("Scene/copy_pass/copy_pass");
|
||||
}
|
||||
|
||||
render_path_base_swap_buf(bufb);
|
||||
}
|
||||
|
||||
function render_path_base_swap_buf(bufb: string) {
|
||||
// Swap buf and last targets
|
||||
let last_target: render_target_t = map_get(render_path_render_targets, "last");
|
||||
last_target.name = bufb;
|
||||
@@ -342,6 +347,7 @@ function render_path_base_draw_taa(bufa: string, bufb: string) {
|
||||
buf_target.name = "last";
|
||||
map_set(render_path_render_targets, bufb, last_target);
|
||||
map_set(render_path_render_targets, "last", buf_target);
|
||||
render_path_base_buf_swapped = !render_path_base_buf_swapped;
|
||||
}
|
||||
|
||||
function render_path_base_draw_gbuffer() {
|
||||
|
||||
@@ -98,13 +98,17 @@ function render_path_raytrace_commands(use_live_layer: bool) {
|
||||
render_path_raytrace_f32a[17] = render_path_raytrace_help_mat.m31;
|
||||
render_path_raytrace_f32a[18] = render_path_raytrace_help_mat.m32;
|
||||
render_path_raytrace_f32a[19] = render_path_raytrace_help_mat.m33;
|
||||
render_path_raytrace_f32a[20] = scene_world.strength * 1.5;
|
||||
render_path_raytrace_f32a[20] = scene_world.strength;
|
||||
if (!context_raw.show_envmap) {
|
||||
render_path_raytrace_f32a[20] = -render_path_raytrace_f32a[20];
|
||||
}
|
||||
render_path_raytrace_f32a[21] = context_raw.envmap_angle;
|
||||
render_path_raytrace_f32a[22] = render_path_raytrace_uv_scale;
|
||||
|
||||
if (render_path_base_buf_swapped) {
|
||||
render_path_base_swap_buf("buf");
|
||||
}
|
||||
|
||||
let framebuffer: render_target_t = map_get(render_path_render_targets, "buf");
|
||||
_gpu_raytrace_dispatch_rays(framebuffer._image, render_path_raytrace_f32a);
|
||||
|
||||
|
||||
@@ -296,7 +296,7 @@ function ui_menubar_draw_category_items() {
|
||||
let env_handle: ui_handle_t = ui_handle(__ID__);
|
||||
env_handle.f = p.strength;
|
||||
ui_menu_align();
|
||||
p.strength = ui_slider(env_handle, tr("Environment"), 0.0, 8.0, true);
|
||||
p.strength = ui_slider(env_handle, tr("Environment"), 0.0, 6.0, true);
|
||||
if (env_handle.changed) {
|
||||
context_raw.ddirty = 2;
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ function uniforms_ext_vec4_link(object: object_t, mat: material_data_t, link: st
|
||||
return v;
|
||||
}
|
||||
else if (link == "_envmap_data") {
|
||||
return vec4_create(context_raw.envmap_angle, math_sin(-context_raw.envmap_angle), math_cos(-context_raw.envmap_angle), scene_world.strength * 1.5);
|
||||
return vec4_create(context_raw.envmap_angle, math_sin(-context_raw.envmap_angle), math_cos(-context_raw.envmap_angle), scene_world.strength * 2.0);
|
||||
}
|
||||
else if (link == "_envmap_data_world") {
|
||||
let tonemap: bool = context_raw.viewport_mode == viewport_mode_t.LIT || context_raw.viewport_mode == viewport_mode_t.PATH_TRACE;
|
||||
|
||||
@@ -31,14 +31,15 @@ function util_render_make_material_preview() {
|
||||
|
||||
let probe: world_data_t = scene_world;
|
||||
let _probe_strength: f32 = probe.strength;
|
||||
probe.strength = 7;
|
||||
probe.strength = 2;
|
||||
let _envmap_angle: f32 = context_raw.envmap_angle;
|
||||
context_raw.envmap_angle = 6.0;
|
||||
context_raw.envmap_angle = 0.0;
|
||||
let _brush_scale: f32 = context_raw.brush_scale;
|
||||
context_raw.brush_scale = 1.5;
|
||||
let _brush_nodes_scale: f32 = context_raw.brush_nodes_scale;
|
||||
context_raw.brush_nodes_scale = 1.0;
|
||||
|
||||
let _envmap: gpu_texture_t = scene_world._.envmap;
|
||||
scene_world._.envmap = context_raw.preview_envmap;
|
||||
// No resize
|
||||
_render_path_last_w = util_render_material_preview_size;
|
||||
@@ -71,7 +72,8 @@ function util_render_make_material_preview() {
|
||||
context_raw.envmap_angle = _envmap_angle;
|
||||
context_raw.brush_scale = _brush_scale;
|
||||
context_raw.brush_nodes_scale = _brush_nodes_scale;
|
||||
scene_world._.envmap = context_raw.show_envmap ? context_raw.saved_envmap : context_raw.empty_envmap;
|
||||
scene_world._.envmap = _envmap;
|
||||
|
||||
make_material_parse_mesh_material();
|
||||
context_raw.ddirty = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user