Skip to content

10. How To

3Dickulus edited this page Aug 4, 2022 · 14 revisions

Table of Contents

Create a KeyFrame Animation

30 - Simple Keyframe Animation.frag
  1. Select "Progressive" and "Stop" from the rendermode toolbar.
  2. Select Menu Item... Edit->Insert Command->Presets->Insert Preset From Current Settings
    or Push the "F8" key. This will give you the opportunity to choose a name or use the one provided.
    By default it will be named "KeyFrame.nnn".
    This will auto increment as you add keyframes.
    Select OK or press Return to add this as a KeyFrame.
  3. Change the camera position by navigating with the keyboard or mouse.
    Push the "F8" key. Repeat...
  4. After adding keyframes select the "Animation" button then select "Play".
    You should see your animation playing.
 Must have at least 2 KeyFrames to begin animating.
 Suggest starting with only a default Preset.
If you already have keyframes and want to adjust one...
  1. Select "Progressive" and "Stop" from the rendermode toolbar.
  2. Select the KeyFrame you want to edit from the "Preset" pull down menu in the "Variable Editor".
  3. "Apply" as current view.
  4. Make adjusments to the camera position using the mouse buttons, wheel and or keyboard control.
  5. In the main menu select "Edit->Insert Command->Presets->Insert Preset From Current Settings"
    or press the "F8" key.
 You will be shown "KeyFrame.nnn" where nnn is the same number as the currently
selected frame. New camera coordinates will replace the block marked keyframe.
 That is it, done! this is how tutorial 30 was created.
 CTRL+S will save the current frag to file with no dialog, overwrites existing file.
Source code
// Number of fractal iterations.
uniform int Iterations;  slider[0,9,100]

// Number of color iterations.
uniform int ColorIterations;  slider[0,9,100]

// Mandelbulb exponent (8 is standard)
uniform float Power; slider[0,8,16]

// Bailout radius
uniform float Bailout; slider[0,5,30]

// Alternate is slightly different, but looks more like a Mandelbrot for Power=2
uniform bool AlternateVersion; checkbox[false]

uniform vec3 RotVector; slider[(0,0,0),(1,1,1),(1,1,1)]

uniform float RotAngle; slider[0.00,0,180]


#group Translation
uniform vec3 TransVector; slider[(-1,-1,-1),(1,0,0),(1,1,1)]
uniform float TransSpeed; slider[0,0,1]
uniform float ImpulseStrength; slider[0,0,10]
uniform float ImpulseRate; slider[0,0,10]
uniform float ImpulseOffset; slider[0,0,10]
uniform vec3 TRotVector; slider[(-1,-1,-1),(1,0,0),(1,1,1)]
uniform float TRotSpeed; slider[0,0,45]

mat3 rot;
uniform float time;

void init() {
	 rot = rotationMatrix3(normalize(RotVector), RotAngle);
}

// This is my power function, based on the standard spherical coordinates
// as defined here http://en.wikipedia.org/wiki/Spherical_coordinate_system
//
// It seems to be similar to the one Quilez uses:
// http://www.iquilezles.org/www/articles/mandelbulb/mandelbulb.htm
//
// Notice the north and south poles are different here.
void powN1(inout vec3 z, float r, inout float dr) {
	// extract polar coordinates
	float theta = acos(z.z/r);
	float phi = atan(z.y,z.x);
	dr =  pow( r, Power-1.0)*Power*dr + 1.0;
	
	// scale and rotate the point
	float zr = pow( r,Power);
	theta = theta*Power;
	phi = phi*Power;
	
	// convert back to cartesian coordinates
	z = zr*vec3(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta));
}

// This is a power function taken from the implementation by Enforcer:
// http://www.fractalforums.com/mandelbulb-implementation/realtime-renderingoptimisations/
//
// I cannot follow its derivation from spherical coordinates,
// but it does give a nice mandelbrot like object for Power=2
void powN2(inout vec3 z, float zr0, inout float dr) {
	float zo0 = asin( z.z/zr0 );
	float zi0 = atan( z.y,z.x );
	float zr = pow( zr0, Power-1.0 );
	float zo = zo0 * Power;
	float zi = zi0 * Power;
	dr = zr*dr*Power + 1.0;
	zr *= zr0;
	z  = zr*vec3( cos(zo)*cos(zi), cos(zo)*sin(zi), sin(zo) );
}



uniform bool Julia; checkbox[false]
uniform vec3 JuliaC; slider[(-2,-2,-2),(0,0,0),(2,2,2)]

// Compute the distance from `pos` to the Mandelbox.
float DE(vec3 pos) {
	vec3 z=pos;
	float r;
	float dr=1.0;
	int i=0;

	if (TRotSpeed>0.0) {
		rot=rotationMatrix3(normalize(TRotVector),TRotSpeed*time);
		z*=rot;
	}
	if (TransSpeed>0.0) {
		z+=normalize(TransVector)*time*TransSpeed*10.0;
	}
	if (ImpulseStrength>0.0) {
		z+=normalize(TransVector)*(0.8+sin(time*ImpulseRate+ImpulseOffset))*ImpulseStrength;
	}

	r=length(z);
	while(r<Bailout && (i<Iterations)) {
		if (AlternateVersion) {
			powN2(z,r,dr);
		} else {
			powN1(z,r,dr);
		}
		z+=(Julia ? JuliaC : pos);
		r=length(z);
		z*=rot;
		if (i<ColorIterations) orbitTrap = min(orbitTrap, abs(vec4(z.x,z.y,z.z,r*r)));
		i++;
	}

//	if ((type==1) && r<Bailout) return 0.0;
	return 0.5*log(r)*r/dr;
	/*
	Use this code for some nice intersections (Power=2)
	float a =  max(0.5*log(r)*r/dr, abs(pos.y));
	float b = 1000;
	if (pos.y>0)  b = 0.5*log(r)*r/dr;
	return min(min(a, b),
		max(0.5*log(r)*r/dr, abs(pos.z)));
	*/
}

