Bevel shader

That’s not very difficult. Since calculating the normal is in world coordinates; and object coords, uv’s, and derivatives are given as global variables at every time, it’s just a matter to output the transformations.

This was interesting from a hard surface/gamedev point of view so I took a different approach by directly baking the bevels into a texture. With a bit more work I might get something usable out of it.

By baking the bevels I mean just taking a low poly mesh and running a script that generates a normal map with bevels where sharp edges are.

edit: Updated the images to feature the script a little better



it looks nice

I’ve also been using RedShift GPU renderer in Maya and there has been some discussion over at their forums about implementing a similar feature but a patent on the rounded corner shader from Mental Ray has been preventing them from publicly releasing it.

Given Blender is open source I wonder if patent issues apply?

I don’t have substance designer, but found this and looks good, and I think there are usefull tips in it.

this is super usefull mzprox, thx!
I tested version 1.0 and its working with curvature textures-no chamfer on penetrating surfaces

version 2.0 works similar to this bevel shader script.

I’m interested to check bevel shader out, but reading this thread I can’t tell which is the latest version.
Not really interested in baking or such, just making hard edges looking good.
Also: is a boolean union needed to make this shader work with intersecting geometry?

hey all can anyone point me the last build of the shader and also can this be baked on normal map?
thanks in advance

That is very cool! Only few minutes of play I was able to create this.


Only thing that makes me sad is that OSL does not support GPU. :confused: I wish blender had real Cycles node of this.

Edit: It somehow does not work very well with glossy shader. The roughness value of the glossy disappears.

See this image of the problem and the node setup I created:

https://dl.dropboxusercontent.com/u/5904620/Blender_aid/bevel_.jpg

Here is actually that my file also:

https://dl.dropboxusercontent.com/u/5904620/Blender_aid/rounded_bevels_test.blend

Edit edit: I think I did not understood correctly how the shader work’d, so I used it little wrong. My next test works correctly! :slight_smile:

I did a small test and bake a bevel to a cube but i didnt get there yet :stuck_out_tongue:
Anyone knows why my baked normalmap looks like that?





also heres the blend https://www.dropbox.com/s/eqrhpe5iu0rduvv/bevel_baker.blend1?dl=0

I can’t check the file right now, but from the pictures I can spot three things:
Both rgbmixers in the node setup must have a factor of 1.0, and the last one should be set to ‘multiply’.
The pass to be baked should be ‘Diffuse Color’ and not ‘Diffuse’ (at least if the shader to which you connected the node setup is a diffuse).

I’ look at your file later to see if there’s anything else. :wink:

i tweaked the mixers like you said but still no good, also on the bake options theres no diffuse color only diffuse.I use the 2.77 blender bw
Thanks in advance

your settings are ok now (the color setting was correct, I just got that idea 'cos I still use 2.72 from time to time and there the color, direct and indirect options are inside the bake type) …

Anyway, I was testing here with other meshes and my results were also flat… :frowning:

So I tested another bevel script that I have (I think an older one from Piotr) and this one worked!!

You may use this script to bake your normal maps. In the meanwhile, I’ll try find some time to debug the script from this thread (I really don’t know why it’s not working).

void rng_seed(output int rng, int seed) 
{ 
  int chash = seed; 
  if (chash == 0) chash = 1; 
  rng = chash * 30391861; 
} 
 
float rng_uniform(output int rng) 
{ 
  float res = rng / float(2137483647) * 0.5 + 0.5; 
  rng *= 30391861; 
  return res; 
} 
 
void to_unit_disk(float x, float y, output float x_out, output float y_out) 
{ 
  float r, phi; 
  float a = 2.0 * x - 1.0; 
  float b = 2.0 * y - 1.0; 
     
  if(a > -b)  
  { if(a > b)  
    { r = a; 
      phi = M_PI_4 *(b/a); 
    } 
    else  
    { r = b; 
      phi = M_PI_4 *(2.0 - a/b); 
  } } 
  else  
  { if(a < b)  
    { r = -a; 
      phi = M_PI_4 *(4.0 + b/a); 
    } 
    else  
    { r = -b; 
      if(b != 0.0) phi = M_PI_4 *(6.0 - a/b); 
      else phi = 0.0; 
  } } 
  x_out = r * cos(phi); 
  y_out = r * sin(phi); 
} 
 
void make_orthonormals(vector N, output vector a, output vector b) 
{ 
  if(N[0] != N[1] || N[0] != N[2]) a = cross(vector(1, 1, 1), N); 
  else a = cross(vector(-1, 1, 1), N); 
   
  a = normalize(a); 
  b = cross(N, a); 
} 
 
vector sample_cos_hemisphere(vector N, float randu, float randv) 
{ 
  vector T, B; 
     
  make_orthonormals(N, T, B); 
  to_unit_disk(randu, randv, randu, randv); 
  float costheta = sqrt(max(1.0 - randu * randu - randv * randv, 0.0)); 
 
  return randu * T + randv * B + costheta * N; 
} 
 
shader node_occlusion2( 
  color Effect = color(0), 
  color No_Effect = color(1), 
  int Mode = 0, /* 0: Concave (AO) 1:Convex (Wear) 2:Both */ 
  int InvertEffect = 0, 
  float Distance = 0.2, 
  int Samples = 1, 
  normal Normal = N, 
  output color Color = 0, 
  output float Fac = 0, 
  output normal outNormal = 0 
) 
{ 
  int i, rng; 
  float f, randu, randv, ray_t, hits = 0; 
  vector ray_P, ray_R; 
  normal hit_normal = N; 
  outNormal = Normal; 
  float hit_dist; 
 
  f = fmod(cellnoise(P*123456.0), 1.0); 
  rng_seed(rng, int(f * 21374647)); 
   
  for(i = 0; i < Samples; i++)  
  { randu = rng_uniform(rng); 
    randv = rng_uniform(rng); 
        
    ray_P = P; 
    ray_R = sample_cos_hemisphere(-N, randu, randv); 
    ray_t = Distance; 
     
         
    if (!Mode) 
    { if(trace(ray_P, -ray_R, "maxdist", ray_t)) { 
            hits += 1.0; 
            int HitNormal = getmessage ("trace", "N", hit_normal); 
            outNormal = outNormal + (hit_normal); 
        } 
    } 
    else if (Mode == 1) 
    { if(trace(ray_P, ray_R, "maxdist", ray_t)) { 
           hits += 1.0; 
           int HitNormal = getmessage ("trace", "N", hit_normal); 
           if (dot(I, -hit_normal) > 0.0) outNormal = outNormal - (hit_normal); 
        } 
    } 
    else {  
        if(trace(ray_P, -ray_R, "maxdist", ray_t)) { 
            hits += 1.0; 
            int HitNormal = getmessage ("trace", "N", hit_normal); 
            outNormal = outNormal + (hit_normal); 
        } 
        if(trace(ray_P, ray_R, "maxdist", ray_t)) { 
           hits += 1.0; 
           int HitNormal = getmessage ("trace", "N", hit_normal); 
           if (dot(I, -hit_normal) > 0.0) outNormal = outNormal - (hit_normal); 
        } 
    }  
  } 
  Fac = 1.0 - (hits/Samples); 
  if(InvertEffect) Color = mix(No_Effect, Effect, Fac); 
  else Color = mix(Effect, No_Effect, Fac); 
  outNormal = normalize(outNormal); 
}

I test the bake node with last script but didnt get any good results, pls if you could upload a .blend i d greatful :slight_smile:

it’s not work good to smooth edges.

Hi! So still nothing about usefulness this stuff for baking and exporting normal?

+1

It is super useful for games, arch, product design - anything. This thread is a good indicator of that. I hope one day we’ll see CyclesGPU have support for this feature.

The problem is not about Cycles atm. It’s about OSL, that does not support GPU.

Does anyone considered adding this as a request to the current 2.8 branch? This could be implemented as a node to the new PBR viewport, I just dont know how viable it would be for the development time.

You misinterpret me. I was on about the rounded corners feature in general- not refering to osl nor this shader which seems to have a few issues. Most production render engines have good support for this feature. There seems to be a clear demand here as well. I just hope to see native support for this feature on GPU sooner or later :slight_smile: