Skip to content

Commit 9410a47

Browse files
committed
feat: add grid renderer
1 parent ffa3150 commit 9410a47

File tree

11 files changed

+240
-1
lines changed

11 files changed

+240
-1
lines changed

docs/features.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Reference Renderer:
9797
* Tonemapping
9898
* gltf model loading
9999
* stl model loading
100+
* grid renderer
100101

101102
Wishlist:
102103
* Morph target animation (with sparse accessor)

editor/app.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ typedef struct _plAppData
149149
bool bContinuousBVH;
150150
bool bFrustumCulling;
151151
bool bShowSkybox;
152+
bool bShowGrid;
152153
bool bShowBVH;
153154
bool bEditorAttached;
154155
bool bShowEntityWindow;
@@ -693,6 +694,9 @@ pl_app_update(plAppData* ptAppData)
693694
if(ptAppData->bShowBVH)
694695
gptRenderer->debug_draw_bvh(ptAppData->ptView);
695696

697+
if(ptAppData->bShowGrid)
698+
gptRenderer->show_grid(ptAppData->ptView);
699+
696700
// render scene
697701
gptRenderer->prepare_scene(ptAppData->ptScene);
698702
gptRenderer->prepare_view(ptAppData->ptView, ptCamera);
@@ -781,7 +785,6 @@ pl__show_editor_window(plAppData* ptAppData)
781785
gptUI->checkbox("Editor Attached", &ptAppData->bEditorAttached);
782786
gptUI->checkbox("Show Debug Lights", &ptAppData->bShowDebugLights);
783787
gptUI->checkbox("Show Bounding Boxes", &ptAppData->bDrawAllBoundingBoxes);
784-
gptUI->checkbox("Show Skybox", &ptAppData->bShowSkybox);
785788

786789
gptUI->vertical_spacing();
787790

@@ -871,6 +874,8 @@ pl__show_editor_window(plAppData* ptAppData)
871874

872875
gptUI->checkbox("Show Origin", &ptRuntimeOptions->bShowOrigin);
873876
gptUI->checkbox("Show BVH", &ptAppData->bShowBVH);
877+
gptUI->checkbox("Show Skybox", &ptAppData->bShowSkybox);
878+
gptUI->checkbox("Show Grid", &ptAppData->bShowGrid);
874879

875880
if(gptUI->checkbox("Wireframe", &ptRuntimeOptions->bWireframe)) bReloadShaders = true;
876881
if(gptUI->checkbox("MultiViewport Shadows", &ptRuntimeOptions->bMultiViewportShadows)) bReloadShaders = true;

editor/editor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,9 @@ pl_app_update(plAppData* ptAppData)
528528
if(ptAppData->bShowSkybox)
529529
gptRenderer->show_skybox(ptAppData->ptView);
530530

531+
if(ptAppData->bShowGrid)
532+
gptRenderer->show_grid(ptAppData->ptView);
533+
531534
if(ptAppData->bShowBVH)
532535
gptRenderer->debug_draw_bvh(ptAppData->ptView);
533536

@@ -1065,6 +1068,7 @@ pl__show_editor_window(plAppData* ptAppData)
10651068
ImGui::Checkbox("Show Origin", &ptRuntimeOptions->bShowOrigin);
10661069
ImGui::Checkbox("Show BVH", &ptAppData->bShowBVH);
10671070
ImGui::Checkbox("Show Skybox", &ptAppData->bShowSkybox);
1071+
ImGui::Checkbox("Show Grid", &ptAppData->bShowGrid);
10681072
if(ImGui::Checkbox("Wireframe", &ptRuntimeOptions->bWireframe)) bReloadShaders = true;
10691073
if(ImGui::Checkbox("MultiViewport Shadows", &ptRuntimeOptions->bMultiViewportShadows)) bReloadShaders = true;
10701074
if(ImGui::Checkbox("Image Based Lighting", &ptRuntimeOptions->bImageBasedLighting)) bReloadShaders = true;

editor/editor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ typedef struct _plAppData
178178
bool bShowImGuiDemo;
179179
bool bContinuousBVH;
180180
bool bShowSkybox;
181+
bool bShowGrid;
181182
bool bShowPlotDemo;
182183
bool bShowUiDemo;
183184
bool bShowUiDebug;

extensions/pl_renderer_ext.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,11 @@ pl_renderer_initialize(plRendererSettings tSettings)
264264
gptData->tRuntimeOptions.fSaturation = 1.0f;
265265
gptData->tRuntimeOptions.tTonemapMode = PL_TONEMAP_MODE_SIMPLE;
266266

267+
gptData->tRuntimeOptions.fGridCellSize = 0.025f;
268+
gptData->tRuntimeOptions.fGridMinPixelsBetweenCells = 2.0f;
269+
gptData->tRuntimeOptions.tGridColorThin = (plVec4){0.5f, 0.5f, 0.5f, 1.0f};
270+
gptData->tRuntimeOptions.tGridColorThick = (plVec4){1.0f, 1.0f, 1.0f, 1.0f};
271+
267272
gptResource->initialize((plResourceManagerInit){.ptDevice = gptData->ptDevice, .uMaxTextureResolution = tSettings.uMaxTextureResolution});
268273

269274
if(gptData->tDeviceInfo.tCapabilities & PL_DEVICE_CAPABILITY_MULTIPLE_VIEWPORTS)
@@ -2789,6 +2794,33 @@ pl_renderer_render_view(plView* ptView, plCamera* ptCamera, plCamera* ptCullCame
27892794
}
27902795
gptGfx->draw_stream(ptSceneEncoder, 1, &tArea);
27912796

2797+
if(ptView->bShowGrid)
2798+
{
2799+
plShaderHandle tGridShader = gptShaderVariant->get_shader("grid", NULL, NULL, NULL, &gptData->tRenderPassLayout);
2800+
gptGfx->bind_shader(ptSceneEncoder, tGridShader);
2801+
2802+
plDynamicBinding tGridDynamicBinding = pl__allocate_dynamic_data(ptDevice);
2803+
plGpuDynGrid* ptGridDynamicData = (plGpuDynGrid*)tGridDynamicBinding.pcData;
2804+
const float fGridFactor = pl_squaref(ptCamera->fFarZ) - pl_squaref(ptCamera->tPos.y);
2805+
ptGridDynamicData->fGridSize = fGridFactor > 0.0f ? sqrtf(fGridFactor) : 100.0f;
2806+
ptGridDynamicData->fGridCellSize = gptData->tRuntimeOptions.fGridCellSize;
2807+
ptGridDynamicData->fGridMinPixelsBetweenCells = gptData->tRuntimeOptions.fGridMinPixelsBetweenCells;
2808+
ptGridDynamicData->tGridColorThin = gptData->tRuntimeOptions.tGridColorThin;
2809+
ptGridDynamicData->tGridColorThick = gptData->tRuntimeOptions.tGridColorThick;
2810+
ptGridDynamicData->fCameraXPos = ptCamera->tPos.x;
2811+
ptGridDynamicData->fCameraZPos = ptCamera->tPos.z;
2812+
ptGridDynamicData->tCameraViewProjection = tMVP;
2813+
2814+
gptGfx->bind_graphics_bind_groups(ptSceneEncoder, tGridShader, 0, 0, NULL, 1, &tGridDynamicBinding);
2815+
2816+
plDraw tGridDraw = {
2817+
.uVertexCount = 6,
2818+
.uInstanceCount = 1,
2819+
};
2820+
*gptData->pdDrawCalls += 1.0;
2821+
gptGfx->draw(ptSceneEncoder, 1, &tGridDraw);
2822+
}
2823+
27922824
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~debug drawing~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27932825

27942826
// bounding boxes
@@ -3706,6 +3738,12 @@ pl_renderer_show_skybox(plView* ptView)
37063738
ptView->bShowSkybox = true;
37073739
}
37083740