float dummy(vec3 p){
p*=time;
return time;
}


#preset Default
FOV = 0.62536
Eye = 1.65826,-1.22975,0.277736
Target = -5.2432,4.25801,-0.607125
Up = 0.401286,0.369883,-0.83588
EquiRectangular = false
FocalPlane = 1
AutoFocus = false
Aperture = 0
Gamma = 2.08335
ToneMapping = 3
Exposure = 0.6522
Brightness = 1
Contrast = 1
Saturation = 1
GaussianWeight = 1
AntiAliasScale = 2
Detail = -2.84956
DetailAO = -1.35716
FudgeFactor = 1
MaxRaySteps = 164
BoundingSphere = 10
Dither = 0.51754
NormalBackStep = 1
AO = 0,0,0,0.85185
Specular = 1.6456
SpecularExp = 16.364
SpecularMax = 10
SpotLight = 1,1,1,1
SpotLightDir = -0.22666,0.5
CamLight = 1,1,1,1.53846
CamLightMin = 0.12121
Glow = 1,1,1,0.43836
GlowMax = 52
Fog = 0
HardShadow = 0.35385
ShadowSoft = 12.5806
Reflection = 0
BaseColor = 1,1,1
OrbitStrength = 0.14286
X = 1,1,1,1
Y = 0.345098,0.666667,0,0.02912
Z = 1,0.666667,0,1
R = 0.0784314,1,0.941176,-0.0194
BackgroundColor = 0.607843,0.866667,0.560784
GradientBackground = 0.3261
CycleColors = false
Cycles = 4.04901
EnableFloor = true
FloorNormal = 0,1,0
FloorHeight = -2
FloorColor = 1,1,1
Iterations = 12
ColorIterations = 8
Power = 8
Bailout = 6.279
AlternateVersion = true
RotVector = 1,1,1
RotAngle = 0
Julia = false
JuliaC = 0,0,0
#endpreset


#preset KeyFrame.001
FOV = 0.62536
Eye = 1.65826,-1.22975,0.277736
Target = -5.2432,4.25801,-0.607125
Up = 0.401286,0.369883,-0.83588
#endpreset

#preset KeyFrame.002
FOV = 0.62536
Eye = 3.96463,0.917888,0.279432
Target = -4.74042,-0.257782,-0.320685
Up = -0.709039,0.700838,-0.0780331
#endpreset

#preset KeyFrame.003
FOV = 0.62536
Eye = 1.33376,0.978975,2.81437
Target = -2.37223,0.395544,-5.15089
Up = 0.0655203,0.994792,0.0780753
#endpreset

#preset KeyFrame.004
FOV = 0.62536
Eye = -0.146262,0.991041,-0.550259
Target = -7.41034,2.09513,-5.36868
Up = 0.0484982,0.797152,0.601827
#endpreset

Enable Auto Focus

31 - Simple Focal Plane Tracking Target.frag
Add this line to your frag code, preferably in the "Camera" group
if the AutoFocus widget doesn't already exist...
 uniform bool AutoFocus; checkbox[false]
Now you can enable/disable focal plane target tracking, the focal plane
default maximum distance is 5, if you need more than that open the .frag file
that contains the "FocalPlane" widget and edit the maximum...
 uniform float FocalPlane; slider[0,1,5]
to what ever you need like...
 uniform float FocalPlane; slider[0,1,50]
Keep in mind that the target floats around at some distance from the camera,
dynamically adjusted (sometimes a lot) as you navigate, it is generally beyond
what you are looking at and will need to be set before you create a keyframe or
they will need to be adjusted by hand in the keyframe presets.
 NOTE:Mid Mouse Button Click on the fractal object should set the target
at the surface of the fractal where you click.
Source code
#group Raytracer
// Sets focal plane to Target location 
//uniform bool AutoFocus; checkbox[false]

#include "DE-Raytracer-v0.9.10.frag"
#include "MathUtils.frag"

#group Mandelbulb

// Number of fractal iterations.
uniform int Iterations;  slider[0,9,100]

// Number of color iterations.
uniform int ColorIterations;  slider[0,9,100]

// Mandelbulb exponent (8 is standard)
uniform float Power; slider[0,8,16]

// Bailout radius
uniform float Bailout; slider[0,5,30]

// Alternate is slightly different, but looks more like a Mandelbrot for Power=2
uniform bool AlternateVersion; checkbox[false]

uniform vec3 RotVector; slider[(0,0,0),(1,1,1),(1,1,1)]

uniform float RotAngle; slider[0.00,0,180]

#group Translation
uniform vec3 TransVector; slider[(-1,-1,-1),(1,0,0),(1,1,1)]
uniform float TransSpeed; slider[0,0,1]
uniform float ImpulseStrength; slider[0,0,10]
uniform float ImpulseRate; slider[0,0,10]
uniform float ImpulseOffset; slider[0,0,10]
uniform vec3 TRotVector; slider[(-1,-1,-1),(1,0,0),(1,1,1)]
uniform float TRotSpeed; slider[0,0,45]

