
mdl 1.4;

import ::df::*;
import ::base::*;
import ::math::*;
import ::state::*;
import ::anno::*;
import ::tex::*;

float2 XYZtoUV(float3 p)
{
    p=math::normalize(p);
    return float2(math::atan2(p.x,-p.y)/math::acos(-1)*0.5+0.5,math::asin(-p.z)/math::acos(-1)+0.5);
}

color DrawSphereGrid(float3 p,float2 gridsize,float ThicknessExp,color GridColor)
{
    float2 uv=XYZtoUV(p);
    // float chess4=(math::frac((uv.x-0.5)*2)>0.5)^(math::frac((uv.y-0.5)*1)>0.5);
    uv=(uv-float2(0.5))*gridsize;
    // uv*=math::exp2(ScaleExp*0.1);
    float2 p2f=math::frac(uv);
    float2 p2w=math::floor(uv)/gridsize;
    float chess=(math::frac(uv.x/2)>0.5)^(math::frac(uv.y/2)>0.5);
    // float3 cv=float3(p2f.x,p2f.y,chess);
    // float2 dv=math::abs(math::frac(uv)*2-1)*math::exp2(7-ThicknessExp*0.1)/math::pow(math::abs(uv/p.z),.5);
    float2 dv=math::abs(math::frac(uv+0.5)*2-1)*math::exp2(11-ThicknessExp*0.1)*float2(math::length(float2(p.x,p.y)),0.5)/gridsize;
    float grid=math::max(math::saturate(1-dv.x),math::saturate(1-dv.y));

    color c=color(1);
    c=math::lerp(color(p2f.x,p2f.y,1),color(p2w.x,p2w.y,0),chess);
    c=math::lerp(c,GridColor,grid);

    return c;
}

color DrawJulia(float3 p,uniform float ScaleExp,uniform float HorizonFactor,uniform float2 OffsetTop,uniform float2 OffsetBottom)
{
    float pz=math::abs(p.z)+math::exp2(ScaleExp*0.1+HorizonFactor*0.1-3);
    float2 uv=float2(p.x/pz,p.y/pz);

    float2 u=uv*math::exp2(ScaleExp*0.1-2);
    float2 z=u;
    float2 c=p.z>0?OffsetTop:OffsetBottom;
    color col=color(1);

    bool stop=false;
    for(int i=0;i<50&&!stop;i++){
        z=((float2((z.x)*(z.x)-(z.y)*(z.y),2*(z.x)*(z.y))+c));
        stop=math::length(z)>2;
        // g=math::lerp(g,g+1,1-math::smoothstep(0,2,math::length(z)));
        color ncol=color(0.5)+color(0.5*math::sin(2*math::log2(float(i+1)*math::sqrt(float3(3,5,7)))));
        ncol=ncol+color(.1/math::length(z-float2(1.+0.8*math::sin(float(i)),0)));
        col=math::lerp(col,ncol,1-math::smoothstep(0,2,math::length(z)));
    }
    // c=color(g);
    // c=color(math::length(z.x));
    return col;
}

export material dome_gridspherejulia (
	color emissive_color = color(1.0),
    uniform float Intensity=1000 [[ anno::soft_range(float(0.0f), float(1000.0f)) ]],
    uniform float Exposure=0,
    color GridColor = color(0.9),
    uniform int GridX=90,
    uniform int GridY=45,
    uniform float ScaleExp=0,
    uniform float ThicknessExp=0,
    uniform float HorizonFactor=0,
    uniform float2 OffsetTop=float2(0.025,0.644),
    uniform float2 OffsetBottom=float2(-0.191,0.672)
) = let {
    //base::texture_coordinate_info uvw = base::coordinate_source(base::texture_coordinate_object,0);
    //float3 p = float3(uvw.position.x,uvw.position.y,uvw.position.z);
    float3 p = state::position();
    color col_1=emissive_color*DrawSphereGrid(p,float2(GridX,GridY),ThicknessExp,GridColor);
    color col_2=emissive_color*DrawJulia(p,ScaleExp,HorizonFactor,OffsetTop,OffsetBottom);

    float s = math::max(0, p.z - 0.3) / 0.17;
    float ss = math::saturate(s*s / 10);

    // When this material was written the RTX Renderer was off by a factor of pi internally.
    // https://nvidia-omniverse.atlassian.net/browse/OM-30721
    // To keep golden images, we divide here by pi now.
    color col= math::lerp(col_1, col_2, ss) / math::PI;

    //Other examples:
    //color col= math::lerp(col_1, col_2, p.y);
    //color col= col_1;
    //color col= color(p.y, p.y, p.y);
    //color col= color(p.z, p.z, p.z);

} in material(
	surface: material_surface(
        emission:  material_emission (
            df::diffuse_edf(),
            intensity: col*Intensity*math::exp2(Exposure)
        )
    )
);
