here’s an OSL script that does (allmost) the same job as the nodes…
/*
* Diffraction Grating Reflection
*/
#include "stdosl.h"
void rng_seed(output int rng, int seed)
{
int chash = seed;
if (chash == 0) chash = 1;
rng = chash * 891694213;
}
float rng_uniform(output int rng)
{
float res = rng / float(2137483647) * 0.5 + 0.5;
rng *= 891694213;
return res;
}
float randomInterval(float minval, float maxval, int seed, point ipt)
{
int rng;
float f=0;
float delta=maxval-minval;
f = fmod(cellnoise(ipt*12345.0), 1.0);
rng_seed(rng, int(f * 2137483647)+seed);
return delta*rng_uniform(rng)+minval;
}
void rotateVector(vector v, vector axis, float angle)
{
float sf=0, cf=0;
sincos(angle, sf, cf);
v=(normalize(cross(axis,v))*sf)+(v*cf);
}
shader Diffraction
(
color Color=1.0,
float Distance=1200,
float Roughness=0.0,
float Rotation=0.0,
normal Normal = N,
normal Tangent = normal(0.0,0.0,0.0),
int samples=1,
output closure color BRDF=reflection(N)
)
{
float Rg=clamp(Roughness,0,1);
float Rt=clamp(Rotation,0,1);
int smps=clamp(samples,1,32);
/* setup Tangent direction */
normal Tg=Tangent;
if (Tangent==normal(0.0,0.0,0.0))
{
normal Zaxis=normal(0.0,0.0,1.0);
Zaxis = transform("object", "world", Zaxis);
Tg=normalize(cross(Zaxis,Normal));
}
rotateVector(Tg, Normal, Rotation*M_2PI);
/* setup max order */
float maxorder=Distance/190;
/* setup loop */
normal NN;
color cl;
BRDF=0;
/* do sampling */
for(int i=1; i<=smps;i++){
/* setup random samples */
float wave=randomInterval(380, 780, i*19, P);
float order=round(randomInterval(1,maxorder,i*17,P));
float sgl=randomInterval(-1,1,i*13,P);
/* calculate angle */
float sTheta=sin(acos(dot(Normal,I)));
float wfac=sTheta-wave*order/Distance;
float angle= asin(wfac);
if (sgl>0){angle=-angle;}
/* rotate normal */
NN=Normal;
rotateVector(NN, Tg, angle);
cl=Color*wavelength_color(wave)/smps;
if(Roughness==0.0)
{
BRDF= BRDF + (cl * reflection(NN));
} else {
BRDF= BRDF + (cl * microfacet_beckmann(NN,Roughness));
}
}
}
And @moony, when I saw your setup, I thought in some kind of shader that do not need to be precise with the Light/Incoming relation… something like opals or other types of half chaotic iridescence… I’m going to play a bit with your ideas, and see what will come out