{"id":21497321,"url":"https://github.com/jazzfool/parkbox2","last_synced_at":"2025-03-17T12:25:35.550Z","repository":{"id":137122423,"uuid":"372356535","full_name":"jazzfool/parkbox2","owner":"jazzfool","description":null,"archived":false,"fork":false,"pushed_at":"2022-12-20T05:58:02.000Z","size":31032,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-23T22:14:01.685Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jazzfool.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-31T02:02:31.000Z","updated_at":"2022-12-20T05:58:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"e338c4cc-1bab-4b74-ab1b-0e9593aaa5dc","html_url":"https://github.com/jazzfool/parkbox2","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzfool%2Fparkbox2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzfool%2Fparkbox2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzfool%2Fparkbox2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazzfool%2Fparkbox2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jazzfool","download_url":"https://codeload.github.com/jazzfool/parkbox2/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244031761,"owners_count":20386658,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-23T16:23:12.636Z","updated_at":"2025-03-17T12:25:35.518Z","avatar_url":"https://github.com/jazzfool.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Parkbox2\n\nReal-time plant growth simulation paired with a Vulkan rendering engine specialized for dense foliage.\n\nPBX2 leverages several modern GPU features and techniques to achieve high performance:\n- Instanced rendering\n- Indirect GPU-driven rendering\n- Multi-draw\n- Bindless rendering\n\nAll these rendering techniques reduce overhead for:\n- PBR rendering (with IBL)\n- Ground-truth AO\n- Temporal soft shadows (no PCF, PCSS, or VSMs, etc).\n\n## Graphics\n\nThe PBR rendering is primarily based on Filament.\n\nGround-truth AO is implemented based on the original paper.\n\nTemporal soft shadows are a niche shadow filtering technique. I only know of one other renderer which does this; Blender Eevee.\nThey are still a quite performant solution to shadow filtering as they give you PCSS-like contact hardening whilst only requring a single sample from the shadow map.\nThe temporal accumulation currently only reprojects UV and rejects based on depth. Motion vectors are not used (yet).\n\n## Temporal shadows\n\n\u003cimg src=\"res/screen1.png\" alt=\"shadow screenshot\" width=\"400\"/\u003e\n\nTraditional techniques for shadow rendering involve PCF filtering to soften edges of shadows uniformly, or the more expensive PCSS filtering in order to achieve a \"soft-shadows\" look where shadows harden at contact and are softened more further away from the shadow caster. However, a much simpler approach which can be integrated with existing shadow map implementations with relative ease is temporal reprojecton of the shadows in screen space, with each frame jittering the shadow view matrix by a small random amount (the range of the random distribution gives softer/harder shadows). This shadow map in screen space can be averaged with the previous N frames to give the softness effect.\n\nStarting with the shadow map (in this case a cascaded shadow map):\n\n\u003cimg src=\"res/screen2.png\" alt=\"shadow map\" width=\"300\"/\u003e\n\nThis can be sampled as normal, however, taking the previous N frames average (take this as a rolling average, as in it is stored in a single texture):\n\n\u003cimg src=\"res/screen3.png\" alt=\"previous screen shadows\" width=\"300\"/\u003e\n\nAdding the shadow samples **with a given coefficient**:\n\n\u003cimg src=\"res/screen4.png\" alt=\"previous screen shadows\" width=\"300\"/\u003e\n\nGives the final screen-space shadow map. This is ready to use in subsequent passes as it can simply be sampled with fragment coordinates.\n\nThe primary coefficient in this implementation is 0.05, however a secondary coefficient is used for dithering by a Bayer matrix, which improves the quality of the temporal accumulation at a very low cost. The accumulated shadow texture is considered an exponential moving average of the shadow samples:\n\n$$\ns_n = (1 - \\alpha) s_{n-1} + \\alpha x\n$$\n\nThe bulk of this implementation can be seen in res/shaders/shadow_accum.fs.\n\nAn alternative is to perform the temporal reprojection in shadow space - however, \"regular\" shadow maps won't work well for this. Instead, this would require the use of variance shadow maps or moment shadow maps, which can be convoluted in shadow map space. Effective application of this would reduce the motion artifacts present in this project's implementation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazzfool%2Fparkbox2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjazzfool%2Fparkbox2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazzfool%2Fparkbox2/lists"}