How to step through 3D noise for volume textures? - unity3d

I'm creating volume textures for volumetric ray marching (Creating this with Unity and a fragment shader)
Example
I have depth value that increases the starting position on the x, y or z axis.
Doing this additivley, results in an ulgy side view where you can see the stacked planes.
Example:
Example
When I multiply the depth value with the starting position, the result is a bit more convincing but the frequency will increase with the depth. I didn't find any 3D noise algorithms that take an extra parameter for the frequency, they all do it with the UVs (the position in my case).
Example
Can't really figure out how to do it correctly.

Found the solution.
As I was stepping along the z-value of the noise, I was multiplying it by my depth value. This of course increases/decreases the frequency.
All I had to do was to add it to the z-value.

Related

Smoothing algorithm, 2.5D

The picture below shows a triangular surface mesh. Its vertices are exactly on the surface of the original 3D object but the straight edges and faces have of course some geometric error where the original surface bends and I need some algorithm to estimate the smooth original surface.
Details: I have a height field of (a projectable part of) this surface (a 2.5D triangulation where each x,y pair has a unique height z) and I need to compute the height z of arbitrary x,y pairs. For example the z-value of the point in the image where the cursor points to.
If it was a 2D problem, I would use cubic splines but for surfaces I'm not sure what is the best solution.
As commented by #Darren what you need are patches.
It can be bi-linear patches or bi-quadratic or Coon's patches or other.
I have found no much reference doing a quick search but this links:
provide an overview: http://www.cs.cornell.edu/Courses/cs4620/2013fa/lectures/17surfaces.pdf
while this is more technical: https://www.doc.ic.ac.uk/~dfg/graphics/graphics2010/GraphicsHandout05.pdf
The concept is that you calculate splines along the edges (height function with respect to the straight edge segment itself) and then make a blending inside the surface delimited by the edges.
The patch os responsible for the blending meaning that inside any face you have an height which is a function of the point position coordinates inside the face and the values of the spline ssegments which are defined on the edges of the same face.
As per my knowledge it is quite easy to use this approach on a quadrilateral mesh (because it becomes easy to define on which edges sequence to do the splines) while I am not sure how to apply if you are forced to go for an actual triangulation.

Verify that camera calibration is still valid

How do you determine that the intrinsic and extrinsic parameters you have calculated for a camera at time X are still valid at time Y?
My idea would be
to use a known calibration object (a chessboard) and place it in the camera's field of view at time Y.
Calculate the chessboard corner points in the camera's image (at time Y).
Define one of the chessboard corner points as world origin and calculate the world coordinates of all remaining chessboard corners based on that origin.
Relate the coordinates of 3. with the camera coordinate system.
Use the parameters calculated at time X to calculate the image points of the points from 4.
Calculate distances between points from 2. with points from 5.
Is that a clever way to go about it? I'd eventually like to implement it in MATLAB and later possibly openCV. I think I'd know how to do steps 1)-2) and step 6). Maybe someone can give a rough implementation for steps 2)-5). Especially I'd be unsure how to relate the "chessboard-world-coordinate-system" with the "camera-world-coordinate-system", which I believe I would have to do.
Thanks!
If you have a single camera you can easily follow the steps from this article:
Evaluating the Accuracy of Single Camera Calibration
For achieving step 2, you can easily use detectCheckerboardPoints function from MATLAB.
[imagePoints, boardSize, imagesUsed] = detectCheckerboardPoints(imageFileNames);
Assuming that you are talking about stereo-cameras, for stereo pairs, imagePoints(:,:,:,1) are the points from the first set of images, and imagePoints(:,:,:,2) are the points from the second set of images. The output contains M number of [x y] coordinates. Each coordinate represents a point where square corners are detected on the checkerboard. The number of points the function returns depends on the value of boardSize, which indicates the number of squares detected. The function detects the points with sub-pixel accuracy.
As you can see in the following image the points are estimated relative to the first point that covers your third step.
[The image is from this page at MATHWORKS.]
You can consider point 1 as the origin of your coordinate system (0,0). The directions of the axes are shown on the image and you know the distance between each point (in the world coordinate), so it is just the matter of depth estimation.
To find a transformation matrix between the points in the world CS and the points in the camera CS, you should collect a set of points and perform an SVD to estimate the transformation matrix.
But,
I would estimate the parameters of the camera and compare them with the initial parameters at time X. This is easier, if you have saved the images that were used when calibrating the camera at time X. By repeating the calibrating process using those images you should get very similar results, if the camera calibration is still valid.
Edit: Why you need the set of images used in the calibration process at time X?
You have a set of images to do the calibrations for the first time, right? To recalibrate the camera you need to use a new set of images. But for checking the previous calibration, you can use the previous images. If the parameters of the camera are changes, there would be an error between the re-estimation and the first estimation. This can be used for evaluating the validity of the calibration not for recalibrating the camera.

