unity shader : Applying ZOrder to sprite renderer conditionally - unity3d

here's scene object info of above figure.
all of object's renderer is 'SpriteRenderer', and Material is 'Sprites-Default'.
[A (Car)]
OrderInLayer : 302
Local Z Position : -9.8
[B (Land)]
OrderInLayer : 270
Local Z Position : -9
[C1, C2 (Land)]
OrderInLayer : 300
Local Z Position : -10
[D (Land)]
OrderInLayer : 330
Local Z Position : -11
I hope that you do not obstruct the 'D' is 'A' in the above situation.
But such a situation can not use OrderInLayer.
So I'm not sure at all that you will use the same shader.
Help!

Related

Cluster analysis of a Rasterlayer

Is there a way that i can analyse a cluster of a rasterlayer directly? If modify my Raster into a Matrix it does not work.I used kmeans so far, after i turned my raster into a matrix. But still dont work. I also used this code: r <- getValues(r) to turn my raster into a matrix but still does not work.Another problem is that all my values are NA if i turn my Raster into a matrix. So i dont know how to handle this problem.
my Raster looks like this:
class : RasterLayer
dimensions : 23320, 37199, 867480680 (nrow, ncol, ncell)
resolution : 0.02, 0.02 (x, y)
extent : 341668.9, 342412.9, 5879602, 5880069 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=33 +ellps=WGS84 +units=m +no_defs
source : r_tmp_2022-07-13_141214_9150_15152.grd
names : layer
values : 2.220446e-16, 1 (min, max)

Unity wants a Y-flipped projection matrix when rendering under Direct3D

First of all, hello,
I have several questions tied together to this title, because I can't summarize all into one good question.
To put the settings, I am using Unity 2020.1.2f1 URP and I am trying to rebuild myself the Unity's projection matrix used with Direct3D 11 in order to fully understand the working of it.
I know that Unity uses the left-handed system for the object and world spaces, but not for the view space, which still use the OpenGL's old convention of the right-handed one. I could say that the clip space is LH too as the Z axis points towards the screen, but Unity makes me doubt a lot.
Let me explain : we all know that the handedness is given by the matrix, which is why the projection matrix (column-major here) used by Unity for OpenGL-like APIs looks like that :
[ x 0 0 0 ] x = cot(fovH/2) c = (f+n)/(n-f)
[ 0 y 0 0 ] y = cot(fovV/2) e = (2*f*n)/(n-f)
[ 0 0 c e ] d = -1
[ 0 0 d 0 ]
where 'c' and 'e' clip and flip 'z' into the depth buffer from the RH view space to the LH clip space (or NDC once the perspective division is applied), 'w' holds the flipped view depth, and the depth buffer is not reversed.
With the near plane = 0.3 and the far plane = 100, the Unity's frame debugger confirms that our matrix sent to the shader is equal to 'glstate_matrix_projection' (it's the matrix behind UNITY_MATRIX_P macro in the shader), as well as the projection matrix from the camera itself 'camera.projectionMatrix' since it's the matrix built internally by Unity, following the OpenGL convention. It is even confirmed with 'GL.GetGPUProjectionMatrix()' which tweaks the projection matrix of our camera to match the Graphic API requirements before sending it to the GPU, but changes nothing in this case.
// _CamProjMat
float n = viewCam.nearClipPlane;
float f = viewCam.farClipPlane;
float fovV = Mathf.Deg2Rad * viewCam.fieldOfView;
float fovH = 2f * Mathf.Atan(Mathf.Tan(fovH / 2f) * viewCam.aspect);
Matrix4x4 projMat = new Matrix4x4();
projMat.m00 = 1f / Mathf.Tan(fovH / 2f);
projMat.m11 = 1f / Mathf.Tan(fovV / 2f);
projMat.m22 = (f + n) / (n - f);
projMat.m23 = 2 * f * n / (n - f);
projMat.m32 = -1f;
// _GPUProjMat
Matrix4x4 GPUMat = GL.GetGPUProjectionMatrix(viewCam.projectionMatrix, false);
Shader.SetGlobalMatrix("_GPUProjMat", projMat);
// _UnityProjMat
Shader.SetGlobalMatrix("_UnityProjMat", viewCam.projectionMatrix);
gives us :
frame_debugger_OpenGL
HOWEVER, when I switch to Direct3D11 the 'glstate_matrix_projection' is flipped vertically. I mean that the m11 component of the matrix is negative, which flips the Y axis when applied to the vertex. The projection matrix for Direct3D used in Unity applies the Reversed Z buffer technique, giving us a matrix like :
[ x 0 0 0 ] x = cot(fovH/2) c = n/(f-n)
[ 0 y 0 0 ] y = -cot(fovV/2) e = (f*n)/(f-n)
[ 0 0 c e ] d = -1
[ 0 0 d 0 ]
(you'll notice that 'c' and 'e' are respectively the same as f/(n-f) and (fn)/(n-f)* given by Direct3D documentation of D3DXMatrixPerspectiveFovRH() function, with 'f' and 'n' swapped to apply the Reversed Z buffer )
From there, there are several concerns :
if we try to give a projection matrix to the shader, instead of 'glstate_matrix_projection', using 'GL.GetGPUProjectionMatrix()' specifying false as the second parameter, the matrix won't be correct, the rendered screen will be flipped vertically, which is not wrong given the parameter.
frame_debugger_Direct3D
Indeed, this boolean parameter is to modify the matrix whether the image is rendered into a renderTexture or not, and it is justified since OpenGL vs Direct3D render texture coordinates are like this :
D3D_vs_OGL_rt_coord
In a way that makes sense because the screen space of Direct3D is in pixel coordinates, where the handedness is the same as for render texture coordinates, accessed in the pixel shader through the 'SV_Position' semantic. The clip space is only flipped vertically then, into a right-handed system with the positive Y going down the screen, and the positive Z going towards the screen.
Nontheless, I render my vertices directly to the screen, and not into any render texture ... is this parameter from 'GL.GetGPUProjectionMatrix()' a trick to set to true when used with Direct3D like APIs ?
another concern is that we can guess that, given the clip space, NDC, and screen space are left-handed in OpenGL-like APIs, these spaces are right-handed in Direct3D-like APIs... right ? where am I wrong ? Although nobody never qualified or stated on any topic, documentation, dev blog, etc.. I ever read, the handedness of those doesn't seem to bother anyone. Even the projection matrices provided by the official Direct3D documentation don't flip the Y-axis, why then ? I admit I only tried to render graphics with D3D or OGL only inside Unity, perhaps Unity does black magic again under the coat, as usual heh.
I hope I explained clearly enough all this mess, thanks to everyone who reach this point ;)
I really need to find out what's going on here, because Unity's documentation becomes more and more legacy, with poor explanation on precise engine parts.
Any help is really appreciated !!

