-
Notifications
You must be signed in to change notification settings - Fork 13
CAD DTM Rendering #186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
CAD DTM Rendering #186
Conversation
…Examples-and-Tests into dtm
if (textureId != InvalidTextureIndex) | ||
{ | ||
const float2 maxCellCoords = float2(round(gridExtents.x / cellWidth), round(gridExtents.y / cellWidth)); | ||
const float2 location = (cellCoords + float2(0.5f, 0.5f)) / maxCellCoords; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why force sampling the middle of the texel when you can just use the uv value?
you're getting the cell coordinates based on uv and then you're gathering from exactly the middle.
I don't think it's going to affect the result of your gather, because gather will act very similar to your code getting the cell coordinates to gather the pixels from.
Please let me know if I'm missing something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you gather 4 pixels with centers the nearest to the point, so if uv = { 0, 0 } then you gather 3 pixels outside of the original texture for example
float2 gridSpaceCellTopLeftCoords = cellCoords * cellWidth; | ||
|
||
//printf("uv = { %f, %f } diagonalTLtoBR = %i triangleA = %i, insiceCellCoords = { %f, %f }", uv.x, uv.y, int(diagonalFromTopLeftToBottomRight), int(triangleA), insideCellCoord.x / cellWidth, insideCellCoord.y / cellWidth); | ||
|
||
if (diagonalFromTopLeftToBottomRight) | ||
{ | ||
v[0] = float3(gridSpaceCellTopLeftCoords.x, gridSpaceCellTopLeftCoords.y, cellHeights.w); | ||
v[1] = float3(gridSpaceCellTopLeftCoords.x + cellWidth, gridSpaceCellTopLeftCoords.y + cellWidth, cellHeights.y); | ||
v[2] = triangleA ? float3(gridSpaceCellTopLeftCoords.x, gridSpaceCellTopLeftCoords.y + cellWidth, cellHeights.x) : float3(gridSpaceCellTopLeftCoords.x + cellWidth, gridSpaceCellTopLeftCoords.y, cellHeights.z); | ||
} | ||
else | ||
{ | ||
v[0] = float3(gridSpaceCellTopLeftCoords.x, gridSpaceCellTopLeftCoords.y + cellWidth, cellHeights.x); | ||
v[1] = float3(gridSpaceCellTopLeftCoords.x + cellWidth, gridSpaceCellTopLeftCoords.y, cellHeights.z); | ||
v[2] = triangleA ? float3(gridSpaceCellTopLeftCoords.x, gridSpaceCellTopLeftCoords.y, cellHeights.w) : float3(gridSpaceCellTopLeftCoords.x + cellWidth, gridSpaceCellTopLeftCoords.y + cellWidth, cellHeights.y); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you see sdf codes in shadertoy there is a nice trick when it comes to the coordinate space you do your SDFs in.
You're trying very hard to convert your triangle points to screensapce by computing and adding gridSpaceCellTopLeftCoords
to every triangle vertex. then later on adding topLeft
of the grid to everypoint and doing sdf with input.position.xy
Now the simple trick is: instead of converting every point in the cell to screenspace, compute your vertices in local grid cell and convert your point to local grid cell and do sdf with: (`input.position.xy - (gridTopLeft + cellTopLeft))
It will give you the exact same sdf and instead of 3*2 vector additions you just get 1 subtraction to bring your point in question to local grid cell.
your vertices for example can be (0, 0, h0)
& (cellWidth, 0, h1)
& (cellWidth, cellWidth, h2)
and then your screenspace point will be brought into this space by simple translation.
Bonus point for curious minds: since this coordinate transformation is a simple translation it won't affect distances/lengths, so it won't change the sdf value from your previous version, BUT if it also had uniform scaling, it would affect the distances and you'd need to adjust the sdf accordingly. (for example when you decided to use (1, 1) instead of (cellWidth, cellWidth) and scale to some unit space to do your sdf calculations in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
if (triangleA) | ||
{ | ||
outlineLineSegments[0] = nbl::hlsl::shapes::Line<float>::construct(v[2].xy, v[0].xy); | ||
outlineLineSegments[1] = nbl::hlsl::shapes::Line<float>::construct(v[2].xy, v[1].xy); | ||
} | ||
else | ||
{ | ||
outlineLineSegments[0] = nbl::hlsl::shapes::Line<float>::construct(v[1].xy, v[2].xy); | ||
outlineLineSegments[1] = nbl::hlsl::shapes::Line<float>::construct(v[0].xy, v[2].xy); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so this is not the way I want you to do outlines at all.
- Triangle formation (your v[3]) should only be done for CONTOUR and HEIGHT_SHADING (skip tthe formation calculations if only outlines is requested)
- Outline SDF and color calculation should be independant from triangle formation, based on the point you're going to do SDF with (2 lines out of 4)
- You'll be doing sdf with the whole larger lines, you don't have to adjust phaseshift anymore (extra unnecessary calculations), we'll handle clipping for all types of objects later on in case it was super zoomed in the sdf might be less accurate, but it's a simple line sdf so no big problem.
- Remember that the whole dilation emulation thing (iterating over all neighbouring cells and doing sdf with them) should also be independant from outline rendering
- Last but not least I want to be able to draw a grid without a heightmap texture and triangle formation. make sure your code can handle that. Because we're going to abuse this code to draw simple regular grids in n4ce, where there is no height values and heightmaps, formations or triangles; just simple grid
} | ||
if (dtmSettings.drawOutlineEnabled()) | ||
dtmColor = dtm::blendUnder(dtmColor, dtm::calculateGridDTMOutlineColor(dtmSettings.outlineLineStyleIdx, outlineLineSegments, input.position.xy, outlinePhaseShift)); | ||
if (dtmSettings.drawHeightShadingEnabled() && !outOfBoundsUV) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&& !outOfBoundsUV
Ok I can live with this. just know that you're implicitly discarding height shading for out of bounds UVs. if your grid was rotated you'd get aliasing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Try creating the image and allocating memory for it: | ||
nbl::video::IGPUImage::SCreationParams params = {}; | ||
params = imageParams; | ||
auto gpuImage = device->createImage(std::move(params)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do you add the ECF_MUTABLE_FORMAT_BIT
flag? I think it should be added when override is valid and not equal to ICPUImage format (the image creation params given).
It shouldn't be user's job to add it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the view format override in params.viewFormat
(if valid and inequal to image format).
because we want the image creation to fail if we cannot create view with that format for the image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the view format override in
params.viewFormat
(if valid and inequal to image format). because we want the image creation to fail if we cannot create view with that format for the image.
62_CAD/DrawResourcesFiller.cpp
Outdated
uint64_t textureID, | ||
const DTMSettingsInfo& dtmSettingsInfo, | ||
SIntendedSubmitInfo& intendedNextSubmit, | ||
bool drawGridOnly/* = false*/) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this param and use dtmSettings mode instead. if it's OUTLINE then it's GRID only.
textureID can be invalid, if that's the case the grid will be drawn in complete
but if the textureID is valid, we need to upload and work with the heights, because of holes that can appear.
make sure that's documented in DrawResources.h.
62_CAD/DrawResourcesFiller.cpp
Outdated
if (disableHeightRelatedDTMModes) | ||
activeDTMSettings.mode &= E_DTM_MODE::OUTLINE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for this or the new bool param
https://github.com/Devsh-Graphics-Programming/Nabla-Examples-and-Tests/pull/186/files#r2159989917
CAD DTM Rendering Example
Devsh-Graphics-Programming/Nabla#858