mat3 rot;
uniform float time;

void init() {
	 rot = rotationMatrix3(normalize(RotVector), RotAngle);
}

// This is my power function, based on the standard spherical coordinates
// as defined here http://en.wikipedia.org/wiki/Spherical_coordinate_system
//
// It seems to be similar to the one Quilez uses:
// http://www.iquilezles.org/www/articles/mandelbulb/mandelbulb.htm
//
// Notice the north and south poles are different here.
void powN1(inout vec3 z, float r, inout float dr) {
	// extract polar coordinates
	float theta = acos(z.z/r);
	float phi = atan(z.y,z.x);
	dr =  pow( r, Power-1.0)*Power*dr + 1.0;
	
	// scale and rotate the point
	float zr = pow( r,Power);
	theta = theta*Power;
	phi = phi*Power;
	
	// convert back to cartesian coordinates
	z = zr*vec3(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta));
}

// This is a power function taken from the implementation by Enforcer:
// http://www.fractalforums.com/mandelbulb-implementation/realtime-renderingoptimisations/
//
// I cannot follow its derivation from spherical coordinates,
// but it does give a nice mandelbrot like object for Power=2
void powN2(inout vec3 z, float zr0, inout float dr) {
	float zo0 = asin( z.z/zr0 );
	float zi0 = atan( z.y,z.x );
	float zr = pow( zr0, Power-1.0 );
	float zo = zo0 * Power;
	float zi = zi0 * Power;
	dr = zr*dr*Power + 1.0;
	zr *= zr0;
	z  = zr*vec3( cos(zo)*cos(zi), cos(zo)*sin(zi), sin(zo) );
}



uniform bool Julia; checkbox[false]
uniform vec3 JuliaC; slider[(-2,-2,-2),(0,0,0),(2,2,2)]

// Compute the distance from `pos` to the Mandelbox.
float DE(vec3 pos) {
	vec3 z=pos;
	float r;
	float dr=1.0;
	int i=0;

	if (TRotSpeed>0.0) {
		rot=rotationMatrix3(normalize(TRotVector),TRotSpeed*time);
		z*=rot;
	}
	if (TransSpeed>0.0) {
		z+=normalize(TransVector)*time*TransSpeed*10.0;
	}
	if (ImpulseStrength>0.0) {
		z+=normalize(TransVector)*(0.8+sin(time*ImpulseRate+ImpulseOffset))*ImpulseStrength;
	}

	r=length(z);
	while(r<Bailout && (i<Iterations)) {
		if (AlternateVersion) {
			powN2(z,r,dr);
		} else {
			powN1(z,r,dr);
		}
		z+=(Julia ? JuliaC : pos);
		r=length(z);
		z*=rot;
		if (i<ColorIterations) orbitTrap = min(orbitTrap, abs(vec4(z.x,z.y,z.z,r*r)));
		i++;
	}

//	if ((type==1) && r<Bailout) return 0.0;
	return 0.5*log(r)*r/dr;
	/*
	Use this code for some nice intersections (Power=2)
	float a =  max(0.5*log(r)*r/dr, abs(pos.y));
	float b = 1000;
	if (pos.y>0)  b = 0.5*log(r)*r/dr;
	return min(min(a, b),
		max(0.5*log(r)*r/dr, abs(pos.z)));
	*/
}

float dummy(vec3 p){
p*=time;
return time;
}

#preset Default
FOV = 0.62536
Eye = 1.65826,-1.22975,0.277736
Target = -5.2432,4.25801,-0.607125
Up = 0,1,0
EquiRectangular = false
AutoFocus = true
FocalPlane = 1
Aperture = 0.05
Gamma = 2.08335
ToneMapping = 3
Exposure = 0.6522
Brightness = 1
Contrast = 1
Saturation = 1
GaussianWeight = 1
AntiAliasScale = 2
Detail = -2.84956
DetailAO = -1.35716
FudgeFactor = 1
MaxRaySteps = 164
BoundingSphere = 10
Dither = 0.51754
NormalBackStep = 1
AO = 0,0,0,0.85185
Specular = 1.6456
SpecularExp = 16.364
SpecularMax = 10
SpotLight = 1,1,1,1
SpotLightDir = -0.22666,0.5
CamLight = 1,1,1,1.53846
CamLightMin = 0.12121
Glow = 1,1,1,0.43836
GlowMax = 52
Fog = 0
HardShadow = 0.35385
ShadowSoft = 12.5806
Reflection = 0
BaseColor = 1,1,1
OrbitStrength = 0.14286
X = 1,1,1,1
Y = 0.345098,0.666667,0,0.02912
Z = 1,0.666667,0,1
R = 0.0784314,1,0.941176,-0.0194
BackgroundColor = 0.607843,0.866667,0.560784
GradientBackground = 0.3261
CycleColors = false
Cycles = 4.04901
EnableFloor = true
FloorNormal = 0,1,0
FloorHeight = -2
FloorColor = 1,1,1
Iterations = 12
ColorIterations = 8
Power = 8
Bailout = 6.279
AlternateVersion = true
RotVector = 1,1,1
RotAngle = 0
TransVector = 1,0,0
TransSpeed = 0
ImpulseStrength = 0
ImpulseRate = 0
ImpulseOffset = 0
TRotVector = 1,0,0
TRotSpeed = 0
Julia = false
JuliaC = 0,0,0
#endpreset


