diff --git a/game/graphics/renderer.cpp b/game/graphics/renderer.cpp index 97099d756..ef92244ab 100644 --- a/game/graphics/renderer.cpp +++ b/game/graphics/renderer.cpp @@ -185,11 +185,11 @@ void Renderer::resetSwapchain() { gi.voteTable = device.ssbo(nullptr, gi.hashTable.byteSize()); gi.probes = device.ssbo(nullptr, 8*1024*1024); // ~26K gi.freeList = device.ssbo(nullptr, gi.probes.byteSize()); // TODO: fine size - - uint32_t zero = 0; - gi.probes .update(&zero, 0, sizeof(uint32_t)); - gi.freeList.update(&zero, 0, sizeof(uint32_t)); } + + uint32_t zero = 0; + gi.probes .update(&zero, 0, sizeof(uint32_t)); + gi.freeList.update(&zero, 0, sizeof(uint32_t)); } prepareUniforms(); diff --git a/game/graphics/rtscene.cpp b/game/graphics/rtscene.cpp index cb480e080..f21bea909 100644 --- a/game/graphics/rtscene.cpp +++ b/game/graphics/rtscene.cpp @@ -47,7 +47,10 @@ void RtScene::addInstance(const Matrix4x4& pos, const AccelerationStructure& bla RtObjectDesc desc = {}; desc.instanceId = bucketId; - desc.firstPrimitive = firstPrimitive; + desc.firstPrimitive = firstPrimitive & 0x00FFFFFF; // 24 bit for primmitive + 8 for utility + + if(mat.alpha==Material::Solid) + desc.bits |= 0x1; RtInstance ix; ix.mat = pos; diff --git a/game/graphics/rtscene.h b/game/graphics/rtscene.h index edd6bc903..fe3c1c50c 100644 --- a/game/graphics/rtscene.h +++ b/game/graphics/rtscene.h @@ -22,7 +22,8 @@ class RtScene { struct RtObjectDesc { uint32_t instanceId; - uint32_t firstPrimitive; + uint32_t firstPrimitive : 24; + uint32_t bits: 8; }; void notifyTlas(const Material& m, RtScene::Category cat) const; diff --git a/game/graphics/sky/sky.cpp b/game/graphics/sky/sky.cpp index f8f4ba9bd..715d89db1 100644 --- a/game/graphics/sky/sky.cpp +++ b/game/graphics/sky/sky.cpp @@ -216,6 +216,7 @@ void Sky::updateLight(const int64_t now) { static float sunMul = 1; static float ambMul = 1; // static auto groundAlbedo = Vec3(0.34f, 0.42f, 0.26f); // Foliage(MacBeth) + // static auto groundAlbedo = Vec3(0.47f); // Neutral5 (MacBeth) static auto groundAlbedo = Vec3(0.39f, 0.40f, 0.33f); static float lumScale = 5.f / DirectSunLux; diff --git a/shader/lighting/irradiance.comp b/shader/lighting/irradiance.comp index 00f2bb77a..e39ba2f65 100644 --- a/shader/lighting/irradiance.comp +++ b/shader/lighting/irradiance.comp @@ -88,8 +88,8 @@ void main() { if(b.w>0) b.rgb /= b.w; - imageStore(result, ivec2(laneId,0), vec4(a.rgb,1.0)); - imageStore(result, ivec2(laneId,1), vec4(b.rgb,1.0)); + imageStore(result, ivec2(laneId,0), vec4(a.rgb * M_PI,1.0)); + imageStore(result, ivec2(laneId,1), vec4(b.rgb * M_PI,1.0)); } } diff --git a/shader/lighting/rt/probe_allocation.comp b/shader/lighting/rt/probe_allocation.comp index 3f80c2efb..46e81c116 100644 --- a/shader/lighting/rt/probe_allocation.comp +++ b/shader/lighting/rt/probe_allocation.comp @@ -152,7 +152,7 @@ void main_gc() { if((probe[probeId].bits & REUSE_BIT)!=0) return; - probe[probeId].bits |= FREE_BIT; + probe[probeId].bits |= UNUSED_BIT; const uint cursor = atomicAdd(freeList.cursor, 1); freeList.list[cursor] = probeId; } diff --git a/shader/lighting/rt/probe_ambient.frag b/shader/lighting/rt/probe_ambient.frag index 834be1bcf..f19a920f1 100644 --- a/shader/lighting/rt/probe_ambient.frag +++ b/shader/lighting/rt/probe_ambient.frag @@ -67,6 +67,11 @@ void gather(vec3 pos, vec3 norm, int lod, bool ignoreBad) { } } +vec3 textureAlbedo(vec3 diff) { + return textureLinear(diff) * PhotoLum; + //return srgbDecode(diff.rgb); + } + void main() { const float z = texelFetch(depth,ivec2(gl_FragCoord.xy),0).x; if(z>=0.99995) @@ -86,15 +91,11 @@ void main() { gather(pos, norm, lod, true); } - const vec3 linear = textureLinear(diff); - // const vec3 linear = acesTonemapInv(srgbDecode(diff)); - // const vec3 linear = srgbDecode(diff); - // const vec3 linear = vec3(1); + const vec3 linear = textureAlbedo(diff); vec3 color = colorSum.rgb/max(colorSum.w,0.000001); color *= linear; color *= scene.exposure; - color *= 25; // color = linear; outColor = vec4(color, 1); } diff --git a/shader/lighting/rt/probe_common.glsl b/shader/lighting/rt/probe_common.glsl index c3654cbc5..7b017ac73 100644 --- a/shader/lighting/rt/probe_common.glsl +++ b/shader/lighting/rt/probe_common.glsl @@ -5,10 +5,11 @@ struct Hash { uint value; }; -const uint FREE_BIT = 0x1; +const uint UNUSED_BIT = 0x1; const uint TRACED_BIT = 0x2; const uint REUSE_BIT = 0x4; const uint BAD_BIT = 0x8; +const uint NEW_BIT = 0x10; //for debug view struct Probe { vec3 pos; diff --git a/shader/lighting/rt/probe_dbg.frag b/shader/lighting/rt/probe_dbg.frag index e9fd4658b..08bfcefd0 100644 --- a/shader/lighting/rt/probe_dbg.frag +++ b/shader/lighting/rt/probe_dbg.frag @@ -48,6 +48,8 @@ void main(void) { vec3 clr = probeReadAmbient(p, norm) * scene.exposure; if((p.bits & BAD_BIT)!=0) clr = vec3(1,0,0); + if((p.bits & NEW_BIT)!=0) + clr = vec3(0,1,0); outColor = vec4(clr,1.0); // outColor = vec4(1,0,0,1.0); diff --git a/shader/lighting/rt/probe_trace.comp b/shader/lighting/rt/probe_trace.comp index e37917626..f3d33af68 100644 --- a/shader/lighting/rt/probe_trace.comp +++ b/shader/lighting/rt/probe_trace.comp @@ -64,18 +64,27 @@ vec3 sampleHemisphere(uint i, uint numSamples, float offsetAng) { return vec3(cos(a) * u1p, xi.y, sin(a) * u1p); } -vec3 resolveHit(const vec3 rayOrigin, const vec3 rayDirection, const vec3 sunDir, vec3 albedo, vec3 normal, float shadow) { - const float lambert = max(0, dot(normal, sunDir)); +vec3 textureAlbedo(vec3 diff) { + return textureLinear(diff) * PhotoLum; + } + +vec3 resolveHit(const vec3 rayOrigin, const vec3 rayDirection, const vec3 sunDir, in vec3 diff, vec3 normal, bool opaque, float shadow) { + vec3 albedo = textureAlbedo(diff); + + const float dt = dot(normal, sunDir); + const float lambert = max(opaque ? 0 : 0.2, dt); + // if(!opaque) + // return vec3(1,0,0) * scene.GSunIntensity; else + // return vec3(0,0,1) * scene.GSunIntensity; + const vec3 lcolor = (scene.sunCl.rgb * scene.GSunIntensity * lambert * shadow); - const vec3 ambient = scene.ambient; - const vec3 atmo = vec3(0.05) * scene.sunCl.rgb * scene.GSunIntensity; + const vec3 ambient = scene.ambient * 0.25; // no proper multi-bounce yet + const vec3 atmo = vec3(0.01) * scene.sunCl.rgb * scene.GSunIntensity; vec3 color = vec3(0); color += lcolor; - color += ambient; // no proper multi-bounce yet - color += atmo; - // color += albedo * (scene.sunCl * scene.GSunIntensity) * 10; - // color *= 25; // HACK! + color += ambient; + //color += atmo; return albedo*color; } @@ -90,7 +99,8 @@ vec3 resolveMiss(const vec3 rayOrigin, const vec3 rayDirection, const vec3 sunDi } vec4 sampleScene(const vec3 rayOrigin, const vec3 rayDirection, const vec3 sunDir) { - uint flags = gl_RayFlagsSkipAABBEXT; + // CullFront due to vegetation + uint flags = gl_RayFlagsSkipAABBEXT | gl_RayFlagsCullFrontFacingTrianglesEXT;// | gl_RayFlagsCullNoOpaqueEXT; float tMin = 1; float rayDistance = 200*100; // Lumen rt-probe uses 200-meters range @@ -100,6 +110,8 @@ vec4 sampleScene(const vec3 rayOrigin, const vec3 rayDirection, const vec3 sunDi rayQueryProceedShadow(rayQuery); // NOTE: fix naming if(rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT) { + if(rayDirection.y<-0.9) + atomicAdd(badHits, 1); // shoot to ground and hit nothing return vec4(resolveMiss(rayOrigin, rayDirection, sunDir), 1); } @@ -134,11 +146,8 @@ vec4 sampleScene(const vec3 rayOrigin, const vec3 rayDirection, const vec3 sunDi vec4 shCoord = scene.viewShadow[1]*vec4(pos,1); float shadow = shadowFactor(shCoord); - const vec3 diff = textureLod(sampler2D(textures[nonuniformEXT(id)], smp),uv,0).rgb; - const vec3 linear = textureLinear(diff.rgb); - // const vec3 linear = srgbDecode(diff.rgb); - - return vec4(resolveHit(rayOrigin, rayDirection, sunDir, linear, nr, shadow), (badbit ? 0 : 1)); + const vec3 diff = textureLod(sampler2D(textures[nonuniformEXT(id)], smp),uv,0).rgb; + return vec4(resolveHit(rayOrigin, rayDirection, sunDir, diff, nr, hit.opaque, shadow), (badbit ? 0 : 1)); } void storeSample(vec3 dir, vec3 val) { @@ -166,12 +175,12 @@ void gather(const vec3 origin) { } void processProbe(const uint probeId) { - const uint laneId = gl_LocalInvocationIndex; - const bool cached = ((probe[probeId].bits & (TRACED_BIT | FREE_BIT))!=0); + const uint laneId = gl_LocalInvocationIndex; + const bool skip = ((probe[probeId].bits & (TRACED_BIT | UNUSED_BIT))!=0); barrier(); - if(cached) { - probe[probeId].bits &= ~REUSE_BIT; + if(skip) { + probe[probeId].bits &= ~(REUSE_BIT | NEW_BIT); return; } @@ -191,15 +200,6 @@ void processProbe(const uint probeId) { barrier(); const bool badbit = (badHits>(gl_WorkGroupSize.x*samplesCount*2)/4); - if(badbit && laneId<3) { - vec3 c = vec3(1,0,0); - probe[probeId].color[laneId][0] = c; - probe[probeId].color[laneId][1] = c; - probe[probeId].bits |= BAD_BIT; - } - if(badbit) - return; - for(uint i=gl_WorkGroupSize.x; i>0;) { i /= 2; if(laneId0) b.rgb /= b.w; - probe[probeId].color[laneId][0] = a.rgb; - probe[probeId].color[laneId][1] = b.rgb; - probe[probeId].bits = TRACED_BIT; // newly computed + probe[probeId].color[laneId][0] = a.rgb * M_PI; + probe[probeId].color[laneId][1] = b.rgb * M_PI; + } + + if(laneId==0) { + probe[probeId].bits = TRACED_BIT | NEW_BIT; // newly computed + if(badbit) { + // bad probes sometimes are only probes aviable for fragment - store what we can + probe[probeId].bits |= BAD_BIT; + } } if(laneId==0) { diff --git a/shader/lighting/rt/rt_common.glsl b/shader/lighting/rt/rt_common.glsl index 9d490a3d0..3530250b3 100644 --- a/shader/lighting/rt/rt_common.glsl +++ b/shader/lighting/rt/rt_common.glsl @@ -18,6 +18,7 @@ struct HitDesc { uint instanceId; uint primitiveId; vec3 baryCoord; + bool opaque; }; #if defined(RAY_QUERY_AT) @@ -27,9 +28,9 @@ struct RtObjectDesc { }; layout(binding = 7) uniform sampler smp; layout(binding = 8) uniform texture2D textures[]; -layout(binding = 9, std430) readonly buffer Vbo { float vert[]; } vbo[]; -layout(binding = 10, std430) readonly buffer Ibo { uint index[]; } ibo[]; -layout(binding = 11, std430) readonly buffer Off { RtObjectDesc rtDesc[]; }; +layout(binding = 9, std430) readonly buffer Vbo { float vert[]; } vbo[]; +layout(binding = 10, std430) readonly buffer Ibo { uint index[]; } ibo[]; +layout(binding = 11, std430) readonly buffer Desc { RtObjectDesc rtDesc[]; }; #endif #if defined(RAY_QUERY_AT) @@ -66,10 +67,12 @@ HitDesc pullHitDesc(in rayQueryEXT rayQuery) { d.instanceId = desc.instanceId; d.primitiveId = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, commited); - d.primitiveId += desc.firstPrimitive; + d.primitiveId += desc.firstPrimitive & 0x00FFFFFF; - d.baryCoord = vec3(0,rayQueryGetIntersectionBarycentricsEXT(rayQuery, commited)); - d.baryCoord.x = (1-d.baryCoord.y-d.baryCoord.z); + d.baryCoord = vec3(0,rayQueryGetIntersectionBarycentricsEXT(rayQuery, commited)); + d.baryCoord.x = (1-d.baryCoord.y-d.baryCoord.z); + + d.opaque = (desc.firstPrimitive & 0x01000000)!=0; return d; } @@ -86,10 +89,12 @@ HitDesc pullCommitedHitDesc(in rayQueryEXT rayQuery) { d.instanceId = desc.instanceId; d.primitiveId = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, commited); - d.primitiveId += desc.firstPrimitive; + d.primitiveId += desc.firstPrimitive & 0x00FFFFFF; + + d.baryCoord = vec3(0,rayQueryGetIntersectionBarycentricsEXT(rayQuery, commited)); + d.baryCoord.x = (1-d.baryCoord.y-d.baryCoord.z); - d.baryCoord = vec3(0,rayQueryGetIntersectionBarycentricsEXT(rayQuery, commited)); - d.baryCoord.x = (1-d.baryCoord.y-d.baryCoord.z); + d.opaque = (desc.firstPrimitive & 0x01000000)!=0; return d; }