0
0
Fork 0

me-main #1

Merged
Nate Rupsis merged 123 commits from me-main into main 2023-02-13 18:39:11 +01:00
4 changed files with 52 additions and 52 deletions
Showing only changes of commit 5f842ef336 - Show all commits

View File

@ -631,7 +631,7 @@ struct LightData {
float2 spot_size_inv;
/** Spot angle tangent. */
float spot_tan;
/** Reuse for directionnal lod bias. */
/** Reuse for directional LOD bias. */
#define _clipmap_lod_bias spot_tan
/** Power depending on shader type. */
float diffuse_power;
@ -643,12 +643,12 @@ struct LightData {
/** Directional : Near clip distance. Float stored as int for atomic operations. */
int clip_near;
int clip_far;
/** Directional : Clip-map lod range to avoid sampling outside of valid range. */
/** Directional : Clip-map LOD range to avoid sampling outside of valid range. */
int clipmap_lod_min;
int clipmap_lod_max;
/** Index of the first tile-map. */
int tilemap_index;
/** Directional : Offset of the lod min in lod min tile units. */
/** Directional : Offset of the LOD min in LOD min tile units. */
int2 clipmap_base_offset;
/** Punctual & Directional : Normal matrix packed for automatic bias. */
float2 normal_mat_packed;
@ -758,7 +758,7 @@ struct ShadowTileData {
uint2 page;
/** Page index inside pages_cached_buf. Only valid if `is_cached` is true. */
uint cache_index;
/** Lod pointed to LOD 0 tile page. (cubemap only) */
/** LOD pointed to LOD 0 tile page. (cube-map only). */
uint lod;
/** If the tile is needed for rendering. */
bool is_used;

View File

@ -137,7 +137,7 @@ void ShadowTileMap::debug_draw() const
ShadowTileMapPool::ShadowTileMapPool()
{
free_indices.reserve(SHADOW_MAX_TILEMAP);
/* Reverse order to help debugging (first allocated tilemap will get 0). */
/* Reverse order to help debugging (first allocated tile-map will get 0). */
for (int i = SHADOW_MAX_TILEMAP - 1; i >= 0; i--) {
free_indices.append(i * SHADOW_TILEDATA_PER_TILEMAP);
}
@ -154,7 +154,7 @@ ShadowTileMapPool::ShadowTileMapPool()
ShadowTileMap *ShadowTileMapPool::acquire()
{
if (free_indices.is_empty()) {
/* Grow the tilemap buffer. See `end_sync`. */
/* Grow the tile-map buffer. See `end_sync`. */
for (auto i : IndexRange(free_indices.size(), SHADOW_MAX_TILEMAP)) {
free_indices.append(i * SHADOW_TILEDATA_PER_TILEMAP);
}
@ -180,7 +180,7 @@ void ShadowTileMapPool::end_sync(ShadowModule &module)
tiles_data.resize(needed_tilemap_capacity * SHADOW_TILEDATA_PER_TILEMAP);
tilemaps_clip.resize(needed_tilemap_capacity);
/* We reallocated the tile-map buffer, discarding all the data it contained.
* We need to re-init the page heaps. */
* We need to re-initialize the page heaps. */
module.do_full_update = true;
}
@ -191,8 +191,8 @@ void ShadowTileMapPool::end_sync(ShadowModule &module)
Span<uint> newly_unused_indices = free_indices.as_span().slice(last_free_len,
newly_unused_count);
for (uint index : newly_unused_indices) {
/* Push a dummy tilemap to a unused tilemap buffer. It is then processed through the some of
* the setup steps to release the pages. */
/* Push a dummy tile-map to a unused tile-map buffer. It is then processed through the some
* of the setup steps to release the pages. */
ShadowTileMapData tilemap_data = {};
tilemap_data.tiles_index = index;
tilemap_data.clip_data_index = 0;
@ -261,7 +261,7 @@ void ShadowPunctual::end_sync(Light &light, float lod_bias)
obmat_tmp[0][3] = obmat_tmp[1][3] = obmat_tmp[2][3] = 0.0f;
obmat_tmp[3][3] = 1.0f;
/* Acquire missing tilemaps. */
/* Acquire missing tile-maps. */
while (tilemaps_.size() < tilemaps_needed_) {
tilemaps_.append(tilemap_pool.acquire());
}
@ -311,23 +311,23 @@ void ShadowPunctual::end_sync(Light &light, float lod_bias)
/* -------------------------------------------------------------------- */
/** \name Directional Shadow Maps
*
* In order to inprove shadow map density, we switch between two tilemap distribution mode.
* One is beter suited for large FOV (clipmap), the other for really small FOV or Orthographic
* In order to improve shadow map density, we switch between two tile-map distribution mode.
* One is beater suited for large FOV (clip-map), the other for really small FOV or Orthographic
* projections (cascade).
*
* Clipmap distribution centers a number of log2 sized tilemaps around the view position.
* Clip-map distribution centers a number of log2 sized tile-maps around the view position.
* https://developer.nvidia.com/gpugems/gpugems2/part-i-geometric-complexity/chapter-2-terrain-rendering-using-gpu-based-geometry
*
* Cascade distribution puts tilemaps along the frustum projection to the light space.
* Cascade distribution puts tile-maps along the frustum projection to the light space.
* https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-10-parallel-split-shadow-maps-programmable-gpus
*
* We choose to distribute cascades linearly to acheive uniform density and simplify lookup.
* Using clipmap instead of cascades for perspective view also allows for better caching.
* We choose to distribute cascades linearly to achieve uniform density and simplify lookup.
* Using clip-map instead of cascades for perspective view also allows for better caching.
* \{ */
eShadowProjectionType ShadowDirectional::directional_distribution_type_get(const Camera &camera)
{
/* TODO(fclem): Enable the cascade projection if the fov is tiny in perspective mode. */
/* TODO(fclem): Enable the cascade projection if the FOV is tiny in perspective mode. */
return camera.is_perspective() ? SHADOW_PROJECTION_CLIPMAP : SHADOW_PROJECTION_CASCADE;
}
@ -347,24 +347,24 @@ void ShadowDirectional::cascade_tilemaps_distribution_near_far_points(const Came
float3x3(object_mat_.view<3, 3>());
}
/* \note All tilemaps are meant to have the same LOD but we still return a range starting at the
/* \note All tile-maps are meant to have the same LOD but we still return a range starting at the
* unique LOD. */
IndexRange ShadowDirectional::cascade_level_range(const Camera &camera, float lod_bias)
{
using namespace blender::math;
/* 16 is arbitrary. To avoid too much tilemap per directional lights. */
/* 16 is arbitrary. To avoid too much tile-map per directional lights. */
const int max_tilemap_per_shadows = 16;
const CameraData &cam_data = camera.data_get();
float3 near_point, far_point;
cascade_tilemaps_distribution_near_far_points(camera, near_point, far_point);
/* This gives the maximum resolution in depth we can have with a fixed set of tilemaps. Gives
/* This gives the maximum resolution in depth we can have with a fixed set of tile-maps. Gives
* the best results when view direction is orthogonal to the light direction. */
float depth_range_in_shadow_space = distance(far_point.xy(), near_point.xy());
float min_depth_tilemap_size = 2 * (depth_range_in_shadow_space / max_tilemap_per_shadows);
/* This allow coverage of the whole view with a single tilemap if camera forward is colinear
/* This allow coverage of the whole view with a single tile-map if camera forward is colinear
* with the light direction. */
float min_diagonal_tilemap_size = cam_data.screen_diagonal_length;
@ -373,28 +373,28 @@ IndexRange ShadowDirectional::cascade_level_range(const Camera &camera, float lo
min_diagonal_tilemap_size *= cam_data.clip_far / cam_data.clip_near;
}
/* Allow better tilemap usage without missing pages near end of view. */
/* Allow better tile-map usage without missing pages near end of view. */
lod_bias += 0.5f;
/* Level of detail (or size) of every tilemaps of this light. */
/* Level of detail (or size) of every tile-maps of this light. */
int lod_level = ceil(log2(max_ff(min_depth_tilemap_size, min_diagonal_tilemap_size)) + lod_bias);
/* Tilemaps "rotate" around the first one so their effective range is only half their size. */
/* Tile-maps "rotate" around the first one so their effective range is only half their size. */
float per_tilemap_coverage = ShadowDirectional::coverage_get(lod_level) * 0.5f;
/* Number of tilemaps needed to cover the whole view. */
/* Number of tile-maps needed to cover the whole view. */
/* Note: floor + 0.5 to avoid 0 when parallel. */
int tilemap_len = ceil(0.5f + depth_range_in_shadow_space / per_tilemap_coverage);
return IndexRange(lod_level, tilemap_len);
}
/**
* Distribute tilemaps in a linear pattern along camera forward vector instead of a clipmap
* Distribute tile-maps in a linear pattern along camera forward vector instead of a clipmap
* centered on camera position.
*/
void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera &camera)
{
using namespace blender::math;
/* All tilemaps use the first level size. */
/* All tile-maps use the first level size. */
float half_size = ShadowDirectional::coverage_get(levels_range.first()) / 2.0f;
float tile_size = ShadowDirectional::tile_size_get(levels_range.first());
@ -407,14 +407,14 @@ void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera
/* Offset for smooth level transitions. */
light.object_mat.location() = near_point;
/* Offset in tiles from the origin to the center of the first tilemaps. */
/* Offset in tiles from the origin to the center of the first tile-maps. */
int2 origin_offset = int2(round(float2(near_point) / tile_size));
/* Offset in tiles between the first andlod the last tilemaps. */
/* Offset in tiles between the first andlod the last tile-maps. */
int2 offset_vector = int2(round(farthest_tilemap_center / tile_size));
light.clipmap_base_offset = (offset_vector * (1 << 16)) / max_ii(levels_range.size() - 1, 1);
/* \note: cascade_level_range starts the range at the unique LOD to apply to all tilemaps. */
/* \note: cascade_level_range starts the range at the unique LOD to apply to all tile-maps. */
int level = levels_range.first();
for (int i : IndexRange(levels_range.size())) {
ShadowTileMap *tilemap = tilemaps_[i];
@ -433,8 +433,8 @@ void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera
light.type = LIGHT_SUN_ORTHO;
/* Not really clipmaps, but this is in order to make light_tilemap_max_get() work and determine
* the scalling. */
/* Not really clip-maps, but this is in order to make #light_tilemap_max_get() work and determine
* the scaling. */
light.clipmap_lod_min = levels_range.first();
light.clipmap_lod_max = levels_range.last();
@ -505,7 +505,7 @@ void ShadowDirectional::clipmap_tilemaps_distribution(Light &light,
for (int lod : IndexRange(levels_range.size() - 1)) {
/* Since offset can only differ by one tile from the higher level, we can compress that as a
* single integer where one bit contains offset between 2 levels. Then a single bit shift in
* the shader gives the number of tile to offset in the given tilemap space. However we need
* the shader gives the number of tile to offset in the given tile-map space. However we need
* also the sign of the offset for each level offset. To this end, we split the negative
* offsets to a separate int.
* Recovering the offset with: (pos_offset >> lod) - (neg_offset >> lod). */
@ -583,7 +583,7 @@ void ShadowDirectional::end_sync(Light &light, const Camera &camera, float lod_b
clipmap_level_range(camera);
if (levels_range != levels_new) {
/* Acquire missing tilemaps. */
/* Acquire missing tile-maps. */
IndexRange isect_range = levels_new.intersect(levels_range);
int64_t before_range = isect_range.start() - levels_new.start();
int64_t after_range = levels_new.one_after_last() - isect_range.one_after_last();
@ -666,7 +666,7 @@ void ShadowModule::init()
inst_.info = "Error: Could not allocate shadow atlas. Most likely out of GPU memory.";
}
/* Read end of the swapchain to avoid stall. */
/* Read end of the swap-chain to avoid stall. */
{
if (inst_.sampling.finished_viewport()) {
/* Swap enough to read the last one. */
@ -769,7 +769,7 @@ void ShadowModule::sync_object(const ObjectHandle &handle,
void ShadowModule::end_sync()
{
/* Delete unused shadows first to release tilemaps that could be reused for new lights. */
/* Delete unused shadows first to release tile-maps that could be reused for new lights. */
for (Light &light : inst_.lights.light_map_.values()) {
if (!light.used || !enabled_) {
light.shadow_discard_safe(*this);
@ -782,7 +782,7 @@ void ShadowModule::end_sync()
}
}
/* Allocate new tilemaps and fill shadow data of the lights. */
/* Allocate new tile-maps and fill shadow data of the lights. */
tilemap_pool.tilemaps_data.clear();
for (Light &light : inst_.lights.light_map_.values()) {
if (light.directional != nullptr) {
@ -831,7 +831,7 @@ void ShadowModule::end_sync()
/* Clear tiles to not reference any page. */
tilemap_pool.tiles_data.clear_to_zero();
/* Clear tilemap clip buffer. */
/* Clear tile-map clip buffer. */
union {
ShadowTileMapClip clip;
int4 i;
@ -877,7 +877,7 @@ void ShadowModule::end_sync()
sub.barrier(GPU_BARRIER_SHADER_STORAGE);
}
{
/** Clear usage bits. Tag update from the tilemap for sun shadow clip-maps shifting. */
/** Clear usage bits. Tag update from the tile-map for sun shadow clip-maps shifting. */
PassSimple::Sub &sub = pass.sub("Init");
sub.shader_set(inst_.shaders.static_shader_get(SHADOW_TILEMAP_INIT));
sub.bind_ssbo("tilemaps_buf", tilemap_pool.tilemaps_data);
@ -1120,15 +1120,15 @@ void ShadowModule::set_view(View &view)
tile_update_remains = false;
}
else {
/* This provoke a GPU/CPU sync. Avoid it if we are sure that all tilemaps will be rendered in
* a single iteration. */
/* This provoke a GPU/CPU sync. Avoid it if we are sure that all tile-maps will be rendered
* in a single iteration. */
bool enough_tilemap_for_single_iteration = tilemap_pool.tilemaps_data.size() <=
SHADOW_VIEW_MAX;
if (enough_tilemap_for_single_iteration) {
tile_update_remains = false;
}
else {
/* Readback and check if there is still tilemap to update. */
/* Read back and check if there is still tile-map to update. */
tile_update_remains = false;
statistics_buf_.current().read();
ShadowStatistics stats = statistics_buf_.current();

View File

@ -123,7 +123,7 @@ struct ShadowTileMapPool {
Vector<uint> free_indices;
/** Pool containing shadow tile structure on CPU. */
Pool<ShadowTileMap> tilemap_pool;
/** Sorted descriptions for each tilemap in the pool. Updated each frame. */
/** Sorted descriptions for each tile-map in the pool. Updated each frame. */
ShadowTileMapDataBuf tilemaps_data = {"tilemaps_data"};
/** Previously used tile-maps that needs to release their tiles/pages. Updated each frame. */
ShadowTileMapDataBuf tilemaps_unused = {"tilemaps_unused"};
@ -190,7 +190,7 @@ class ShadowModule {
Map<ObjectKey, ShadowObject> objects_;
/* -------------------------------------------------------------------- */
/** \name Tilemap Management
/** \name Tile-map Management
* \{ */
PassSimple tilemap_setup_ps_ = {"TilemapSetup"};
@ -214,7 +214,7 @@ class ShadowModule {
StorageArrayBuffer<uint, SHADOW_MAX_PAGE> clear_page_buf_ = {"clear_page_buf"};
int3 dispatch_depth_scan_size_;
/* Ratio between tilemap pixel world "radius" and film pixel world "radius". */
/* Ratio between tile-map pixel world "radius" and film pixel world "radius". */
float tilemap_projection_ratio_;
/* Statistics that are read back to CPU after a few frame (to avoid stall). */
@ -230,7 +230,7 @@ class ShadowModule {
/** Atlas containing all physical pages. */
Texture atlas_tx_ = {"shadow_atlas_tx_"};
/** Pool of unallocated pages waiting to be assigned to specific tiles in the tilemap atlas. */
/** Pool of unallocated pages waiting to be assigned to specific tiles in the tile-map atlas. */
ShadowPageHeapBuf pages_free_data_ = {"PagesFreeBuf"};
/** Pool of cached tiles waiting to be reused. */
ShadowPageCacheBuf pages_cached_data_ = {"PagesCachedBuf"};
@ -259,7 +259,7 @@ class ShadowModule {
64,
nullptr,
SHADOW_TILEMAP_LOD + 1};
/** An empty frame-buffer (no attachment) the size of a whole tilemap. */
/** An empty frame-buffer (no attachment) the size of a whole tile-map. */
Framebuffer render_fb_;
/** \} */
@ -416,7 +416,7 @@ class ShadowDirectional : public NonCopyable, NonMovable {
*/
void end_sync(Light &light, const Camera &camera, float lod_bias);
/* Return coverage of the whole tilemap in world unit. */
/* Return coverage of the whole tile-map in world unit. */
static float coverage_get(int lvl)
{
/* This function should be kept in sync with shadow_directional_level(). */
@ -424,7 +424,7 @@ class ShadowDirectional : public NonCopyable, NonMovable {
return exp2(lvl);
}
/* Return coverage of a single tile for a tilemap of this LOD in world unit. */
/* Return coverage of a single tile for a tile-map of this LOD in world unit. */
static float tile_size_get(int lvl)
{
return coverage_get(lvl) / SHADOW_TILEMAP_RES;
@ -441,8 +441,8 @@ class ShadowDirectional : public NonCopyable, NonMovable {
float3 &near_point,
float3 &far_point);
/* Choose between clipmap and cascade distribution of shadowmap precision depending on the camera
* projection type and bounds. */
/* Choose between clip-map and cascade distribution of shadow-map precision depending on the
* camera projection type and bounds. */
static eShadowProjectionType directional_distribution_type_get(const Camera &camera);
};

View File

@ -470,7 +470,7 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
const int div = boundary_distance / radius;
const float mod = fmodf(boundary_distance, radius);
falloff_distance = div % 2 == 0 ? mod : radius - mod;
/* Inverts the faloff in the intervals 1 2 5 6 9 10 ... */
/* Inverts the falloff in the intervals 1 2 5 6 9 10 ... etc. */
if (((div - 1) & 2) == 0) {
direction = -1.0f;
}