Understanding depth values in 3D point cloud

I have problems understanding the depth (Z) value in 3D point cloud resulted from 3d sparse reconstruction like this example in MATLAB: http://www.mathworks.com/help/vision/ug/sparse-3-d-reconstruction-from-multiple-views.html
I have attached a picture showing the reconstructed 3D point cloud in the above example. I have put some datatips on the figure so we know the (x,y,z) coordinates of the points. here are my questions:
1- what does the Z value in point cloud represent? is it the distance in millimeters from the camera? if that's the case then it does not make sense based on the picture I attached since I am sure the distance of the sphere and checkerboard from the camera must be greater than 200 mm.
Or maybe it is from some reference point in space? then what is this reference point? and how can I make a 3D point cloud that the Z values indicate the distance from the camera?
2- why is there negative values for Z? what does that mean in terms of distance to the camera?
I appreciate if someone can explain.
In this example the world coordinates are defined by the checkerboard. The checkerboard defines the X-Y plane, and the Z-axis points into the checkerboard, as explained in the documentation:
Since your 3D points are above the checkerboard, they have negative Z-coordinates.
Your (x,y,z) coordinates are in world units, which are completely disconnected from metric values (unless you build a scale between world and metric, there are various methods to do it). So the z value tells you about the depth of each point in world coordinates.
If you have the pose of each camera, and you multiply each point by the camera projection matrix, you will get the (x',y',z') points in camera coordinates. At that point, if z' is negative, it means it's behind the camera.

pca in matlab - 2D curve stretching

I have N 3D observations taken from an optical motion capture system in XYZ form.
The motion that was captured was just a simple circle arc, derived from a rigid body with fixed axis of rotation.
I used the princomp function in matlab to get all marker points on the same plane i.e. the plane on which the motion has been done.
(See a pic representing 3D data on the plane that was found, below)
What i want to do after the previous step is to look the fitted data on the plane that was found and get the curve of the captured motion in 2D.
In the princomp how to, it is said that
The first two coordinates of the principal component scores give the
projection of each point onto the plane, in the coordinate system of
the plane.
(from "Fitting an Orthogonal Regression Using Principal Components Analysis" article on mathworks help site)
So i thought that if i just plot those pc scores -plot(score(:,1),score(:,2))- i'll get the motion curve. Instead what i got is this.
(See a pic representing curve data in 2D derived from pc scores, below)
The 2d curve seems stretched and nonlinear (different y values for same x values) when it shouldn't be. The curve that i am looking for, should be interpolated by just using simple polynomial (polyfit) or circle fit in matlab.
Is this happening because the plane that was found looks like rhombus relative to the original coordinate system and the pc axes are rotated with respect to the basis of plane in such way that produce this stretch?
Then i thought that, this is happening because of the different coordinate systems of optical system and Matlab. Optical system's (ie cameras) co.sys. is XZY oriented and Matlab's default (i think) co.sys is XYZ oriented. I transformed my data to correspond to Matlab's co.sys through a rotation matrix, run again princomp but i got the same stretch in the 2D curve (the new curve just had different orientation now).
Somewhere else i read that
Principal Components Analysis chooses the first PCA axis as that line
that goes through the centroid, but also minimizes the square of the
distance of each point to that line. Thus, in some sense, the line is
as close to all of the data as possible. Equivalently, the line goes
through the maximum variation in the data. The second PCA axis also
must go through the centroid, and also goes through the maximum
variation in the data, but with a certain constraint: It must be
completely uncorrelated (i.e. at right angles, or "orthogonal") to PCA
axis 1.
I know that i am missing something but i have a problem understanding why i get a stretched curve. What i have to do so i can get the curve right?
Thanks in advance.
EDIT: Here is a sample data file (3 columns XYZ coords for 2 markers)
w w w.sendspace.com/file/2hiezc

What is DOT3 lighting?

An answer to my question suggests that DOT3 lighting can help with OpenGL ES rendering, but I'm having trouble finding a decent definition of what DOT3 lighting is.
Edit 1
iPhone related information is greatly appreciated.
DOT3-lighting is often referred to as per-pixel lighting. With vertex lighting the lighting is calculated at every vertex and the resulting lighting is interpolated over the triangle. In per-pixel lighting, as the name implies, the object is to calculate the lighting at every pixel.
The way this is done on fixed function hardware as the iPhone is with so called register combiners. The name DOT3 comes from this render state:
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
Look at this blog entry on Wolfgang Engels blog for more info on exactly how to set this up.
When doing per-pixel lighting it's popular to also utilize a so called normal map. This means that the normal of every point on an object is stored in a special texture map, a normal map. This was popularized in the game DOOM 3 by ID software where pretty low polygon models where used but with high resolution normal maps. The reason for using this technique is that the eye is more sensitive to variation in lighting than variation in shape.
I saw in your other question that the reason this came up was that you wanted to reduce the memory footprint of the vertex data. This is true, instead of storing three components for a normal in every vertex, you only need to store two components for the texture coordinates to the normal map. Enabling per-pixel lighting will come with a performance cost though so I'm not sure if this will be a net win, as usual the advice is to try and see.
Finally the diffuse lighting intensity in a point is proportional to the cosine of the angle between the surface normal and the direction of the light. For two vector the dot product is defined as:
a dot b = |a||b| cos(theta)
where |a| and |b| is the length of the vectors a and b respectively and theta is the angle between them. If the length is equal to one, |a| and |b| are referred to as unit vectors and the formula simplifies to:
a dot b = cos(theta)
this means that the diffuse lighting intensity is given by the dot product between the surface normal and the direction of the light. This means that all diffuse lighting is a form of DOT3-lighting, even if the name has come to refer to the per-pixel kind.
From here:
Bumpmapping is putting a texture on a model where each texel's brightness defines the height of that texel.
The height of each texel is then used to perturb the lighting across the surface.
Normal mapping is putting a texture on a model where each texel's color is really three values that define the direction that location on the surface points.
A color of (255, 0, 0) for example, might mean that the surface at that location points down the positive X axis.
In other words, each texel is a normal.
The Dot3 name comes from what you actually do with these normals.
Let's say you have a vector which points in the direction your light source points. And let's say you have the vector which is the normal at a specific texel on your model that tells you which direction that texel points.
If you do a simple math equation called a "dot product" on these two normal vectors, like so:
Dot = N1xN2x + N1yN2y + N1z*N2z
Then the resulting value is a number which tells you how much those two vectors point in the same direction.
If the value is -1, then they point in opposite directions, which actually means that the texel is pointing at the light source, and the light source is pointing at the texel, so the texel should be lit.
If the value is 1, then they point in the same direction, which means the texel is pointing away from the light source.
And if the value is 0, then one of the vectors points at 90 degrees relative to the other. Ie: If you are standing on the ground looking forward, then your view vector is 90 degrees relative to the normal of the ground which points up.