Thanks Effie that explanation has saved me lots of time trying to figure out how it was done it another shader. I can't seem to get it to work though. I don't have a lot of time right now so I'm going to give up for now ( there are other problems with the raymarcher that I have to figure out also when I have more time.) But just in case you can quickly see what I'm doing wrong I'll post the raymarcher below. The two lines you suggested I add are in the getLight and shadows functions.
Also if anyone has an idea of why I'm getting moving/distorted orbitTrap coloring when the camera moves or why there is a lot of noise produced in the image when the camera is far from the center of the scene I would really like to hear what you would say.
Thanks again Effie I really appreciate all the help you've been giving me.
//layout(location = 0) out vec4 fragColor;
//Raymarcher largely based on code by Syntopia, IQ, Effie, and Kali
//the comments on the variabl declarations are because I'm using UI elements for another raymarcher
uniform float raytracer[9];
uniform vec4 light[15];
uniform vec4 color[17];
uniform vec3 camera[3];
uniform vec4 uResolution;
float FOV = camera[0].x;
vec3 TransCam = camera[1]* vec3(1.0,1.0,-1.0);
vec3 RotateCam = camera[2];
int MaxRaySteps = int(raytracer[4]);
float MaxDistance = raytracer[8];
float Detail = raytracer[1];
float DetailAO = raytracer[2];
float FudgeFactor = raytracer[3];
float Dither = raytracer[6];
vec3 DiffuseLight = light[4].xyz; // spotlight dir
vec3 ColDiffuse = light[3].rgb * light[3].a; // spotlight color
vec3 ColSpecular = light[1].rgb;
float SpecularGain = light[1].a;
float SpecularExp = light[2].x;
vec3 ColCamLight= light[5].rgb * light[5].a;; // camlight color
vec3 ColBackLight = light[7].rgb * light[7].a;; // glow color
vec3 ColAmbient = light[14].rgb * light[14].a; // background color
//vec2 AO = light[0].zw * vec2(4.0,6.0);
vec4 AO = light[0]; // AO based on the number of raymarching steps
float Shadow = light[10].x;
float FallOff = light[11].x;
//vec4 ColorBase = vec4(color[0].rgb,color[1].r); // base color
vec3 ColorBase = color[0].rgb;
float OrbitStrength = color[1].r;
vec4 OrbitX = color[2]; // orbit X
vec4 OrbitY = color[3]; // orbit y
vec4 OrbitZ = color[4]; // orbit Z
vec4 OrbitW = color[5]; // orbit W
bool CycleColors = bool(color[8].x);
float Cycles= color[9].x;
vec3 DepthMap;// = color[6].rgb* vec3(1.0,4.0,4.0)-vec3(0.0,2.0,2.0); // background color
float kTile = color[13].w;
int kIterations = int(color[14].x);
float kZoom = color[14].y;
float kOffset = color[14].z;
float kDisp = color[14].w;
vec3 kJulia= color[15].xyz;
float kScale= color[15].w;
float kColorMix = color[16].x;
float Kaliset(vec3 pos) {
if (kIterations == 0) return 0;
if (kTile > 0.0) pos = abs(2.0*kTile-mod(pos-kTile,kTile*4.0))-kTile;
vec3 p = pos*kZoom+kOffset; // Zoom and Offset values set the scale and relative position of the Kaliset fractal
int i=0;
float ln=0;
float lnprev=0;
float expsmooth=0;
for (i=0; i<kIterations; i++) {
// Kaliset formula (Scale and Julia are the params):
p=abs(p);
p=p/dot(p,p); // means that the vector is divided by the square of it's length (inversion)
p=p*kScale+kJulia;
// Exp. smoothing calculation:
lnprev=ln;
ln=length(p);
expsmooth+=exp(-1/abs(lnprev-ln));
}
return expsmooth;
}
mat3 rotCam = rotationMatrixXYZ4(RotateCam);
vec4 orbitTrap = vec4(1.0);
float shadow = 0.0;
float DE(vec3 pos) ;
float minDist = pow(10.0,Detail);
float aoEps = pow(10.0,DetailAO);
void init();
float rand(vec2 co){
// implementation found at: lumina.sourceforge.net/Tutorials/Noise.html
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
float trace(in vec3 viewPos, in vec3 viewAngle)
{
float detail = Detail * 0.001;
float dist = detail * 2.0;
float totalDist = 0.0;
float eps = minDist;
float epsMod = 0.0;
for (int i=0; i<MaxRaySteps; i++)
{
if ( abs(dist) < detail || totalDist > MaxDistance) continue;
dist = DE(viewPos+viewAngle*totalDist);
dist *= FudgeFactor;
if (i == 0) dist*=(Dither*rand(viewAngle.xy))+(1.0-Dither);
totalDist += dist;
epsMod = pow(totalDist,1.0)*eps;
if (dist < epsMod) break;
}
if (totalDist > MaxDistance) totalDist = -1.0;
return totalDist;
}
vec3 getNormal(in vec3 pos)
{
vec3 eps = vec3(0.0,0.00001,0.0);
return normalize(vec3(
DE(pos+eps.yxx)-DE(pos-eps.yxx),
DE(pos+eps.xyx)-DE(pos-eps.xyx),
DE(pos+eps.xxy)-DE(pos-eps.xxy)));
}
float softshadow( in vec3 ro, in vec3 rd, float mint, float k)
{
float res = 1.0;
float t = mint;
float h = 1.0;
//Effie's suggestion? - DiffuseLight is light Position
float distToLight = length(DiffuseLight-ro);
for( int i=0; i<35; i++ )
{
if (h >= distToLight) break;
h = DE(ro + rd*t);
res = min( res, k*h/t );
t += clamp( h, 0.02, 2.0 );
}
return clamp(res,0.0,1.0);
}
float ambientOcclusion(vec3 p, vec3 n)
{
float ao = 0.0;
float d1 = DE(p);
float wSum = 0.0;
float w = 1.0;
float d = 1.0 - (Dither*rand(p.xy));
for (float i = 1.0; i < 6.0; i ++)
{
float D = (DE(p + d*n*i*i*aoEps)-d1) / (d*i*i*aoEps);
w *= 0.6;
ao += w * clamp(1.0-D,0.0,1.0);
wSum += w;
}
return clamp(AO.w*ao/wSum,0.0,1.0);
}
vec3 getLight(in vec3 normal, in vec3 pos, in vec4 orbit, in vec3 cam)
{
//Attempt at Effie's light position, the DiffuseLight variable is the light position - was the light vector
vec3 lightDir = normalize(DiffuseLight-pos);
float diffuse = clamp( dot( lightDir, normal ), 0.0, 1.0 );
//float diffuse = clamp( dot( DiffuseLight, normal ), 0.0, 1.0 );
float sf = max(0.0, dot( normal,DiffuseLight));
float specular = pow(sf,SpecularExp);
float background = clamp(dot(-DiffuseLight, normal),0.0,1.0);
float ambient = clamp(dot(cam, cam),0.0,1.0);
float camlight = clamp( dot( -cam, normal ), 0.0, 1.0 );
if (diffuse > 0.01 && Shadow > 0.0) shadow = softshadow(pos+0.001*normal,normalize(DiffuseLight),0.0005, FallOff);
else shadow = 1.0;
vec3 brdf = ColCamLight*camlight;
brdf += ColDiffuse*diffuse*pow(vec3(shadow),vec3(4.0))*shadow;
brdf += ColDiffuse*diffuse*(1.0-Shadow);
brdf += ColSpecular*specular*SpecularGain*pow(vec3(shadow),vec3(4.0))*shadow;
brdf += ColBackLight*background;
brdf += ColAmbient * ambient;
return brdf;
}
vec3 cycle(vec3 c, float s) {
return vec3(0.5)+0.5*vec3(cos(s*Cycles+c.x),cos(s*Cycles+c.y),cos(s*Cycles+c.z));
}
vec4 getMaterial(in vec4 orbit)
{
vec4 rgba;
vec3 orbitColor;
orbitTrap.w = sqrt(orbitTrap.w);
if (CycleColors)
{
orbitColor = (cycle(OrbitX.xyz,orbitTrap.x)*OrbitX.w*orbitTrap.x +
cycle(OrbitY.xyz,orbitTrap.y)*OrbitY.w*orbitTrap.y +
cycle(OrbitZ.xyz,orbitTrap.z)*OrbitZ.w*orbitTrap.z +
cycle(OrbitW.xyz,orbitTrap.w)*OrbitW.w*orbitTrap.w);
}
else
{
orbitColor = (OrbitX.xyz*OrbitX.w*orbitTrap.x +
OrbitY.xyz*OrbitY.w*orbitTrap.y +
OrbitZ.xyz*OrbitZ.w*orbitTrap.z +
OrbitW.xyz*OrbitW.w*orbitTrap.w);
}
/* vec3 orbitColor = (OrbitX.xyz*OrbitX.x*pow(clamp(1.0-2.0*orbitTrap.x,0.0,1.0),8.0) +
OrbitY.xyz*OrbitY.y*pow(clamp(1.0-2.0*orbitTrap.y,0.0,1.0),8.0) +
OrbitZ.xyz*OrbitZ.z*pow(clamp(1.0-2.0*orbitTrap.z,0.0,1.0),8.0) +
OrbitW.xyz*OrbitW.w*pow(clamp(1.0-2.0*orbitTrap.w,0.0,1.0),8.0));
*/
rgba = vec4(mix(ColorBase,orbitColor,OrbitStrength),1.0);
return rgba;
}
void rayMarchMain()
{
init();
//vec2 p = -1.0 + 2.0 * gl_FragCoord.st/uTDOutputInfo.res.zw;
//p.x *= uTDOutputInfo.res.z/uTDOutputInfo.res.w;
vec2 p = -1.0 + 2.0 * gl_FragCoord.st/uResolution.zw;
p.x *= (uResolution.z/uResolution.w)*FOV*4.0;
p.y *= FOV*4.0;
vec3 viewRotCam = normalize(p.x*rotCam[0] + p.y*rotCam[1] + 2.0 * rotCam[2]);
vec4 color = vec4(0.0);
float rayMarch = trace(TransCam,viewRotCam);
vec3 pos = vec3(0.0);
vec4 trap = orbitTrap;
if (rayMarch > 0.0)
{
pos = TransCam + rayMarch * viewRotCam;
vec3 norm = getNormal(pos);
vec4 mat = getMaterial(trap);
float ao = ambientOcclusion(pos,norm);
if (AO.a > 0.0) mat.rgb = mix(mat.rgb, AO.rgb, ao);
vec3 light = getLight(norm, pos, trap, viewRotCam);
color = mat * vec4(light,1.0) * vec4(vec3(exp(minDist*rayMarch)),1.0);
}
color = sqrt(color);
color = mix(color, smoothstep(0.0,1.0,color),0.25);
//vec3 depthVec = pos * viewRotCam; // need rotate z based on camera angle
//float depth = 1- pos.z * DepthMap.y - DepthMap.z;
//color = mix(color,vec4(vec3(depth),1.0),DepthMap.x);
//if (DepthMap.x == 1.0) color *= vec4(clamp(vec3(depth),0.0,1.0),1.0);
//else if (DepthMap.x == 2.0) color = vec4(vec3(depth),1.0);
gl_FragColor = vec4(color);
}