as.polygons(SpatRaster, values=FALSE) seems to dissolve cells when it should not

Maybe there is something I do not understand. According to the help page, as.polygons() applied to a SpatRaster with the option values = FALSE should not dissolve cells. But:
library(terra)
# terra 1.5.21
r <- rast(ncols=2, nrows=2, vals=1)
as.polygons(r) # correctly gives a dissolved 1x1 polygon:
# class : SpatVector
# geometry : polygons
# dimensions : 1, 1 (geometries, attributes)
# extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
# coord. ref. : lon/lat WGS 84
# names : lyr.1
# type : <int>
# values : 1
as.polygons(r, values=FALSE) # improperly (?) gives a dissolved 1x1 polygon:
# class : SpatVector
# geometry : polygons
# dimensions : 1, 0 (geometries, attributes)
# extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
# coord. ref. : lon/lat WGS 84
whereas it should give an undissolved polygon, such as the one obtained with dissolve=FALSE (but without the values):
as.polygons(r,dissolve=FALSE)
# class : SpatVector
# geometry : polygons
# dimensions : 4, 1 (geometries, attributes)
# extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
# coord. ref. : lon/lat WGS 84
As you noted, the documentation is incorrect. If you do not want the cells to be dissolved, you need to use dissolve=FALSE.
If you do not want to dissolve, and do not want the values, you can do
library(terra)
r <- rast(ncols=2, nrows=2, vals=1)
p <- as.polygons(r, dissolve=FALSE, values=FALSE)
# or
p <- as.polygons(rast(r))
p
# class : SpatVector
# geometry : polygons
# dimensions : 4, 0 (geometries, attributes)
# extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
# coord. ref. : lon/lat WGS 84
The latter works the way it does, despite the default dissolve=TRUE because there is nothing to dissolve with since rast(r) has no values. If you want the extent you can do
as.polygons(r, extent=TRUE)
# class : SpatVector
# geometry : polygons
# dimensions : 1, 0 (geometries, attributes)
# extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
# coord. ref. : lon/lat WGS 84
That is a (much more) efficient approach that is otherwise equivalent to dissolving (aggregating) all cells.

Extract coordinates of raster cells that overlap with multilinestring

I'm working with R and I have a raster (population) with population density data on each cell and a multilinestring (border_365_366) that represents an international border. I'd like to extract the coordinates of the raster cells that overlap with the international border.
Does anyone know how to extract this? I think one of the major issues here is that I'm working with a multilestring instead of a data.frame with coordinates.
> class(border_365_366)
[1] "sf" "data.frame"
> class(population)
[1] "RasterLayer"
attr(,"package")
[1] "raster"
> border_365_366
Simple feature collection with 1 feature and 0 fields
geometry type: MULTILINESTRING
dimension: XY
bbox: xmin: 27.32998 ymin: 57.52933 xmax: 28.21014 ymax: 59.46253
geographic CRS: WGS 84
geometry
1 MULTILINESTRING ((27.66656 ...
> population
class : RasterLayer
dimensions : 21600, 34926, 754401600 (nrow, ncol, ncell)
resolution : 0.01030751, 0.01046373 (x, y)
extent : -180, 180, -120.053, 105.9636 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
names : pop_new
values : 0, 107475 (min, max)
I was able to solve this issue by converting the line to linestring
border_365_366<- st_cast(border_365_366,'LINESTRING')

Colliders in unity behaving the way they, as I think, shouldn't

I am learning to work with unity now and I noticed one error. I am working with 2D and have two box colliders.
One of them is:
Size : X = 8, Y = 0.3
Center: X = 0, Y = 4.9
The Other one is
Size : X = 3, Y = 0.6
Center: X = 0, Y = 3.95
So from this information we can see that the gap between those two colliders is 0.5, but a rigidbody with a circle collider with a radius of 0.25 is not able to move through that gap, it gets stuck.
Maybe there's something I don't know about the way colliders work and you could shed some light.