#preset KeyFrame.001
FOV = 0.62536
Eye = 2,0,0
Target = 1,0,0
Up = 0,1,0
#endpreset

#preset KeyFrame.002
FOV = 0.62536
Eye = 0.73087,0.0286388,1.42303
Target = 0.31975,-0.0253,0.62258
Up = 0,1,0
#endpreset

#preset KeyFrame.003
FOV = 0.62536
Eye = 0.034575,-0.00331298,1.59962
Target = 0.0,0.0,0.0
Up = -0.368,1,0
#endpreset

#preset KeyFrame.004
FOV = 0.62536
Eye = 0.034575,-0.00331298,1.59962
Target = 0.05491,-0.00217,0.99997
Up = 0.17544,1,0
#endpreset

#preset KeyFrame.005
FOV = 0.62536
Eye = 0.0244074,-0.00388447,1.89945
Target = 0.05491,-0.00217,0.99997
Up = 0,1,0
#endpreset

#preset KeyFrame.006
FOV = 0.62536
Eye = 0.0108507,-0.00464646,2.29922
Target = 0.05491,-0.00217,0.99997
Up = 0,1,0
#endpreset

#preset KeyFrame.007
FOV = 0.62536
Eye = 0.0108507,-0.00464646,2.29922
Target = 0.02745,-0.0018,0.454545
Up = 0,1,0
#endpreset

#preset KeyFrame.008
FOV = 0.62536
Eye = 0.0108507,-0.00464646,2.29922
Target = 0,0,0
Up = 0,1,0
#endpreset

#preset KeyFrame.009
FOV = 0.62536
Eye = 0.0108507,-0.00464646,2.29922
Target = 0.05491,-0.00217,0.99997
Up = 0,1,0
#endpreset

#preset KeyFrame.010
FOV = 0.62536
Eye = 0.0108507,-0.00464646,2.29922
Target = 0.05491,-0.00217,0.99997
Up = 0,1,0
#endpreset

Create a Parameter Morph Animation

32 - Simple Multi-Parameter Easing Animation.frag

Easing curve settings can be saved by using "Range" in the preset name like
"#preset Range-100-200", the frame numbers have no impact on the easing curve
values and are ignored, they are so the human can be reminded of what this range
covers, allows for unique names like "Range-fogIn" "Range-fogOut" etc., only active
easing curves will be saved, these ranges can also be applied via fqScript
eg: applyPresetByName("Range-fogIn")

These can be placed in the "Default" preset so that when a frag is loaded from cmdline
eg:remote machine, they will be active immediately. They might look like this...
 Cycles1:CosineCurve:44:1:24:1:240:0.3:1:1.7:1:0
 Power1:SineCurve:43:1:6:20:220:0.3:1:1.7:1:0
 RotAngle1:OutInBack:36:0:360:40:200:0.3:1:1.7:1:0
Variable names are suffixed with their slider number, so each vec slider can have an
easing curve setting. The items on each line are used as follows...
 [Variable]:[Ease]:[Ease]:[start]:[end]:[begin]:[end]:[period]:[amplitude]:[overshoot]:[loops]:[pong]
yes yes a lot of silly things to remember but fortunately there's a nice GUI for all that :)

  1. load tutorial 32
  2. Select the "Mandelbulb" tab
  3. Select the "Power" slider
  4. Push "F7" key (or menu item "Edit->Add Easing Curve")
  5. Change some settings
  6. Select OK that is it, done!
Frames before start frame will use start value until start frame is reached.
Frames after finish frame will use finish value until end of animation is reached.
These become active when the animation is playing.

When you do this to a variable that already has a curve you will be prompted...

"Apply" will change these settings for this variable (like it, keep it)
"Discard" will delete the settings for this variable (clean up, no animating)
"Cancel" does nothing

This only saves the changes internally, if you like the result then

  1. you need to save parameters file or
  2. add a new preset with a new name and save the GLSL script or
  3. render a highres or anim to create "frag-name_Files" folder.
    This will have all of your easing curve settings in a single default preset.

Easing curve settings should all be in one named (not keyframe) preset.
Source code
#group Raytracer
// Sets focal plane to Target location
//uniform bool AutoFocus; checkbox[false]

#include "DE-Raytracer.frag"
#include "MathUtils.frag"

#group Mandelbulb

// Number of fractal iterations.
uniform int Iterations;  slider[0,9,100]

// Number of color iterations.
uniform int ColorIterations;  slider[0,9,100]

// Mandelbulb exponent (8 is standard)
uniform float Power; slider[0,8,16]

// Bailout radius
uniform float Bailout; slider[0,5,30]

// Alternate is slightly different, but looks more like a Mandelbrot for Power=2
uniform bool AlternateVersion; checkbox[false]

uniform vec3 RotVector; slider[(0,0,0),(1,1,1),(1,1,1)]

uniform float RotAngle; slider[0.00,0,360]

mat3 rot;
uniform float time;

void init() {
	rot = rotationMatrix3(normalize(RotVector), RotAngle);
}

// This is my power function, based on the standard spherical coordinates
// as defined here http://en.wikipedia.org/wiki/Spherical_coordinate_system
//
// It seems to be similar to the one Quilez uses:
// http://www.iquilezles.org/www/articles/mandelbulb/mandelbulb.htm
//
// Notice the north and south poles are different here.
void powN1(inout vec3 z, float r, inout float dr) {
	// extract polar coordinates
	float theta = acos(z.z/r);
	float phi = atan(z.y,z.x);
	dr =  pow( r, Power-1.0)*Power*dr + 1.0;

	// scale and rotate the point
	float zr = pow( r,Power);
	theta = theta*Power;
	phi = phi*Power;

	// convert back to cartesian coordinates
	z = zr*vec3(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta));
}

// This is a power function taken from the implementation by Enforcer:
// http://www.fractalforums.com/mandelbulb-implementation/realtime-renderingoptimisations/
//
// I cannot follow its derivation from spherical coordinates,
// but it does give a nice mandelbrot like object for Power=2
void powN2(inout vec3 z, float zr0, inout float dr) {
	float zo0 = asin( z.z/zr0 );
	float zi0 = atan( z.y,z.x );
	float zr = pow( zr0, Power-1.0 );
	float zo = zo0 * Power;
	float zi = zi0 * Power;
	dr = zr*dr*Power + 1.0;
	zr *= zr0;
	z  = zr*vec3( cos(zo)*cos(zi), cos(zo)*sin(zi), sin(zo) );
}



uniform bool Julia; checkbox[false]
uniform vec3 JuliaC; slider[(-2,-2,-2),(0,0,0),(2,2,2)]

// Compute the distance from `pos` to the Mandelbox.
float DE(vec3 pos) {
	vec3 z=pos;
	float r;
	float dr=1.0;
	int i=0;

	r=length(z);
	while(r<Bailout && (i<Iterations)) {
		if (AlternateVersion) {
			powN2(z,r,dr);
		} else {
			powN1(z,r,dr);
		}
		z+=(Julia ? JuliaC : pos);
		r=length(z);
		z*=rot;
		if (i<ColorIterations) orbitTrap = min(orbitTrap, abs(vec4(z.x,z.y,z.z,r*r)));
		i++;
	}

//	if ((type==1) && r<Bailout) return 0.0;
	return 0.5*log(r)*r/dr;
	/*
	Use this code for some nice intersections (Power=2)
	float a =  max(0.5*log(r)*r/dr, abs(pos.y));
	float b = 1000;
	if (pos.y>0)  b = 0.5*log(r)*r/dr;
	return min(min(a, b),
		max(0.5*log(r)*r/dr, abs(pos.z)));
	*/
}

float dummy(vec3 p){
p*=time;
return time;
}

#preset Default
FOV = 0.62536
Eye = 2.42106,0.501576,0.263686
Target = -6.2468,-0.836125,-0.622262
Up = 0,1,0
EquiRectangular = false
AutoFocus = false
FocalPlane = 1
Aperture = 0
Gamma = 2.08335
ToneMapping = 3
Exposure = 0.6522
Brightness = 1
Contrast = 1
Saturation = 1
GaussianWeight = 1
AntiAliasScale = 2
Detail = -2.84956
DetailAO = -1.35716
FudgeFactor = 1
MaxRaySteps = 164
BoundingSphere = 10
Dither = 0.51754
NormalBackStep = 1
AO = 0,0,0,0.85185
Specular = 1.6456
SpecularExp = 16.364
SpecularMax = 10
SpotLight = 1,1,1,1
SpotLightDir = 0.22666,0.5
CamLight = 1,1,1,1.53846
CamLightMin = 0.12121
Glow = 1,1,1,0.43836
GlowMax = 52
Fog = 0
HardShadow = 0.35385
ShadowSoft = 12.5806
Reflection = 0
BaseColor = 1,1,1
OrbitStrength = 1
X = 1,1,1,1
Y = 0.345098,0.666667,0,0.02912
Z = 1,0.666667,0,1
R = 0.0784314,1,0.941176,-0.0194
BackgroundColor = 0.607843,0.866667,0.560784
GradientBackground = 0.3261
CycleColors = true
Cycles1:CosineCurve:44:1:24:1:240:0.3:1:1.7:1:0
Cycles = 12.4928
EnableFloor = true
FloorNormal = 0,1,0
FloorHeight = -2
FloorColor = 1,1,1
Iterations = 12
ColorIterations = 8
Power1:SineCurve:43:1:6:20:220:0.3:1:1.7:1:0
Power = 1
Bailout = 6.279
AlternateVersion = true
RotVector = 1,1,1
RotAngle1:OutInBack:36:0:360:40:200:0.3:1:1.7:1:0
RotAngle = 0.0
Julia = false
JuliaC = 0,0,0
#endpreset

#preset KeyFrame.001
FOV = 0.62536
Eye = 2.42106,0.501576,0.263686
Target = -6.2468,-0.836125,-0.622262
Up = 0,1,0
#endpreset

#preset KeyFrame.002
FOV = 0.62536
Eye = 2.42106,0.501576,0.263686
Target = -6.2468,-0.836125,-0.622262
Up = 0,1,0
#endpreset

Using a Cube Sampler

33 - Simple Skybox.frag
#define providesBackground
#define  providesColor

#include "MathUtils.frag"
#include "DE-Raytracer.frag"

#group Skybox
uniform samplerCube skybox; file[cubemap.png]
vec3  backgroundColor(vec3 dir) {
float t = length(from-dir);
dir *= -1.;
    return mix(textureCube(skybox, dir.xzy).rgb, BackgroundColor, 1.0-exp(-pow(Fog,4.0)*t*t));
}

uniform float RefractiveIndex; slider[0,1,10]
vec3 baseColor(vec3 point, vec3 N){
    float ratio = 1.00 / RefractiveIndex;
    vec3 I = (point - from);
    vec3 R = refract(I, -N, ratio);
    return textureCube(skybox, R.xzy).rgb;
}

