Page MenuHome

Cycles: Support bump mapping in GLSL viewport
ClosedPublic

Authored by Sergey Sharybin (sergey) on May 20 2016, 2:21 PM.

Details

Summary

This commit implements Bump node in GLSL, making it possible to
see previews of bump mapping in viewport without need to render.
Nothing really fancy going on here, just uses internal dFdx/dFdy
functions to get derivatives of the surface and map itself.
Quite basic but seems to behave correct-ish.

This commit also makes Displacement material output to affect
viewport shading by re-linking unconnected Normal input to a
node which was used for displacement output (via Bump node).

Intention of all this is to make it really easy to do bump map
painting with Cycles as an active render engine.

Diff Detail

Repository
rB Blender

Event Timeline

Some demo file:

Hi @Sergey Sharybin (sergey)

One thing to keep in mind: derivatives are not well defined if there are conditionals in the shader execution leading up to the .evaluation of the derivatives (For instance, read http://hacksoflife.blogspot.de/2011/01/derivatives-ii-conditional-texture.html). The cycles node system allows arbitrary code to run in order to evaluate uvs, therefore you might fall into issues with that. You may be able to hardcode this into some node (for instance, the UV node itself), and this would work much better.

Anyways, that's it for now, proper review later.

More comments...

source/blender/gpu/shaders/gpu_shader_material.glsl
3163

I guess you are trying to substitute mtex_bump_init_viewspace( vec3 surf_pos, vec3 surf_norm,
mtex_bump_init_viewspace and mtex_bump_tap3 here, but not sure if a derivative on the height itself is equivalent to derivative of texture coordinates + sampling 3 times - you'd need to check Morten's original paper for the math (https://docs.unrealengine.com/latest/attachments/Engine/Rendering/LightingAndShadows/BumpMappingWithoutTangentSpace/mm_sfgrad_bump.pdf)

3180

better use clamp instead of max? I see you assume strength is in 0.0 - 1.0 range below

source/blender/gpu/shaders/gpu_shader_material.glsl
3163

Trying to mimmic Cycles bump map SVM shader actually.

In one of the eariler versions of the patch it was much-much closer to Cycles and was doing all the derivatives stuffi n the object space. However, it will also require conerting bump mup partial derivatives to the object space, which i'm not really sure how to do efficiently here.

3180

Think you're right here. However, Cycles uses max(), hrrrm. Brecht? :)

Brecht Van Lommel (brecht) accepted this revision.

Generally looks good to me.

Not sure what to do with the conditionals issues.

If there is a discontinuity in the texture (due to conditionals, using a function like fmod, ..), then we will fail to compute proper derivatives regardless of the method we use. dFdx, manual texture taps, OSL style auto-differentiation, ...all of those things fail in one way or another.

I think we can just hope for the best knowing that this works ok for the important cases, and deal with any problem cases if they come up and are considered important.

source/blender/gpu/shaders/gpu_shader_material.glsl
3163

This is matching the Cycles code, which is based on the same paper. The derivative of the height is what we really want, it's what defines the normal.

Using the derivatives of the texture coordinates with finite differencing gives us an approximation to the true height differentials. The OpenGL dFdx and dFdy also gives us an approximation, normally implemented though finite differencing by computing a 2x2 block of pixels.

Both are approximating the same thing, and in practice I believe the approximations will be about equally accurate.

source/blender/nodes/shader/node_shader_tree.c
268

Typo.

This revision is now accepted and ready to land.May 21 2016, 4:35 PM
source/blender/gpu/shaders/gpu_shader_material.glsl
3180

I'm not sure why it's only using max, 0..1 is the intended range and this could be changed to clamp.

It's a minor compatibility break but I'm not really worried about this being a problem in practice. On the other hand values > 1 don't really break anything either, the normal stays normalized and is continuous, so not sure it's worth changing if it risk breaking some existing files.

This revision was automatically updated to reflect the committed changes.