3741+
void
3742+
pl_renderer_show_grid(plView* ptView)
3743+
{
3744+
ptView->bShowGrid = true;
3745+
}
3746+
37093747
static void
37103748
pl__object_update_job(plInvocationData tInvoData, void* pData, void* pGroupSharedMemory)
37113749
{
@@ -3999,6 +4037,7 @@ pl_load_renderer_ext(plApiRegistryI* ptApiRegistry, bool bReload)
39994037
tApi.debug_draw_all_bound_boxes = pl_renderer_debug_draw_all_bound_boxes;
40004038
tApi.debug_draw_bvh = pl_renderer_debug_draw_bvh;
40014039
tApi.show_skybox = pl_renderer_show_skybox;
4040+
tApi.show_grid = pl_renderer_show_grid;
40024041
tApi.register_ecs_system = pl_renderer_register_system;
40034042
tApi.create_material = pl_renderer_create_material;
40044043
tApi.create_skin = pl_renderer_create_skin;

extensions/pl_renderer_ext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ typedef struct _plRendererI
161161

162162
// per frame options
163163
void (*show_skybox) (plView*);
164+
void (*show_grid) (plView*);
164165
void (*debug_draw_lights) (plView*, const plLightComponent*, uint32_t lightCount);
165166
void (*debug_draw_all_bound_boxes)(plView*);
166167
void (*debug_draw_bvh) (plView*);
@@ -249,6 +250,12 @@ typedef struct _plRendererRuntimeOptions
249250
float fContrast;
250251
float fSaturation;
251252

253+
// grid
254+
float fGridCellSize;
255+
float fGridMinPixelsBetweenCells;
256+
plVec4 tGridColorThin;
257+
plVec4 tGridColorThick;
258+
252259
} plRendererRuntimeOptions;
253260

254261
typedef struct _plTextureMap

extensions/pl_renderer_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ typedef struct _plView
274274
plScene* ptParentScene;
275275

276276
bool bShowSkybox;
277+
bool bShowGrid;
277278

278279
// renderpasses
279280
plRenderPassHandle tRenderPass;

shaders/grid.frag

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#version 460 core
2+
3+
#include "pl_shader_interop_renderer.h"
4+
5+
layout(set = 3, binding = 0) uniform PL_DYNAMIC_DATA
6+
{
7+
plGpuDynGrid tData;
8+
} tObjectInfo;
9+
10+
layout (location=0) in vec2 uv;
11+
layout (location=1) in vec2 camPos;
12+
layout (location=0) out vec4 fragColor;
13+
14+
float
15+
log10(float x)
16+
{
17+
return log(x) / log(10.0);
18+
}
19+
20+
float
21+
satf(float x)
22+
{
23+
return clamp(x, 0.0, 1.0);
24+
}
25+
26+
vec2
27+
satv(vec2 x)
28+
{
29+
return clamp(x, vec2(0.0), vec2(1.0));
30+
}
31+
32+
float
33+
max2(vec2 v)
34+
{
35+
return max(v.x, v.y);
36+
}
37+
38+
vec4
39+
gridColor(vec2 uv, vec2 camPos)
40+
{
41+
vec2 dudv = vec2(
42+
length(vec2(dFdx(uv.x), dFdy(uv.x))),
43+
length(vec2(dFdx(uv.y), dFdy(uv.y)))
44+
);
45+
46+
float lodLevel = max(0.0, log10((length(dudv) * tObjectInfo.tData.fGridMinPixelsBetweenCells) / tObjectInfo.tData.fGridCellSize) + 1.0);
47+
float lodFade = fract(lodLevel);
48+
49+
// cell sizes for lod0, lod1 and lod2
50+
float lod0 = tObjectInfo.tData.fGridCellSize * pow(10.0, floor(lodLevel));
51+
float lod1 = lod0 * 10.0;
52+
float lod2 = lod1 * 10.0;
53+
54+
// each anti-aliased line covers up to 4 pixels
55+
dudv *= 4.0;
56+
57+
// set grid coordinates to the centers of anti-aliased lines for subsequent alpha calculations
58+
uv += dudv * 0.5;
59+
60+
// calculate absolute distances to cell line centers for each lod and pick max X/Y to get coverage alpha value
61+
float lod0a = max2( vec2(1.0) - abs(satv(mod(uv, lod0) / dudv) * 2.0 - vec2(1.0)) );
62+
float lod1a = max2( vec2(1.0) - abs(satv(mod(uv, lod1) / dudv) * 2.0 - vec2(1.0)) );
63+
float lod2a = max2( vec2(1.0) - abs(satv(mod(uv, lod2) / dudv) * 2.0 - vec2(1.0)) );
64+
65+
uv -= camPos;
66+
67+
// blend between falloff colors to handle LOD transition
68+
vec4 c = lod2a > 0.0 ? tObjectInfo.tData.tGridColorThick : lod1a > 0.0 ? mix(tObjectInfo.tData.tGridColorThick, tObjectInfo.tData.tGridColorThin, lodFade) : tObjectInfo.tData.tGridColorThin;
69+
70+
// calculate opacity falloff based on distance to grid extents
71+
float opacityFalloff = (1.0 - satf(length(uv) / tObjectInfo.tData.fGridSize));
72+
73+
// blend between LOD level alphas and scale with opacity falloff
74+
c.a *= (lod2a > 0.0 ? lod2a : lod1a > 0.0 ? lod1a : (lod0a * (1.0-lodFade))) * opacityFalloff;
75+
76+
return c;
77+
}
78+
79+
void main()
80+
{
81+
fragColor = gridColor(uv, camPos);
82+
}

shaders/grid.vert

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#version 460 core
2+
3+
#include "pl_shader_interop_renderer.h"
4+
5+
layout(set = 3, binding = 0) uniform PL_DYNAMIC_DATA
6+
{
7+
plGpuDynGrid tData;
8+
} tObjectInfo;
9+
10+
layout (location=0) out vec2 uv;
11+
layout (location=1) out vec2 out_camPos;
12+
13+
const vec3 pos[4] = vec3[4](
14+
vec3(-1.0, 0.0, -1.0),
15+
vec3( 1.0, 0.0, -1.0),
16+
vec3( 1.0, 0.0, 1.0),
17+
vec3(-1.0, 0.0, 1.0)
18+
);
19+
20+
const int indices[6] = int[6](
21+
0, 1, 2, 2, 3, 0
22+
);
23+
24+
void main()
25+
{
26+
int idx = indices[gl_VertexIndex];
27+
vec3 position = pos[idx] * tObjectInfo.tData.fGridSize;
28+
29+
position.x += tObjectInfo.tData.fCameraXPos;
30+
position.z += tObjectInfo.tData.fCameraZPos;
31+
32+
out_camPos.x = tObjectInfo.tData.fCameraXPos;
33+
out_camPos.y = tObjectInfo.tData.fCameraZPos;
34+
35+
gl_Position = tObjectInfo.tData.tCameraViewProjection * vec4(position, 1.0);
36+
uv = position.xz;
37+
}

shaders/pl_shader_interop_renderer.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Index of this file:
1111
// [SECTION] common
1212
// [SECTION] scene
1313
// [SECTION] view
14+
// [SECTION] grid
1415
// [SECTION] tonemapping
1516
// [SECTION] environment filtering
1617
// [SECTION] shadows
@@ -159,6 +160,36 @@ PL_BEGIN_STRUCT(plGpuViewData)
159160
// ~~~~~~~~~~~~~~~~224 bytes~~~~~~~~~~~~~~~~
160161
PL_END_STRUCT(plGpuViewData)
161162

163+
//-----------------------------------------------------------------------------
164+
// [SECTION] grid
165+
//-----------------------------------------------------------------------------
166+
167+
PL_BEGIN_STRUCT(plGpuDynGrid)
168+
169+
float fCameraXPos;
170+
float fCameraZPos;
171+
float fGridSize;
172+
float fGridCellSize;
173+
// ~~~~~~~~~~~~~~~~16 bytes~~~~~~~~~~~~~~~~
174+
175+
float fGridMinPixelsBetweenCells;
176+
int _iUnused0;
177+
int _iUnused1;
178+
int _iUnused2;
179+
// ~~~~~~~~~~~~~~~~16 bytes~~~~~~~~~~~~~~~~
180+
181+
vec4 tGridColorThin;
182+
// ~~~~~~~~~~~~~~~~16 bytes~~~~~~~~~~~~~~~~
183+
184+
vec4 tGridColorThick;
185+
// ~~~~~~~~~~~~~~~~16 bytes~~~~~~~~~~~~~~~~
186+
187+
mat4 tCameraViewProjection;
188+
// ~~~~~~~~~~~~~~~~64 bytes~~~~~~~~~~~~~~~~
189+
190+
// ~~~~~~~~~~~~~~~~128 bytes~~~~~~~~~~~~~~~~
191+
PL_END_STRUCT(plGpuDynGrid)
192+
162193
//-----------------------------------------------------------------------------
163194
// [SECTION] tonemapping
164195
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)