diff --git a/Shaders/raytrace/raytrace_brute.cso b/Shaders/raytrace/raytrace_brute.cso index 5b25878a..a0f86a57 100644 Binary files a/Shaders/raytrace/raytrace_brute.cso and b/Shaders/raytrace/raytrace_brute.cso differ diff --git a/Shaders/raytrace/src/raytrace_brute.hlsl b/Shaders/raytrace/src/raytrace_brute.hlsl index 4fd0a534..9a069ad0 100644 --- a/Shaders/raytrace/src/raytrace_brute.hlsl +++ b/Shaders/raytrace/src/raytrace_brute.hlsl @@ -38,7 +38,8 @@ Texture2D mytexture_rank : register(t9); static const int rrStart = 2; static const float rrProbability = 0.5; // map to albedo static const int SAMPLES = 64; -static const int DEPTH = 3; // 3 - 5 +static const int DEPTH = 3; // Opaque hits +static const int DEPTH_TRANSPARENT = 16; // Transparent hits static uint seed = 0; [shader("raygeneration")] @@ -54,12 +55,13 @@ void raygeneration() { float2 screen_pos = xy / DispatchRaysDimensions().xy * 2.0 - 1.0; RayDesc ray; - ray.TMin = 0.01; + ray.TMin = 0.0001; ray.TMax = 10.0; generate_camera_ray(screen_pos, ray.Origin, ray.Direction, constant_buffer.eye.xyz, constant_buffer.inv_vp); RayPayload payload; payload.color = float4(1, 1, 1, j); + int transparentHits = 0; for (int i = 0; i < DEPTH; ++i) { @@ -74,13 +76,19 @@ void raygeneration() { TraceRay(scene, RAY_FLAG_FORCE_OPAQUE, ~0, 0, 1, 0, ray, payload); if (payload.color.a < 0) { - if (i == 0) { - // return; - if (constant_buffer.params.y == 0) { + // Transparent + if (payload.color.a == -2 && transparentHits < DEPTH_TRANSPARENT) { + payload.color.a = j; + transparentHits++; + i--; + } + else { + // Miss + if (i == 0 && constant_buffer.params.y == 0) { // No envmap payload.color.rgb = float3(0.05, 0.05, 0.05); } + break; } - break; } payload.color.rgb *= rrFactor; @@ -113,13 +121,6 @@ void closesthit(inout RayPayload payload, in BuiltInTriangleIntersectionAttribut uint base_index = PrimitiveIndex() * triangleIndexStride; uint3 indices_sample = indices.Load3(base_index); - float3 vertex_normals[3] = { - float3(vertices[indices_sample[0]].normal), - float3(vertices[indices_sample[1]].normal), - float3(vertices[indices_sample[2]].normal) - }; - float3 n = normalize(hit_attribute(vertex_normals, attr)); - float2 vertex_uvs[3] = { float2(vertices[indices_sample[0]].tex), float2(vertices[indices_sample[1]].tex), @@ -129,18 +130,33 @@ void closesthit(inout RayPayload payload, in BuiltInTriangleIntersectionAttribut uint2 size; mytexture0.GetDimensions(size.x, size.y); - float3 texpaint0 = mytexture0.Load(uint3(tex_coord * size, 0)).rgb; - float3 texpaint1 = mytexture1.Load(uint3(tex_coord * size, 0)).rgb; - float3 texpaint2 = mytexture2.Load(uint3(tex_coord * size, 0)).rgb; + float4 texpaint0 = mytexture0.Load(uint3(tex_coord * size, 0)); + + if (texpaint0.a <= 0.1) { + payload.ray_dir = WorldRayDirection(); + payload.ray_origin = hit_world_position() + payload.ray_dir * 0.0001f; + payload.color.a = -2; + return; + } + + float3 vertex_normals[3] = { + float3(vertices[indices_sample[0]].normal), + float3(vertices[indices_sample[1]].normal), + float3(vertices[indices_sample[2]].normal) + }; + float3 n = normalize(hit_attribute(vertex_normals, attr)); + + float4 texpaint1 = mytexture1.Load(uint3(tex_coord * size, 0)); + float4 texpaint2 = mytexture2.Load(uint3(tex_coord * size, 0)); float3 color = payload.color.rgb * texpaint0.rgb; float3 tangent = float3(0, 0, 0); float3 binormal = float3(0, 0, 0); create_basis(n, tangent, binormal); - texpaint1 = normalize(texpaint1 * 2.0 - 1.0); + texpaint1.rgb = normalize(texpaint1.rgb * 2.0 - 1.0); texpaint1.g = -texpaint1.g; - n = mul(texpaint1, float3x3(tangent, binormal, n)); + n = mul(texpaint1.rgb, float3x3(tangent, binormal, n)); float f = rand(DispatchRaysIndex().x, DispatchRaysIndex().y, payload.color.a, seed, constant_buffer.eye.w, mytexture_sobol, mytexture_scramble, mytexture_rank); float3 wo = -WorldRayDirection(); diff --git a/Sources/arm/Layers.hx b/Sources/arm/Layers.hx index b1a8db41..3591f141 100644 --- a/Sources/arm/Layers.hx +++ b/Sources/arm/Layers.hx @@ -53,7 +53,7 @@ class Layers { var layers = Project.layers; layers[0].texpaint.g4.begin(); - layers[0].texpaint.g4.clear(kha.Color.fromFloats(defaultBase, defaultBase, defaultBase, 0.0)); // Base + layers[0].texpaint.g4.clear(kha.Color.fromFloats(defaultBase, defaultBase, defaultBase, 1.0)); // Base layers[0].texpaint.g4.end(); layers[0].texpaint_nor.g4.begin(); diff --git a/Sources/arm/node/MakeMesh.hx b/Sources/arm/node/MakeMesh.hx index f1912b2f..3e2add74 100644 --- a/Sources/arm/node/MakeMesh.hx +++ b/Sources/arm/node/MakeMesh.hx @@ -89,7 +89,11 @@ class MakeMesh { if (Context.layer.paintBase) { frag.add_shared_sampler('sampler2D texpaint'); - frag.write('basecol = textureLodShared(texpaint, texCoord, 0.0).rgb;'); + frag.write('vec4 texpaint_sample = textureLodShared(texpaint, texCoord, 0.0);'); + #if kha_direct3d12 + frag.write('if (texpaint_sample.a < 0.1) discard;'); + #end + frag.write('basecol = texpaint_sample.rgb;'); } else { frag.write('basecol = vec3(0.0, 0.0, 0.0);'); diff --git a/Sources/arm/node/MakePaint.hx b/Sources/arm/node/MakePaint.hx index b5533001..245849f0 100644 --- a/Sources/arm/node/MakePaint.hx +++ b/Sources/arm/node/MakePaint.hx @@ -196,7 +196,8 @@ class MakePaint { frag.write('float occlusion = $occ;'); frag.write('vec3 nortan = $nortan;'); frag.write('float height = $height;'); - frag.write('float opacity = $opac;'); + frag.write('float mat_opacity = $opac;'); + frag.write('float opacity = mat_opacity;'); if (Context.layer.material_mask == null) { frag.write('opacity *= brushOpacity;'); } @@ -322,7 +323,11 @@ class MakePaint { frag.add_uniform('sampler2D texpaint_pack_undo', '_texpaint_pack_undo'); frag.write('vec4 sample_nor_undo = textureLod(texpaint_nor_undo, sample_tc, 0.0);'); frag.write('vec4 sample_pack_undo = textureLod(texpaint_pack_undo, sample_tc, 0.0);'); + #if kha_direct3d12 + frag.write('fragColor[0] = vec4(' + MaterialBuilder.blendMode(frag, UITrait.inst.brushBlending, 'sample_undo.rgb', 'basecol', 'str') + ', mat_opacity);'); + #else frag.write('fragColor[0] = vec4(' + MaterialBuilder.blendMode(frag, UITrait.inst.brushBlending, 'sample_undo.rgb', 'basecol', 'str') + ', 0.0);'); + #end frag.write('fragColor[1] = vec4(mix(sample_nor_undo.rgb, nortan, str), matid);'); if (Context.material.paintHeight && MaterialBuilder.heightUsed) { frag.write('fragColor[2] = mix(sample_pack_undo, vec4(occlusion, roughness, metallic, height), str);'); diff --git a/Sources/arm/node/Material.hx b/Sources/arm/node/Material.hx index 56c539d9..0355bbb8 100644 --- a/Sources/arm/node/Material.hx +++ b/Sources/arm/node/Material.hx @@ -1424,6 +1424,9 @@ class Material { else { textureMap.set(tex_store, 'texture($tex_name, $uv_name.xy)'); curshader.write('vec4 $tex_store = texture($tex_name, $uv_name.xy);'); + if (!tex.file.endsWith(".jpg")) { // Pre-mult alpha + curshader.write('$tex_store.rgb *= $tex_store.a;'); + } } if (sample_bump) { diff --git a/Sources/arm/render/RenderPathPaint.hx b/Sources/arm/render/RenderPathPaint.hx index 2d90a834..8f52288d 100644 --- a/Sources/arm/render/RenderPathPaint.hx +++ b/Sources/arm/render/RenderPathPaint.hx @@ -184,20 +184,18 @@ class RenderPathPaint { path.clearTarget(0xff000000); } - var blendA = "texpaint_blend0"; - var blendB = "texpaint_blend1"; - path.setTarget(blendB); - path.bindTarget(blendA, "tex"); + path.setTarget("texpaint_blend1"); + path.bindTarget("texpaint_blend0", "tex"); path.drawShader("shader_datas/copy_pass/copy_pass"); var isMask = Context.layerIsMask; var texpaint = isMask ? "texpaint_mask" + tid : "texpaint" + tid; - path.setTarget(texpaint, ["texpaint_nor" + tid, "texpaint_pack" + tid, blendA]); + path.setTarget(texpaint, ["texpaint_nor" + tid, "texpaint_pack" + tid, "texpaint_blend0"]); path.bindTarget("_main", "gbufferD"); if ((UITrait.inst.xray || UITrait.inst.brushAngleReject) && UITrait.inst.brush3d) { path.bindTarget("gbuffer0", "gbuffer0"); } - path.bindTarget(blendB, "paintmask"); + path.bindTarget("texpaint_blend1", "paintmask"); #if (!kha_direct3d12) if (Context.tool == ToolBake && UITrait.inst.bakeType == BakeAO) { path.bindTarget("voxels", "voxels");