#group Mandelbulb

// Number of fractal iterations.
uniform int Iterations;  slider[0,9,100]

// Number of color iterations.
uniform int ColorIterations;  slider[0,9,100]

// Mandelbulb exponent (8 is standard)
uniform float Power; slider[0,8,16]

// Bailout radius
uniform float Bailout; slider[0,5,30]
// mermelada's tweak Derivative bias
uniform float DerivativeBias; slider[0,1,10]

// Alternate is slightly different, but looks more like a Mandelbrot for Power=2
uniform bool AlternateVersion; checkbox[false]

uniform vec3 RotVector; slider[(0,0,0),(1,1,1),(1,1,1)]

uniform float RotAngle; slider[0.00,0,180]

uniform bool Julia; checkbox[false]
uniform vec3 JuliaC; slider[(-2,-2,-2),(0,0,0),(2,2,2)]

uniform float time;
mat3 rot;
void init() {
	 rot = rotationMatrix3(normalize(RotVector), RotAngle);
}

// This is my power function, based on the standard spherical coordinates as defined here:
// http://en.wikipedia.org/wiki/Spherical_coordinate_system
//
// It seems to be similar to the one Quilez uses:
// http://www.iquilezles.org/www/articles/mandelbulb/mandelbulb.htm
//
// Notice the north and south poles are different here.
void powN1(inout vec3 z, float r, inout float dr) {
	// extract polar coordinates
	float theta = acos(z.z/r);
	float phi = atan(z.y,z.x);
   // mermelada's tweak
   // http://www.fractalforums.com/new-theories-and-research/error-estimation-of-distance-estimators/msg102670/?topicseen#msg102670
	dr =  max(dr*DerivativeBias,pow( r, Power-1.0)*Power*dr + 1.0);
	// scale and rotate the point
	float zr = pow( r,Power);
	theta = theta*Power;
	phi = phi*Power;

	// convert back to cartesian coordinates
	z = zr*vec3(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta));
}

// This is a power function taken from the implementation by Enforcer:
// http://www.fractalforums.com/mandelbulb-implementation/realtime-renderingoptimisations/
//
// I cannot follow its derivation from spherical coordinates,
// but it does give a nice mandelbrot like object for Power=2
void powN2(inout vec3 z, float zr0, inout float dr) {
	float zo0 = asin( z.z/zr0 );
	float zi0 = atan( z.y,z.x );
	float zr = pow( zr0, Power-1.0 );
	float zo = zo0 * Power;
	float zi = zi0 * Power;
   // mermelada's tweak
   // http://www.fractalforums.com/new-theories-and-research/error-estimation-of-distance-estimators/msg102670/?topicseen#msg102670
	dr = max(dr*DerivativeBias,zr*dr*Power + 1.0);

	zr *= zr0;
	z  = zr*vec3( cos(zo)*cos(zi), cos(zo)*sin(zi), sin(zo) );
}



// Compute the distance from `pos` to the Mandelbox.
float DE(vec3 pos) {
	vec3 z=pos;
	float r;
	float dr=1.0;
	int i=0;
	r=length(z);
	while(r<Bailout && (i<Iterations)) {
		if (AlternateVersion) {
			powN2(z,r,dr);
		} else {
			powN1(z,r,dr);
		}
		z+=(Julia ? JuliaC : pos);
		r=length(z);
		z*=rot;
		if (i<ColorIterations) orbitTrap = min(orbitTrap, abs(vec4(z.x,z.y,z.z,r*r)));
		i++;
	}
//	if ((type==1) && r<Bailout) return 0.0;
	return 0.5*log(r)*r/dr;
	/*
	Use this code for some nice intersections (Power=2)
	float a =  max(0.5*log(r)*r/dr, abs(pos.y));
	float b = 1000;
	if (pos.y>0)  b = 0.5*log(r)*r/dr;
	return min(min(a, b),
		max(0.5*log(r)*r/dr, abs(pos.z)));
	*/
}

#preset Default
FOV = 0.62536
Eye = 1.578295,-2.374888,-0.1754925
Target = -2.237496,5.621949,-0.038792
Up = 0.0250519,0.0290368,-0.9993381
EquiRectangular = false
AutoFocus = false
FocalPlane = 1
Aperture = 0
Gamma = 2.08335
ToneMapping = 3
Exposure = 0.6522
Brightness = 1
Contrast = 1
Saturation = 1
GaussianWeight = 1
AntiAliasScale = 2
DepthToAlpha = false
ShowDepth = false
DepthMagnitude = 1
Detail = -2.84956
DetailAO = -1.35716
FudgeFactor = 1
MaxDistance = 1000
MaxRaySteps = 164
Dither = 0.51754
NormalBackStep = 1
AO = 0,0,0,0.85185
Specular = 0.336
SpecularExp = 16.364
SpecularMax = 10
SpotLight = 1,1,1,1
SpotLightDir = 0.7,-0.42
CamLight = 1,1,1,1.53846
CamLightMin = 0.12121
Glow = 1,1,1,0.43836
GlowMax = 52
Fog = 0
HardShadow = 0.35385
ShadowSoft = 12.5806
QualityShadows = false
Reflection = 0
DebugSun = false
BaseColor = 1,1,1
OrbitStrength = 0
X = 1,1,1,1
Y = 0.345098,0.666667,0,0.02912
Z = 1,0.666667,0,1
R = 0.0784314,1,0.941176,-0.0194
BackgroundColor = 0.607843,0.866667,0.560784
GradientBackground = 0.9701493
CycleColors = false
Cycles = 4.04901
EnableFloor = false
FloorNormal = 0,0,-1
FloorHeight = -3.095238
FloorColor = 1,1,1
Iterations = 12
ColorIterations = 8
Power = 8
Bailout = 6.279
AlternateVersion = true
RotVector = 1,1,1
RotAngle = 0
Julia = false
JuliaC = 0,0,0
skybox = cubemap.png
RefractiveIndex = 5.604396
DerivativeBias = 1
#endpreset

#preset Octobulb
FOV = 0.62536
Eye = -0.184126,0.843469,1.32991
Target = 1.48674,-5.55709,-4.56665
Up = 0,1,0
AntiAlias = 1
Detail = -2.47786
DetailAO = -0.21074
FudgeFactor = 1
MaxRaySteps = 164
BoundingSphere = 2
Dither = 0.5
AO = 0,0,0,0.7
Specular = 1
SpecularExp = 27.082
SpotLight = 1,1,1,0.94565
SpotLightDir = 0.5619,0.18096
CamLight = 1,1,1,0.23656
CamLightMin = 0.15151
Glow = 0.415686,1,0.101961,0.18421
Fog = 0.60402
HardShadow = 0.7230800
Reflection = 0.0
BaseColor = 1,1,1
OrbitStrength = 0.62376
X = 0.411765,0.6,0.560784,-0.37008
Y = 0.666667,0.666667,0.498039,0.86886
Z = 0.666667,0.333333,1,-0.25984
R = 0.4,0.7,1,0.36508
BackgroundColor = 0.666667,0.666667,0.498039
GradientBackground = 0.5
CycleColors = true
Cycles = 7.03524
FloorNormal = 0,0,0
FloorHeight = 0
FloorColor = 1,1,1
Iterations = 14
ColorIterations = 6
Power = 8.18304
Bailout = 6.279
AlternateVersion = true
RotVector = 1,0,0
RotAngle = 77.8374
#endpreset


#preset Refraction
FOV = 0.807947
Eye = 1.49337,-0.0604384,-1.459009
Target = -4.526366,-0.2098799,5.042469
Up = -0.02031,0.9980528,0.0041359
EquiRectangular = false
AutoFocus = false
FocalPlane = 1
Aperture = 0
Gamma = 2
ToneMapping = 5
Exposure = 1
Brightness = 1
Contrast = 1
Saturation = 1
GaussianWeight = 1
AntiAliasScale = 2
DepthToAlpha = false
ShowDepth = false
DepthMagnitude = 1
Detail = -3.601449
DetailAO = -1.35716
FudgeFactor = 1
MaxDistance = 1000
MaxRaySteps = 1185
Dither = 0.51754
NormalBackStep = 1
AO = 0,0,0,0
Specular = 0
SpecularExp = 0
SpecularMax = 0
SpotLight = 1,1,1,1
SpotLightDir = 0.63626,0.5
CamLight = 1,1,1,1.53846
CamLightMin = 0.12121
Glow = 1,1,1,1
GlowMax = 1000
Fog = 0
HardShadow = 0.35385
ShadowSoft = 12.5806
QualityShadows = false
Reflection = 0
DebugSun = false
BaseColor = 1,1,1
OrbitStrength = 1
X = 1,1,1,1
Y = 0.345098,0.666667,0,0.02912
Z = 1,0.666667,0,1
R = 0.0784314,1,0.941176,-0.0194
BackgroundColor = 0.607843,0.866667,0.560784
GradientBackground = 0.3261
CycleColors = false
Cycles = 4.04901
EnableFloor = false
FloorNormal = 0,0,0
FloorHeight = 0
FloorColor = 1,1,1
Iterations = 0
ColorIterations = 10
Power = 8
Bailout = 6.279
DerivativeBias = 1
AlternateVersion = false
RotVector = 1,1,1
RotAngle = 0
Julia = false
JuliaC = 1,1,1
skybox = cubemap.png
RefractiveIndex = 1.52
#endpreset

#preset Reflection
FOV = 1
Eye = 2.193986,2.218407,0.2322807
Target = -5.850334,-1.498805,0.2174372
Up = -0.0086972,0.021624,-0.7018754
EquiRectangular = false
AutoFocus = false
FocalPlane = 1
Aperture = 0
Gamma = 2
ToneMapping = 5
Exposure = 0.6522
Brightness = 1
Contrast = 1
Saturation = 1
GaussianWeight = 1
AntiAliasScale = 2
DepthToAlpha = false
ShowDepth = false
DepthMagnitude = 1
Detail = -1.318841
DetailAO = -1.35716
FudgeFactor = 1
MaxDistance = 1000
MaxRaySteps = 164
Dither = 0.51754
NormalBackStep = 1
AO = 0,0,0,0.85185
Specular = 1
SpecularExp = 16.364
SpecularMax = 10
SpotLight = 1,1,1,1
SpotLightDir = 0.7,-0.42
CamLight = 1,1,1,1.53846
CamLightMin = 0.12121
Glow = 1,1,1,0.43836
GlowMax = 52
Fog = 0
HardShadow = 0.35385
ShadowSoft = 12.5806
QualityShadows = false
Reflection = 1
DebugSun = false
BaseColor = 1,1,1
OrbitStrength = 0.14286
X = 1,1,1,1
Y = 0.345098,0.666667,0,0.02912
Z = 1,0.666667,0,1
R = 0.0784314,1,0.941176,-0.0194
BackgroundColor = 0.607843,0.866667,0.560784
GradientBackground = 0.3261
CycleColors = false
Cycles = 4.04901
EnableFloor = false
FloorNormal = 0,0,0
FloorHeight = 0
FloorColor = 1,1,1
Iterations = 0
ColorIterations = 8
Power = 8
Bailout = 6.279
AlternateVersion = true
RotVector = 1,1,1
RotAngle = 0
Julia = true
JuliaC = 0,0,0
skybox = cubemap.png
RefractiveIndex = 1.52
DerivativeBias = 0
#endpreset

Using the Z channel

no frag in Examples yet
Selecting "Depth to Alpha" from the "Post" tab will save RGBZ images when using OpenEXR format that FragM can load and use. The first thing you need to do is render a few for testing.
In your fragment code just add a normal 2D sampler with the .exr image as the filename.
uniform sampler2D tex; file[/path/to/file/name.exr]
if the texture files are placed in the same folder as the fragment code that uses them the full path is not required, just the filename will do.
By defining providesColor the raytracer is told to call the user defined function, baseColor() for surface coloring. In this case returning the RGB part of the RGBZ texture.
In the DE() function the Z channel (.a) is used to distort the quad surface.
Source code
// Output generated from file: /Fragmentarium/FragMTestSuite/EXRChannelTest/testingChannels.frag
// Created: Sat Jul 18 21:30:49 2020
// Write fragment code here...

#define providesColor
#include "MathUtils.frag"
#include "DE-Raytracer.frag"

#group Channels
uniform vec4 v4; slider[(0,0,0,0),(1,1,1,1),(1,1,1,1)]
uniform sampler2D tex; file[test-channels.exr]

// udQuad from http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
float dot2( in vec3 v ) { return dot(v,v); }
float udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d ) {

 vec3 ba = b - a;
 vec3 pa = p - a;
 vec3 cb = c - b;
 vec3 pb = p - b;
 vec3 dc = d - c;
 vec3 pc = p - c;
 vec3 ad = a - d;
 vec3 pd = p - d;
 vec3 nor = cross( ba, ad);
 return sqrt(	(sign(dot(cross(ba,nor),pa)) +
					 sign(dot(cross(cb,nor),pb)) +
					 sign(dot(cross(dc,nor),pc)) +
					 sign(dot(cross(ad,nor),pd))<3.0)
					 ?
					 min( min( min(
					 dot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),
					 dot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),
					 dot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),
					 dot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )
					 :
					 dot(nor,pa)*dot(nor,pa)/dot2(nor) );
 }

float scale = 16./9.;

vec3 baseColor(vec3 p, vec3 q) {

     	return texture2D(tex,vec2((p.x/scale),p.y)).rgb;
}

float DE(vec3 pos) {

   pos.z+= v4.w*texture2D(tex,vec2((pos.x/scale),pos.y)).a;
   pos*=v4.xyz;

   return udQuad( pos, vec3(0,0,1),
								vec3(0,1,1),
								vec3(scale,1,1),
								vec3(scale,0,1) );
}

#preset Default
FOV = 0.51132686
Eye = 0.954419631,-0.702383823,0.594244256
Target = -1.9541712,5.56087158,0.229176256
Up = 0.067047704,-0.026748228,-0.993089834
EquiRectangular = false
AutoFocus = false
FocalPlane = 1
Aperture = 0
Gamma = 2
ToneMapping = 5
Exposure = 1
Brightness = 1
Contrast = 1
AvgLumin = 0.5,0.5,0.5
Saturation = 1
LumCoeff = 0.212500006,0.715399981,0.0720999986
Hue = 0
GaussianWeight = 1
AntiAliasScale = 2
DepthToAlpha = false
ShowDepth = false
DepthMagnitude = 1
Detail = -3.5
DetailAO = 0
FudgeFactor = 0.15614035
MaxDistance = 32
MaxRaySteps = 2070
Dither = 1
NormalBackStep = 1
AO = 0,0,0,0.74021353
Specular = 0.3414966
SpecularExp = 16
SpecularMax = 32.230216
SpotLight = 1,1,1,0.400000006
SpotLightDir = 0.67368422,-0.80701754
CamLight = 1,1,1,1.08745248
CamLightMin = 0
Glow = 1,1,1,0
GlowMax = 20
Fog = 0.37741936
HardShadow = 0
ShadowSoft = 2
QualityShadows = false
Reflection = 0.5
DebugSun = false
BaseColor = 0.439215686,1,0.376470588
OrbitStrength = 0.80106573
X = 0.5,0.600000024,0.600000024,0.699999988
Y = 1,0.600000024,0,0.400000006
Z = 0.800000012,0.779999971,1,0.5
R = 0.400000006,0.699999988,1,0.119999997
BackgroundColor = 0.243137255,0.356862745,0.411764706
GradientBackground = 0
CycleColors = false
Cycles = 1.1
EnableFloor = true
FloorNormal = 0,0,1
FloorHeight = 0.999999999
FloorColor = 0.0549019608,0.125490196,0.0470588235
v4 = 0,0,1,1
tex = test-channels.exr R;G;B;Z
#endpreset
Exr image. (png for display purposes) test-channels Default preset using EXR image as displacement. channel-test For this HowTo you will need to create test-channels.exr rendered with "Z to Alpha" option or use an EXR image with RGBZ channels.
Clone this wiki locally