14

Computing the normal from vertex positions is quite simple using the vector cross product. The cross product of two vectors $u$ and $v$ (noted $u \times v$, or sometimes $u \wedge v$) is a vector perpendicular to $u$ and $v$, of length $||u \times v|| = ||u|| \cdot ||v|| sin(\theta)$, with $\theta$ the angle between $u$ and $v$. The direction of the vector ...


7

Assuming that the normal was created by differentiating some height field f(u,v): N = normalize(df_du, df_dv, 1) What you probably want to achieve is to "strengthen" your normals as-if by scaling that height field by a factor C: g(u,v) = C*f(u,v) Then your new normal would be: M = normalize(dg_du, dg_dv, 1) = normalize(C*N0, C*N1, N2) Translating that ...


6

A rigid body has 6 degrees of freedom, in 3D- space. So that means you need 6 values to represent the object. The common way to do this is to store a position vector for position and 3 rotations. But for obvious reasons any 6 variables that are independent of each other would do this. The problem with vectors is that they aren't the most efficient way to ...


5

"decent" is quite subjective and if you are restricting the capture to certain types of surfaces and controlled lighting conditions. For example normals and other SVBRDF parameters for shiny metallic surfaces are very difficult to capture compared to non-metallic, matte and bright surfaces without texture. There are tools proposed in comments (CrazyBump, ...


5

After some researches and some answers from professionals here is my conclusion. Pros Don’t require tangents or binormals. Less interpolators. Only need two channels. less texture memory. Don’t suffer from tangent seams. Can be blended using alpha blending, without renormalization. Less mesh memory: We don’t need to store a tangent vector. Fast ...


4

How are screenspace normals created, and is this step before or after using normal maps or bump maps? They are created after using normal maps. In deferred rendering, you write to the various buffers (diffuse, normal, depth, etc.) in fragment shaders. By this time, the normal maps would have already been read. If it's done before using normal maps, how ...


4

Yes, you do need to transform the fetch direction into the space of the cubemap. If you could somehow figure out the fetch direction in the vertex shader, then you could do the transformation there instead, but that would produce worse lighting. It also may be worth optimizing for a smaller number of interpolants between the vertex and pixel shaders (rather ...


4

In my opinion, yes, it does. I've heard it claimed that in reality, the ratio of the tallest mountain on Earth to the Earth's diameter is smaller than the variations in height of an apple's skin to its diameter. So I can't say that it would be realistic, but it certainly looks better than not doing it. At the least it gives you some shading between high and ...


4

You can do this a little bit more efficiently and accurately by calculating derivatives of $P$ with respect to $u, v$—or the derivatives with respect to $\phi, \theta$, equivalently (up to a scalar multiple). Start by expressing $P$ in terms of the spherical coordinates: $$\begin{aligned} P_x &= r \cos \theta \cos \phi \\ P_y &= r \sin \theta \\ P_z ...


4

Idea A: Draw an invisible mesh that will occlude the points we don't want. Create a mesh from the point cloud. Render that mesh to a depth buffer but not to the color buffer. Render the point cloud using a depth test "closer or equal". This approach should give the expected result, but the problem with it is the first part, which is not trivial ...


4

I have managed to fix the error. It turns out the error was never situated in the normal calulation it was the shading algorith. The floating point precision error caused the new ray to be slightly below the surface, which meant it would intersect itself and become darker. This is a problem common in biased raytracers, the phenomenon known as "Shadow acne". ...


4

Maps with z = 1.0 everywhere are likely partial derivative maps. This is a variant on normal maps that's become fairly widespread. There are a few reasons to prefer it, but probably the most important is it lets you store the map as just two channels (red and green), which allows using better quality BC5 compression, while being cheap to decode in the shader....


3

You are not too far off with your second averaging approach. The problem is, that the area is the wrong weighting factor for what you want to achieve. You want each of the 3 sides of the cube to contribute equally to the vertex normal, but you need to extract the information from the adjacent triangles. The area and the number of triangles are bad weighting ...


3

The 2D pipeline involves ... [coordinate transformation terms] Can someone give me the detail differentiation among these? This is something I very recently learned while trying to understand how software handles 3D graphics behind the scenes. I've never encountered these terms in reference to 2D graphics before, but the ideas still apply. 2D graphics are ...


3

Conceptually simplest would be to treat it as a ray-casting problem, representing each point as a small sphere. It should work like the shadow rays in a conventional raytracer: iterate over all of your points, and for each one, trace a ray to the camera. If the ray intersects the sphere representing another point, then remove it. If the number of points is ...


3

That is, to my knowledge, a problem without a proper solution. You're seeing the discrepancy between shading normal and geometry normal and it becomes obvious, that the shading normal is just a trick. PBRT has a paragraph on this, their solution is to look at the geometric normal to determine whether to call the BRDF (reflection) or the BTDF (transmission), ...


3

I'm trying to condense my Deferred Rendering G-Buffer. So I have some questions about getting 2-component Screenspace Normals. I know Frostbite and Killzone (the only two AAA company's G-Buffers I could find) use them. I'm confused when you say "screenspace normals", Killzone uses view-space normals, they store the X & Y coordinate of the normal in FP16 ...


3

There are numerous approaches to setting up tangent bases on a mesh, and unfortunately, no totally universal standard for how they are calculated. Tangents are based on the mesh's UV mapping, so that the tangent vector points (at least roughly) along the U axis in texture space, and the bitangent along the V axis. This means each triangle in a mesh has its ...


2

Huge thanks to @MJP who answered this. The aim is to avoid the simplification made when using tangent space normals. Here is the paper : Blending in detail But only implement equation (4) which gives you this. float3 ReorientNormal(in float3 u, in float3 t, in float3 s) { // Build the shortest-arc quaternion float4 q = float4(cross(s, t), dot(s, t) ...


2

Skimming the math. Starting with a quaternion $Q=w+\left(x,y,z\right)$ then we can rotate $\mathbf{v}$ by: $$\mathbf{v}' = Q\mathbf{v}Q^{-1}$$ and if $Q$ is unit magnitude this reduces to: $$\mathbf{v}' = Q\mathbf{v}Q^*$$ To create a matrix we need to apply the rotation to the basis set to form our three equations: $$ \mathbf{x} = \left(1,0,0\right) \\ ...


2

Silly me, posting all of this hoping to get someone to solve it for me, I managed to find the solution tho, but perhaps more as a result of trial and error, than of actual understanding. Either way, this is the object I'm looking at now: Looking at my current tangent calculation: vector<vec4>tangentref(texkoordref.size()); //math UV size, w=amount ...


2

Since the question was somewhat clarified I will formalize both the question and the answer for future readers. Having a differentiable scalar field $f : \mathbb{R}^4 \rightarrow \mathbb{R}$ we want to find the gradient of the field with respect to $\theta, \phi$ on the 2-manifold defined parametrically by: $$(x(\theta,\phi), y(\theta,\phi) z(\theta,\phi), ...


2

You are correct, when they are talking about taking the inverse-transpose they are talking about the 3x3 part of the affine transformation leaving the translation since it doesn't affect the normal vector. Check : Normal / Transforming Normals | Wikipedia About how or why is it the inverse transpose, a simple explanation, that is also given in the book "...


1

In the most common normal map encoding, an RGB value of (0.5,0.5,1) would be uniformly flat. If the shader is meant to be unlit, you should be able to remove anything in the code that’s using the surface normal, light / view direction, etc.


1

Turns out I needed to be looking at the former normal as a unit vector $(\hat{r}, \hat{\theta},\hat{\varphi})$, and then use a rotation matrix as outlined here to find $(\hat{x},\hat{y},\hat{z})$.


1

Yeah, that doesn’t look like any bump, height, or normal map I’ve ever seen—as you’ve identified, there’s only information about the surface contour along a single axis. If anything, it looks like it’s meant to be overlaid on a texture as a cheap form of fake bump-mapping in an era where it was too expensive to do it for real.


1

The usual way of doing this with raymarching is to define your surface as a signed-distance field and use finite differences to get the gradient of the distance function at the point you’re sampling. In other words, if you have a function map(p) that returns the signed distance value at a point p, the normal at p is given by: float epsilon = 0.001; // ...


1

Your normal calculation looks backwards: edge2.cross(edge1), but (assuming CCW winding) it should be edge1 × edge2. The sign flip for back facing normals is also reversed; the ray direction and triangle normal should be facing in opposite directions, thus should have negative dot product, but it looks like you're flipping it to make the dot product always ...


1

(Is gouraud shading even supposed to be perspective correct?) Originally, it wouldn't have been perspective correct, but on (hardware) systems these days it will be. FWIW Dreamcast had perspective correct Gouraud shading because, once you are doing perspective correct texturing, it is relatively little additional cost to do Gouraud "correctly". I have ...


Only top voted, non community-wiki answers of a minimum length are eligible