diff --git a/base/assets/bnoise256.png b/base/assets/bnoise256.png new file mode 100644 index 00000000..29a91ffc Binary files /dev/null and b/base/assets/bnoise256.png differ diff --git a/base/assets/brdf.png b/base/assets/brdf.png deleted file mode 100644 index 0c418b6d..00000000 Binary files a/base/assets/brdf.png and /dev/null differ diff --git a/base/shaders/raytrace/raytrace_brute_core.metal b/base/shaders/raytrace/raytrace_brute_core.metal index 9ddef4ca..1648f5d0 100644 --- a/base/shaders/raytrace/raytrace_brute_core.metal +++ b/base/shaders/raytrace/raytrace_brute_core.metal @@ -225,6 +225,7 @@ kernel void raytracingKernel( float2 tex_coord = fract(equirect(ray.direction, constant_buffer.params.y)); uint2 size = uint2(mytexture_env.get_width(), mytexture_env.get_height()); float3 texenv = mytexture_env.read(uint2(tex_coord * float2(size)), 0).rgb * abs(constant_buffer.params.x); + // .sample() payload.color = float4(payload.color.rgb * texenv.rgb, -1); } else { @@ -299,12 +300,25 @@ kernel void raytracingKernel( #else float3 specular_dir = reflect(ray.direction, n); #endif - payload.ray_dir = mix(specular_dir, diffuse_dir, texpaint2.g * texpaint2.g); - float3 v = normalize(constant_buffer.eye.xyz - hit_world_position(ray, intersection)); - float dotnv = max(dot(n, v), 0.0); + float roughness = texpaint2.g; + float exponent = max(1.0 / (roughness * roughness) - 1.0, 0.01); + seed += 2; + float u1 = rand(tid.x, tid.y, payload.color.a, seed, constant_buffer.eye.w, mytexture_sobol, mytexture_scramble, mytexture_rank); + seed += 1; + float u2 = rand(tid.x, tid.y, payload.color.a, seed, constant_buffer.eye.w, mytexture_sobol, mytexture_scramble, mytexture_rank); + seed += 1; + float cos_theta = pow(u1, 1.0 / (exponent + 1.0)); + float sin_theta = sqrt(1.0 - cos_theta * cos_theta); + float phi = u2 * 2.0 * 3.1415926535; + float3 tangent_r; + float3 binormal_r; + create_basis(specular_dir, tangent_r, binormal_r); + float3 dir_local = float3(cos(phi) * sin_theta, sin(phi) * sin_theta, cos_theta); + payload.ray_dir = float3x3(tangent_r, binormal_r, specular_dir) * dir_local; float3 specular = surface_specular(texcolor, texpaint2.b); - payload.color.xyz *= env_brdf_approx(specular, texpaint2.g, dotnv); + payload.color.xyz *= specular; + #ifdef _FRESNEL payload.color.xyz /= specular_chance; #endif @@ -320,6 +334,8 @@ kernel void raytracingKernel( payload.color.xyz *= 0.5; #endif + // float dotnv = abs(dot(n, -WorldRayDirection())); + // payload.ray_origin = hit_world_position() + n * lerp(0.1f, 0.0001f, dotnv); payload.ray_origin = hit_world_position(ray, intersection) + payload.ray_dir * 0.0001f; #ifdef _EMISSION diff --git a/base/shaders/raytrace/raytrace_brute_full.metal b/base/shaders/raytrace/raytrace_brute_full.metal index a2d53f64..9406b52f 100644 --- a/base/shaders/raytrace/raytrace_brute_full.metal +++ b/base/shaders/raytrace/raytrace_brute_full.metal @@ -226,6 +226,7 @@ kernel void raytracingKernel( float2 tex_coord = fract(equirect(ray.direction, constant_buffer.params.y)); uint2 size = uint2(mytexture_env.get_width(), mytexture_env.get_height()); float3 texenv = mytexture_env.read(uint2(tex_coord * float2(size)), 0).rgb * abs(constant_buffer.params.x); + // .sample() payload.color = float4(payload.color.rgb * texenv.rgb, -1); } else { @@ -300,12 +301,25 @@ kernel void raytracingKernel( #else float3 specular_dir = reflect(ray.direction, n); #endif - payload.ray_dir = mix(specular_dir, diffuse_dir, texpaint2.g * texpaint2.g); - float3 v = normalize(constant_buffer.eye.xyz - hit_world_position(ray, intersection)); - float dotnv = max(dot(n, v), 0.0); + float roughness = texpaint2.g; + float exponent = max(1.0 / (roughness * roughness) - 1.0, 0.01); + seed += 2; + float u1 = rand(tid.x, tid.y, payload.color.a, seed, constant_buffer.eye.w, mytexture_sobol, mytexture_scramble, mytexture_rank); + seed += 1; + float u2 = rand(tid.x, tid.y, payload.color.a, seed, constant_buffer.eye.w, mytexture_sobol, mytexture_scramble, mytexture_rank); + seed += 1; + float cos_theta = pow(u1, 1.0 / (exponent + 1.0)); + float sin_theta = sqrt(1.0 - cos_theta * cos_theta); + float phi = u2 * 2.0 * 3.1415926535; + float3 tangent_r; + float3 binormal_r; + create_basis(specular_dir, tangent_r, binormal_r); + float3 dir_local = float3(cos(phi) * sin_theta, sin(phi) * sin_theta, cos_theta); + payload.ray_dir = float3x3(tangent_r, binormal_r, specular_dir) * dir_local; float3 specular = surface_specular(texcolor, texpaint2.b); - payload.color.xyz *= env_brdf_approx(specular, texpaint2.g, dotnv); + payload.color.xyz *= specular; + #ifdef _FRESNEL payload.color.xyz /= specular_chance; #endif @@ -321,6 +335,8 @@ kernel void raytracingKernel( payload.color.xyz *= 0.5; #endif + // float dotnv = abs(dot(n, -WorldRayDirection())); + // payload.ray_origin = hit_world_position() + n * lerp(0.1f, 0.0001f, dotnv); payload.ray_origin = hit_world_position(ray, intersection) + payload.ray_dir * 0.0001f; #ifdef _EMISSION diff --git a/base/shaders/raytrace/src/raytrace_brute.hlsl b/base/shaders/raytrace/src/raytrace_brute.hlsl index 4dfa952a..35c0d555 100644 --- a/base/shaders/raytrace/src/raytrace_brute.hlsl +++ b/base/shaders/raytrace/src/raytrace_brute.hlsl @@ -282,7 +282,6 @@ void closesthit(inout RayPayload payload, in BuiltInTriangleIntersectionAttribut float dotnv = abs(dot(n, -WorldRayDirection())); payload.ray_origin = hit_world_position() + n * lerp(0.1f, 0.0001f, dotnv); - // payload.ray_origin = hit_world_position() + payload.ray_dir * 0.0001f; #ifdef _EMISSION diff --git a/base/sources/backends/direct3d12_gpu.c b/base/sources/backends/direct3d12_gpu.c index 9f2dd23e..16631a79 100644 --- a/base/sources/backends/direct3d12_gpu.c +++ b/base/sources/backends/direct3d12_gpu.c @@ -1787,7 +1787,9 @@ void gpu_raytrace_set_pipeline(gpu_raytrace_pipeline_t *pipeline) { void gpu_raytrace_set_target(gpu_texture_t *output) { if (!output->impl.has_storage_bit) { output->impl.has_storage_bit = true; - gpu_texture_destroy(output); + // gpu_texture_destroy(output); + resources_to_destroy[resources_to_destroy_count] = output->impl.image; + resources_to_destroy_count++; D3D12_HEAP_PROPERTIES heap_properties = { .Type = D3D12_HEAP_TYPE_DEFAULT, @@ -1800,24 +1802,24 @@ void gpu_raytrace_set_target(gpu_texture_t *output) { .Height = output->height, .DepthOrArraySize = 1, .MipLevels = 1, - .Format = DXGI_FORMAT_R16G16B16A16_FLOAT, + .Format = convert_format(output->format), .SampleDesc.Count = 1, .SampleDesc.Quality = 0, .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, .Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, }; D3D12_CLEAR_VALUE clear_value; - clear_value.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; + clear_value.Format = convert_format(output->format); clear_value.Color[0] = 0.0f; clear_value.Color[1] = 0.0f; clear_value.Color[2] = 0.0f; clear_value.Color[3] = 0.0f; - device->lpVtbl->CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COMMON, &clear_value, + device->lpVtbl->CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, &clear_value, &IID_ID3D12Resource, &output->impl.image); D3D12_RENDER_TARGET_VIEW_DESC view = { - .Format = DXGI_FORMAT_R16G16B16A16_FLOAT, + .Format = convert_format(output->format), .ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D, .Texture2D.MipSlice = 0, .Texture2D.PlaneSlice = 0, @@ -1843,7 +1845,7 @@ void gpu_raytrace_set_target(gpu_texture_t *output) { D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = { .ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D, .Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, - .Format = DXGI_FORMAT_R16G16B16A16_FLOAT, + .Format = convert_format(output->format), .Texture2D.MipLevels = 1, .Texture2D.MostDetailedMip = 0, .Texture2D.ResourceMinLODClamp = 0.0f, diff --git a/paint/assets/Scene.arm b/paint/assets/Scene.arm index 533d948f..42f2bc93 100644 Binary files a/paint/assets/Scene.arm and b/paint/assets/Scene.arm differ diff --git a/paint/assets/World_irradiance.arm b/paint/assets/World_irradiance.arm index 482f130c..0455dd01 100644 Binary files a/paint/assets/World_irradiance.arm and b/paint/assets/World_irradiance.arm differ diff --git a/paint/assets/World_radiance.hdr b/paint/assets/World_radiance.hdr index 87a0e266..02cb2e19 100644 Binary files a/paint/assets/World_radiance.hdr and b/paint/assets/World_radiance.hdr differ diff --git a/paint/assets/World_radiance_0.hdr b/paint/assets/World_radiance_0.hdr index 7d883be2..b935032f 100644 Binary files a/paint/assets/World_radiance_0.hdr and b/paint/assets/World_radiance_0.hdr differ diff --git a/paint/assets/World_radiance_1.hdr b/paint/assets/World_radiance_1.hdr index fad6b7d2..a0452933 100644 Binary files a/paint/assets/World_radiance_1.hdr and b/paint/assets/World_radiance_1.hdr differ diff --git a/paint/assets/World_radiance_2.hdr b/paint/assets/World_radiance_2.hdr index 7f62117c..55d7b991 100644 Binary files a/paint/assets/World_radiance_2.hdr and b/paint/assets/World_radiance_2.hdr differ diff --git a/paint/assets/World_radiance_3.hdr b/paint/assets/World_radiance_3.hdr index 7f628313..b1f46929 100644 Binary files a/paint/assets/World_radiance_3.hdr and b/paint/assets/World_radiance_3.hdr differ diff --git a/paint/assets/World_radiance_4.hdr b/paint/assets/World_radiance_4.hdr index a40cca53..d0e4dac6 100644 Binary files a/paint/assets/World_radiance_4.hdr and b/paint/assets/World_radiance_4.hdr differ diff --git a/paint/shaders/deferred_light.kong b/paint/shaders/deferred_light.kong index a287ce13..62e20382 100644 --- a/paint/shaders/deferred_light.kong +++ b/paint/shaders/deferred_light.kong @@ -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; } diff --git a/paint/shaders/prefilter_envmap.kong b/paint/shaders/prefilter_envmap.kong index 5e58631e..77f995b3 100644 --- a/paint/shaders/prefilter_envmap.kong +++ b/paint/shaders/prefilter_envmap.kong @@ -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; } diff --git a/paint/shaders/world_pass.kong b/paint/shaders/world_pass.kong index 5979fc1e..92b1545b 100644 --- a/paint/shaders/world_pass.kong +++ b/paint/shaders/world_pass.kong @@ -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); } diff --git a/paint/sources/import_envmap.ts b/paint/sources/import_envmap.ts index 40764039..524e95f5 100644 --- a/paint/sources/import_envmap.ts +++ b/paint/sources/import_envmap.ts @@ -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(); } diff --git a/paint/sources/make_mesh.ts b/paint/sources/make_mesh.ts index bfeb0dff..313901a6 100644 --- a/paint/sources/make_mesh.ts +++ b/paint/sources/make_mesh.ts @@ -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; \ +} \ +"; diff --git a/paint/sources/project.ts b/paint/sources/project.ts index 1b3f530e..037f85c5 100644 --- a/paint/sources/project.ts +++ b/paint/sources/project.ts @@ -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; } diff --git a/paint/sources/render_path_base.ts b/paint/sources/render_path_base.ts index 0575d7bf..7a61bc90 100644 --- a/paint/sources/render_path_base.ts +++ b/paint/sources/render_path_base.ts @@ -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() { diff --git a/paint/sources/render_path_raytrace.ts b/paint/sources/render_path_raytrace.ts index f9266f90..a8accd98 100644 --- a/paint/sources/render_path_raytrace.ts +++ b/paint/sources/render_path_raytrace.ts @@ -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); diff --git a/paint/sources/ui_menubar.ts b/paint/sources/ui_menubar.ts index 657b17c5..5bd1bd2d 100644 --- a/paint/sources/ui_menubar.ts +++ b/paint/sources/ui_menubar.ts @@ -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; } diff --git a/paint/sources/uniforms_ext.ts b/paint/sources/uniforms_ext.ts index ac5cfebe..0960b955 100644 --- a/paint/sources/uniforms_ext.ts +++ b/paint/sources/uniforms_ext.ts @@ -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; diff --git a/paint/sources/util_render.ts b/paint/sources/util_render.ts index 67b26eb2..2e1bfb62 100644 --- a/paint/sources/util_render.ts +++ b/paint/sources/util_render.ts @@ -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; }