In D3D HLSL, we could output the depth value into depth register in Pixel Shader directly. But it request the value should be between 0 and 1.
If I want to set depth to be greater than 1 how can I do that?
24 bits for storing the depth value is too limited for my very large scene graph.
You can output a value outside of [0,1], but it will be clamped to the [0,1] range before being used in the depth test (if enabled) and before being written to the depth target. This is true for both Z16/Z24 formats (which can't even represent values outside [0,1]) and for the Z32F format.
Why is 24 bits too limited -- do you need a larger range or do you need more precision?
Your question suggests that you need a larger range than [0,1], but your scene graph can use any range you want as long as the vertex shader maps that range to [0,1] (this range mapping usually happens in the model/view/projection transforms).
If you need more precision, you can't get that natively: the 32-bit floats used throughout the API and hardware only have 23 mantissa bits, and the implicit leading 1 effectively gives you 24 bits of precision. To deal with this, the typical solution is to chop the world up into segments (e.g. a grid), and store object positions relative to the segment they're in. When an object moves from one segment to another, you translate its position to be relative to the new segment. When rendering use the segment containing the camera as (0,0,0) and map the segments that fall within the view frustum to the [0,1] depth range.
Related
Apologies for the overlap with existing questions; mine is at a more basic skill level. I am working with very sparse occurrences spanning very large areas, so I would like to calculate probability at pixels using the density.ppp function (as opposed to relrisk.ppp, where specifying presences+absences would be computationally intractable). Is there a straightforward way to convert density (intensity) to probabilities at each point?
Maxdist=50
dtruncauchy=function(x,L=60) L/(diff(atan(c(-1,1)*Maxdist/L)) * (L^2 + x^2))
dispersfun=function(x,y) dtruncauchy(sqrt(x^2+y^2))
n=1e3; PPP=ppp(1:n,1:n, c(1,n),c(1,n), marks=rep(1,n));
density.ppp(PPP,cutoff=Maxdist,kernel=dispersfun,at="points",leaveoneout=FALSE) #convert to probabilies?
Thank you!!
I think there is a misunderstanding about fundamentals. The spatstat package is designed mainly for analysing "mapped point patterns", datasets which record the locations where events occurred or things were located. It is designed for "presence-only" data, not "presence/absence" data (with some exceptions).
The relrisk function expects input data about the presence of two different types of events, such as the mapped locations of trees belonging to two different species, and then estimates the spatially-varying probability that a tree will belong to each species.
If you have 'presence-only' data stored in a point pattern object X of class "ppp", then density(X, ....) will produce a pixel image of the spatially-varying intensity (expected number of points per unit area). For example if the spatial coordinates were expressed in metres, then the intensity values are "points per square metre". If you want to calculate the probability of presence in each pixel (i.e. for each pixel, the probability that there is at least one presence point in the pixel), you just need to multiply the intensity value by the area of one pixel, which gives the expected number of points in the pixel. If pixels are small (the usual case) then the presence probability is just equal to this value. For physically larger pixels the probability is 1 - exp(-m) where m is the expected number of points.
Example:
X <- redwood
D <- density(X, 0.2)
pixarea <- with(D, xstep * ystep)
M <- pixarea * D
p <- 1 - exp(-M)
then M and p are images which should be almost equal, and can both be interpreted as probability of presence.
For more information see Chapter 6 of the spatstat book.
If, instead, you had a pixel image of presence/absence data, with pixel values equal to 1 or 0 for presence or absence respectively, then you can just use the function blur in the spatstat package to perform kernel smoothing of the image, and the resulting pixel values are presence probabilities.
Is there a spatial lookup grid or binning system that works on the surface of a (3D) sphere? I have the requirements that
The bins must be uniform (so you can look up in constant time if there exists a point r distance away from any spot on the sphere, given constant r.)†
The number of bins must be at most linear with the surface area of the sphere. (Alternatively, increasing the surface resolution of the grid shouldn’t make it grow faster than the area it maps.)
I’ve already considered
Spherical coordinates: not good because the cells created are extremely nonuniform making it useless for proximity testing.
Cube meshes: Less distortion than spherical coordinates, but still very difficult to determine which cells to search for a given query.
3D voxel binning: Wastes the entire interior volume of the sphere with empty bins that will never be used (as well as the empty bins at the 6 corners of the bounding cube). Space requirements grow with O(n sqrt(n)) with increasing sphere surface area.
kd-Trees: perform poorly in 3D and are technically logarithmic complexity, not constant per query.
My best idea for a solution involves using the 3D voxel binning method, but somehow excluding the voxels that the sphere will never intersect. However I have no idea how to determine which voxels to exclude, nor how to calculate an index into such a structure given a query location on the sphere.
† For what it’s worth the points have a minimum spacing so a good grid really would guarantee constant lookup.
My suggestion would be a variant of the spherical coordinates, such that the polar angle is not sampled uniformly but instead the sine of this angle is sampled uniformly. This way, the element of area sinφ dφ dΘ is kept constant, leading to tiles of the same area (though variable aspect ratio).
At the poles, merge all tiles in a single disk-like polygon.
Another possibility is to project a regular icosahedron onto the sphere and to triangulate the spherical triangles so obtained. This takes a little of spherical trigonometry.
I had a similar problem and used "sparse" 3D voxel binning. Basically, my spatial index is a hash map from (x, y, z) coordinates to bins.
Because I also had a minimum distance constraint on my points, I chose the bin size such that a bin can contain at most one point. This is accomplished if the edge of the (cubic) bins is at most d / sqrt(3), where d is the minimum separation of two points on the sphere. The advantage is that you can represent a full bin as a single point, and an empty bin can just be absent from the hash map.
My only query was for points within a radius d (the same d), which then requires scanning the surrounding 125 bins (a 5×5×5 cube). You could technically leave off the 8 corners to get this down to 117, but I didn't bother.
An alternative for the bin size is to optimize it for queries rather than storage size and simplicity, and choose it such that you always have to scan at most 27 bins (a 3×3×3 cube). That would require a bin edge length of d. I think (but haven't thought hard about it) that a bin could contain up to 4 points in that case. You could represent these with a fixed-size array to save one pointer indirection.
In either case, the memory usage of your spatial index will be O(n) for n points, so it doesn't get any better than that.
Here is a excerpt from Peter Shirley's Fundamentals of computer graphics:
11.1.2 Texture Arrays
We will assume the two dimensions to be mapped are called u and v.
We also assume we have an nx and ny image that we use as the texture.
Somehow we need every (u,v) to have an associated color found from the
image. A fairly standard way to make texturing work for (u,v) is to
first remove the integer portion of (u,v) so that it lies in the unit
square. This has the effect of "tiling" the entire uv plane with
copies of the now-square texture. We then use one of the three
interpolation strategies to compute the image color for the
coordinates.
My question is: What are the integer portion of (u,v)? I thought u,v are 0 <= u,v <= 1.0. If there is an integer portion, shouldn't we be dividing u,v by the texture image width and height to get the normalized u,v values?
UV values can be less than 0 or greater than 1. The reason for dropping the integer portion is that UV values use the fractional part when indexing textures, where (0,0), (0,1), (1,0) and (1,1) correspond to the texture's corners. Allowing UV values to go beyond 0 and 1 is what enables the "tiling" effect to work.
For example, if you have a rectangle whose corners are indexed with the UV points (0,0), (0,2), (2,0), (2,2), and assuming the texture is set to tile the rectangle, then four copies of the texture will be drawn on that rectangle.
The meaning of a UV value's integer part depends on the wrapping mode. In OpenGL, for example, there are at least three wrapping modes:
GL_REPEAT - The integer part is ignored and has no meaning. This is what allows textures to tile when UV values go beyond 0 and 1.
GL_MIRRORED_REPEAT - The fractional part is mirrored if the integer part is odd.
GL_CLAMP_TO_EDGE - Values greater than 1 are clamped to 1, and values less than 0 are clamped to 0.
Peter O's answer is excellent. I want to add a high level point that the coordinate systems used in graphics are a convention that people just stick to as a defacto standard-- there's no law of nature here and it is arbitrary (but a decent standard thank goodness). I think one reason texture mapping is often confusing is that the arbitrariness of this stardard isn't obvious. This is that the image has a de facto coordinate system on the unit square [0,1]^2. Give me a (u,v) on the unit square and I will tell you a point in the image (for example, (0.2,0.3) is 20% to the right and 30% up from the bottom-left corner of the image). But what if you give me a (u,v) that is outside [0,1]^2 like (22.7, -13.4)? Some rule is used to make that on [0.1]^2, and the GL modes described are just various useful hacks to deal with that case.
what gives one the ability to define how deep the zooming process would be?
what i mean is that i tried earlier to run mandelbrot set with 200 iteration and then compared the results with a 1000 iterations run. the results were kinda surprising because i got the same zooming level.the iterations were constant the entire process and the mandelbrot set was defined with 512X512 pixels constant. what should i change in order to get a deeper zooming level?
thanks!
edit : i would also like to mention that from nice looking picture, after i get to the 2nd-3rd level of mandelbrot the entire set is viewed as a giant pixel. why is that?
2d edit : after an extensive research i've just noticed that what makes the entire set to look like a big pixel is because all points get same iterations count,in my case they are all 60...
This may be too abstract, or too concrete, or incomprehensible. Like I said in the comment, it would be easier to discuss with your code at hand.
If you mean what I think you mean by zooming, you'd change the boundaries of c (in the formula z[n+1] = z[n]^2 + c).
To explain, the full Mandelbrot set is contained within a circle with radius 2 around a center [0;0]. The c in the formula is a complex number, i.e. [r;i] (real;imaginary), which, on the computer screen, corresponds to x and y.
In other words, if we place that radius 2 circle so that it is exactly contained within our image, then [-2;2] will be the upper left corner of our image, and [2;-2] is the lower right corner.
We then take each point of our image, calculate what its pixel coordinates [x;y] correspond to in terms of the smaller, "actual" coordinate system [r;i]. Then we have our c and can send it through our iterations.
So, to "zoom", you'd pick other boundaries [r;i] than the full [-2;2],[2:-2], e.g. [-1;1],[1:-1].
With 512x512 pixels, and an "actual" coordinate system that's now 2 by 2, that would mean each pixel corresponds to 2/512 units of the "actual" coordinate system. So your first r value would be -1, the next would be -1 + 2/512 = -0.99609375 etc.
The number of iterations only decide how accurate your rendering will be. Generally, the further you "zoom" in, the more accurate they'll need to be, so the more iterations you'll need in order to capture the details.
I need to calculate the minimum and maximum UV values assigned to the pixels produced when a given object is drawn onscreen from a certain perspective. For example, if I have a UV-mapped cube but only the front face is visible, min(UV) and max(UV) should be set to the minimum and maximum UV coordinates assigned to the pixels of the visible face.
I'd like to do this using Direct3D 9 shaders (and the lowest shader model possible) to speed up processing. The vertex shader could be as simple as taking each input vertex's UV coordinates and passing them on, unmodified, to the pixel shader. The pixel shader, on the other hand, would have to take the values produced by the vertex shader and use these to compute the minimum and maximum UV values.
What I'd like to know is:
How do I maintain state (current min and max values) between invocations of the pixel shader?
How do I get the final min and max values produced by the shader into my program?
Is there any way to do this in HLSL, or am I stuck doing it by hand? If HLSL won't work, what would be the most efficient way to do this without the use of shaders?
1) You don't.
2) You would have to do a read back at some point. This will be a fairly slow process and cause a pipeline stall.
In general I can't think of a good way to do this. What exactly are you trying to acheieve with this? There may be some other way to achieve the result you are after.
You "may" be able to get something going using multiple render targets and writing the UVs for each pixel to the render target. Then you'd need to pass the render target back to main memory and then parse it for your min and max values. This is a realy slow and very ugly solution.
If you can do it as a couple of seperate pass you may be able to render to a very small render target and use 1 pass with a Max and 1 pass with a Min alpha blend op. Again ... not a great solution.