Skip to content
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

Add support for black and white Bump Maps to compute normals PR #559

Closed
wants to merge 5 commits into from

Conversation

dongho-shin
Copy link
Contributor

related : #558

also this pr has a problem(I write a details in related issue #558 )

bumpMap applied not fully success(especially plane)

image Untitled (28)

@gkjohnson
Copy link
Owner

Thanks - this is easier to understand. I think it's best to look at how normal mapping is handled in the path tracer and use similar code. A bump map is basically a normal map - you just have to compute the normals from a notional "height" computed from the black and white values.

@gkjohnson
Copy link
Owner

You'll also want to make sure that tangents are generated when bump maps are present instead of just when normal maps are:

https://github.com/gkjohnson/three-gpu-pathtracer/blob/main/src/core/DynamicPathTracingSceneGenerator.js#L83-L84

@dongho-shin
Copy link
Contributor Author

@gkjohnson i miss that... I'll check tangents I use only bumpMap at mesh and I can't get tangent attributes normally at shader

@dongho-shin
Copy link
Contributor Author

dongho-shin commented Mar 14, 2024

I'm pretty new in glsl or graphics so i don't have a idea how to do dFdx and dFdy manually can i get a hint?

This is as far as I understand it at this point. surf_pos (- vViewPosition) that input of perturbNormalArb(in my pr and three.js bumpMap function) from vertex shader so its value has no effected pathTracing sampling but dFdx, dFdy (surf_pos) has effected right?
because dFdx dFdy get near gl_Fragcoord and get change of x or y automatically

then should I get a near vertex position in screen space and add by uniform and use it in glsl?

** I also check blender cycles osl codes(node_bump.osl)

/* "Bump Mapping Unparameterized Surfaces on the GPU"
 * Morten S. Mikkelsen, 2010 */

surface node_bump(int invert = 0,
                  int use_object_space = 0,
                  normal NormalIn = N,
                  float Strength = 0.1,
                  float Distance = 1.0,
                  float SampleCenter = 0.0,
                  float SampleX = 0.0,
                  float SampleY = 0.0,
                  output normal NormalOut = N)
{
  point Ptmp = P;
  normal Normal = NormalIn;

  if (use_object_space) {
    Ptmp = transform("object", Ptmp);
    Normal = normalize(transform("object", Normal));
  }

  /* get surface tangents from normal */
  vector dPdx = Dx(Ptmp);
  vector dPdy = Dy(Ptmp);

  vector Rx = cross(dPdy, Normal);
  vector Ry = cross(Normal, dPdx);

  /* compute surface gradient and determinant */
  float det = dot(dPdx, Rx);
  vector surfgrad = (SampleX - SampleCenter) * Rx + (SampleY - SampleCenter) * Ry;

  float absdet = fabs(det);

  float strength = max(Strength, 0.0);
  float dist = Distance;

  if (invert)
    dist *= -1.0;

  /* compute and output perturbed normal */
  NormalOut = normalize(absdet * Normal - dist * sign(det) * surfgrad);
  NormalOut = normalize(strength * NormalOut + (1.0 - strength) * Normal);

  if (use_object_space) {
    NormalOut = normalize(transform("object", "world", NormalOut));
  }
}

I think it's same in three.js codes
still work in progress...

@dongho-shin
Copy link
Contributor Author

image

I fix a shader but it looks fine as you said I caculate height like normal map doing and add it to normal

normal += vTBN * perturbNormalArb( -vViewPosition, (normal * 2.0 - 1.0), dHdxy ,  surfaceHit.side);

@gkjohnson
Copy link
Owner

I'm pretty new in glsl or graphics so i don't have a idea how to do dFdx and dFdy manually can i get a hint?

Of course! Feel free to ask questions. I'm happy to have some help adding additional features to the project.

Regarding the dFdX and dFdY functions - they compute the apparent change in a variable from pixel to pixel in screen space. It does this by checking sibling pixels and computing the difference between the variable value. This great for traditional rasterization but of course because all of these path tracing operations occur as a light ray bounces around a scene it's not appropriate to compute the change in texture value in screen space.

Likewise the idea of using a "view position" or "direction" (which is based on the view ray from the original camera position) doesn't make sense since the rays can hit a surface from any direction after bouncing around. This is why the perturbNormalArb cannot be used.

So on to how to compute the derivative (dFdX, dFdY) of the texture without using the built in functions - the derivative is the change in a variable over time along some dimension. So, instead, to manually compute the change along the X axis, for example, you can sample the value at the point hit and one pixel to the left and right and compute the derivative from those values.

Since a bump map is basically a height map the derivative of a pixel represents the slope of the surface represented in the bump map which you can use to compute the normal.

Hopefully this was helpful - let me know if you need me to elaborate on anything.

@dongho-shin
Copy link
Contributor Author

then approach would simple with conversion of bump to normal... I'm going to find a solution of it

@gkjohnson gkjohnson closed this Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants