Specular highlight behavior in mixed bsdf


I’m working on adding MDL material integration in Blender Cycles.

Currently, I managed to replicate Diffuse and Glossy Reflection BSDF.

However, there’s a weird behaviour with glossy reflection.

I tested the following MDL material script in Cycles - https://pastebin.com/U4HPvUWY
This is a simple mix of diffuse_reflection_bsdf and simple_glossy_bsdf.

Somehow, the render of this material in Cycles generates specular highlight when none is generated with same MDL script in Iray. (Also tested with equivalent material in Cycles)

I found that this specular highlight is added by Bsdf_evaluate_data.bsdf_glossy when evaluated in direct light sampling.

Hoping to get clues on why Bsdf_evaluate_data.bsdf_glossy is generating specular highlight in my implementation but not in Iray.

MDL implementation render in Cycles:

Iray render in Daz Studio:

Equivalent Blender Cycles Material render:


Could you provide the material source directly (shouldn’t be that big). pastebin[.]com seems not to work for me.

Without looking in the material source I can still try to guess. The generated code separates diffuse and glossy contribution. In your case, it is expected that the part of the bsdf generated by the diffuse_reflection_bsdf will be returned through Bsdf_evaluate_data.bsdf_diffuse. The part generated by the simple_glossy_bsdf will be returned through Bsdf_evaluate_data.bsdf_glossy.
If you don’t care about this separation, you can simply add them together. basically (bsdf_diffuse+bsdf_glossy)*light.

export material mix_mat()
= material(
surface: material_surface(
                    weight: 0.25f,
                    component: df::diffuse_reflection_bsdf(
                        tint: color(1,0,0),
                        handle: "")),
                    weight: 0.75f,
                    component: df::simple_glossy_bsdf(
                        roughness_u: 0,
                        roughness_v: 0,
                        tint: color(0,0,1),
                        handle: ""))
backface: material_surface()

Above is the MDL material script used.

I was able to identify what caused the specular highlight to appear.
It comes from Phong distribution evaluation in

Specular highlight is caused by the returned value when nh > 0.99999f.
I was testing with instance compilation and the returned value was translated to a really large number (i.e. 300k+)
When I dialled the number to be much smaller (i.e. <=1000), the specular highlight disappeared. (while retaining same behaviour for other lighting & material parameter scenarios i tested)

Also, I was using Point Light here in Cycles which is implemented as a sphere with a radius that emits light.
If I increase the radius of the sphere, the Blender Cycles Material also showed specular highlight which looked the same as MDL counterpart.
It was only when I dialled the sphere radius to be <= 0.001 that this discrepancy in behaviour happened.

Another thing, I was testing with instance compilation, so I will test with class compilation and see whether I get the same behavior.
And if I do, I will see what change could be suggested for the MDL compiler.

Are you generating code using the MDL backends or are you implementing the nodes yourself? In the MDL source, you are usually not able to set exponents directly. Instead, you set a roughness between 0 and 1.

I am implementing the node myself. I initially was going to integrate MDL SDK API into Cycles codebase. But realised it would require too many refactoring and generally make the code much harder to maintain than simply following the existing design.
Also I referenced VisRTX codebase from Github which implements simple_glossy_bsdf to understand and troubleshoot.