diff --git a/extensions/pl_ecs_ext.h b/extensions/pl_ecs_ext.h index e497179..3842a30 100644 --- a/extensions/pl_ecs_ext.h +++ b/extensions/pl_ecs_ext.h @@ -385,9 +385,10 @@ enum _plHumanoidBone enum _plEnvironmentProbeFlags { - PL_ENVIRONMENT_PROBE_FLAGS_NONE = 0, - PL_ENVIRONMENT_PROBE_FLAGS_DIRTY = 1 << 0, - PL_ENVIRONMENT_PROBE_FLAGS_REALTIME = 1 << 1 + PL_ENVIRONMENT_PROBE_FLAGS_NONE = 0, + PL_ENVIRONMENT_PROBE_FLAGS_DIRTY = 1 << 0, + PL_ENVIRONMENT_PROBE_FLAGS_REALTIME = 1 << 1, + PL_ENVIRONMENT_PROBE_FLAGS_INCLUDE_SKY = 1 << 2 }; //----------------------------------------------------------------------------- diff --git a/extensions/pl_renderer_ext.c b/extensions/pl_renderer_ext.c index f1dfe29..687194e 100644 --- a/extensions/pl_renderer_ext.c +++ b/extensions/pl_renderer_ext.c @@ -606,6 +606,12 @@ pl_refr_create_scene(void) .pcDebugName = "camera buffers" }; + const plBufferDesc atProbeDataBufferDesc = { + .tUsage = PL_BUFFER_USAGE_STORAGE | PL_BUFFER_USAGE_STAGING, + .szByteSize = 4096, + .pcDebugName = "probe buffers" + }; + for(uint32_t i = 0; i < gptGfx->get_frames_in_flight(); i++) { ptScene->atPLightShadowDataBuffer[i] = pl__refr_create_staging_buffer(&atLightShadowDataBufferDesc, "p shadow", i); @@ -613,6 +619,7 @@ pl_refr_create_scene(void) ptScene->atSLightShadowDataBuffer[i] = pl__refr_create_staging_buffer(&atLightShadowDataBufferDesc, "s shadow", i); ptScene->atSShadowCameraBuffers[i] = pl__refr_create_staging_buffer(&atCameraBuffersDesc, "s shadow buffer", i); + ptScene->atGPUProbeDataBuffers[i] = pl__refr_create_staging_buffer(&atProbeDataBufferDesc, "probe buffer", i); } @@ -1178,6 +1185,7 @@ pl_refr_cleanup(void) for(uint32_t j = 0; j < ptScene->uViewCount; j++) { plRefView* ptView = &ptScene->atViews[j]; + pl_sb_free(ptView->sbtVisibleDrawables); pl_sb_free(ptView->sbtVisibleOpaqueDrawables); pl_sb_free(ptView->sbtVisibleTransparentDrawables); pl_sb_free(ptView->tDirectionLightShadowData.sbtDLightShadowData); @@ -1195,6 +1203,7 @@ pl_refr_cleanup(void) pl_sb_free(ptProbe->tDirectionLightShadowData.sbtDLightShadowData); } + pl_sb_free(ptScene->sbtGPUProbeData); pl_sb_free(ptScene->sbtProbeData); pl_sb_free(ptScene->sbtShadowRects); pl_sb_free(ptScene->sbuShadowDeferredDrawables); @@ -1208,17 +1217,14 @@ pl_refr_cleanup(void) pl_sb_free(ptScene->sbtVertexDataBuffer); pl_sb_free(ptScene->sbuIndexBuffer); pl_sb_free(ptScene->sbtMaterialBuffer); - pl_sb_free(ptScene->sbtDeferredDrawables); - pl_sb_free(ptScene->sbtForwardDrawables); - pl_sb_free(ptScene->sbtNewDeferredDrawables); - pl_sb_free(ptScene->sbtNewForwardDrawables); + pl_sb_free(ptScene->sbtDrawables); + pl_sb_free(ptScene->sbtNewDrawables); pl_sb_free(ptScene->sbtSkinData); pl_sb_free(ptScene->sbtSkinVertexDataBuffer); pl_sb_free(ptScene->sbtOutlineDrawables); pl_sb_free(ptScene->sbtOutlineDrawablesOldShaders); pl_sb_free(ptScene->sbtOutlineDrawablesOldEnvShaders); - pl_hm_free(ptScene->ptDeferredHashmap); - pl_hm_free(ptScene->ptForwardHashmap); + pl_hm_free(ptScene->ptDrawableHashmap); pl_hm_free(ptScene->ptMaterialHashmap); pl_hm_free(ptScene->ptTextureIndexHashmap); pl_hm_free(ptScene->ptCubeTextureIndexHashmap); @@ -1698,17 +1704,10 @@ pl_refr_select_entities(uint32_t uSceneHandle, uint32_t uCount, plEntity* atEnti // const uint64_t ulVariantHash = pl_hm_hash(tOutlineVariant.pTempConstantData, szSpecializationSize, tOutlineVariant.tGraphicsState.ulValue); // pl_hm_remove(&gptData->ptVariantHashmap, ulVariantHash); - if(pl_hm_has_key(ptScene->ptDeferredHashmap, tEntity.ulData)) - { - uint64_t ulIndex = pl_hm_lookup(ptScene->ptDeferredHashmap, tEntity.ulData); - plDrawable* ptDrawable = &ptScene->sbtDeferredDrawables[ulIndex]; - ptDrawable->tShader = ptScene->sbtOutlineDrawablesOldShaders[i]; - ptDrawable->tEnvShader = ptScene->sbtOutlineDrawablesOldEnvShaders[i]; - } - else if(pl_hm_has_key(ptScene->ptForwardHashmap, tEntity.ulData)) + if(pl_hm_has_key(ptScene->ptDrawableHashmap, tEntity.ulData)) { - uint64_t ulIndex = pl_hm_lookup(ptScene->ptForwardHashmap, tEntity.ulData); - plDrawable* ptDrawable = &ptScene->sbtForwardDrawables[ulIndex]; + uint64_t ulIndex = pl_hm_lookup(ptScene->ptDrawableHashmap, tEntity.ulData); + plDrawable* ptDrawable = &ptScene->sbtDrawables[ulIndex]; ptDrawable->tShader = ptScene->sbtOutlineDrawablesOldShaders[i]; ptDrawable->tEnvShader = ptScene->sbtOutlineDrawablesOldEnvShaders[i]; } @@ -1764,13 +1763,14 @@ pl_refr_select_entities(uint32_t uSceneHandle, uint32_t uCount, plEntity* atEnti iObjectRenderingFlags, pl_sb_capacity(ptScene->sbtDLightData), pl_sb_capacity(ptScene->sbtPLightData), - pl_sb_capacity(ptScene->sbtSLightData) + pl_sb_capacity(ptScene->sbtSLightData), + pl_sb_capacity(ptScene->sbtProbeData), }; - if(pl_hm_has_key(ptScene->ptDeferredHashmap, tEntity.ulData)) + if(pl_hm_has_key(ptScene->ptDrawableHashmap, tEntity.ulData)) { - uint64_t ulIndex = pl_hm_lookup(ptScene->ptDeferredHashmap, tEntity.ulData); - plDrawable* ptDrawable = &ptScene->sbtDeferredDrawables[ulIndex]; + uint64_t ulIndex = pl_hm_lookup(ptScene->ptDrawableHashmap, tEntity.ulData); + plDrawable* ptDrawable = &ptScene->sbtDrawables[ulIndex]; plShader* ptOldShader = gptGfx->get_shader(ptDevice, ptDrawable->tShader); plGraphicsState tVariantTemp = ptOldShader->tDesc.tGraphicsState; @@ -1803,9 +1803,7 @@ pl_refr_select_entities(uint32_t uSceneHandle, uint32_t uCount, plEntity* atEnti .tGraphicsState = tOutlineVariantTemp }; - // plShaderHandle tOutlineShader = pl__get_shader_variant(uSceneHandle, gptData->tOutlineShader, &tOutlineVariant); pl_sb_push(ptScene->sbtOutlineDrawables, *ptDrawable); - // ptScene->sbtOutlineDrawables[pl_sb_size(ptScene->sbtOutlineDrawables) - 1].tShader = tOutlineShader; const plShaderVariant tVariant = { .pTempConstantData = aiConstantData0, @@ -1814,56 +1812,11 @@ pl_refr_select_entities(uint32_t uSceneHandle, uint32_t uCount, plEntity* atEnti pl_sb_push(ptScene->sbtOutlineDrawablesOldShaders, ptDrawable->tShader); pl_sb_push(ptScene->sbtOutlineDrawablesOldEnvShaders, ptDrawable->tEnvShader); - ptDrawable->tShader = pl__get_shader_variant(uSceneHandle, gptData->tDeferredShader, &tVariant); - } - else if(pl_hm_has_key(ptScene->ptForwardHashmap, tEntity.ulData)) - { - uint64_t ulIndex = pl_hm_lookup(ptScene->ptForwardHashmap, tEntity.ulData); - plDrawable* ptDrawable = &ptScene->sbtForwardDrawables[ulIndex]; - plShader* ptOldShader = gptGfx->get_shader(ptDevice, ptDrawable->tShader); - plGraphicsState tVariantTemp = ptOldShader->tDesc.tGraphicsState; - - // write into stencil buffer - tVariantTemp.ulStencilTestEnabled = 1; - tVariantTemp.ulStencilMode = PL_COMPARE_MODE_ALWAYS; - tVariantTemp.ulStencilRef = 0xff; - tVariantTemp.ulStencilMask = 0xff; - tVariantTemp.ulStencilOpFail = PL_STENCIL_OP_REPLACE; - tVariantTemp.ulStencilOpDepthFail = PL_STENCIL_OP_REPLACE; - tVariantTemp.ulStencilOpPass = PL_STENCIL_OP_REPLACE; - - // use stencil buffer - const plGraphicsState tOutlineVariantTemp = { - .ulDepthWriteEnabled = 0, - .ulDepthMode = PL_COMPARE_MODE_ALWAYS, - .ulCullMode = PL_CULL_MODE_CULL_FRONT, - .ulWireframe = 0, - .ulStencilTestEnabled = 1, - .ulStencilMode = PL_COMPARE_MODE_LESS, - .ulStencilRef = 128, - .ulStencilMask = 0xff, - .ulStencilOpFail = PL_STENCIL_OP_KEEP, - .ulStencilOpDepthFail = PL_STENCIL_OP_KEEP, - .ulStencilOpPass = PL_STENCIL_OP_KEEP - }; - - const plShaderVariant tOutlineVariant = { - .pTempConstantData = aiConstantData0, - .tGraphicsState = tOutlineVariantTemp - }; - - // plShaderHandle tOutlineShader = pl__get_shader_variant(uSceneHandle, gptData->tOutlineShader, &tOutlineVariant); - pl_sb_push(ptScene->sbtOutlineDrawables, *ptDrawable); - // ptScene->sbtOutlineDrawables[pl_sb_size(ptScene->sbtOutlineDrawables) - 1].tShader = tOutlineShader; - - const plShaderVariant tVariant = { - .pTempConstantData = aiConstantData0, - .tGraphicsState = tVariantTemp - }; - pl_sb_push(ptScene->sbtOutlineDrawablesOldShaders, ptDrawable->tShader); - pl_sb_push(ptScene->sbtOutlineDrawablesOldEnvShaders, ptDrawable->tEnvShader); - ptDrawable->tShader = pl__get_shader_variant(uSceneHandle, gptData->tForwardShader, &tVariant); + if(ptDrawable->tFlags & PL_DRAWABLE_FLAG_FORWARD) + ptDrawable->tShader = pl__get_shader_variant(uSceneHandle, gptData->tForwardShader, &tVariant); + else if(ptDrawable->tFlags & PL_DRAWABLE_FLAG_DEFERRED) + ptDrawable->tShader = pl__get_shader_variant(uSceneHandle, gptData->tDeferredShader, &tVariant); } } } @@ -1914,7 +1867,7 @@ pl_refr_reload_scene_shaders(uint32_t uSceneHandle) { const plLightComponent* sbtLights = ptScene->tComponentLibrary.tLightComponentManager.pComponents; - int aiLightingConstantData[] = {iSceneWideRenderingFlags, pl_sb_capacity(ptScene->sbtDLightData), pl_sb_capacity(ptScene->sbtPLightData), pl_sb_capacity(ptScene->sbtSLightData)}; + int aiLightingConstantData[] = {iSceneWideRenderingFlags, pl_sb_capacity(ptScene->sbtDLightData), pl_sb_capacity(ptScene->sbtPLightData), pl_sb_capacity(ptScene->sbtSLightData), pl_sb_size(ptScene->sbtProbeData)}; plShaderDesc tLightingShaderDesc = { .tPixelShader = gptShader->load_glsl("../shaders/lighting.frag", "main", NULL, NULL), .tVertexShader = gptShader->load_glsl("../shaders/lighting.vert", "main", NULL, NULL), @@ -1984,14 +1937,15 @@ pl_refr_reload_scene_shaders(uint32_t uSceneHandle) { .uSlot = 4, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, { .uSlot = 5, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, { .uSlot = 6, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, + { .uSlot = 7, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, }, .atSamplerBindings = { - {.uSlot = 7, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} + {.uSlot = 8, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} }, } } }; - for(uint32_t i = 0; i < 4; i++) + for(uint32_t i = 0; i < 5; i++) { tLightingShaderDesc.atConstants[i].uID = i; tLightingShaderDesc.atConstants[i].uOffset = i * sizeof(int); @@ -2045,6 +1999,12 @@ pl_refr_reload_scene_shaders(uint32_t uSceneHandle) pl__refr_process_drawables(uSceneHandle, true); + uint32_t uDrawableCount = pl_sb_size(ptScene->sbtDrawables); + for(uint32_t i = 0; i < uDrawableCount; i++) + { + ptScene->sbtDrawables[i].tIndexBuffer = ptScene->sbtDrawables[i].uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer; + } + pl_end_cpu_sample(gptProfile, 0); } @@ -2209,7 +2169,7 @@ pl_refr_finalize_scene(uint32_t uSceneHandle) // create lighting shader { - int aiLightingConstantData[] = {iSceneWideRenderingFlags, pl_sb_capacity(ptScene->sbtDLightData), pl_sb_capacity(ptScene->sbtPLightData), pl_sb_capacity(ptScene->sbtSLightData)}; + int aiLightingConstantData[] = {iSceneWideRenderingFlags, pl_sb_capacity(ptScene->sbtDLightData), pl_sb_capacity(ptScene->sbtPLightData), pl_sb_capacity(ptScene->sbtSLightData), pl_sb_size(ptScene->sbtProbeData)}; plShaderDesc tLightingShaderDesc = { .tPixelShader = gptShader->load_glsl("../shaders/lighting.frag", "main", NULL, NULL), .tVertexShader = gptShader->load_glsl("../shaders/lighting.vert", "main", NULL, NULL), @@ -2279,14 +2239,15 @@ pl_refr_finalize_scene(uint32_t uSceneHandle) { .uSlot = 4, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, { .uSlot = 5, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, { .uSlot = 6, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, + { .uSlot = 7, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, }, .atSamplerBindings = { - {.uSlot = 7, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} + {.uSlot = 8, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} }, } } }; - for(uint32_t i = 0; i < 4; i++) + for(uint32_t i = 0; i < 5; i++) { tLightingShaderDesc.atConstants[i].uID = i; tLightingShaderDesc.atConstants[i].uOffset = i * sizeof(int); @@ -2417,6 +2378,12 @@ pl_refr_finalize_scene(uint32_t uSceneHandle) ptScene->tShadowRenderPass = gptGfx->create_render_pass(gptData->ptDevice, &tDepthRenderPassDesc, atShadowAttachmentSets); ptScene->tFirstShadowRenderPass = gptGfx->create_render_pass(gptData->ptDevice, &tFirstDepthRenderPassDesc, atShadowAttachmentSets); + uint32_t uDrawableCount = pl_sb_size(ptScene->sbtDrawables); + for(uint32_t i = 0; i < uDrawableCount; i++) + { + ptScene->sbtDrawables[i].tIndexBuffer = ptScene->sbtDrawables[i].uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer; + } + pl_end_cpu_sample(gptProfile, 0); } @@ -2540,6 +2507,28 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const plBuffer* ptSShadowDataBuffer = gptGfx->get_buffer(ptDevice, ptScene->atSLightShadowDataBuffer[uFrameIdx]); memcpy(ptSShadowDataBuffer->tMemoryAllocation.pHostMapped, ptScene->sbtSLightShadowData, sizeof(plGPULightShadowData) * pl_sb_size(ptScene->sbtSLightShadowData)); + pl_sb_reset(ptScene->sbtGPUProbeData); + for(uint32_t i = 0; i < pl_sb_size(ptScene->sbtProbeData); i++) + { + plEnvironmentProbeComponent* ptProbe = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_ENVIRONMENT_PROBE, ptScene->sbtProbeData[i].tEntity); + plGPUProbeData tProbeData = { + .tPosition = ptProbe->tPosition, + .fRangeSqr = ptProbe->fRange * ptProbe->fRange, + .uGGXEnvSampler = ptScene->sbtProbeData[i].uGGXEnvSampler, + .uLambertianEnvSampler = ptScene->sbtProbeData[i].uLambertianEnvSampler, + .uGGXLUT = ptScene->sbtProbeData[i].uGGXLUT, + }; + pl_sb_push(ptScene->sbtGPUProbeData, tProbeData); + } + + if(pl_sb_size(ptScene->sbtGPUProbeData) > 0) + { + + plBuffer* ptProbeDataBuffer = gptGfx->get_buffer(ptDevice, ptScene->atGPUProbeDataBuffers[uFrameIdx]); + memcpy(ptProbeDataBuffer->tMemoryAllocation.pHostMapped, ptScene->sbtGPUProbeData, sizeof(plGPUProbeData) * pl_sb_size(ptScene->sbtGPUProbeData)); + } + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~add scene lights~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pl_sb_reset(ptScene->sbtDLightData); @@ -2662,9 +2651,10 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const { .uSlot = 4, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_PIXEL | PL_STAGE_VERTEX}, { .uSlot = 5, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_PIXEL | PL_STAGE_VERTEX}, { .uSlot = 6, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_PIXEL | PL_STAGE_VERTEX}, + { .uSlot = 7, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_PIXEL | PL_STAGE_VERTEX}, }, .atSamplerBindings = { - {.uSlot = 7, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} + {.uSlot = 8, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} }, }; @@ -2676,7 +2666,7 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const const plBindGroupUpdateSamplerData tShadowSamplerData = { .tSampler = gptData->tShadowSampler, - .uSlot = 7 + .uSlot = 8 }; const plBindGroupLayout tPickBG0Layout = { @@ -2726,50 +2716,32 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~culling~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - const uint32_t uDeferredDrawableCount = pl_sb_size(ptScene->sbtDeferredDrawables); - const uint32_t uForwardDrawableCount = pl_sb_size(ptScene->sbtForwardDrawables); + const uint32_t uDrawableCount = pl_sb_size(ptScene->sbtDrawables); - plAtomicCounter* ptDeferredCounter = NULL; - plAtomicCounter* ptForwardCounter = NULL; + plAtomicCounter* ptCullCounter = NULL; if(ptCullCamera) { - plCullData tDeferredCullData = { + plCullData tCullData = { .ptScene = ptScene, .ptCullCamera = ptCullCamera, - .atDrawables = ptScene->sbtDeferredDrawables + .atDrawables = ptScene->sbtDrawables }; - plJobDesc tDeferredJobDesc = { + plJobDesc tJobDesc = { .task = pl__refr_cull_job, - .pData = &tDeferredCullData + .pData = &tCullData }; - gptJob->dispatch_batch(uDeferredDrawableCount, 0, tDeferredJobDesc, &ptDeferredCounter); - - plCullData tForwardCullData = { - .ptScene = ptScene, - .ptCullCamera = ptCullCamera, - .atDrawables = ptScene->sbtForwardDrawables - }; - - plJobDesc tForwardJobDesc = { - .task = pl__refr_cull_job, - .pData = &tForwardCullData - }; - gptJob->dispatch_batch(uForwardDrawableCount, 0, tForwardJobDesc, &ptForwardCounter); + gptJob->dispatch_batch(uDrawableCount, 0, tJobDesc, &ptCullCounter); } else // no culling, just copy drawables over { - if(pl_sb_size(ptView->sbtVisibleOpaqueDrawables) != uDeferredDrawableCount) - { - pl_sb_resize(ptView->sbtVisibleOpaqueDrawables, uDeferredDrawableCount); - memcpy(ptView->sbtVisibleOpaqueDrawables, ptScene->sbtDeferredDrawables, sizeof(plDrawable) * uDeferredDrawableCount); - } - if(pl_sb_size(ptView->sbtVisibleTransparentDrawables) != uForwardDrawableCount) + if(pl_sb_size(ptView->sbtVisibleDrawables) != uDrawableCount) { - pl_sb_resize(ptView->sbtVisibleTransparentDrawables, uForwardDrawableCount); - memcpy(ptView->sbtVisibleTransparentDrawables, ptScene->sbtForwardDrawables, sizeof(plDrawable) * uForwardDrawableCount); + pl_sb_resize(ptView->sbtVisibleDrawables, uDrawableCount); + for(uint32_t i = 0; i < uDrawableCount; i++) + ptView->sbtVisibleDrawables[i] = i; } } @@ -2836,6 +2808,44 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~render scene~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gptJob->wait_for_counter(ptCullCounter); + pl_end_cpu_sample(gptProfile, 0); // prep scene + if(ptCullCamera) + { + pl_sb_reset(ptView->sbtVisibleOpaqueDrawables); + pl_sb_reset(ptView->sbtVisibleTransparentDrawables); + pl_sb_reset(ptView->sbtVisibleDrawables); + + for(uint32_t uDrawableIndex = 0; uDrawableIndex < uDrawableCount; uDrawableIndex++) + { + const plDrawable tDrawable = ptScene->sbtDrawables[uDrawableIndex]; + if(!tDrawable.bCulled) + { + if(tDrawable.tFlags & PL_DRAWABLE_FLAG_DEFERRED) + { + pl_sb_push(ptView->sbtVisibleOpaqueDrawables, uDrawableIndex); + pl_sb_push(ptView->sbtVisibleDrawables, uDrawableIndex); + } + else if(tDrawable.tFlags & PL_DRAWABLE_FLAG_PROBE) + { + if(gptData->bShowProbes) + { + pl_sb_push(ptView->sbtVisibleTransparentDrawables, uDrawableIndex); + pl_sb_push(ptView->sbtVisibleDrawables, uDrawableIndex); + } + } + else if(tDrawable.tFlags & PL_DRAWABLE_FLAG_FORWARD) + { + pl_sb_push(ptView->sbtVisibleTransparentDrawables, uDrawableIndex); + pl_sb_push(ptView->sbtVisibleDrawables, uDrawableIndex); + } + + } + } + } + + *gptData->pdDrawCalls += (double)(pl_sb_size(ptView->sbtVisibleOpaqueDrawables) + pl_sb_size(ptView->sbtVisibleTransparentDrawables) + 1); + const plVec2 tDimensions = gptGfx->get_render_pass(ptDevice, ptView->tRenderPass)->tDesc.tDimensions; plDrawArea tArea = { @@ -2871,25 +2881,11 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const plRenderEncoder* ptSceneEncoder = gptGfx->begin_render_pass(ptSceneCmdBuffer, ptView->tRenderPass, NULL); gptGfx->set_depth_bias(ptSceneEncoder, 0.0f, 0.0f, 0.0f); - gptJob->wait_for_counter(ptDeferredCounter); - pl_end_cpu_sample(gptProfile, 0); // prep scene - if(ptCullCamera) - { - pl_sb_reset(ptView->sbtVisibleOpaqueDrawables); - for(uint32_t uDrawableIndex = 0; uDrawableIndex < uDeferredDrawableCount; uDrawableIndex++) - { - const plDrawable tDrawable = ptScene->sbtDeferredDrawables[uDrawableIndex]; - if(!tDrawable.bCulled) - pl_sb_push(ptView->sbtVisibleOpaqueDrawables, tDrawable); - } - } - const uint32_t uVisibleDeferredDrawCount = pl_sb_size(ptView->sbtVisibleOpaqueDrawables); - *gptData->pdDrawCalls += (double)uVisibleDeferredDrawCount; gptGfx->reset_draw_stream(ptStream, uVisibleDeferredDrawCount); for(uint32_t i = 0; i < uVisibleDeferredDrawCount; i++) { - const plDrawable tDrawable = ptView->sbtVisibleOpaqueDrawables[i]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptView->sbtVisibleOpaqueDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -2897,7 +2893,7 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const DynamicData* ptDynamicData = (DynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialOffset = tDrawable.uMaterialIndex; ptDynamicData->uGlobalIndex = 0; @@ -2911,10 +2907,10 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tDeferredBG1 @@ -2942,10 +2938,11 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const { .uSlot = 4, .tBuffer = ptView->tDirectionLightShadowData.atDLightShadowDataBuffer[uFrameIdx], .szBufferRange = sizeof(plGPULightShadowData) * pl_sb_size(ptView->tDirectionLightShadowData.sbtDLightShadowData)}, { .uSlot = 5, .tBuffer = ptScene->atPLightShadowDataBuffer[uFrameIdx], .szBufferRange = sizeof(plGPULightShadowData) * pl_sb_size(ptScene->sbtPLightShadowData)}, { .uSlot = 6, .tBuffer = ptScene->atSLightShadowDataBuffer[uFrameIdx], .szBufferRange = sizeof(plGPULightShadowData) * pl_sb_size(ptScene->sbtSLightShadowData)}, + { .uSlot = 7, .tBuffer = ptScene->atGPUProbeDataBuffers[uFrameIdx], .szBufferRange = sizeof(plGPUProbeData) * pl_sb_size(ptScene->sbtGPUProbeData)}, }; const plBindGroupUpdateData tSceneBGData = { - .uBufferCount = 7, + .uBufferCount = 8, .atBufferBindings = atSceneBGBufferData, .uSamplerCount = 1, .atSamplerBindings = &tShadowSamplerData @@ -2972,7 +2969,6 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const ptLightingDynamicData->uGlobalIndex = 0; gptGfx->reset_draw_stream(ptStream, 1); - *gptData->pdDrawCalls += 1.0; pl_add_to_draw_stream(ptStream, (plDrawStreamData) { .tShader = ptScene->tLightingShader, @@ -3028,7 +3024,6 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const ptSkyboxDynamicData->uGlobalIndex = 0; gptGfx->reset_draw_stream(ptStream, 1); - *gptData->pdDrawCalls += 1.0; pl_add_to_draw_stream(ptStream, (plDrawStreamData) { .tShader = gptData->tSkyboxShader, @@ -3054,24 +3049,11 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const gptGfx->draw_stream(ptSceneEncoder, 1, &tArea); } - gptJob->wait_for_counter(ptForwardCounter); - if(ptCullCamera) - { - pl_sb_reset(ptView->sbtVisibleTransparentDrawables); - for(uint32_t uDrawableIndex = 0; uDrawableIndex < uForwardDrawableCount; uDrawableIndex++) - { - const plDrawable tDrawable = ptScene->sbtForwardDrawables[uDrawableIndex]; - if(!tDrawable.bCulled) - pl_sb_push(ptView->sbtVisibleTransparentDrawables, tDrawable); - } - } - const uint32_t uVisibleForwardDrawCount = pl_sb_size(ptView->sbtVisibleTransparentDrawables); gptGfx->reset_draw_stream(ptStream, uVisibleForwardDrawCount); - *gptData->pdDrawCalls += (double)uVisibleForwardDrawCount; for(uint32_t i = 0; i < uVisibleForwardDrawCount; i++) { - const plDrawable tDrawable = ptView->sbtVisibleTransparentDrawables[i]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptView->sbtVisibleTransparentDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -3079,7 +3061,7 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const DynamicData* ptDynamicData = (DynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialOffset = tDrawable.uMaterialIndex; ptDynamicData->uGGXEnvSampler = ptScene->sbtProbeData[0].uGGXEnvSampler; @@ -3096,10 +3078,10 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, - .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .tIndexBuffer = tDrawable.tIndexBuffer, + .uIndexOffset = tDrawable.uIndexOffset, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tSceneBG @@ -3194,15 +3176,9 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const // debug drawing if(gptData->bDrawAllBoundingBoxes) { - for(uint32_t i = 0; i < uDeferredDrawableCount; i++) - { - plMeshComponent* ptMesh = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MESH, ptScene->sbtDeferredDrawables[i].tEntity); - - gptDraw->add_3d_aabb(ptView->pt3DDrawList, ptMesh->tAABBFinal.tMin, ptMesh->tAABBFinal.tMax, (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(1.0f, 0.0f, 0.0f), .fThickness = 0.02f}); - } - for(uint32_t i = 0; i < uForwardDrawableCount; i++) + for(uint32_t i = 0; i < uDrawableCount; i++) { - plMeshComponent* ptMesh = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MESH, ptScene->sbtForwardDrawables[i].tEntity); + plMeshComponent* ptMesh = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MESH, ptScene->sbtDrawables[i].tEntity); gptDraw->add_3d_aabb(ptView->pt3DDrawList, ptMesh->tAABBFinal.tMin, ptMesh->tAABBFinal.tMax, (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(1.0f, 0.0f, 0.0f), .fThickness = 0.02f}); } @@ -3211,13 +3187,7 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const { for(uint32_t i = 0; i < uVisibleDeferredDrawCount; i++) { - plMeshComponent* ptMesh = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MESH, ptView->sbtVisibleOpaqueDrawables[i].tEntity); - - gptDraw->add_3d_aabb(ptView->pt3DDrawList, ptMesh->tAABBFinal.tMin, ptMesh->tAABBFinal.tMax, (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(1.0f, 0.0f, 0.0f), .fThickness = 0.02f}); - } - for(uint32_t i = 0; i < uVisibleForwardDrawCount; i++) - { - plMeshComponent* ptMesh = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MESH, ptView->sbtVisibleTransparentDrawables[i].tEntity); + plMeshComponent* ptMesh = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MESH, ptScene->sbtDrawables[ptView->sbtVisibleDrawables[i]].tEntity); gptDraw->add_3d_aabb(ptView->pt3DDrawList, ptMesh->tAABBFinal.tMin, ptMesh->tAABBFinal.tMax, (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(1.0f, 0.0f, 0.0f), .fThickness = 0.02f}); } @@ -3262,14 +3232,6 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const unsigned char* pucMapping = &pucMapping2[uPos]; gptData->tPickedEntity.uIndex = pucMapping[0] + 256 * pucMapping[1] + 65536 * pucMapping[2]; gptData->tPickedEntity.uGeneration = ptScene->tComponentLibrary.sbtEntityGenerations[gptData->tPickedEntity.uIndex]; - - // plImageWriteInfo tBlah = { - // .iWidth = (int)ptTexture->tDesc.tDimensions.x, - // .iHeight = (int)ptTexture->tDesc.tDimensions.y, - // .iComponents = 4, - // .iByteStride = 4 * (int)ptTexture->tDesc.tDimensions.x - // }; - // gptImage->write("pick.png", pucMapping2, &tBlah); } bool bOwnMouse = gptUI->wants_mouse_capture(); @@ -3302,10 +3264,12 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const gptGfx->bind_shader(ptPickEncoder, gptData->tPickShader); gptGfx->bind_vertex_buffer(ptPickEncoder, ptScene->tVertexBuffer); - *gptData->pdDrawCalls += (double)uVisibleDeferredDrawCount; - for(uint32_t i = 0; i < uVisibleDeferredDrawCount; i++) + const uint32_t uVisibleDrawCount = pl_sb_size(ptView->sbtVisibleDrawables); + *gptData->pdDrawCalls += (double)uVisibleDrawCount; + + for(uint32_t i = 0; i < uVisibleDrawCount; i++) { - const plDrawable tDrawable = ptView->sbtVisibleOpaqueDrawables[i]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptView->sbtVisibleDrawables[i]]; uint32_t uId = tDrawable.tEntity.uIndex; @@ -3344,47 +3308,6 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const gptGfx->draw(ptPickEncoder, 1, &tDraw); } } - - *gptData->pdDrawCalls += (double)uVisibleForwardDrawCount; - for(uint32_t i = 0; i < uVisibleForwardDrawCount; i++) - { - const plDrawable tDrawable = ptView->sbtVisibleTransparentDrawables[i]; - - plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); - plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); - - plDynamicBinding tDynamicBinding = pl__allocate_dynamic_data(ptDevice); - plPickDynamicData* ptDynamicData = (plPickDynamicData*)tDynamicBinding.pcData; - const uint32_t uId = tDrawable.tEntity.uIndex; - ptDynamicData->tColor = (plVec4){ - ((float)(uId & 0x000000ff) / 255.0f), - ((float)((uId & 0x0000ff00) >> 8) / 255.0f), - ((float)((uId & 0x00ff0000) >> 16) / 255.0f), - 1.0f}; - ptDynamicData->tModel = ptTransform->tWorld; - - gptGfx->bind_graphics_bind_groups(ptPickEncoder, gptData->tPickShader, 0, 1, &tPickBG0, 1, &tDynamicBinding); - - if(tDrawable.uIndexCount > 0) - { - plDrawIndex tDraw = { - .tIndexBuffer = ptScene->tIndexBuffer, - .uIndexCount = tDrawable.uIndexCount, - .uIndexStart = tDrawable.uIndexOffset, - .uInstanceCount = 1 - }; - gptGfx->draw_indexed(ptPickEncoder, 1, &tDraw); - } - else - { - plDraw tDraw = { - .uVertexStart = tDrawable.uVertexOffset, - .uInstanceCount = 1, - .uVertexCount = tDrawable.uVertexCount - }; - gptGfx->draw(ptPickEncoder, 1, &tDraw); - } - } gptGfx->end_render_pass(ptPickEncoder); plBuffer* ptCachedStagingBuffer = gptGfx->get_buffer(ptDevice, gptData->tCachedStagingBuffer); @@ -3863,41 +3786,23 @@ pl_add_drawable_objects_to_scene(uint32_t uSceneHandle, uint32_t uDeferredCount, { plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; - #if 1 - const uint32_t uTransparentStart = pl_sb_size(ptScene->sbtNewForwardDrawables); - pl_sb_add_n(ptScene->sbtNewForwardDrawables, uForwardCount); - - const uint32_t uOpaqueStart = pl_sb_size(ptScene->sbtNewDeferredDrawables); - pl_sb_add_n(ptScene->sbtNewDeferredDrawables, uDeferredCount); - - for(uint32_t i = 0; i < uDeferredCount; i++) - ptScene->sbtNewDeferredDrawables[uOpaqueStart + i].tEntity = atDeferredObjects[i]; - - for(uint32_t i = 0; i < uForwardCount; i++) - ptScene->sbtNewForwardDrawables[uTransparentStart + i].tEntity = atForwardObjects[i]; - #endif - - #if 0 // send through forward pass only - const uint32_t uTransparentStart = pl_sb_size(ptScene->sbtNewForwardDrawables); - pl_sb_add_n(ptScene->sbtNewForwardDrawables, uForwardCount + uDeferredCount); + uint32_t uStart = pl_sb_size(ptScene->sbtNewDrawables); + pl_sb_add_n(ptScene->sbtNewDrawables, uDeferredCount); for(uint32_t i = 0; i < uDeferredCount; i++) - ptScene->sbtNewForwardDrawables[uTransparentStart + i].tEntity = atDeferredObjects[i]; - - for(uint32_t i = 0; i < uForwardCount; i++) - ptScene->sbtNewForwardDrawables[uDeferredCount + uTransparentStart + i].tEntity = atForwardObjects[i]; - #endif - - #if 0 // send through deferred pass only - const uint32_t uTransparentStart = pl_sb_size(ptScene->sbtNewDeferredDrawables); - pl_sb_add_n(ptScene->sbtNewDeferredDrawables, uForwardCount + uDeferredCount); + { + ptScene->sbtNewDrawables[uStart + i].tEntity = atDeferredObjects[i]; + ptScene->sbtNewDrawables[uStart + i].tFlags = PL_DRAWABLE_FLAG_DEFERRED; + } - for(uint32_t i = 0; i < uDeferredCount; i++) - ptScene->sbtNewDeferredDrawables[uTransparentStart + i].tEntity = atDeferredObjects[i]; + uStart = pl_sb_size(ptScene->sbtNewDrawables); + pl_sb_add_n(ptScene->sbtNewDrawables, uForwardCount); for(uint32_t i = 0; i < uForwardCount; i++) - ptScene->sbtNewDeferredDrawables[uDeferredCount + uTransparentStart + i].tEntity = atForwardObjects[i]; - #endif + { + ptScene->sbtNewDrawables[uStart + i].tEntity = atForwardObjects[i]; + ptScene->sbtNewDrawables[uStart + i].tFlags = PL_DRAWABLE_FLAG_FORWARD; + } } static void @@ -3913,6 +3818,7 @@ pl_show_graphics_options(const char* pcTitle) if(gptUI->checkbox("MultiViewport Shadows", &gptData->bMultiViewportShadows)) bReloadShaders = true; if(gptUI->checkbox("Image Based Lighting", &gptData->bImageBasedLighting)) bReloadShaders = true; if(gptUI->checkbox("Punctual Lighting", &gptData->bPunctualLighting)) bReloadShaders = true; + gptUI->checkbox("Show Probes", &gptData->bShowProbes); if(bReloadShaders) { diff --git a/extensions/pl_renderer_internal.c b/extensions/pl_renderer_internal.c index b7fce98..f717aea 100644 --- a/extensions/pl_renderer_internal.c +++ b/extensions/pl_renderer_internal.c @@ -1070,7 +1070,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm *gptData->pdDrawCalls += (double)uVisibleOpaqueDrawCount; for(uint32_t i = 0; i < uVisibleOpaqueDrawCount; i++) { - const plDrawable tDrawable = ptScene->sbtDeferredDrawables[ptScene->sbuShadowDeferredDrawables[i]]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowDeferredDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1078,7 +1078,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)uPCameraBufferIndex; @@ -1092,10 +1092,10 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tGlobalBG0 @@ -1111,7 +1111,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm *gptData->pdDrawCalls += (double)uVisibleTransparentDrawCount; for(uint32_t i = 0; i < uVisibleTransparentDrawCount; i++) { - const plDrawable tDrawable = ptScene->sbtForwardDrawables[ptScene->sbuShadowForwardDrawables[i]]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowForwardDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1119,7 +1119,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)uPCameraBufferIndex; @@ -1133,10 +1133,10 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tGlobalBG0 @@ -1249,7 +1249,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm *gptData->pdDrawCalls += (double)uVisibleOpaqueDrawCount; for(uint32_t i = 0; i < uVisibleOpaqueDrawCount; i++) { - const plDrawable tDrawable = ptScene->sbtDeferredDrawables[i]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowDeferredDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1257,7 +1257,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)uPCameraBufferIndex + uFaceIndex; @@ -1271,10 +1271,10 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tGlobalBG0 @@ -1290,7 +1290,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm *gptData->pdDrawCalls += (double)uVisibleTransparentDrawCount; for(uint32_t i = 0; i < uVisibleTransparentDrawCount; i++) { - const plDrawable tDrawable = ptScene->sbtForwardDrawables[i]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowForwardDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1298,7 +1298,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)uPCameraBufferIndex + uFaceIndex; @@ -1312,10 +1312,10 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tGlobalBG0 @@ -1373,7 +1373,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm *gptData->pdDrawCalls += (double)uVisibleOpaqueDrawCount; for(uint32_t i = 0; i < uVisibleOpaqueDrawCount; i++) { - const plDrawable tDrawable = ptScene->sbtDeferredDrawables[i]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowDeferredDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1381,7 +1381,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)uSCameraBufferIndex; @@ -1395,10 +1395,10 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tGlobalBG1 @@ -1414,7 +1414,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm *gptData->pdDrawCalls += (double)uVisibleTransparentDrawCount; for(uint32_t i = 0; i < uVisibleTransparentDrawCount; i++) { - const plDrawable tDrawable = ptScene->sbtForwardDrawables[i]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowForwardDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1422,7 +1422,7 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)uSCameraBufferIndex; @@ -1436,10 +1436,10 @@ pl_refr_generate_shadow_maps(plRenderEncoder* ptEncoder, plCommandBuffer* ptComm .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tGlobalBG1 @@ -1723,7 +1723,7 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer *gptData->pdDrawCalls += (double)uOpaqueDrawableCount; for(uint32_t i = 0; i < uOpaqueDrawableCount; i++) { - const plDrawable tDrawable = ptScene->sbtDeferredDrawables[ptScene->sbuShadowDeferredDrawables[i]]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowDeferredDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1731,7 +1731,7 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)ptDShadowData->uOffsetIndex + (int)uIndexingOffset; @@ -1745,10 +1745,10 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tShadowBG1 @@ -1764,7 +1764,7 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer *gptData->pdDrawCalls += (double)uTransparentDrawableCount; for(uint32_t i = 0; i < uTransparentDrawableCount; i++) { - const plDrawable tDrawable = ptScene->sbtForwardDrawables[ptScene->sbuShadowForwardDrawables[i]]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowForwardDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1772,7 +1772,7 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)ptDShadowData->uOffsetIndex + (int)uIndexingOffset; @@ -1786,10 +1786,10 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tShadowBG1 @@ -1876,7 +1876,7 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer *gptData->pdDrawCalls += (double)uOpaqueDrawableCount; for(uint32_t i = 0; i < uOpaqueDrawableCount; i++) { - const plDrawable tDrawable = ptScene->sbtDeferredDrawables[ptScene->sbuShadowDeferredDrawables[i]]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowDeferredDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1884,7 +1884,7 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)uCascade + (int)ptDShadowData->uOffsetIndex; @@ -1898,10 +1898,10 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tShadowBG1 @@ -1917,7 +1917,7 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer *gptData->pdDrawCalls += (double)uTransparentDrawableCount; for(uint32_t i = 0; i < uTransparentDrawableCount; i++) { - const plDrawable tDrawable = ptScene->sbtForwardDrawables[ptScene->sbuShadowForwardDrawables[i]]; + const plDrawable tDrawable = ptScene->sbtDrawables[ptScene->sbuShadowForwardDrawables[i]]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); plTransformComponent* ptTransform = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform); @@ -1925,7 +1925,7 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer plShadowDynamicData* ptDynamicData = (plShadowDynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialIndex = tDrawable.uMaterialIndex; ptDynamicData->iIndex = (int)uCascade + (int)ptDShadowData->uOffsetIndex; @@ -1939,10 +1939,10 @@ pl_refr_generate_cascaded_shadow_map(plRenderEncoder* ptEncoder, plCommandBuffer .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tShadowBG1 @@ -2150,7 +2150,7 @@ pl_refr_create_global_shaders(void) }; gptData->tEnvFilterShader = gptGfx->create_compute_shader(gptData->ptDevice, &tFilterComputeShaderDesc); - int aiConstantData[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int aiConstantData[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; plShaderDesc tDeferredShaderDescription = { .tPixelShader = gptShader->load_glsl("../shaders/primitive.frag", "main", NULL, NULL), @@ -2283,14 +2283,15 @@ pl_refr_create_global_shaders(void) { .uSlot = 4, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, { .uSlot = 5, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, { .uSlot = 6, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, + { .uSlot = 7, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL}, }, .atSamplerBindings = { - {.uSlot = 7, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} + {.uSlot = 8, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} }, } } }; - for(uint32_t i = 0; i < 8; i++) + for(uint32_t i = 0; i < 9; i++) { tForwardShaderDescription.atConstants[i].uID = i; tForwardShaderDescription.atConstants[i].uOffset = i * sizeof(int); @@ -3428,7 +3429,10 @@ pl__create_probe_data(uint32_t uSceneHandle, plEntity tProbeHandle) } } - pl_add_drawable_objects_to_scene(uSceneHandle, 0, NULL, 1, &tProbeHandle); + const uint32_t uTransparentStart = pl_sb_size(ptScene->sbtNewDrawables); + pl_sb_add(ptScene->sbtNewDrawables); + ptScene->sbtNewDrawables[uTransparentStart].tEntity = tProbeHandle; + ptScene->sbtNewDrawables[uTransparentStart].tFlags = PL_DRAWABLE_FLAG_PROBE | PL_DRAWABLE_FLAG_FORWARD; }; static uint64_t @@ -3464,9 +3468,10 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) { .uSlot = 4, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_PIXEL | PL_STAGE_VERTEX}, { .uSlot = 5, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_PIXEL | PL_STAGE_VERTEX}, { .uSlot = 6, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_PIXEL | PL_STAGE_VERTEX}, + { .uSlot = 7, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_PIXEL | PL_STAGE_VERTEX}, }, .atSamplerBindings = { - {.uSlot = 7, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} + {.uSlot = 8, .tStages = PL_STAGE_VERTEX | PL_STAGE_PIXEL} }, }; const plBindGroupDesc tSceneBGDesc = { @@ -3501,7 +3506,7 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) const plBindGroupUpdateSamplerData tShadowSamplerData = { .tSampler = gptData->tShadowSampler, - .uSlot = 7 + .uSlot = 8 }; const plBindGroupLayout tGBufferFillBG1Layout = { @@ -3538,15 +3543,14 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) ptProbe->tDirectionLightShadowData.uOffset = 0; ptProbe->tDirectionLightShadowData.uOffsetIndex = 0; - const uint32_t uOpaqueDrawableCount = pl_sb_size(ptScene->sbtDeferredDrawables); - const uint32_t uTransparentDrawableCount = pl_sb_size(ptScene->sbtForwardDrawables); + const uint32_t uDrawableCount = pl_sb_size(ptScene->sbtDrawables); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~probe face pre-calc~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // temporary data for probes // create scene bind group (camera, lights, shadows) - const plBindGroupUpdateBufferData tSceneBGBufferData[7] = + const plBindGroupUpdateBufferData tSceneBGBufferData[] = { { .uSlot = 0, .tBuffer = ptProbe->atGlobalBuffers[uFrameIdx], .szBufferRange = sizeof(BindGroup_0) * 6 }, { .uSlot = 1, .tBuffer = ptScene->atDLightBuffer[uFrameIdx], .szBufferRange = sizeof(plGPULight) * pl_sb_size(ptScene->sbtDLightData)}, @@ -3555,10 +3559,11 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) { .uSlot = 4, .tBuffer = ptProbe->tDirectionLightShadowData.atDLightShadowDataBuffer[uFrameIdx], .szBufferRange = sizeof(plGPULightShadowData) * pl_sb_size(ptProbe->tDirectionLightShadowData.sbtDLightShadowData)}, { .uSlot = 5, .tBuffer = ptScene->atPLightShadowDataBuffer[uFrameIdx], .szBufferRange = sizeof(plGPULightShadowData) * pl_sb_size(ptScene->sbtPLightShadowData)}, { .uSlot = 6, .tBuffer = ptScene->atSLightShadowDataBuffer[uFrameIdx], .szBufferRange = sizeof(plGPULightShadowData) * pl_sb_size(ptScene->sbtSLightShadowData)}, + { .uSlot = 7, .tBuffer = ptScene->atGPUProbeDataBuffers[uFrameIdx], .szBufferRange = sizeof(plGPUProbeData) * pl_sb_size(ptScene->sbtGPUProbeData)}, }; const plBindGroupUpdateData tSceneBGData = { - .uBufferCount = 7, + .uBufferCount = 8, .atBufferBindings = tSceneBGBufferData, .uSamplerCount = 1, .atSamplerBindings = &tShadowSamplerData @@ -3709,26 +3714,32 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) plRenderEncoder* ptProbeEncoder = gptGfx->begin_render_pass(ptCmdBuffer, ptProbe->atRenderPasses[uFace], NULL); gptGfx->set_depth_bias(ptProbeEncoder, 0.0f, 0.0f, 0.0f); - plCullData tDeferredCullData = { + plCullData tCullData = { .ptScene = ptScene, .ptCullCamera = &atEnvironmentCamera[uFace], - .atDrawables = ptScene->sbtDeferredDrawables + .atDrawables = ptScene->sbtDrawables }; - plJobDesc tDeferredJobDesc = { + plJobDesc tJobDesc = { .task = pl__refr_cull_job, - .pData = &tDeferredCullData + .pData = &tCullData }; - plAtomicCounter* ptDeferredCounter = NULL; - gptJob->dispatch_batch(uOpaqueDrawableCount, 0, tDeferredJobDesc, &ptDeferredCounter); - gptJob->wait_for_counter(ptDeferredCounter); + plAtomicCounter* ptCullCounter = NULL; + gptJob->dispatch_batch(uDrawableCount, 0, tJobDesc, &ptCullCounter); + gptJob->wait_for_counter(ptCullCounter); pl_sb_reset(ptProbe->sbtVisibleOpaqueDrawables[uFace]); - for(uint32_t uDrawableIndex = 0; uDrawableIndex < uOpaqueDrawableCount; uDrawableIndex++) + pl_sb_reset(ptProbe->sbtVisibleTransparentDrawables[uFace]); + for(uint32_t uDrawableIndex = 0; uDrawableIndex < uDrawableCount; uDrawableIndex++) { - const plDrawable tDrawable = ptScene->sbtDeferredDrawables[uDrawableIndex]; + const plDrawable tDrawable = ptScene->sbtDrawables[uDrawableIndex]; if(!tDrawable.bCulled) - pl_sb_push(ptProbe->sbtVisibleOpaqueDrawables[uFace], tDrawable); + { + if(tDrawable.tFlags & PL_DRAWABLE_FLAG_DEFERRED) + pl_sb_push(ptProbe->sbtVisibleOpaqueDrawables[uFace], tDrawable); + else if(tDrawable.tFlags & PL_DRAWABLE_FLAG_FORWARD) + pl_sb_push(ptProbe->sbtVisibleTransparentDrawables[uFace], tDrawable); + } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~update bind groups~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3746,7 +3757,7 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) DynamicData* ptDynamicData = (DynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialOffset = tDrawable.uMaterialIndex; ptDynamicData->uGlobalIndex = uFace; @@ -3760,10 +3771,10 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tGBufferFillBG1 @@ -3831,28 +3842,7 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) gptGfx->next_subpass(ptProbeEncoder, NULL); - plCullData tForwardCullData = { - .ptScene = ptScene, - .ptCullCamera = &atEnvironmentCamera[uFace], - .atDrawables = ptScene->sbtForwardDrawables - }; - - plJobDesc tForwardJobDesc = { - .task = pl__refr_cull_job, - .pData = &tForwardCullData - }; - plAtomicCounter* ptForwardCounter = NULL; - gptJob->dispatch_batch(uTransparentDrawableCount, 0, tForwardJobDesc, &ptForwardCounter); - gptJob->wait_for_counter(ptForwardCounter); - pl_sb_reset(ptProbe->sbtVisibleTransparentDrawables[uFace]); - for(uint32_t uDrawableIndex = 0; uDrawableIndex < uTransparentDrawableCount; uDrawableIndex++) - { - const plDrawable tDrawable = ptScene->sbtForwardDrawables[uDrawableIndex]; - if(!tDrawable.bCulled) - pl_sb_push(ptProbe->sbtVisibleTransparentDrawables[uFace], tDrawable); - } - - if(ptScene->tSkyboxTexture.uIndex != 0) + if(ptScene->tSkyboxTexture.uIndex != 0 && ptProbeComp->tFlags & PL_ENVIRONMENT_PROBE_FLAGS_INCLUDE_SKY) { plDynamicBinding tSkyboxDynamicData = pl__allocate_dynamic_data(ptDevice); @@ -3902,7 +3892,7 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) DynamicData* ptDynamicData = (DynamicData*)tDynamicBinding.pcData; ptDynamicData->iDataOffset = tDrawable.uDataOffset; - ptDynamicData->iVertexOffset = tDrawable.uIndexCount == 0 ? 0 : tDrawable.uVertexOffset; + ptDynamicData->iVertexOffset = tDrawable.uDynamicVertexOffset; ptDynamicData->tModel = ptTransform->tWorld; ptDynamicData->iMaterialOffset = tDrawable.uMaterialIndex; ptDynamicData->uGlobalIndex = uFace; @@ -3916,10 +3906,10 @@ pl__update_environment_probes(uint32_t uSceneHandle, uint64_t ulValue) .atVertexBuffers = { ptScene->tVertexBuffer, }, - .tIndexBuffer = tDrawable.uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer, + .tIndexBuffer = tDrawable.tIndexBuffer, .uIndexOffset = tDrawable.uIndexOffset, - .uTriangleCount = tDrawable.uIndexCount == 0 ? tDrawable.uVertexCount / 3 : tDrawable.uIndexCount / 3, - .uVertexOffset = tDrawable.uIndexCount == 0 ? tDrawable.uVertexOffset : 0, + .uTriangleCount = tDrawable.uTriangleCount, + .uVertexOffset = tDrawable.uStaticVertexOffset, .atBindGroups = { ptScene->tGlobalBindGroup, tSceneBG @@ -4351,191 +4341,178 @@ pl__refr_process_drawables(uint32_t uSceneHandle, bool bReload) // fill CPU buffers & drawable list - pl_sb_reset(ptScene->sbtDeferredDrawables); - pl_sb_reset(ptScene->sbtForwardDrawables); + pl_sb_reset(ptScene->sbtDrawables); pl_sb_reset(ptScene->sbuShadowDeferredDrawables); pl_sb_reset(ptScene->sbuShadowForwardDrawables); - plDrawable* sbtNewDrawables[] = { - ptScene->sbtNewDeferredDrawables, - ptScene->sbtNewForwardDrawables, - }; - - plDrawable* sbtDrawables[] = { - ptScene->sbtDeferredDrawables, - ptScene->sbtForwardDrawables, - }; - - uint32_t* sbuShadowDrawables[] = { - ptScene->sbuShadowDeferredDrawables, - ptScene->sbuShadowForwardDrawables, - }; - - plShaderHandle atTemplateShaders[] = { - gptData->tDeferredShader, - gptData->tForwardShader - }; - - plShaderHandle atTemplateShadowShaders[] = { - gptData->tShadowShader, - gptData->tAlphaShadowShader - }; + const uint32_t uDrawableCount = pl_sb_size(ptScene->sbtNewDrawables); + pl_sb_reserve(ptScene->sbtDrawables, uDrawableCount); + if(!bReload) + { + pl_hm_resize(ptScene->ptDrawableHashmap, uDrawableCount); + } + for(uint32_t i = 0; i < uDrawableCount; i++) + { - plGraphicsState atTemplateVariants[] = { - { - .ulDepthWriteEnabled = 1, - .ulDepthMode = PL_COMPARE_MODE_GREATER, - .ulCullMode = PL_CULL_MODE_CULL_BACK, - .ulStencilMode = PL_COMPARE_MODE_ALWAYS, - .ulStencilRef = 0xff, - .ulStencilMask = 0xff, - .ulStencilOpFail = PL_STENCIL_OP_KEEP, - .ulStencilOpDepthFail = PL_STENCIL_OP_KEEP, - .ulStencilOpPass = PL_STENCIL_OP_KEEP - }, + ptScene->sbtNewDrawables[i].uSkinIndex = UINT32_MAX; + plEntity tEntity = ptScene->sbtNewDrawables[i].tEntity; + + if(!bReload) { - .ulDepthWriteEnabled = 1, - .ulDepthMode = PL_COMPARE_MODE_GREATER_OR_EQUAL, - .ulCullMode = PL_CULL_MODE_NONE, - .ulStencilMode = PL_COMPARE_MODE_ALWAYS, - .ulStencilRef = 0xff, - .ulStencilMask = 0xff, - .ulStencilOpFail = PL_STENCIL_OP_KEEP, - .ulStencilOpDepthFail = PL_STENCIL_OP_KEEP, - .ulStencilOpPass = PL_STENCIL_OP_KEEP + pl_hm_insert(ptScene->ptDrawableHashmap, tEntity.ulData, i); } - }; - plHashMap* atHashmaps[] = { - ptScene->ptDeferredHashmap, - ptScene->ptForwardHashmap - }; + // get actual components + plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tEntity); + plMeshComponent* ptMesh = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MESH, ptObject->tMesh); + plMaterialComponent* ptMaterial = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MATERIAL, ptMesh->tMaterial); - for(uint32_t uDrawableBatchIndex = 0; uDrawableBatchIndex < 2; uDrawableBatchIndex++) - { - plHashMap* ptHashmap = atHashmaps[uDrawableBatchIndex]; - const uint32_t uDrawableCount = pl_sb_size(sbtNewDrawables[uDrawableBatchIndex]); - if(!bReload) + uint32_t uMaterialIndex = UINT32_MAX; + + if(pl_hm_has_key(ptScene->ptMaterialHashmap, ptMesh->tMaterial.ulData)) { - pl_hm_resize(ptHashmap, uDrawableCount); + uMaterialIndex = (uint32_t)pl_hm_lookup(ptScene->ptMaterialHashmap, ptMesh->tMaterial.ulData); } - for(uint32_t i = 0; i < uDrawableCount; i++) + else { - (sbtNewDrawables[uDrawableBatchIndex])[i].uSkinIndex = UINT32_MAX; - plEntity tEntity = (sbtNewDrawables[uDrawableBatchIndex])[i].tEntity; - - if(!bReload) + uint64_t ulValue = pl_hm_get_free_index(ptScene->ptMaterialHashmap); + if(ulValue == UINT64_MAX) { - pl_hm_insert(ptHashmap, tEntity.ulData, i); + ulValue = pl_sb_size(ptScene->sbtMaterialBuffer); + pl_sb_add(ptScene->sbtMaterialBuffer); } - // get actual components - plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tEntity); - plMeshComponent* ptMesh = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MESH, ptObject->tMesh); - plMaterialComponent* ptMaterial = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MATERIAL, ptMesh->tMaterial); + uMaterialIndex = (uint32_t)ulValue; + + plTextureHandle tBaseColorTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_BASE_COLOR_MAP, true, 0); + plTextureHandle tNormalTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_NORMAL_MAP, false, 0); + plTextureHandle tEmissiveTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_EMISSIVE_MAP, true, 0); + plTextureHandle tMetallicRoughnessTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_METAL_ROUGHNESS_MAP, false, 0); + plTextureHandle tOcclusionTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_OCCLUSION_MAP, false, 1); + + int iBaseColorTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tBaseColorTex); + int iNormalTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tNormalTex); + int iEmissiveTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tEmissiveTex); + int iMetallicRoughnessTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tMetallicRoughnessTex); + int iOcclusionTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tOcclusionTex); + + plGPUMaterial tMaterial = { + .fMetallicFactor = ptMaterial->fMetalness, + .fRoughnessFactor = ptMaterial->fRoughness, + .tBaseColorFactor = ptMaterial->tBaseColor, + .tEmissiveFactor = ptMaterial->tEmissiveColor.rgb, + .fAlphaCutoff = ptMaterial->fAlphaCutoff, + .fOcclusionStrength = 1.0f, + .fEmissiveStrength = 1.0f, + .iBaseColorUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_BASE_COLOR_MAP].uUVSet, + .iNormalUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_NORMAL_MAP].uUVSet, + .iEmissiveUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_EMISSIVE_MAP].uUVSet, + .iOcclusionUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_OCCLUSION_MAP].uUVSet, + .iMetallicRoughnessUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_METAL_ROUGHNESS_MAP].uUVSet, + .iBaseColorTexIdx = iBaseColorTexIdx, + .iNormalTexIdx = iNormalTexIdx, + .iEmissiveTexIdx = iEmissiveTexIdx, + .iMetallicRoughnessTexIdx = iMetallicRoughnessTexIdx, + .iOcclusionTexIdx = iOcclusionTexIdx + }; + ptScene->sbtMaterialBuffer[uMaterialIndex] = tMaterial; + pl_hm_insert(ptScene->ptMaterialHashmap, ptMesh->tMaterial.ulData, ulValue); + } - uint32_t uMaterialIndex = UINT32_MAX; + ptScene->sbtNewDrawables[i].uMaterialIndex = uMaterialIndex; - if(pl_hm_has_key(ptScene->ptMaterialHashmap, ptMesh->tMaterial.ulData)) - { - uMaterialIndex = (uint32_t)pl_hm_lookup(ptScene->ptMaterialHashmap, ptMesh->tMaterial.ulData); - } - else - { + // add data to global buffers + if(!bReload) + { + pl__add_drawable_data_to_global_buffer(ptScene, i, ptScene->sbtNewDrawables); + pl__add_drawable_skin_data_to_global_buffer(ptScene, i, ptScene->sbtNewDrawables); + } - uint64_t ulValue = pl_hm_get_free_index(ptScene->ptMaterialHashmap); - if(ulValue == UINT64_MAX) - { - ulValue = pl_sb_size(ptScene->sbtMaterialBuffer); - pl_sb_add(ptScene->sbtMaterialBuffer); - } + int iDataStride = 0; + int iFlagCopy0 = (int)ptMesh->ulVertexStreamMask; + while(iFlagCopy0) + { + iDataStride += iFlagCopy0 & 1; + iFlagCopy0 >>= 1; + } - uMaterialIndex = (uint32_t)ulValue; - - plTextureHandle tBaseColorTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_BASE_COLOR_MAP, true, 0); - plTextureHandle tNormalTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_NORMAL_MAP, false, 0); - plTextureHandle tEmissiveTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_EMISSIVE_MAP, true, 0); - plTextureHandle tMetallicRoughnessTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_METAL_ROUGHNESS_MAP, false, 0); - plTextureHandle tOcclusionTex = pl__create_texture_helper(ptMaterial, PL_TEXTURE_SLOT_OCCLUSION_MAP, false, 1); - - int iBaseColorTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tBaseColorTex); - int iNormalTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tNormalTex); - int iEmissiveTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tEmissiveTex); - int iMetallicRoughnessTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tMetallicRoughnessTex); - int iOcclusionTexIdx = (int)pl__get_bindless_texture_index(uSceneHandle, tOcclusionTex); - - plGPUMaterial tMaterial = { - .fMetallicFactor = ptMaterial->fMetalness, - .fRoughnessFactor = ptMaterial->fRoughness, - .tBaseColorFactor = ptMaterial->tBaseColor, - .tEmissiveFactor = ptMaterial->tEmissiveColor.rgb, - .fAlphaCutoff = ptMaterial->fAlphaCutoff, - .fOcclusionStrength = 1.0f, - .fEmissiveStrength = 1.0f, - .iBaseColorUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_BASE_COLOR_MAP].uUVSet, - .iNormalUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_NORMAL_MAP].uUVSet, - .iEmissiveUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_EMISSIVE_MAP].uUVSet, - .iOcclusionUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_OCCLUSION_MAP].uUVSet, - .iMetallicRoughnessUVSet = (int)ptMaterial->atTextureMaps[PL_TEXTURE_SLOT_METAL_ROUGHNESS_MAP].uUVSet, - .iBaseColorTexIdx = iBaseColorTexIdx, - .iNormalTexIdx = iNormalTexIdx, - .iEmissiveTexIdx = iEmissiveTexIdx, - .iMetallicRoughnessTexIdx = iMetallicRoughnessTexIdx, - .iOcclusionTexIdx = iOcclusionTexIdx - }; - ptScene->sbtMaterialBuffer[uMaterialIndex] = tMaterial; - pl_hm_insert(ptScene->ptMaterialHashmap, ptMesh->tMaterial.ulData, ulValue); - } + int iTextureMappingFlags = 0; + for(uint32_t j = 0; j < PL_TEXTURE_SLOT_COUNT; j++) + { + if((ptMaterial->atTextureMaps[j].acName[0] != 0)) + iTextureMappingFlags |= 1 << j; + } - (sbtNewDrawables[uDrawableBatchIndex])[i].uMaterialIndex = uMaterialIndex; + int iObjectRenderingFlags = iSceneWideRenderingFlags; - // add data to global buffers - if(!bReload) - { - pl__add_drawable_data_to_global_buffer(ptScene, i, (sbtNewDrawables[uDrawableBatchIndex])); - pl__add_drawable_skin_data_to_global_buffer(ptScene, i, (sbtNewDrawables[uDrawableBatchIndex])); - } + if(ptMaterial->tFlags & PL_MATERIAL_FLAG_CAST_RECEIVE_SHADOW) + { + iObjectRenderingFlags |= PL_RENDERING_FLAG_SHADOWS; + } + if(ptMaterial->tFlags & PL_MATERIAL_FLAG_CAST_SHADOW) + { + if(ptScene->sbtNewDrawables[i].tFlags & PL_DRAWABLE_FLAG_FORWARD) + pl_sb_push(ptScene->sbuShadowForwardDrawables, i); + else if(ptScene->sbtNewDrawables[i].tFlags & PL_DRAWABLE_FLAG_DEFERRED) + pl_sb_push(ptScene->sbuShadowDeferredDrawables, i); + } - int iDataStride = 0; - int iFlagCopy0 = (int)ptMesh->ulVertexStreamMask; - while(iFlagCopy0) - { - iDataStride += iFlagCopy0 & 1; - iFlagCopy0 >>= 1; - } + // choose shader variant + int aiConstantData0[] = { + (int)ptMesh->ulVertexStreamMask, + iDataStride, + iTextureMappingFlags, + PL_INFO_MATERIAL_METALLICROUGHNESS, + iObjectRenderingFlags, + pl_sb_capacity(ptScene->sbtDLightData), + pl_sb_capacity(ptScene->sbtPLightData), + pl_sb_capacity(ptScene->sbtSLightData), + pl_sb_size(ptScene->sbtProbeData), + }; - int iTextureMappingFlags = 0; - for(uint32_t j = 0; j < PL_TEXTURE_SLOT_COUNT; j++) - { - if((ptMaterial->atTextureMaps[j].acName[0] != 0)) - iTextureMappingFlags |= 1 << j; - } + if(ptScene->sbtNewDrawables[i].tFlags & PL_DRAWABLE_FLAG_DEFERRED) + { - int iObjectRenderingFlags = iSceneWideRenderingFlags; + plGraphicsState tVariantTemp = { + .ulDepthWriteEnabled = 1, + .ulDepthMode = PL_COMPARE_MODE_GREATER, + .ulCullMode = PL_CULL_MODE_CULL_BACK, + .ulStencilMode = PL_COMPARE_MODE_ALWAYS, + .ulStencilRef = 0xff, + .ulStencilMask = 0xff, + .ulStencilOpFail = PL_STENCIL_OP_KEEP, + .ulStencilOpDepthFail = PL_STENCIL_OP_KEEP, + .ulStencilOpPass = PL_STENCIL_OP_KEEP + }; - if(ptMaterial->tFlags & PL_MATERIAL_FLAG_CAST_RECEIVE_SHADOW) - { - iObjectRenderingFlags |= PL_RENDERING_FLAG_SHADOWS; - } - if(ptMaterial->tFlags & PL_MATERIAL_FLAG_CAST_SHADOW) - { - pl_sb_push(sbuShadowDrawables[uDrawableBatchIndex], i); - } + if(ptMaterial->tFlags & PL_MATERIAL_FLAG_DOUBLE_SIDED) + tVariantTemp.ulCullMode = PL_CULL_MODE_NONE; - // choose shader variant - int aiConstantData0[] = { - (int)ptMesh->ulVertexStreamMask, - iDataStride, - iTextureMappingFlags, - PL_INFO_MATERIAL_METALLICROUGHNESS, - iObjectRenderingFlags, - pl_sb_capacity(ptScene->sbtDLightData), - pl_sb_capacity(ptScene->sbtPLightData), - pl_sb_capacity(ptScene->sbtSLightData) + const plShaderVariant tVariant = { + .pTempConstantData = aiConstantData0, + .tGraphicsState = tVariantTemp }; - plGraphicsState tVariantTemp = atTemplateVariants[uDrawableBatchIndex]; + ptScene->sbtNewDrawables[i].tShader = pl__get_shader_variant(uSceneHandle, gptData->tDeferredShader, &tVariant); + aiConstantData0[4] = gptData->bPunctualLighting ? (PL_RENDERING_FLAG_USE_PUNCTUAL | PL_RENDERING_FLAG_SHADOWS) : 0; + ptScene->sbtNewDrawables[i].tEnvShader = pl__get_shader_variant(uSceneHandle, gptData->tDeferredShader, &tVariant); + } + + else if(ptScene->sbtNewDrawables[i].tFlags & PL_DRAWABLE_FLAG_FORWARD) + { + + plGraphicsState tVariantTemp = { + .ulDepthWriteEnabled = 1, + .ulDepthMode = PL_COMPARE_MODE_GREATER_OR_EQUAL, + .ulCullMode = PL_CULL_MODE_NONE, + .ulStencilMode = PL_COMPARE_MODE_ALWAYS, + .ulStencilRef = 0xff, + .ulStencilMask = 0xff, + .ulStencilOpFail = PL_STENCIL_OP_KEEP, + .ulStencilOpDepthFail = PL_STENCIL_OP_KEEP, + .ulStencilOpPass = PL_STENCIL_OP_KEEP + }; if(ptMaterial->tFlags & PL_MATERIAL_FLAG_DOUBLE_SIDED) tVariantTemp.ulCullMode = PL_CULL_MODE_NONE; @@ -4545,38 +4522,31 @@ pl__refr_process_drawables(uint32_t uSceneHandle, bool bReload) .tGraphicsState = tVariantTemp }; - (sbtNewDrawables[uDrawableBatchIndex])[i].tShader = pl__get_shader_variant(uSceneHandle, atTemplateShaders[uDrawableBatchIndex], &tVariant); + ptScene->sbtNewDrawables[i].tShader = pl__get_shader_variant(uSceneHandle, gptData->tForwardShader, &tVariant); aiConstantData0[4] = gptData->bPunctualLighting ? (PL_RENDERING_FLAG_USE_PUNCTUAL | PL_RENDERING_FLAG_SHADOWS) : 0; - (sbtNewDrawables[uDrawableBatchIndex])[i].tEnvShader = pl__get_shader_variant(uSceneHandle, atTemplateShaders[uDrawableBatchIndex], &tVariant); - - if(uDrawableBatchIndex > 0) - { - const plShaderVariant tShadowVariant = { - .pTempConstantData = aiConstantData0, - .tGraphicsState = { - .ulDepthWriteEnabled = 1, - .ulDepthMode = PL_COMPARE_MODE_GREATER_OR_EQUAL, - .ulCullMode = PL_CULL_MODE_NONE, - .ulWireframe = 0, - .ulStencilMode = PL_COMPARE_MODE_ALWAYS, - .ulStencilRef = 0xff, - .ulStencilMask = 0xff, - .ulStencilOpFail = PL_STENCIL_OP_KEEP, - .ulStencilOpDepthFail = PL_STENCIL_OP_KEEP, - .ulStencilOpPass = PL_STENCIL_OP_KEEP - } - }; - (sbtNewDrawables[uDrawableBatchIndex])[i].tShadowShader = pl__get_shader_variant(uSceneHandle, atTemplateShadowShaders[uDrawableBatchIndex], &tShadowVariant); - } - - pl_sb_push(sbtDrawables[uDrawableBatchIndex], (sbtNewDrawables[uDrawableBatchIndex])[i]); + ptScene->sbtNewDrawables[i].tEnvShader = pl__get_shader_variant(uSceneHandle, gptData->tForwardShader, &tVariant); + + const plShaderVariant tShadowVariant = { + .pTempConstantData = aiConstantData0, + .tGraphicsState = { + .ulDepthWriteEnabled = 1, + .ulDepthMode = PL_COMPARE_MODE_GREATER_OR_EQUAL, + .ulCullMode = PL_CULL_MODE_NONE, + .ulWireframe = 0, + .ulStencilMode = PL_COMPARE_MODE_ALWAYS, + .ulStencilRef = 0xff, + .ulStencilMask = 0xff, + .ulStencilOpFail = PL_STENCIL_OP_KEEP, + .ulStencilOpDepthFail = PL_STENCIL_OP_KEEP, + .ulStencilOpPass = PL_STENCIL_OP_KEEP + } + }; + ptScene->sbtNewDrawables[i].tShadowShader = pl__get_shader_variant(uSceneHandle, gptData->tAlphaShadowShader, &tShadowVariant); } - atHashmaps[uDrawableBatchIndex] = ptHashmap; + + ptScene->sbtNewDrawables[i].uTriangleCount = ptScene->sbtNewDrawables[i].uIndexCount == 0 ? ptScene->sbtNewDrawables[i].uVertexCount / 3 : ptScene->sbtNewDrawables[i].uIndexCount / 3; + ptScene->sbtNewDrawables[i].uStaticVertexOffset = ptScene->sbtNewDrawables[i].uIndexCount == 0 ? ptScene->sbtNewDrawables[i].uVertexOffset : 0; + ptScene->sbtNewDrawables[i].uDynamicVertexOffset = ptScene->sbtNewDrawables[i].uIndexCount == 0 ? 0 : ptScene->sbtNewDrawables[i].uVertexOffset; + pl_sb_push(ptScene->sbtDrawables, ptScene->sbtNewDrawables[i]); } - ptScene->sbtDeferredDrawables = sbtDrawables[0]; - ptScene->sbtForwardDrawables = sbtDrawables[1]; - ptScene->sbuShadowDeferredDrawables = sbuShadowDrawables[0]; - ptScene->sbuShadowForwardDrawables = sbuShadowDrawables[1]; - ptScene->ptDeferredHashmap = atHashmaps[0]; - ptScene->ptForwardHashmap = atHashmaps[1]; } \ No newline at end of file diff --git a/extensions/pl_renderer_internal.h b/extensions/pl_renderer_internal.h index a20179c..6a4bd28 100644 --- a/extensions/pl_renderer_internal.h +++ b/extensions/pl_renderer_internal.h @@ -103,6 +103,16 @@ Index of this file: // [SECTION] internal structs //----------------------------------------------------------------------------- +typedef int plDrawableFlags; + +enum _plDrawableFlags +{ + PL_DRAWABLE_FLAG_NONE = 0, + PL_DRAWABLE_FLAG_FORWARD = 1 << 0, + PL_DRAWABLE_FLAG_DEFERRED = 1 << 1, + PL_DRAWABLE_FLAG_PROBE = 1 << 2 +}; + typedef struct _plShaderVariant { plGraphicsState tGraphicsState; @@ -128,20 +138,36 @@ typedef struct _plSkinData typedef struct _plDrawable { - plEntity tEntity; - uint32_t uDataOffset; - uint32_t uVertexOffset; - uint32_t uVertexCount; - uint32_t uIndexOffset; - uint32_t uIndexCount; - uint32_t uMaterialIndex; - plShaderHandle tShader; - plShaderHandle tEnvShader; - plShaderHandle tShadowShader; - uint32_t uSkinIndex; - bool bCulled; + plDrawableFlags tFlags; + plEntity tEntity; + uint32_t uDataOffset; + uint32_t uVertexOffset; + uint32_t uVertexCount; + uint32_t uIndexOffset; + uint32_t uIndexCount; + uint32_t uMaterialIndex; + plShaderHandle tShader; + plShaderHandle tEnvShader; + plShaderHandle tShadowShader; + uint32_t uSkinIndex; + uint32_t uTriangleCount; + plBufferHandle tIndexBuffer; + uint32_t uStaticVertexOffset; + uint32_t uDynamicVertexOffset; + bool bCulled; } plDrawable; +typedef struct _plGPUProbeData +{ + plVec3 tPosition; + float fRangeSqr; + + uint32_t uLambertianEnvSampler; + uint32_t uGGXEnvSampler; + uint32_t uGGXLUT; + int _unused0[1]; +} plGPUProbeData; + typedef struct _plGPUMaterial { // Metallic Roughness @@ -323,8 +349,9 @@ typedef struct _plRefView plBufferHandle atGlobalBuffers[PL_MAX_FRAMES_IN_FLIGHT]; // submitted drawables - plDrawable* sbtVisibleOpaqueDrawables; - plDrawable* sbtVisibleTransparentDrawables; + uint32_t* sbtVisibleDrawables; + uint32_t* sbtVisibleOpaqueDrawables; + uint32_t* sbtVisibleTransparentDrawables; // drawing api plDrawList3D* pt3DGizmoDrawList; @@ -387,11 +414,11 @@ typedef struct _plRefScene // drawables (per scene, will be culled by views) - plDrawable* sbtNewDeferredDrawables; // unprocessed - plDrawable* sbtNewForwardDrawables; // unprocessed + plDrawable* sbtNewDrawables; // unprocessed + + plDrawable* sbtDrawables; // regular rendering - plDrawable* sbtDeferredDrawables; // regular rendering - plDrawable* sbtForwardDrawables; // regular rendering + uint32_t* sbuProbeDrawables; uint32_t* sbuShadowDeferredDrawables; // shadow rendering (index into regular drawables) uint32_t* sbuShadowForwardDrawables; // shadow rendering (index into regular drawables) @@ -401,8 +428,7 @@ typedef struct _plRefScene plShaderHandle* sbtOutlineDrawablesOldEnvShaders; // entity to drawable hashmaps - plHashMap* ptDeferredHashmap; - plHashMap* ptForwardHashmap; + plHashMap* ptDrawableHashmap; // bindless texture system uint32_t uTextureIndexCount; @@ -426,6 +452,8 @@ typedef struct _plRefScene // environment probes plEnvironmentProbeData* sbtProbeData; + plGPUProbeData* sbtGPUProbeData; + plBufferHandle atGPUProbeDataBuffers[PL_MAX_FRAMES_IN_FLIGHT]; plBufferHandle atFilterWorkingBuffers[7]; } plRefScene; @@ -524,6 +552,7 @@ typedef struct _plRefRendererData plHashMap* ptTextureHashmap; // graphics options + bool bShowProbes; bool bWireframe; bool bReloadSwapchain; bool bReloadMSAA; diff --git a/extensions/pl_ui_widgets.c b/extensions/pl_ui_widgets.c index 2da9fe0..bce5199 100644 --- a/extensions/pl_ui_widgets.c +++ b/extensions/pl_ui_widgets.c @@ -844,6 +844,7 @@ pl_radio_button(const char* pcText, int* piValue, int iButtonValue) plRect tBoundingBox = pl_rect_expand_vec2(&tTextBounding, (plVec2){0.5f * (gptCtx->tStyle.tFramePadding.x + gptCtx->tStyle.tInnerSpacing.x + tWidgetSize.y), 0.0f}); tBoundingBox = pl_rect_move_start_x(&tBoundingBox, tStartPos.x + gptCtx->tStyle.tFramePadding.x); + tBoundingBox.tMax.y = tStartPos.y + tWidgetSize.y; const plRect* ptClipRect = gptDraw->get_clip_rect(gptCtx->ptDrawlist); tBoundingBox = pl_rect_clip_full(&tBoundingBox, ptClipRect); bool bHovered = false; diff --git a/sandbox/app.c b/sandbox/app.c index 7a388c0..cf496ae 100644 --- a/sandbox/app.c +++ b/sandbox/app.c @@ -211,20 +211,27 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plEditorData* ptEditorData) plTransformComponent* ptPLightTransform = gptEcs->add_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, tPointLight); ptPLightTransform->tTranslation = (plVec3){0.0f, 1.497f, 2.0f}; - plEntity tSpotLight = gptEcs->create_spot_light(ptMainComponentLibrary, "spot light", (plVec3){0.0f, 2.0f, 0.0f}, (plVec3){0.0, -1.0f, 0.0f}, &ptLight); - ptLight->uShadowResolution = 1024; - ptLight->fRange = 5.0f; - ptLight->fRadius = 0.025f; - ptLight->fIntensity = 20.0f; - ptLight->tFlags |= PL_LIGHT_FLAG_CAST_SHADOW | PL_LIGHT_FLAG_VISUALIZER; - plTransformComponent* ptSLightTransform = gptEcs->add_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, tSpotLight); - ptSLightTransform->tTranslation = (plVec3){0.0f, 4.0f, 0.0f}; + // plEntity tSpotLight = gptEcs->create_spot_light(ptMainComponentLibrary, "spot light", (plVec3){0.0f, 2.0f, 0.0f}, (plVec3){0.0, -1.0f, 0.0f}, &ptLight); + // ptLight->uShadowResolution = 1024; + // ptLight->fRange = 5.0f; + // ptLight->fRadius = 0.025f; + // ptLight->fIntensity = 20.0f; + // ptLight->tFlags |= PL_LIGHT_FLAG_CAST_SHADOW | PL_LIGHT_FLAG_VISUALIZER; + // plTransformComponent* ptSLightTransform = gptEcs->add_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, tSpotLight); + // ptSLightTransform->tTranslation = (plVec3){0.0f, 4.0f, 0.0f}; plEnvironmentProbeComponent* ptProbe = NULL; - gptEcs->create_environment_probe(ptMainComponentLibrary, "Main Probe", (plVec3){0.0f, 2.0f, 2.0f}, &ptProbe); - ptProbe->fRange = 30.0f; + gptEcs->create_environment_probe(ptMainComponentLibrary, "Main Probe", (plVec3){0.0f, 2.0f, 0.0f}, &ptProbe); + ptProbe->fRange = 10.0f; ptProbe->uResolution = 128; - ptProbe->tFlags = PL_ENVIRONMENT_PROBE_FLAGS_REALTIME; + ptProbe->tFlags = PL_ENVIRONMENT_PROBE_FLAGS_REALTIME | PL_ENVIRONMENT_PROBE_FLAGS_INCLUDE_SKY; + + gptEcs->create_environment_probe(ptMainComponentLibrary, "Probe0", (plVec3){9.0f, 2.0f, 3.0f}, &ptProbe); ptProbe->fRange = 7.0f; + gptEcs->create_environment_probe(ptMainComponentLibrary, "Probe1", (plVec3){-1.274f, 2.0f, 3.0f}, &ptProbe); ptProbe->fRange = 7.0f; + gptEcs->create_environment_probe(ptMainComponentLibrary, "Probe2", (plVec3){-9.1f, 2.0f, 3.0f}, &ptProbe); ptProbe->fRange = 7.0f; + gptEcs->create_environment_probe(ptMainComponentLibrary, "Probe3", (plVec3){8.0f, 2.0f, -3.0f}, &ptProbe); ptProbe->fRange = 7.0f; + gptEcs->create_environment_probe(ptMainComponentLibrary, "Probe4", (plVec3){-1.0f, 2.0f, -3.0f}, &ptProbe); ptProbe->fRange = 7.0f; + gptEcs->create_environment_probe(ptMainComponentLibrary, "Probe5", (plVec3){-9.1f, 2.0f, -3.0f}, &ptProbe); ptProbe->fRange = 7.0f; return ptEditorData; } diff --git a/sandbox/pl_ecs_tools.c b/sandbox/pl_ecs_tools.c index 3902e94..1a55bf6 100644 --- a/sandbox/pl_ecs_tools.c +++ b/sandbox/pl_ecs_tools.c @@ -119,6 +119,16 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, plComponentLibrary* ptLibrary, bo else ptProbeComp->tFlags &= ~PL_ENVIRONMENT_PROBE_FLAGS_REALTIME; } + + bool bIncludeSky = ptProbeComp->tFlags & PL_ENVIRONMENT_PROBE_FLAGS_INCLUDE_SKY; + if(gptUi->checkbox("Include Sky", &bIncludeSky)) + { + if(bIncludeSky) + ptProbeComp->tFlags |= PL_ENVIRONMENT_PROBE_FLAGS_INCLUDE_SKY; + else + ptProbeComp->tFlags &= ~PL_ENVIRONMENT_PROBE_FLAGS_INCLUDE_SKY; + } + if(gptUi->button("Update")) { ptProbeComp->tFlags |= PL_ENVIRONMENT_PROBE_FLAGS_DIRTY; diff --git a/shaders/lighting.frag b/shaders/lighting.frag index 871dcde..cf9fa1c 100644 --- a/shaders/lighting.frag +++ b/shaders/lighting.frag @@ -15,6 +15,7 @@ layout(constant_id = 0) const int iRenderingFlags = 0; layout(constant_id = 1) const int iDirectionLightCount = 0; layout(constant_id = 2) const int iPointLightCount = 0; layout(constant_id = 3) const int iSpotLightCount = 0; +layout(constant_id = 4) const int iProbeCount = 0; //----------------------------------------------------------------------------- // [SECTION] bind group 0 @@ -92,7 +93,12 @@ layout(set = 2, binding = 6) readonly buffer plSShadowData plLightShadowData atData[]; } tSShadowData; -layout(set = 2, binding = 7) uniform sampler tShadowSampler; +layout(set = 2, binding = 7) readonly buffer plProbeData +{ + plEnvironmentProbeData atData[]; +} tProbeData; + +layout(set = 2, binding = 8) uniform sampler tShadowSampler; //----------------------------------------------------------------------------- // [SECTION] dynamic bind group @@ -185,33 +191,33 @@ vec3 BRDF_specularGGX(vec3 f0, vec3 f90, float alphaRoughness, float specularWei return specularWeight * F * Vis * D; } -vec3 getDiffuseLight(vec3 n) +vec3 getDiffuseLight(vec3 n, int iProbeIndex) { // n.z = -n.z; // uncomment if not reverse z // return texture(samplerCube(u_LambertianEnvSampler, tEnvSampler), n).rgb; - return texture(samplerCube(atCubeTextures[nonuniformEXT(tObjectInfo.uLambertianEnvSampler)], tEnvSampler), n).rgb; + return texture(samplerCube(atCubeTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uLambertianEnvSampler)], tEnvSampler), n).rgb; } -vec4 getSpecularSample(vec3 reflection, float lod) +vec4 getSpecularSample(vec3 reflection, float lod, int iProbeIndex) { // reflection.z = -reflection.z; // uncomment if not reverse z // reflection.x = -reflection.x; // uncomment if not reverse z // return textureLod(samplerCube(u_GGXEnvSampler, tEnvSampler), reflection, lod); - return textureLod(samplerCube(atCubeTextures[nonuniformEXT(tObjectInfo.uGGXEnvSampler)], tEnvSampler), reflection, lod); + return textureLod(samplerCube(atCubeTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uGGXEnvSampler)], tEnvSampler), reflection, lod); } -vec3 getIBLRadianceGGX(vec3 n, vec3 v, float roughness, vec3 F0, float specularWeight, int u_MipCount) +vec3 getIBLRadianceGGX(vec3 n, vec3 v, float roughness, vec3 F0, float specularWeight, int u_MipCount, int iProbeIndex) { float lod = roughness * float(u_MipCount - 1); vec3 reflection = normalize(reflect(-v, n)); - vec4 specularSample = getSpecularSample(reflection, lod); + vec4 specularSample = getSpecularSample(reflection, lod, iProbeIndex); float NdotV = clampedDot(n, v); vec2 brdfSamplePoint = clamp(vec2(NdotV, roughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); // vec2 f_ab = texture(sampler2D(u_GGXLUT, tEnvSampler), brdfSamplePoint).rg; - vec2 f_ab = texture(sampler2D(at2DTextures[nonuniformEXT(tObjectInfo.uGGXLUT)], tEnvSampler), brdfSamplePoint).rg; + vec2 f_ab = texture(sampler2D(at2DTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uGGXLUT)], tEnvSampler), brdfSamplePoint).rg; vec3 specularLight = specularSample.rgb; @@ -223,14 +229,14 @@ vec3 getIBLRadianceGGX(vec3 n, vec3 v, float roughness, vec3 F0, float specularW } // specularWeight is introduced with KHR_materials_specular -vec3 getIBLRadianceLambertian(vec3 n, vec3 v, float roughness, vec3 diffuseColor, vec3 F0, float specularWeight) +vec3 getIBLRadianceLambertian(vec3 n, vec3 v, float roughness, vec3 diffuseColor, vec3 F0, float specularWeight, int iProbeIndex) { - vec3 irradiance = getDiffuseLight(n); + vec3 irradiance = getDiffuseLight(n, iProbeIndex); float NdotV = clampedDot(n, v); vec2 brdfSamplePoint = clamp(vec2(NdotV, roughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); // vec2 f_ab = texture(sampler2D(u_GGXLUT, tEnvSampler), brdfSamplePoint).rg; - vec2 f_ab = texture(sampler2D(at2DTextures[nonuniformEXT(tObjectInfo.uGGXLUT)], tEnvSampler), brdfSamplePoint).rg; + vec2 f_ab = texture(sampler2D(at2DTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uGGXLUT)], tEnvSampler), brdfSamplePoint).rg; // see https://bruop.github.io/ibl/#single_scattering_results at Single Scattering Results // Roughness dependent fresnel, from Fdez-Aguera @@ -433,14 +439,30 @@ void main() const float fPerceptualRoughness = AORoughnessMetalnessData.b; float specularWeight = 1.0; vec3 v = normalize(tGlobalInfo.data[tObjectInfo.uGlobalIndex].tCameraPos.xyz - tWorldPosition.xyz); - // int iMips = int(AORoughnessMetalnessData.a); - int iMips = textureQueryLevels(samplerCube(atCubeTextures[nonuniformEXT(tObjectInfo.uGGXEnvSampler)], tEnvSampler)); // Calculate lighting contribution from image based lighting source (IBL) - if(bool(iRenderingFlags & PL_RENDERING_FLAG_USE_IBL)) + if(bool(iRenderingFlags & PL_RENDERING_FLAG_USE_IBL) && iProbeCount > 0) { - f_specular += getIBLRadianceGGX(n, v, fPerceptualRoughness, f0, specularWeight, iMips); - f_diffuse += getIBLRadianceLambertian(n, v, fPerceptualRoughness, c_diff, f0, specularWeight); + int iProbeIndex = 0; + float fCurrentDistance = 10000.0; + for(int i = iProbeCount - 1; i > -1; i--) + { + vec3 tDist = tProbeData.atData[i].tPosition - tWorldPosition.xyz; + tDist = tDist * tDist; + float fDistSqr = tDist.x + tDist.y + tDist.z; + if(fDistSqr <= tProbeData.atData[i].fRangeSqr && fDistSqr < fCurrentDistance) + { + iProbeIndex = i; + fCurrentDistance = fDistSqr; + } + } + + if(iProbeIndex > -1) + { + int iMips = textureQueryLevels(samplerCube(atCubeTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uGGXEnvSampler)], tEnvSampler)); + f_specular += getIBLRadianceGGX(n, v, fPerceptualRoughness, f0, specularWeight, iMips, iProbeIndex); + f_diffuse += getIBLRadianceLambertian(n, v, fPerceptualRoughness, c_diff, f0, specularWeight, iProbeIndex); + } } // punctual stuff diff --git a/shaders/lights.glsl b/shaders/lights.glsl index addeea3..03de388 100644 --- a/shaders/lights.glsl +++ b/shaders/lights.glsl @@ -28,6 +28,15 @@ struct plLightShadowData float fYOffset; }; +struct plEnvironmentProbeData +{ + vec3 tPosition; + float fRangeSqr; + uint uLambertianEnvSampler; + uint uGGXEnvSampler; + uint uGGXLUT; +}; + float getRangeAttenuation(float range2, float dist2) { diff --git a/shaders/transparent.frag b/shaders/transparent.frag index 4cfacd9..0fc1c21 100644 --- a/shaders/transparent.frag +++ b/shaders/transparent.frag @@ -19,6 +19,7 @@ layout(constant_id = 4) const int iRenderingFlags = 0; layout(constant_id = 5) const int iDirectionLightCount = 0; layout(constant_id = 6) const int iPointLightCount = 0; layout(constant_id = 7) const int iSpotLightCount = 0; +layout(constant_id = 8) const int iProbeCount = 0; //----------------------------------------------------------------------------- // [SECTION] bind group 0 @@ -88,7 +89,12 @@ layout(set = 1, binding = 6) readonly buffer plSShadowData plLightShadowData atData[]; } tSShadowData; -layout(set = 1, binding = 7) uniform sampler tShadowSampler; +layout(set = 1, binding = 7) readonly buffer plProbeData +{ + plEnvironmentProbeData atData[]; +} tProbeData; + +layout(set = 1, binding = 8) uniform sampler tShadowSampler; //----------------------------------------------------------------------------- // [SECTION] dynamic bind group @@ -337,29 +343,29 @@ vec3 BRDF_specularGGX(vec3 f0, vec3 f90, float alphaRoughness, float specularWei return specularWeight * F * Vis * D; } -vec3 getDiffuseLight(vec3 n) +vec3 getDiffuseLight(vec3 n, int iProbeIndex) { // n.z = -n.z; uncomment if not reverse z - return texture(samplerCube(atCubeTextures[nonuniformEXT(tObjectInfo.uLambertianEnvSampler)], tEnvSampler), n).rgb; + return texture(samplerCube(atCubeTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uLambertianEnvSampler)], tEnvSampler), n).rgb; } -vec4 getSpecularSample(vec3 reflection, float lod) +vec4 getSpecularSample(vec3 reflection, float lod, int iProbeIndex) { // reflection.z = -reflection.z; uncomment if not reverse z // return textureLod(u_GGXEnvSampler, u_EnvRotation * reflection, lod) * u_EnvIntensity; - return textureLod(samplerCube(atCubeTextures[nonuniformEXT(tObjectInfo.uGGXEnvSampler)], tEnvSampler), reflection, lod); + return textureLod(samplerCube(atCubeTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uGGXEnvSampler)], tEnvSampler), reflection, lod); } -vec3 getIBLRadianceGGX(vec3 n, vec3 v, float roughness, vec3 F0, float specularWeight, int u_MipCount) +vec3 getIBLRadianceGGX(vec3 n, vec3 v, float roughness, vec3 F0, float specularWeight, int u_MipCount, int iProbeIndex) { float NdotV = clampedDot(n, v); float lod = roughness * float(u_MipCount - 1); vec3 reflection = normalize(reflect(-v, n)); vec2 brdfSamplePoint = clamp(vec2(NdotV, roughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); - vec2 f_ab = texture(sampler2D(at2DTextures[nonuniformEXT(tObjectInfo.uGGXLUT)], tEnvSampler), brdfSamplePoint).rg; - vec4 specularSample = getSpecularSample(reflection, lod); + vec2 f_ab = texture(sampler2D(at2DTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uGGXLUT)], tEnvSampler), brdfSamplePoint).rg; + vec4 specularSample = getSpecularSample(reflection, lod, iProbeIndex); vec3 specularLight = specularSample.rgb; @@ -374,13 +380,13 @@ vec3 getIBLRadianceGGX(vec3 n, vec3 v, float roughness, vec3 F0, float specularW // specularWeight is introduced with KHR_materials_specular -vec3 getIBLRadianceLambertian(vec3 n, vec3 v, float roughness, vec3 diffuseColor, vec3 F0, float specularWeight) +vec3 getIBLRadianceLambertian(vec3 n, vec3 v, float roughness, vec3 diffuseColor, vec3 F0, float specularWeight, int iProbeIndex) { float NdotV = clampedDot(n, v); vec2 brdfSamplePoint = clamp(vec2(NdotV, roughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); - vec2 f_ab = texture(sampler2D(at2DTextures[nonuniformEXT(tObjectInfo.uGGXLUT)], tEnvSampler), brdfSamplePoint).rg; + vec2 f_ab = texture(sampler2D(at2DTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uGGXLUT)], tEnvSampler), brdfSamplePoint).rg; - vec3 irradiance = getDiffuseLight(n); + vec3 irradiance = getDiffuseLight(n, iProbeIndex); // see https://bruop.github.io/ibl/#single_scattering_results at Single Scattering Results // Roughness dependent fresnel, from Fdez-Aguera @@ -577,11 +583,28 @@ void main() vec3 f_diffuse = vec3(0.0); // Calculate lighting contribution from image based lighting source (IBL) - if(bool(iRenderingFlags & PL_RENDERING_FLAG_USE_IBL)) + if(bool(iRenderingFlags & PL_RENDERING_FLAG_USE_IBL) && iProbeCount > 0) { - int iMips = textureQueryLevels(samplerCube(atCubeTextures[nonuniformEXT(tObjectInfo.uGGXEnvSampler)], tEnvSampler)); - f_specular += getIBLRadianceGGX(n, v, materialInfo.perceptualRoughness, materialInfo.f0, specularWeight, iMips); - f_diffuse += getIBLRadianceLambertian(n, v, materialInfo.perceptualRoughness, materialInfo.c_diff, materialInfo.f0, specularWeight); + int iProbeIndex = 0; + float fCurrentDistance = 10000.0; + for(int i = iProbeCount - 1; i > -1; i--) + { + vec3 tDist = tProbeData.atData[i].tPosition - tShaderIn.tPosition.xyz; + tDist = tDist * tDist; + float fDistSqr = tDist.x + tDist.y + tDist.z; + if(fDistSqr <= tProbeData.atData[i].fRangeSqr && fDistSqr < fCurrentDistance) + { + iProbeIndex = i; + fCurrentDistance = fDistSqr; + } + } + + if(iProbeIndex > -1) + { + int iMips = textureQueryLevels(samplerCube(atCubeTextures[nonuniformEXT(tProbeData.atData[iProbeIndex].uGGXEnvSampler)], tEnvSampler)); + f_specular += getIBLRadianceGGX(n, v, materialInfo.perceptualRoughness, materialInfo.f0, specularWeight, iMips, iProbeIndex); + f_diffuse += getIBLRadianceLambertian(n, v, materialInfo.perceptualRoughness, materialInfo.c_diff, materialInfo.f0, specularWeight, iProbeIndex); + } } // punctual stuff