Watch
2
0
Fork
You've already forked raylib-cs
0

Raylib 6.0 bugs after tests (#338)

* Sync of all the shaders from upstream + LoadFontData did not match anymore with C and crashed on MacOS

* Updated JuliaSet demo. Did not work with the new shader version.

* Removed unused `pause` variable from JuliaSet example.

---------

Co-authored-by: Meatcorps <info@meatcorps.nl>
This commit is contained in:
Dennis Steffen 2026-05-24 15:43:17 +02:00 committed by GitHub
commit 8daf812930
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
83 changed files with 823 additions and 815 deletions

View file

@ -41,6 +41,10 @@ public class JuliaSet
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
const float zoomSpeed = 1.01f;
const float offsetSpeedMul = 2.0f;
const float startingZoom = 0.75f;
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets"); InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets");
@ -48,14 +52,15 @@ public class JuliaSet
// NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
Shader shader = LoadShader(null, $"resources/shaders/glsl{GlslVersion}/julia_set.fs"); Shader shader = LoadShader(null, $"resources/shaders/glsl{GlslVersion}/julia_set.fs");
// Create a RenderTexture2D to be used for render to texture
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
// c constant to use in z^2 + c // c constant to use in z^2 + c
float[] c = { PointsOfInterest[0][0], PointsOfInterest[0][1] }; float[] c = { PointsOfInterest[0][0], PointsOfInterest[0][1] };
// Offset and zoom to draw the julia set at. (centered on screen and default size) // Offset and zoom to draw the julia set at. (centered on screen and default size)
float[] offset = { -(float)screenWidth / 2, -(float)screenHeight / 2 }; float[] offset = { 0, 0 };
float zoom = 1.0f; float zoom = startingZoom;
Vector2 offsetSpeed = new(0.0f, 0.0f);
// Get variable (uniform) locations on the shader to connect with the program // Get variable (uniform) locations on the shader to connect with the program
// NOTE: If uniform variable could not be found in the shader, function returns -1 // NOTE: If uniform variable could not be found in the shader, function returns -1
@ -63,28 +68,15 @@ public class JuliaSet
int zoomLoc = GetShaderLocation(shader, "zoom"); int zoomLoc = GetShaderLocation(shader, "zoom");
int offsetLoc = GetShaderLocation(shader, "offset"); int offsetLoc = GetShaderLocation(shader, "offset");
// Tell the shader what the screen dimensions, zoom, offset and c are // Upload the shader uniform values!
float[] screenDims = { (float)screenWidth, (float)screenHeight };
Raylib.SetShaderValue(
shader,
GetShaderLocation(shader, "screenDims"),
screenDims,
ShaderUniformDataType.Vec2
);
Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2); Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2);
Raylib.SetShaderValue(shader, zoomLoc, zoomLoc, ShaderUniformDataType.Float); Raylib.SetShaderValue(shader, zoomLoc, zoom, ShaderUniformDataType.Float);
Raylib.SetShaderValue(shader, offsetLoc, offset, ShaderUniformDataType.Vec2); Raylib.SetShaderValue(shader, offsetLoc, offset, ShaderUniformDataType.Vec2);
// Create a RenderTexture2D to be used for render to texture
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
// Multiplier of speed to change c value // Multiplier of speed to change c value
int incrementSpeed = 0; int incrementSpeed = 0;
// Show controls // Show controls
bool showControls = true; bool showControls = true;
// Pause animation
bool pause = false;
SetTargetFPS(60); SetTargetFPS(60);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -136,10 +128,19 @@ public class JuliaSet
Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2); Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2);
} }
if (IsKeyPressed(KeyboardKey.R))
{
zoom = startingZoom;
offset[0] = 1f;
offset[1] = 1f;
Raylib.SetShaderValue(shader, zoomLoc, zoom, ShaderUniformDataType.Float);
Raylib.SetShaderValue(shader, offsetLoc, offset, ShaderUniformDataType.Vec2);
}
// Pause animation (c change) // Pause animation (c change)
if (IsKeyPressed(KeyboardKey.Space)) if (IsKeyPressed(KeyboardKey.Space))
{ {
pause = !pause; incrementSpeed = 0;
} }
// Toggle whether or not to show controls // Toggle whether or not to show controls
@ -148,61 +149,48 @@ public class JuliaSet
showControls = !showControls; showControls = !showControls;
} }
if (!pause) if (IsKeyPressed(KeyboardKey.Right))
{ {
if (IsKeyPressed(KeyboardKey.Right)) incrementSpeed++;
}
else if (IsKeyPressed(KeyboardKey.Left))
{
incrementSpeed--;
}
// If either left or right button is pressed, zoom in/out
if (IsMouseButtonDown(MouseButton.Left) || IsMouseButtonDown(MouseButton.Right))
{
if (IsMouseButtonDown(MouseButton.Left))
{ {
incrementSpeed++; zoom *= zoomSpeed;
}
else if (IsKeyPressed(KeyboardKey.Left))
{
incrementSpeed--;
} }
// TODO: The idea is to zoom and move around with mouse if (IsMouseButtonDown(MouseButton.Right))
// Probably offset movement should be proportional to zoom level
if (IsMouseButtonDown(MouseButton.Left) || IsMouseButtonDown(MouseButton.Right))
{ {
if (IsMouseButtonDown(MouseButton.Left)) zoom *= 1.0f / zoomSpeed;
{
zoom += zoom * 0.003f;
}
if (IsMouseButtonDown(MouseButton.Right))
{
zoom -= zoom * 0.003f;
}
Vector2 mousePos = GetMousePosition();
offsetSpeed.X = mousePos.X - (float)screenWidth / 2;
offsetSpeed.Y = mousePos.Y - (float)screenHeight / 2;
// Slowly move camera to targetOffset
offset[0] += GetFrameTime() * offsetSpeed.X * 0.8f;
offset[1] += GetFrameTime() * offsetSpeed.Y * 0.8f;
}
else
{
offsetSpeed = new Vector2(0.0f, 0.0f);
} }
Vector2 mousePos = GetMousePosition();
Vector2 offsetVelocity = Vector2.Zero;
offsetVelocity.X = (mousePos.X / screenWidth - 0.5f) * offsetSpeedMul / zoom;
offsetVelocity.Y = (mousePos.Y / screenHeight - 0.5f) * offsetSpeedMul / zoom;
// Apply move velocity to camera
offset[0] += GetFrameTime() * offsetVelocity.X;
offset[1] += GetFrameTime() * offsetVelocity.Y;
Raylib.SetShaderValue(shader, zoomLoc, zoom, ShaderUniformDataType.Float); Raylib.SetShaderValue(shader, zoomLoc, zoom, ShaderUniformDataType.Float);
Raylib.SetShaderValue(shader, offsetLoc, offset, ShaderUniformDataType.Vec2); Raylib.SetShaderValue(shader, offsetLoc, offset, ShaderUniformDataType.Vec2);
// Increment c value with time
float amount = GetFrameTime() * incrementSpeed * 0.0005f;
c[0] += amount;
c[1] += amount;
Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2);
} }
//----------------------------------------------------------------------------------
// Draw // Increment c value with time
//---------------------------------------------------------------------------------- float amount = GetFrameTime() * incrementSpeed * 0.0005f;
BeginDrawing(); c[0] += amount;
ClearBackground(Color.Black); c[1] += amount;
Raylib.SetShaderValue(shader, cLoc, c, ShaderUniformDataType.Vec2);
// Using a render texture to draw Julia set // Using a render texture to draw Julia set
// Enable drawing to texture // Enable drawing to texture
@ -216,6 +204,11 @@ public class JuliaSet
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Color.Black); DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Color.Black);
EndTextureMode(); EndTextureMode();
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.Black);
// Draw the saved texture and rendered julia set with shader // Draw the saved texture and rendered julia set with shader
// NOTE: We do not invert texture on Y, already considered inside shader // NOTE: We do not invert texture on Y, already considered inside shader
BeginShaderMode(shader); BeginShaderMode(shader);
@ -229,6 +222,7 @@ public class JuliaSet
DrawText("Press KEYS [1 - 6] to change point of interest", 10, 45, 10, Color.RayWhite); DrawText("Press KEYS [1 - 6] to change point of interest", 10, 45, 10, Color.RayWhite);
DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, Color.RayWhite); DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, Color.RayWhite);
DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, Color.RayWhite); DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, Color.RayWhite);
DrawText("Press KEY_R to recenter the camera", 10, 90, 10, Color.RayWhite);
} }
EndDrawing(); EndDrawing();

View file

@ -41,7 +41,7 @@ public class FontSdf
// Loading font data from memory data // Loading font data from memory data
// Parameters > font size: 16, no chars array provided (0), chars count: 95 (autogenerate chars array) // Parameters > font size: 16, no chars array provided (0), chars count: 95 (autogenerate chars array)
fontDefault.Glyphs = LoadFontData(fileData, (int)fileSize, 16, null, 95, FontType.Default); fontDefault.Glyphs = LoadFontData(fileData, (int)fileSize, 16, null, 95, FontType.Default, &fontDefault.GlyphCount);
// Parameters > chars count: 95, font size: 16, chars padding in image: 4 px, pack method: 0 (default) // Parameters > chars count: 95, font size: 16, chars padding in image: 4 px, pack method: 0 (default)
Image atlas = GenImageFontAtlas(fontDefault.Glyphs, &fontDefault.Recs, 95, 16, 4, 0); Image atlas = GenImageFontAtlas(fontDefault.Glyphs, &fontDefault.Recs, 95, 16, 4, 0);
fontDefault.Texture = LoadTextureFromImage(atlas); fontDefault.Texture = LoadTextureFromImage(atlas);
@ -52,7 +52,7 @@ public class FontSdf
fontSDF.BaseSize = 16; fontSDF.BaseSize = 16;
fontSDF.GlyphCount = 95; fontSDF.GlyphCount = 95;
// Parameters > font size: 16, no chars array provided (0), chars count: 0 (defaults to 95) // Parameters > font size: 16, no chars array provided (0), chars count: 0 (defaults to 95)
fontSDF.Glyphs = LoadFontData(fileData, (int)fileSize, 16, null, 0, FontType.Sdf); fontSDF.Glyphs = LoadFontData(fileData, (int)fileSize, 16, null, 0, FontType.Sdf, &fontDefault.GlyphCount);
// Parameters > chars count: 95, font size: 16, chars padding in image: 0 px, pack method: 1 (Skyline algorythm) // Parameters > chars count: 95, font size: 16, chars padding in image: 0 px, pack method: 1 (Skyline algorythm)
atlas = GenImageFontAtlas(fontSDF.Glyphs, &fontSDF.Recs, 95, 16, 0, 1); atlas = GenImageFontAtlas(fontSDF.Glyphs, &fontSDF.Recs, 95, 16, 0, 1);
fontSDF.Texture = LoadTextureFromImage(atlas); fontSDF.Texture = LoadTextureFromImage(atlas);

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -13,7 +13,7 @@ uniform mat4 mvp;
varying vec2 fragTexCoord; varying vec2 fragTexCoord;
varying vec4 fragColor; varying vec4 fragColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -10,11 +10,11 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
const vec2 size = vec2(800, 450); // render size const vec2 size = vec2(800, 450); // Framebuffer size
const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance const float samples = 5.0; // Pixels per axis; higher = bigger glow, worse performance
const float quality = 2.5; // lower = smaller glow, better quality const float quality = 2.5; // Defines size factor: Lower = smaller glow, better quality
void main() void main()
{ {

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800.0; const float renderWidth = 800.0;

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
float hatchOffsetY = 5.0; float hatchOffsetY = 5.0;
float lumThreshold01 = 0.9; float lumThreshold01 = 0.9;

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800.0; const float renderWidth = 800.0;
@ -23,8 +23,8 @@ vec4 PostFX(sampler2D tex, vec2 uv)
{ {
vec4 c = vec4(0.0); vec4 c = vec4(0.0);
float size = stitchingSize; float size = stitchingSize;
vec2 cPos = uv * vec2(renderWidth, renderHeight); vec2 cPos = uv*vec2(renderWidth, renderHeight);
vec2 tlPos = floor(cPos / vec2(size, size)); vec2 tlPos = floor(cPos/vec2(size, size));
tlPos *= size; tlPos *= size;
int remX = int(mod(cPos.x, size)); int remX = int(mod(cPos.x, size));
@ -38,11 +38,11 @@ vec4 PostFX(sampler2D tex, vec2 uv)
if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y))))) if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y)))))
{ {
if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0); if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0);
else c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; else c = texture2D(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
} }
else else
{ {
if (invert == 1) c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; if (invert == 1) c = texture2D(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
else c = vec4(0.0, 0.0, 0.0, 1.0); else c = vec4(0.0, 0.0, 0.0, 1.0);
} }

View file

@ -16,7 +16,7 @@ float angle = 0.0;
vec2 VectorRotateTime(vec2 v, float speed) vec2 VectorRotateTime(vec2 v, float speed)
{ {
float time = uTime*speed; float time = uTime*speed;
float localTime = fract(time); // The time domain this works on is 1 sec. float localTime = fract(time); // The time domain this works on is 1 sec
if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0; if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0;
else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4.0*sin(2.0*PI*localTime - PI/2.0); else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4.0*sin(2.0*PI*localTime - PI/2.0);

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {
@ -34,4 +34,4 @@ void main()
color = color/9.5; color = color/9.5;
gl_FragColor = color; gl_FragColor = color;
} }

View file

@ -7,12 +7,12 @@ precision mediump float;
The Sieve of Eratosthenes -- a simple shader by ProfJski The Sieve of Eratosthenes -- a simple shader by ProfJski
An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
The screen is divided into a square grid of boxes, each representing an integer value. The screen is divided into a square grid of boxes, each representing an integer value
Each integer is tested to see if it is a prime number. Primes are colored white. Each integer is tested to see if it is a prime number. Primes are colored white
Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer. Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer
You can change the scale variable to make a larger or smaller grid. You can change the scale variable to make a larger or smaller grid
Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers. Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers
WARNING: If you make scale too large, your GPU may bog down! WARNING: If you make scale too large, your GPU may bog down!
@ -38,7 +38,7 @@ vec4 Colorizer(float counter, float maxSize)
void main() void main()
{ {
vec4 color = vec4(1.0); vec4 color = vec4(1.0);
float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid. float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid
float value = scale*floor(fragTexCoord.y*scale) + floor(fragTexCoord.x*scale); // Group pixels into boxes representing integer values float value = scale*floor(fragTexCoord.y*scale) + floor(fragTexCoord.x*scale); // Group pixels into boxes representing integer values
int valuei = int(value); int valuei = int(value);

View file

@ -10,29 +10,29 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
const float PI = 3.1415926535; const float PI = 3.1415926535;
void main() void main()
{ {
float aperture = 178.0; float aperture = 178.0;
float apertureHalf = 0.5 * aperture * (PI / 180.0); float apertureHalf = 0.5*aperture*(PI/180.0);
float maxFactor = sin(apertureHalf); float maxFactor = sin(apertureHalf);
vec2 uv = vec2(0.0); vec2 uv = vec2(0.0);
vec2 xy = 2.0 * fragTexCoord.xy - 1.0; vec2 xy = 2.0*fragTexCoord.xy - 1.0;
float d = length(xy); float d = length(xy);
if (d < (2.0 - maxFactor)) if (d < (2.0 - maxFactor))
{ {
d = length(xy * maxFactor); d = length(xy*maxFactor);
float z = sqrt(1.0 - d * d); float z = sqrt(1.0 - d*d);
float r = atan(d, z) / PI; float r = atan(d, z)/PI;
float phi = atan(xy.y, xy.x); float phi = atan(xy.y, xy.x);
uv.x = r * cos(phi) + 0.5; uv.x = r*cos(phi) + 0.5;
uv.y = r * sin(phi) + 0.5; uv.y = r*sin(phi) + 0.5;
} }
else else
{ {

View file

@ -12,7 +12,7 @@ varying vec3 fragNormal;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
#define MAX_LIGHTS 4 #define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0 #define LIGHT_DIRECTIONAL 0

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -1,5 +1,7 @@
#version 100 #version 100
#extension GL_EXT_frag_depth : enable // Extension required for writing depth #extension GL_EXT_frag_depth : enable // Extension required for writing depth
precision mediump float; // Precision required for OpenGL ES2 (WebGL) precision mediump float; // Precision required for OpenGL ES2 (WebGL)
varying vec2 fragTexCoord; varying vec2 fragTexCoord;
@ -11,6 +13,7 @@ uniform vec4 colDiffuse;
void main() void main()
{ {
vec4 texelColor = texture2D(texture0, fragTexCoord); vec4 texelColor = texture2D(texture0, fragTexCoord);
gl_FragColor = texelColor*colDiffuse*fragColor; gl_FragColor = texelColor*colDiffuse*fragColor;
gl_FragDepthEXT = gl_FragCoord.z; gl_FragDepthEXT = gl_FragCoord.z;
} }

View file

@ -1,8 +1,11 @@
#version 100 #version 100
#extension GL_EXT_frag_depth : enable //Extension required for writing depth #extension GL_EXT_frag_depth : enable //Extension required for writing depth
#extension GL_OES_standard_derivatives : enable //Extension used for fwidth() #extension GL_OES_standard_derivatives : enable //Extension used for fwidth()
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
#define ZERO 0
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord; varying vec2 fragTexCoord;
@ -17,23 +20,22 @@ uniform vec3 camPos;
uniform vec3 camDir; uniform vec3 camDir;
uniform vec2 screenCenter; uniform vec2 screenCenter;
#define ZERO 0 // SRC: https://learnopengl.com/Advanced-OpenGL/Depth-testing
float CalcDepth(in vec3 rd, in float Idist)
// https://learnopengl.com/Advanced-OpenGL/Depth-testing {
float CalcDepth(in vec3 rd, in float Idist){
float local_z = dot(normalize(camDir),rd)*Idist; float local_z = dot(normalize(camDir),rd)*Idist;
return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01); return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01);
} }
// https://iquilezles.org/articles/distfunctions/ // SRC: https://iquilezles.org/articles/distfunctions/
float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w)
{ {
p.x = abs(p.x); p.x = abs(p.x);
float l = length(p.xy); float l = length(p.xy);
p.xy = mat2(-c.x, c.y, p.xy = mat2(-c.x, c.y,
c.y, c.x)*p.xy; c.y, c.x)*p.xy;
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),
(p.x>0.0)?p.y:l ); (p.x>0.0)?p.y:l);
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);
@ -44,67 +46,70 @@ float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w )
// r = sphere's radius // r = sphere's radius
// h = cutting's plane's position // h = cutting's plane's position
// t = thickness // t = thickness
float sdSixWayCutHollowSphere( vec3 p, float r, float h, float t ) float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
{ {
// Six way symetry Transformation // Six way symetry Transformation
vec3 ap = abs(p); vec3 ap = abs(p);
if(ap.x < max(ap.y, ap.z)){ if (ap.x < max(ap.y, ap.z)){
if(ap.y < ap.z) ap.xz = ap.zx; if (ap.y < ap.z) ap.xz = ap.zx;
else ap.xy = ap.yx; else ap.xy = ap.yx;
} }
vec2 q = vec2( length(ap.yz), ap.x ); vec2 q = vec2(length(ap.yz), ap.x);
float w = sqrt(r*r-h*h); float w = sqrt(r*r-h*h);
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : abs(length(q)-r)) - t;
abs(length(q)-r) ) - t;
} }
// https://iquilezles.org/articles/boxfunctions // SRC: https://iquilezles.org/articles/boxfunctions
vec2 iBox( in vec3 ro, in vec3 rd, in vec3 rad ) vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad)
{ {
vec3 m = 1.0/rd; vec3 m = 1.0/rd;
vec3 n = m*ro; vec3 n = m*ro;
vec3 k = abs(m)*rad; vec3 k = abs(m)*rad;
vec3 t1 = -n - k; vec3 t1 = -n - k;
vec3 t2 = -n + k; vec3 t2 = -n + k;
return vec2( max( max( t1.x, t1.y ), t1.z ),
min( min( t2.x, t2.y ), t2.z ) ); return vec2(max(max(t1.x, t1.y), t1.z),
min(min(t2.x, t2.y), t2.z));
} }
vec2 opU( vec2 d1, vec2 d2 ) vec2 opU(vec2 d1, vec2 d2)
{ {
return (d1.x<d2.x) ? d1 : d2; return (d1.x<d2.x) ? d1 : d2;
} }
vec2 map( in vec3 pos ){ vec2 map(in vec3 pos)
vec2 res = vec2( sdHorseshoe( pos-vec3(-1.0,0.08, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.5) ), 11.5 ) ; {
res = opU(res, vec2( sdSixWayCutHollowSphere( pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5 ), 4.5 )) ; vec2 res = vec2(sdHorseshoe(pos-vec3(-1.0,0.08, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.5)), 11.5) ;
res = opU(res, vec2(sdSixWayCutHollowSphere(pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5)) ;
return res; return res;
} }
// https://www.shadertoy.com/view/Xds3zN // SRC: https://www.shadertoy.com/view/Xds3zN
vec2 raycast( in vec3 ro, in vec3 rd ){ vec2 raycast(in vec3 ro, in vec3 rd)
{
vec2 res = vec2(-1.0,-1.0); vec2 res = vec2(-1.0,-1.0);
float tmin = 1.0; float tmin = 1.0;
float tmax = 20.0; float tmax = 20.0;
// raytrace floor plane // Raytrace floor plane
float tp1 = (-ro.y)/rd.y; float tp1 = (-ro.y)/rd.y;
if( tp1>0.0 ) if (tp1>0.0)
{ {
tmax = min( tmax, tp1 ); tmax = min(tmax, tp1);
res = vec2( tp1, 1.0 ); res = vec2(tp1, 1.0);
} }
float t = tmin; float t = tmin;
for( int i=0; i<70 ; i++ ) for (int i=0; i<70 ; i++)
{ {
if(t>tmax) break; if (t>tmax) break;
vec2 h = map( ro+rd*t ); vec2 h = map(ro+rd*t);
if( abs(h.x)<(0.0001*t) ) if (abs(h.x) < (0.0001*t))
{ {
res = vec2(t,h.y); res = vec2(t,h.y);
break; break;
@ -117,54 +122,54 @@ vec2 raycast( in vec3 ro, in vec3 rd ){
// https://iquilezles.org/articles/rmshadows // https://iquilezles.org/articles/rmshadows
float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ) float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
{ {
// bounding volume // bounding volume
float tp = (0.8-ro.y)/rd.y; if( tp>0.0 ) tmax = min( tmax, tp ); float tp = (0.8-ro.y)/rd.y; if (tp>0.0) tmax = min(tmax, tp);
float res = 1.0; float res = 1.0;
float t = mint; float t = mint;
for( int i=ZERO; i<24; i++ ) for (int i = ZERO; i < 24; i++)
{ {
float h = map( ro + rd*t ).x; float h = map(ro + rd*t).x;
float s = clamp(8.0*h/t,0.0,1.0); float s = clamp(8.0*h/t,0.0,1.0);
res = min( res, s ); res = min(res, s);
t += clamp( h, 0.01, 0.2 ); t += clamp(h, 0.01, 0.2);
if( res<0.004 || t>tmax ) break; if (res<0.004 || t>tmax) break;
} }
res = clamp( res, 0.0, 1.0 ); res = clamp(res, 0.0, 1.0);
return res*res*(3.0-2.0*res); return res*res*(3.0-2.0*res);
} }
// https://iquilezles.org/articles/normalsSDF // https://iquilezles.org/articles/normalsSDF
vec3 calcNormal( in vec3 pos ) vec3 calcNormal(in vec3 pos)
{ {
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
return normalize( e.xyy*map( pos + e.xyy ).x + return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map( pos + e.yyx ).x + e.yyx*map(pos + e.yyx).x +
e.yxy*map( pos + e.yxy ).x + e.yxy*map(pos + e.yxy).x +
e.xxx*map( pos + e.xxx ).x ); e.xxx*map(pos + e.xxx).x);
} }
// https://iquilezles.org/articles/nvscene2008/rwwtt.pdf // https://iquilezles.org/articles/nvscene2008/rwwtt.pdf
float calcAO( in vec3 pos, in vec3 nor ) float calcAO(in vec3 pos, in vec3 nor)
{ {
float occ = 0.0; float occ = 0.0;
float sca = 1.0; float sca = 1.0;
for( int i=ZERO; i<5; i++ ) for (int i = ZERO; i < 5; i++)
{ {
float h = 0.01 + 0.12*float(i)/4.0; float h = 0.01 + 0.12*float(i)/4.0;
float d = map( pos + h*nor ).x; float d = map(pos + h*nor).x;
occ += (h-d)*sca; occ += (h-d)*sca;
sca *= 0.95; sca *= 0.95;
if( occ>0.35 ) break; if (occ>0.35) break;
} }
return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ) * (0.5+0.5*nor.y); return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y);
} }
// https://iquilezles.org/articles/checkerfiltering // https://iquilezles.org/articles/checkerfiltering
float checkersGradBox( in vec2 p ) float checkersGradBox(in vec2 p)
{ {
// filter kernel // filter kernel
vec2 w = fwidth(p) + 0.001; vec2 w = fwidth(p) + 0.001;
@ -175,7 +180,7 @@ float checkersGradBox( in vec2 p )
} }
// https://www.shadertoy.com/view/tdS3DG // https://www.shadertoy.com/view/tdS3DG
vec4 render( in vec3 ro, in vec3 rd) vec4 render(in vec3 ro, in vec3 rd)
{ {
// background // background
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
@ -183,37 +188,37 @@ vec4 render( in vec3 ro, in vec3 rd)
// raycast scene // raycast scene
vec2 res = raycast(ro,rd); vec2 res = raycast(ro,rd);
float t = res.x; float t = res.x;
float m = res.y; float m = res.y;
if( m>-0.5 ) if (m>-0.5)
{ {
vec3 pos = ro + t*rd; vec3 pos = ro + t*rd;
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
vec3 ref = reflect( rd, nor ); vec3 ref = reflect(rd, nor);
// material // material
col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
float ks = 1.0; float ks = 1.0;
if( m<1.5 ) if (m<1.5)
{ {
float f = checkersGradBox( 3.0*pos.xz); float f = checkersGradBox(3.0*pos.xz);
col = 0.15 + f*vec3(0.05); col = 0.15 + f*vec3(0.05);
ks = 0.4; ks = 0.4;
} }
// lighting // lighting
float occ = calcAO( pos, nor ); float occ = calcAO(pos, nor);
vec3 lin = vec3(0.0); vec3 lin = vec3(0.0);
// sun // sun
{ {
vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); vec3 lig = normalize(vec3(-0.5, 0.4, -0.6));
vec3 hal = normalize( lig-rd ); vec3 hal = normalize(lig-rd);
float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); float dif = clamp(dot(nor, lig), 0.0, 1.0);
//if( dif>0.0001 ) //if (dif>0.0001)
dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0);
spe *= dif; spe *= dif;
spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0);
//spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0); //spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0);
@ -222,38 +227,39 @@ vec4 render( in vec3 ro, in vec3 rd)
} }
// sky // sky
{ {
float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); float dif = sqrt(clamp(0.5+0.5*nor.y, 0.0, 1.0));
dif *= occ; dif *= occ;
float spe = smoothstep( -0.2, 0.2, ref.y ); float spe = smoothstep(-0.2, 0.2, ref.y);
spe *= dif; spe *= dif;
spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0);
//if( spe>0.001 ) //if (spe>0.001)
spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); spe *= calcSoftshadow(pos, ref, 0.02, 2.5);
lin += col*0.60*dif*vec3(0.40,0.60,1.15); lin += col*0.60*dif*vec3(0.40,0.60,1.15);
lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks;
} }
// back // back
{ {
float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); float dif = clamp(dot(nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
dif *= occ; dif *= occ;
lin += col*0.55*dif*vec3(0.25,0.25,0.25); lin += col*0.55*dif*vec3(0.25,0.25,0.25);
} }
// sss // sss
{ {
float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0);
dif *= occ; dif *= occ;
lin += col*0.25*dif*vec3(1.00,1.00,1.00); lin += col*0.25*dif*vec3(1.00,1.00,1.00);
} }
col = lin; col = lin;
col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
} }
return vec4(vec3( clamp(col,0.0,1.0) ),t); return vec4(vec3(clamp(col,0.0,1.0)),t);
} }
vec3 CalcRayDir(vec2 nCoord){ vec3 CalcRayDir(vec2 nCoord)
{
vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0))); vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0)));
vec3 vertical = normalize(cross(horizontal,camDir)); vec3 vertical = normalize(cross(horizontal,camDir));
return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y); return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y);
@ -261,11 +267,11 @@ vec3 CalcRayDir(vec2 nCoord){
mat3 setCamera() mat3 setCamera()
{ {
vec3 cw = normalize(camDir); vec3 cw = normalize(camDir);
vec3 cp = vec3(0.0, 1.0 ,0.0); vec3 cp = vec3(0.0, 1.0 ,0.0);
vec3 cu = normalize( cross(cw,cp) ); vec3 cu = normalize(cross(cw,cp));
vec3 cv = ( cross(cu,cw) ); vec3 cv = (cross(cu,cw));
return mat3( cu, cv, cw ); return mat3(cu, cv, cw);
} }
void main() void main()
@ -275,14 +281,15 @@ void main()
// focal length // focal length
float fl = length(camDir); float fl = length(camDir);
vec3 rd = ca * normalize( vec3(nCoord,fl) ); vec3 rd = ca*normalize(vec3(nCoord,fl));
vec3 color = vec3(nCoord/2.0 + 0.5, 0.0); vec3 color = vec3(nCoord/2.0 + 0.5, 0.0);
float depth = gl_FragCoord.z; float depth = gl_FragCoord.z;
{ {
vec4 res = render( camPos - vec3(0.0, 0.0, 0.0) , rd ); vec4 res = render(camPos - vec3(0.0, 0.0, 0.0) , rd);
color = res.xyz; color = res.xyz;
depth = CalcDepth(rd,res.w); depth = CalcDepth(rd,res.w);
} }
gl_FragColor = vec4(color , 1.0); gl_FragColor = vec4(color , 1.0);
gl_FragDepthEXT = depth; gl_FragDepthEXT = depth;
} }

View file

@ -6,59 +6,58 @@ precision mediump float;
varying vec2 fragTexCoord; varying vec2 fragTexCoord;
varying vec4 fragColor; varying vec4 fragColor;
uniform vec2 screenDims; // Dimensions of the screen
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
uniform vec2 offset; // Offset of the scale. uniform vec2 offset; // Offset of the scale
uniform float zoom; // Zoom of the scale. uniform float zoom; // Zoom of the scale
// NOTE: Maximum number of shader for-loop iterations depend on GPU, // NOTE: Maximum number of shader for-loop iterations depend on GPU,
// for example, on RasperryPi for this examply only supports up to 60 // for example, on RasperryPi for this examply only supports up to 60
const int MAX_ITERATIONS = 48; // Max iterations to do const int maxIterations = 255; // Max iterations to do.
const float colorCycles = 1.0; // Number of times the color palette repeats.
// Square a complex number // Square a complex number
vec2 ComplexSquare(vec2 z) vec2 ComplexSquare(vec2 z)
{ {
return vec2( return vec2(z.x*z.x - z.y*z.y, z.x*z.y*2.0);
z.x * z.x - z.y * z.y,
z.x * z.y * 2.0
);
} }
// Convert Hue Saturation Value (HSV) color into RGB // Convert Hue Saturation Value (HSV) color into RGB
vec3 Hsv2rgb(vec3 c) vec3 Hsv2rgb(vec3 c)
{ {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); vec3 p = abs(fract(c.xxx + K.xyz)*6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); return c.z*mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
} }
void main() void main()
{ {
/********************************************************************************************** /**********************************************************************************************
Julia sets use a function z^2 + c, where c is a constant. Julia sets use a function z^2 + c, where c is a constant
This function is iterated until the nature of the point is determined. This function is iterated until the nature of the point is determined
If the magnitude of the number becomes greater than 2, then from that point onward If the magnitude of the number becomes greater than 2, then from that point onward
the number will get bigger and bigger, and will never get smaller (tends towards infinity). the number will get bigger and bigger, and will never get smaller (tends towards infinity)
2^2 = 4, 4^2 = 8 and so on. 2^2 = 4, 4^2 = 8 and so on
So at 2 we stop iterating. So at 2 we stop iterating
If the number is below 2, we keep iterating. If the number is below 2, we keep iterating
But when do we stop iterating if the number is always below 2 (it converges)? But when do we stop iterating if the number is always below 2 (it converges)?
That is what MAX_ITERATIONS is for. That is what maxIterations is for
Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can Then we can divide the iterations by the maxIterations value to get a normalized value
then map to a color. that we can then map to a color
We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared. We use dot product (z.x*z.x + z.y*z.y) to determine the magnitude (length) squared
And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power). And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power)
*************************************************************************************************/ *************************************************************************************************/
// The pixel coordinates are scaled so they are on the mandelbrot scale // The pixel coordinates are scaled so they are on the mandelbrot scale
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom); vec2 z = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
z.x += offset.x;
z.y += offset.y;
int iter = 0; int iter = 0;
for (int iterations = 0; iterations < 60; iterations++) for (int iterations = 0; iterations < maxIterations; iterations++)
{ {
z = ComplexSquare(z) + c; // Iterate function z = ComplexSquare(z) + c; // Iterate function
if (dot(z, z) > 4.0) break; if (dot(z, z) > 4.0) break;
@ -66,18 +65,18 @@ void main()
iter = iterations; iter = iterations;
} }
// Another few iterations decreases errors in the smoothing calculation. // Another few iterations decreases errors in the smoothing calculation
// See http://linas.org/art-gallery/escape/escape.html for more information. // See http://linas.org/art-gallery/escape/escape.html for more information
z = ComplexSquare(z) + c; z = ComplexSquare(z) + c;
z = ComplexSquare(z) + c; z = ComplexSquare(z) + c;
// This last part smooths the color (again see link above). // This last part smooths the color (again see link above)
float smoothVal = float(iter) + 1.0 - (log(log(length(z)))/log(2.0)); float smoothVal = float(iter) + 1.0 - (log(log(length(z)))/log(2.0));
// Normalize the value so it is between 0 and 1. // Normalize the value so it is between 0 and 1
float norm = smoothVal/float(MAX_ITERATIONS); float norm = smoothVal/float(maxIterations);
// If in set, color black. 0.999 allows for some float accuracy error. // If in set, color black. 0.999 allows for some float accuracy error
if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
else gl_FragColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0); else gl_FragColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0, 1.0)), 1.0);
} }

View file

@ -12,18 +12,12 @@ varying vec3 fragNormal;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
#define MAX_LIGHTS 4 #define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0 #define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1 #define LIGHT_POINT 1
struct MaterialProperty {
vec3 color;
int useSampler;
sampler2D sampler;
};
struct Light { struct Light {
int enabled; int enabled;
int type; int type;
@ -46,6 +40,8 @@ void main()
vec3 viewD = normalize(viewPos - fragPosition); vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0); vec3 specular = vec3(0.0);
vec4 tint = colDiffuse*fragColor;
// NOTE: Implement here your fragment shader code // NOTE: Implement here your fragment shader code
for (int i = 0; i < MAX_LIGHTS; i++) for (int i = 0; i < MAX_LIGHTS; i++)
@ -73,7 +69,7 @@ void main()
} }
} }
vec4 finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0))); vec4 finalColor = (texelColor*((tint + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
finalColor += texelColor*(ambient/10.0); finalColor += texelColor*(ambient/10.0);
// Gamma correction // Gamma correction

View file

@ -16,7 +16,7 @@ varying vec2 fragTexCoord;
varying vec4 fragColor; varying vec4 fragColor;
varying vec3 fragNormal; varying vec3 fragNormal;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// https://github.com/glslify/glsl-inverse // https://github.com/glslify/glsl-inverse
mat3 inverse(mat3 m) mat3 inverse(mat3 m)

View file

@ -18,7 +18,7 @@ varying vec2 fragTexCoord;
varying vec4 fragColor; varying vec4 fragColor;
varying vec3 fragNormal; varying vec3 fragNormal;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -12,7 +12,7 @@ uniform sampler2D mask;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
uniform int frame; uniform int frame;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -2,7 +2,7 @@
precision mediump float; precision mediump float;
const int colors = 8; const int MAX_INDEXED_COLORS = 8;
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord; varying vec2 fragTexCoord;
@ -10,7 +10,8 @@ varying vec4 fragColor;
// Input uniform values // Input uniform values
uniform sampler2D texture0; uniform sampler2D texture0;
uniform ivec3 palette[colors]; uniform ivec3 palette[MAX_INDEXED_COLORS];
//uniform sampler2D palette; // Alternative to ivec3, palette provided as a 256x1 texture
void main() void main()
{ {
@ -18,13 +19,13 @@ void main()
vec4 texelColor = texture2D(texture0, fragTexCoord)*fragColor; vec4 texelColor = texture2D(texture0, fragTexCoord)*fragColor;
// Convert the (normalized) texel color RED component (GB would work, too) // Convert the (normalized) texel color RED component (GB would work, too)
// to the palette index by scaling up from [0, 1] to [0, 255]. // to the palette index by scaling up from [0..1] to [0..255]
int index = int(texelColor.r*255.0); int index = int(texelColor.r*255.0);
ivec3 color = ivec3(0); ivec3 color = ivec3(0);
// NOTE: On GLSL 100 we are not allowed to index a uniform array by a variable value, // NOTE: On GLSL 100 we are not allowed to index a uniform array by a variable value,
// a constantmust be used, so this logic... // a constant must be used, so this logic...
if (index == 0) color = palette[0]; if (index == 0) color = palette[0];
else if (index == 1) color = palette[1]; else if (index == 1) color = palette[1];
else if (index == 2) color = palette[2]; else if (index == 2) color = palette[2];
@ -34,8 +35,9 @@ void main()
else if (index == 6) color = palette[6]; else if (index == 6) color = palette[6];
else if (index == 7) color = palette[7]; else if (index == 7) color = palette[7];
//gl_FragColor = texture2D(palette, texelColor.xy); // Alternative to ivec3
// Calculate final fragment color. Note that the palette color components // Calculate final fragment color. Note that the palette color components
// are defined in the range [0, 255] and need to be normalized to [0, 1] // are defined in the range [0..255] and need to be normalized to [0..1]
// for OpenGL to work.
gl_FragColor = vec4(float(color.x)/255.0, float(color.y)/255.0, float(color.z)/255.0, texelColor.a); gl_FragColor = vec4(float(color.x)/255.0, float(color.y)/255.0, float(color.z)/255.0, texelColor.a);
} }

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800.0; const float renderWidth = 800.0;

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
float gamma = 0.6; float gamma = 0.6;
float numColors = 8.0; float numColors = 8.0;

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -1,9 +1,9 @@
#version 100 #version 100
precision mediump float;
#extension GL_OES_standard_derivatives : enable #extension GL_OES_standard_derivatives : enable
precision mediump float;
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord; varying vec2 fragTexCoord;
varying vec4 fragColor; varying vec4 fragColor;
@ -34,46 +34,46 @@ uniform vec2 resolution;
// SOFTWARE. // SOFTWARE.
// A list of useful distance function to simple primitives, and an example on how to // A list of useful distance function to simple primitives, and an example on how to
// do some interesting boolean operations, repetition and displacement. // do some interesting boolean operations, repetition and displacement
// //
// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm // More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
#define AA 1 // make this 1 is your machine is too slow #define AA 1 // make this 1 if your machine is too slow
//------------------------------------------------------------------ //------------------------------------------------------------------
float sdPlane( vec3 p ) float sdPlane(vec3 p)
{ {
return p.y; return p.y;
} }
float sdSphere( vec3 p, float s ) float sdSphere(vec3 p, float s)
{ {
return length(p)-s; return length(p)-s;
} }
float sdBox( vec3 p, vec3 b ) float sdBox(vec3 p, vec3 b)
{ {
vec3 d = abs(p) - b; vec3 d = abs(p) - b;
return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
} }
float sdEllipsoid( in vec3 p, in vec3 r ) float sdEllipsoid(in vec3 p, in vec3 r)
{ {
return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z); return (length(p/r) - 1.0)*min(min(r.x,r.y),r.z);
} }
float udRoundBox( vec3 p, vec3 b, float r ) float udRoundBox(vec3 p, vec3 b, float r)
{ {
return length(max(abs(p)-b,0.0))-r; return length(max(abs(p)-b,0.0))-r;
} }
float sdTorus( vec3 p, vec2 t ) float sdTorus(vec3 p, vec2 t)
{ {
return length( vec2(length(p.xz)-t.x,p.y) )-t.y; return length(vec2(length(p.xz)-t.x,p.y))-t.y;
} }
float sdHexPrism( vec3 p, vec2 h ) float sdHexPrism(vec3 p, vec2 h)
{ {
vec3 q = abs(p); vec3 q = abs(p);
#if 0 #if 0
@ -85,24 +85,24 @@ float sdHexPrism( vec3 p, vec2 h )
#endif #endif
} }
float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) float sdCapsule(vec3 p, vec3 a, vec3 b, float r)
{ {
vec3 pa = p-a, ba = b-a; vec3 pa = p-a, ba = b-a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); float h = clamp(dot(pa,ba)/dot(ba,ba), 0.0, 1.0);
return length( pa - ba*h ) - r; return length(pa - ba*h) - r;
} }
float sdEquilateralTriangle( in vec2 p ) float sdEquilateralTriangle( in vec2 p)
{ {
const float k = sqrt(3.0); const float k = sqrt(3.0);
p.x = abs(p.x) - 1.0; p.x = abs(p.x) - 1.0;
p.y = p.y + 1.0/k; p.y = p.y + 1.0/k;
if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0; if (p.x + k*p.y > 0.0) p = vec2(p.x - k*p.y, -k*p.x - p.y)/2.0;
p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 ); p.x += 2.0 - 2.0*clamp((p.x+2.0)/2.0, 0.0, 1.0);
return -length(p)*sign(p.y); return -length(p)*sign(p.y);
} }
float sdTriPrism( vec3 p, vec2 h ) float sdTriPrism(vec3 p, vec2 h)
{ {
vec3 q = abs(p); vec3 q = abs(p);
float d1 = q.z-h.y; float d1 = q.z-h.y;
@ -117,95 +117,95 @@ float sdTriPrism( vec3 p, vec2 h )
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
} }
float sdCylinder( vec3 p, vec2 h ) float sdCylinder(vec3 p, vec2 h)
{ {
vec2 d = abs(vec2(length(p.xz),p.y)) - h; vec2 d = abs(vec2(length(p.xz),p.y)) - h;
return min(max(d.x,d.y),0.0) + length(max(d,0.0)); return min(max(d.x,d.y),0.0) + length(max(d,0.0));
} }
float sdCone( in vec3 p, in vec3 c ) float sdCone(in vec3 p, in vec3 c)
{ {
vec2 q = vec2( length(p.xz), p.y ); vec2 q = vec2(length(p.xz), p.y);
float d1 = -q.y-c.z; float d1 = -q.y-c.z;
float d2 = max( dot(q,c.xy), q.y); float d2 = max(dot(q,c.xy), q.y);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
} }
float sdConeSection( in vec3 p, in float h, in float r1, in float r2 ) float sdConeSection(in vec3 p, in float h, in float r1, in float r2)
{ {
float d1 = -p.y - h; float d1 = -p.y - h;
float q = p.y - h; float q = p.y - h;
float si = 0.5*(r1-r2)/h; float si = 0.5*(r1-r2)/h;
float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q ); float d2 = max(sqrt(dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
} }
float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height } float sdPryamid4(vec3 p, vec3 h) // h = { cos a, sin a, height }
{ {
// Tetrahedron = Octahedron - Cube // Tetrahedron = Octahedron - Cube
float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) ); float box = sdBox(p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z));
float d = 0.0; float d = 0.0;
d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) )); d = max(d, abs(dot(p, vec3(-h.x, h.y, 0))));
d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) )); d = max(d, abs(dot(p, vec3( h.x, h.y, 0))));
d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) )); d = max(d, abs(dot(p, vec3( 0, h.y, h.x))));
d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) )); d = max(d, abs(dot(p, vec3( 0, h.y,-h.x))));
float octa = d - h.z; float octa = d - h.z;
return max(-box,octa); // Subtraction return max(-box,octa); // Subtraction
} }
float length2( vec2 p ) float length2(vec2 p)
{ {
return sqrt( p.x*p.x + p.y*p.y ); return sqrt(p.x*p.x + p.y*p.y);
} }
float length6( vec2 p ) float length6(vec2 p)
{ {
p = p*p*p; p = p*p; p = p*p*p; p = p*p;
return pow( p.x + p.y, 1.0/6.0 ); return pow(p.x + p.y, 1.0/6.0);
} }
float length8( vec2 p ) float length8(vec2 p)
{ {
p = p*p; p = p*p; p = p*p; p = p*p; p = p*p; p = p*p;
return pow( p.x + p.y, 1.0/8.0 ); return pow(p.x + p.y, 1.0/8.0);
} }
float sdTorus82( vec3 p, vec2 t ) float sdTorus82(vec3 p, vec2 t)
{ {
vec2 q = vec2(length2(p.xz)-t.x,p.y); vec2 q = vec2(length2(p.xz)-t.x,p.y);
return length8(q)-t.y; return length8(q)-t.y;
} }
float sdTorus88( vec3 p, vec2 t ) float sdTorus88(vec3 p, vec2 t)
{ {
vec2 q = vec2(length8(p.xz)-t.x,p.y); vec2 q = vec2(length8(p.xz)-t.x,p.y);
return length8(q)-t.y; return length8(q)-t.y;
} }
float sdCylinder6( vec3 p, vec2 h ) float sdCylinder6(vec3 p, vec2 h)
{ {
return max( length6(p.xz)-h.x, abs(p.y)-h.y ); return max(length6(p.xz)-h.x, abs(p.y)-h.y);
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
float opS( float d1, float d2 ) float opS(float d1, float d2)
{ {
return max(-d2,d1); return max(-d2,d1);
} }
vec2 opU( vec2 d1, vec2 d2 ) vec2 opU(vec2 d1, vec2 d2)
{ {
return (d1.x<d2.x) ? d1 : d2; return (d1.x<d2.x) ? d1 : d2;
} }
vec3 opRep( vec3 p, vec3 c ) vec3 opRep(vec3 p, vec3 c)
{ {
return mod(p,c)-0.5*c; return mod(p,c)-0.5*c;
} }
vec3 opTwist( vec3 p ) vec3 opTwist(vec3 p)
{ {
float c = cos(10.0*p.y+10.0); float c = cos(10.0*p.y+10.0);
float s = sin(10.0*p.y+10.0); float s = sin(10.0*p.y+10.0);
@ -215,110 +215,110 @@ vec3 opTwist( vec3 p )
//------------------------------------------------------------------ //------------------------------------------------------------------
vec2 map( in vec3 pos ) vec2 map(in vec3 pos)
{ {
vec2 res = opU( vec2( sdPlane( pos), 1.0 ), vec2 res = opU(vec2(sdPlane( pos), 1.0),
vec2( sdSphere( pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) ); vec2(sdSphere( pos-vec3(0.0,0.25, 0.0), 0.25), 46.9));
res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) ); res = opU(res, vec2(sdBox( pos-vec3(1.0,0.25, 0.0), vec3(0.25)), 3.0));
res = opU( res, vec2( udRoundBox( pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) ); res = opU(res, vec2(udRoundBox( pos-vec3(1.0,0.25, 1.0), vec3(0.15), 0.1), 41.0));
res = opU( res, vec2( sdTorus( pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) ); res = opU(res, vec2(sdTorus( pos-vec3(0.0,0.25, 1.0), vec2(0.20,0.05)), 25.0));
res = opU( res, vec2( sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9 ) ); res = opU(res, vec2(sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9));
res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) ); res = opU(res, vec2(sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05)),43.5));
res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) ); res = opU(res, vec2(sdCylinder( pos-vec3(1.0,0.30,-1.0), vec2(0.1,0.2)), 8.0));
res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) ); res = opU(res, vec2(sdCone( pos-vec3(0.0,0.50,-1.0), vec3(0.8,0.6,0.3)), 55.0));
res = opU( res, vec2( sdTorus82( pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) ); res = opU(res, vec2(sdTorus82( pos-vec3(0.0,0.25, 2.0), vec2(0.20,0.05)),50.0));
res = opU( res, vec2( sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) ); res = opU(res, vec2(sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05)),43.0));
res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) ); res = opU(res, vec2(sdCylinder6(pos-vec3(1.0,0.30, 2.0), vec2(0.1,0.2)), 12.0));
res = opU( res, vec2( sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) ); res = opU(res, vec2(sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05)),17.0));
res = opU( res, vec2( sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25) ),37.0 ) ); res = opU(res, vec2(sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25)),37.0));
res = opU( res, vec2( opS( udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05), res = opU(res, vec2(opS(udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05),
sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) ); sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0));
res = opU( res, vec2( opS( sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)), res = opU(res, vec2(opS(sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)),
sdCylinder( opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0 ) ); sdCylinder( opRep(vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0));
res = opU( res, vec2( 0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ) ); res = opU(res, vec2(0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0));
res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) ); res = opU(res, vec2(0.5*sdTorus(opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7));
res = opU( res, vec2( sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) ); res = opU(res, vec2(sdConeSection(pos-vec3(0.0,0.35,-2.0), 0.15, 0.2, 0.1), 13.67));
res = opU( res, vec2( sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) ); res = opU(res, vec2(sdEllipsoid(pos-vec3(1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05)), 43.17));
return res; return res;
} }
vec2 castRay( in vec3 ro, in vec3 rd ) vec2 castRay(in vec3 ro, in vec3 rd)
{ {
float tmin = 0.2; float tmin = 0.2;
float tmax = 30.0; float tmax = 30.0;
#if 1 #if 1
// bounding volume // bounding volume
float tp1 = (0.0-ro.y)/rd.y; if( tp1>0.0 ) tmax = min( tmax, tp1 ); float tp1 = (0.0-ro.y)/rd.y; if (tp1>0.0) tmax = min(tmax, tp1);
float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 ); float tp2 = (1.6-ro.y)/rd.y; if (tp2>0.0) { if (ro.y>1.6) tmin = max(tmin, tp2);
else tmax = min( tmax, tp2 ); } else tmax = min(tmax, tp2); }
#endif #endif
float t = tmin; float t = tmin;
float m = -1.0; float m = -1.0;
for( int i=0; i<64; i++ ) for (int i=0; i<64; i++)
{ {
float precis = 0.0005*t; float precis = 0.0005*t;
vec2 res = map( ro+rd*t ); vec2 res = map(ro+rd*t);
if( res.x<precis || t>tmax ) break; if (res.x<precis || t>tmax) break;
t += res.x; t += res.x;
m = res.y; m = res.y;
} }
if( t>tmax ) m=-1.0; if (t>tmax) m=-1.0;
return vec2( t, m ); return vec2(t, m);
} }
float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ) float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
{ {
float res = 1.0; float res = 1.0;
float t = mint; float t = mint;
for( int i=0; i<16; i++ ) for (int i=0; i<16; i++)
{ {
float h = map( ro + rd*t ).x; float h = map(ro + rd*t).x;
res = min( res, 8.0*h/t ); res = min(res, 8.0*h/t);
t += clamp( h, 0.02, 0.10 ); t += clamp(h, 0.02, 0.10);
if( h<0.001 || t>tmax ) break; if (h<0.001 || t>tmax) break;
} }
return clamp( res, 0.0, 1.0 ); return clamp(res, 0.0, 1.0);
} }
vec3 calcNormal( in vec3 pos ) vec3 calcNormal(in vec3 pos)
{ {
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
return normalize( e.xyy*map( pos + e.xyy ).x + return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map( pos + e.yyx ).x + e.yyx*map(pos + e.yyx).x +
e.yxy*map( pos + e.yxy ).x + e.yxy*map(pos + e.yxy).x +
e.xxx*map( pos + e.xxx ).x ); e.xxx*map(pos + e.xxx).x);
/* /*
vec3 eps = vec3( 0.0005, 0.0, 0.0 ); vec3 eps = vec3(0.0005, 0.0, 0.0);
vec3 nor = vec3( vec3 nor = vec3(
map(pos+eps.xyy).x - map(pos-eps.xyy).x, map(pos+eps.xyy).x - map(pos-eps.xyy).x,
map(pos+eps.yxy).x - map(pos-eps.yxy).x, map(pos+eps.yxy).x - map(pos-eps.yxy).x,
map(pos+eps.yyx).x - map(pos-eps.yyx).x ); map(pos+eps.yyx).x - map(pos-eps.yyx).x);
return normalize(nor); return normalize(nor);
*/ */
} }
float calcAO( in vec3 pos, in vec3 nor ) float calcAO(in vec3 pos, in vec3 nor)
{ {
float occ = 0.0; float occ = 0.0;
float sca = 1.0; float sca = 1.0;
for( int i=0; i<5; i++ ) for (int i=0; i<5; i++)
{ {
float hr = 0.01 + 0.12*float(i)/4.0; float hr = 0.01 + 0.12*float(i)/4.0;
vec3 aopos = nor * hr + pos; vec3 aopos = nor*hr + pos;
float dd = map( aopos ).x; float dd = map(aopos).x;
occ += -(dd-hr)*sca; occ += -(dd-hr)*sca;
sca *= 0.95; sca *= 0.95;
} }
return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ); return clamp(1.0 - 3.0*occ, 0.0, 1.0);
} }
// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm // http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm
float checkersGradBox( in vec2 p ) float checkersGradBox(in vec2 p)
{ {
// filter kernel // filter kernel
vec2 w = fwidth(p) + 0.001; vec2 w = fwidth(p) + 0.001;
@ -328,43 +328,43 @@ float checkersGradBox( in vec2 p )
return 0.5 - 0.5*i.x*i.y; return 0.5 - 0.5*i.x*i.y;
} }
vec3 render( in vec3 ro, in vec3 rd ) vec3 render(in vec3 ro, in vec3 rd)
{ {
vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8; vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
vec2 res = castRay(ro,rd); vec2 res = castRay(ro,rd);
float t = res.x; float t = res.x;
float m = res.y; float m = res.y;
if( m>-0.5 ) if (m>-0.5)
{ {
vec3 pos = ro + t*rd; vec3 pos = ro + t*rd;
vec3 nor = calcNormal( pos ); vec3 nor = calcNormal(pos);
vec3 ref = reflect( rd, nor ); vec3 ref = reflect(rd, nor);
// material // material
col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) ); col = 0.45 + 0.35*sin(vec3(0.05,0.08,0.10)*(m-1.0));
if( m<1.5 ) if (m<1.5)
{ {
float f = checkersGradBox( 5.0*pos.xz ); float f = checkersGradBox(5.0*pos.xz);
col = 0.3 + f*vec3(0.1); col = 0.3 + f*vec3(0.1);
} }
// lighting // lighting
float occ = calcAO( pos, nor ); float occ = calcAO(pos, nor);
vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) ); vec3 lig = normalize(vec3(cos(-0.4*runTime), sin(0.7*runTime), -0.6));
vec3 hal = normalize( lig-rd ); vec3 hal = normalize(lig-rd);
float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 ); float amb = clamp(0.5+0.5*nor.y, 0.0, 1.0);
float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); float dif = clamp(dot(nor, lig), 0.0, 1.0);
float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); float bac = clamp(dot(nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
float dom = smoothstep( -0.1, 0.1, ref.y ); float dom = smoothstep(-0.1, 0.1, ref.y);
float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 ); float fre = pow(clamp(1.0+dot(nor,rd),0.0,1.0), 2.0);
dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
dom *= calcSoftshadow( pos, ref, 0.02, 2.5 ); dom *= calcSoftshadow(pos, ref, 0.02, 2.5);
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)* float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0)*
dif * dif *
(0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 )); (0.04 + 0.96*pow(clamp(1.0+dot(hal,rd),0.0,1.0), 5.0));
vec3 lin = vec3(0.0); vec3 lin = vec3(0.0);
lin += 1.30*dif*vec3(1.00,0.80,0.55); lin += 1.30*dif*vec3(1.00,0.80,0.55);
@ -375,51 +375,51 @@ vec3 render( in vec3 ro, in vec3 rd )
col = col*lin; col = col*lin;
col += 10.00*spe*vec3(1.00,0.90,0.70); col += 10.00*spe*vec3(1.00,0.90,0.70);
col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) ); col = mix(col, vec3(0.8,0.9,1.0), 1.0-exp(-0.0002*t*t*t));
} }
return vec3( clamp(col,0.0,1.0) ); return vec3(clamp(col,0.0,1.0));
} }
mat3 setCamera( in vec3 ro, in vec3 ta, float cr ) mat3 setCamera(in vec3 ro, in vec3 ta, float cr)
{ {
vec3 cw = normalize(ta-ro); vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0); vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) ); vec3 cu = normalize(cross(cw,cp));
vec3 cv = normalize( cross(cu,cw) ); vec3 cv = normalize(cross(cu,cw));
return mat3( cu, cv, cw ); return mat3(cu, cv, cw);
} }
void main() void main()
{ {
vec3 tot = vec3(0.0); vec3 tot = vec3(0.0);
#if AA>1 #if AA>1
for( int m=0; m<AA; m++ ) for (int m=0; m<AA; m++)
for( int n=0; n<AA; n++ ) for (int n=0; n<AA; n++)
{ {
// pixel coordinates // pixel coordinates
vec2 o = vec2(float(m),float(n)) / float(AA) - 0.5; vec2 o = vec2(float(m),float(n))/float(AA) - 0.5;
vec2 p = (-resolution.xy + 2.0*(gl_FragCoord.xy+o))/resolution.y; vec2 p = (-resolution.xy + 2.0*(gl_FragCoord.xy+o))/resolution.y;
#else #else
vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y; vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y;
#endif #endif
// RAY: Camera is provided from raylib // RAY: Camera is provided from raylib
//vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x) ); //vec3 ro = vec3(-0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x));
vec3 ro = viewEye; vec3 ro = viewEye;
vec3 ta = viewCenter; vec3 ta = viewCenter;
// camera-to-world transformation // camera-to-world transformation
mat3 ca = setCamera( ro, ta, 0.0 ); mat3 ca = setCamera(ro, ta, 0.0);
// ray direction // ray direction
vec3 rd = ca * normalize( vec3(p.xy,2.0) ); vec3 rd = ca*normalize(vec3(p.xy,2.0));
// render // render
vec3 col = render( ro, rd ); vec3 col = render(ro, rd);
// gamma // gamma
col = pow( col, vec3(0.4545) ); col = pow(col, vec3(0.4545));
tot += col; tot += col;
#if AA>1 #if AA>1
@ -427,5 +427,5 @@ void main()
tot /= float(AA*AA); tot /= float(AA*AA);
#endif #endif
gl_FragColor = vec4( tot, 1.0 ); gl_FragColor = vec4(tot, 1.0);
} }

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
float offset = 0.0; float offset = 0.0;
float frequency = 450.0/3.0; float frequency = 450.0/3.0;
@ -35,7 +35,7 @@ void main()
fragColor = color; fragColor = color;
*/ */
// Scanlines method 2 // Scanlines method 2
float globalPos = (fragTexCoord.y + offset) * frequency; float globalPos = (fragTexCoord.y + offset)*frequency;
float wavePos = cos((fract(globalPos) - 0.5)*3.14); float wavePos = cos((fract(globalPos) - 0.5)*3.14);
vec4 color = texture2D(texture0, fragTexCoord); vec4 color = texture2D(texture0, fragTexCoord);

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
vec2 resolution = vec2(800.0, 450.0); vec2 resolution = vec2(800.0, 450.0);
void main() void main()
@ -20,10 +20,10 @@ void main()
vec4 horizEdge = vec4(0.0); vec4 horizEdge = vec4(0.0);
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec4 vertEdge = vec4(0.0); vec4 vertEdge = vec4(0.0);

View file

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values should be passed from code // NOTE: Render size values should be passed from code
const float renderWidth = 800.0; const float renderWidth = 800.0;
@ -42,5 +42,5 @@ void main()
tc += center; tc += center;
vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;;
gl_FragColor = vec4(color.rgb, 1.0);; gl_FragColor = vec4(color.rgb, 1.0);
} }

View file

@ -10,10 +10,8 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
uniform float secondes; uniform float seconds;
uniform vec2 size; uniform vec2 size;
uniform float freqX; uniform float freqX;
uniform float freqY; uniform float freqY;
uniform float ampX; uniform float ampX;
@ -21,16 +19,17 @@ uniform float ampY;
uniform float speedX; uniform float speedX;
uniform float speedY; uniform float speedY;
void main() { void main()
float pixelWidth = 1.0 / size.x; {
float pixelHeight = 1.0 / size.y; float pixelWidth = 1.0/size.x;
float aspect = pixelHeight / pixelWidth; float pixelHeight = 1.0/size.y;
float aspect = pixelHeight/pixelWidth;
float boxLeft = 0.0; float boxLeft = 0.0;
float boxTop = 0.0; float boxTop = 0.0;
vec2 p = fragTexCoord; vec2 p = fragTexCoord;
p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth; p.x += cos((fragTexCoord.y - boxTop)*freqX/(pixelWidth*750.0) + (seconds*speedX))*ampX*pixelWidth;
p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight; p.y += sin((fragTexCoord.x - boxLeft)*freqY*aspect/(pixelHeight*750.0) + (seconds*speedY))*ampY*pixelHeight;
gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor; gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor;
} }

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
uniform vec2 resolution = vec2(800, 450); uniform vec2 resolution = vec2(800, 450);
void main() void main()

View file

@ -13,7 +13,7 @@ uniform mat4 mvp;
varying vec2 fragTexCoord; varying vec2 fragTexCoord;
varying vec4 fragColor; varying vec4 fragColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
const vec2 size = vec2(800, 450); // Framebuffer size const vec2 size = vec2(800, 450); // Framebuffer size
const float samples = 5.0; // Pixels per axis; higher = bigger glow, worse performance const float samples = 5.0; // Pixels per axis; higher = bigger glow, worse performance

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800.0; const float renderWidth = 800.0;

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
float hatchOffsetY = 5.0; float hatchOffsetY = 5.0;
float lumThreshold01 = 0.9; float lumThreshold01 = 0.9;

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800.0; const float renderWidth = 800.0;
@ -21,8 +21,8 @@ vec4 PostFX(sampler2D tex, vec2 uv)
{ {
vec4 c = vec4(0.0); vec4 c = vec4(0.0);
float size = stitchingSize; float size = stitchingSize;
vec2 cPos = uv * vec2(renderWidth, renderHeight); vec2 cPos = uv*vec2(renderWidth, renderHeight);
vec2 tlPos = floor(cPos / vec2(size, size)); vec2 tlPos = floor(cPos/vec2(size, size));
tlPos *= size; tlPos *= size;
int remX = int(mod(cPos.x, size)); int remX = int(mod(cPos.x, size));
@ -36,11 +36,11 @@ vec4 PostFX(sampler2D tex, vec2 uv)
if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y))))) if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y)))))
{ {
if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0); if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0);
else c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; else c = texture2D(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
} }
else else
{ {
if (invert == 1) c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; if (invert == 1) c = texture2D(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
else c = vec4(0.0, 0.0, 0.0, 1.0); else c = vec4(0.0, 0.0, 0.0, 1.0);
} }

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {
@ -32,4 +32,4 @@ void main()
color = color/9.5; color = color/9.5;
gl_FragColor = color; gl_FragColor = color;
} }

View file

@ -8,29 +8,29 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
const float PI = 3.1415926535; const float PI = 3.1415926535;
void main() void main()
{ {
float aperture = 178.0; float aperture = 178.0;
float apertureHalf = 0.5 * aperture * (PI / 180.0); float apertureHalf = 0.5*aperture*(PI/180.0);
float maxFactor = sin(apertureHalf); float maxFactor = sin(apertureHalf);
vec2 uv = vec2(0.0); vec2 uv = vec2(0.0);
vec2 xy = 2.0 * fragTexCoord.xy - 1.0; vec2 xy = 2.0*fragTexCoord.xy - 1.0;
float d = length(xy); float d = length(xy);
if (d < (2.0 - maxFactor)) if (d < (2.0 - maxFactor))
{ {
d = length(xy * maxFactor); d = length(xy*maxFactor);
float z = sqrt(1.0 - d * d); float z = sqrt(1.0 - d*d);
float r = atan(d, z) / PI; float r = atan(d, z)/PI;
float phi = atan(xy.y, xy.x); float phi = atan(xy.y, xy.x);
uv.x = r * cos(phi) + 0.5; uv.x = r*cos(phi) + 0.5;
uv.y = r * sin(phi) + 0.5; uv.y = r*sin(phi) + 0.5;
} }
else else
{ {

View file

@ -10,7 +10,7 @@ varying vec3 fragNormal;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
#define MAX_LIGHTS 4 #define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0 #define LIGHT_DIRECTIONAL 0

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -10,18 +10,12 @@ varying vec3 fragNormal;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
#define MAX_LIGHTS 4 #define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0 #define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1 #define LIGHT_POINT 1
struct MaterialProperty {
vec3 color;
int useSampler;
sampler2D sampler;
};
struct Light { struct Light {
int enabled; int enabled;
int type; int type;
@ -44,6 +38,8 @@ void main()
vec3 viewD = normalize(viewPos - fragPosition); vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0); vec3 specular = vec3(0.0);
vec4 tint = colDiffuse*fragColor;
// NOTE: Implement here your fragment shader code // NOTE: Implement here your fragment shader code
for (int i = 0; i < MAX_LIGHTS; i++) for (int i = 0; i < MAX_LIGHTS; i++)
@ -71,7 +67,7 @@ void main()
} }
} }
vec4 finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0))); vec4 finalColor = (texelColor*((tint + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
finalColor += texelColor*(ambient/10.0); finalColor += texelColor*(ambient/10.0);
// Gamma correction // Gamma correction

View file

@ -16,7 +16,7 @@ varying vec2 fragTexCoord;
varying vec4 fragColor; varying vec4 fragColor;
varying vec3 fragNormal; varying vec3 fragNormal;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// https://github.com/glslify/glsl-inverse // https://github.com/glslify/glsl-inverse
mat3 inverse(mat3 m) mat3 inverse(mat3 m)

View file

@ -13,15 +13,15 @@ uniform ivec3 palette[colors];
void main() void main()
{ {
// Texel color fetching from texture sampler // Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord) * fragColor; vec4 texelColor = texture(texture0, fragTexCoord)*fragColor;
// Convert the (normalized) texel color RED component (GB would work, too) // Convert the (normalized) texel color RED component (GB would work, too)
// to the palette index by scaling up from [0, 1] to [0, 255]. // to the palette index by scaling up from [0, 1] to [0, 255]
int index = int(texelColor.r * 255.0); int index = int(texelColor.r*255.0);
ivec3 color = palette[index]; ivec3 color = palette[index];
// Calculate final fragment color. Note that the palette color components // Calculate final fragment color. Note that the palette color components
// are defined in the range [0, 255] and need to be normalized to [0, 1] // are defined in the range [0, 255] and need to be normalized to [0, 1]
// for OpenGL to work. // for OpenGL to work
gl_FragColor = vec4(color / 255.0, texelColor.a); gl_FragColor = vec4(color/255.0, texelColor.a);
} }

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800.0; const float renderWidth = 800.0;

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
float gamma = 0.6; float gamma = 0.6;
float numColors = 8.0; float numColors = 8.0;

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
float offset = 0.0; float offset = 0.0;
float frequency = 450.0/3.0; float frequency = 450.0/3.0;
@ -33,7 +33,7 @@ void main()
fragColor = color; fragColor = color;
*/ */
// Scanlines method 2 // Scanlines method 2
float globalPos = (fragTexCoord.y + offset) * frequency; float globalPos = (fragTexCoord.y + offset)*frequency;
float wavePos = cos((fract(globalPos) - 0.5)*3.14); float wavePos = cos((fract(globalPos) - 0.5)*3.14);
vec4 color = texture2D(texture0, fragTexCoord); vec4 color = texture2D(texture0, fragTexCoord);

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
vec2 resolution = vec2(800.0, 450.0); vec2 resolution = vec2(800.0, 450.0);
void main() void main()
@ -18,10 +18,10 @@ void main()
vec4 horizEdge = vec4(0.0); vec4 horizEdge = vec4(0.0);
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec4 vertEdge = vec4(0.0); vec4 vertEdge = vec4(0.0);

View file

@ -8,7 +8,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values should be passed from code // NOTE: Render size values should be passed from code
const float renderWidth = 800; const float renderWidth = 800;

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {
@ -20,6 +20,9 @@ void main()
// NOTE: Implement here your fragment shader code // NOTE: Implement here your fragment shader code
finalColor = texelColor*colDiffuse; // final color is the color from the texture
// times the tint color (colDiffuse)
// times the fragment color (interpolated vertex color)
finalColor = texelColor*colDiffuse*fragColor;
} }

View file

@ -13,7 +13,7 @@ uniform mat4 mvp;
out vec2 fragTexCoord; out vec2 fragTexCoord;
out vec4 fragColor; out vec4 fragColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
const vec2 size = vec2(800, 450); // Framebuffer size const vec2 size = vec2(800, 450); // Framebuffer size
const float samples = 5.0; // Pixels per axis; higher = bigger glow, worse performance const float samples = 5.0; // Pixels per axis; higher = bigger glow, worse performance

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800; const float renderWidth = 800;

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
float hatchOffsetY = 5.0; float hatchOffsetY = 5.0;
float lumThreshold01 = 0.9; float lumThreshold01 = 0.9;

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800.0; const float renderWidth = 800.0;
@ -25,8 +25,8 @@ vec4 PostFX(sampler2D tex, vec2 uv)
{ {
vec4 c = vec4(0.0); vec4 c = vec4(0.0);
float size = stitchingSize; float size = stitchingSize;
vec2 cPos = uv * vec2(renderWidth, renderHeight); vec2 cPos = uv*vec2(renderWidth, renderHeight);
vec2 tlPos = floor(cPos / vec2(size, size)); vec2 tlPos = floor(cPos/vec2(size, size));
tlPos *= size; tlPos *= size;
int remX = int(mod(cPos.x, size)); int remX = int(mod(cPos.x, size));
@ -40,11 +40,11 @@ vec4 PostFX(sampler2D tex, vec2 uv)
if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y))))) if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y)))))
{ {
if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0); if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0);
else c = texture(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; else c = texture(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
} }
else else
{ {
if (invert == 1) c = texture(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4; if (invert == 1) c = texture(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
else c = vec4(0.0, 0.0, 0.0, 1.0); else c = vec4(0.0, 0.0, 0.0, 1.0);
} }

View file

@ -17,7 +17,7 @@ float angle = 0.0;
vec2 VectorRotateTime(vec2 v, float speed) vec2 VectorRotateTime(vec2 v, float speed)
{ {
float time = uTime*speed; float time = uTime*speed;
float localTime = fract(time); // The time domain this works on is 1 sec. float localTime = fract(time); // The time domain this works on is 1 sec
if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0; if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0;
else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4*sin(2*PI*localTime - PI/2); else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4*sin(2*PI*localTime - PI/2);

View file

@ -7,7 +7,7 @@ out vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {
@ -31,4 +31,4 @@ void main()
color = color/9.5; color = color/9.5;
fragColor = color; fragColor = color;
} }

View file

@ -5,12 +5,12 @@
The Sieve of Eratosthenes -- a simple shader by ProfJski The Sieve of Eratosthenes -- a simple shader by ProfJski
An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
The screen is divided into a square grid of boxes, each representing an integer value. The screen is divided into a square grid of boxes, each representing an integer value
Each integer is tested to see if it is a prime number. Primes are colored white. Each integer is tested to see if it is a prime number. Primes are colored white
Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer. Non-primes are colored with a color that indicates the smallest factor which evenly divides our integer
You can change the scale variable to make a larger or smaller grid. You can change the scale variable to make a larger or smaller grid
Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers. Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers
WARNING: If you make scale too large, your GPU may bog down! WARNING: If you make scale too large, your GPU may bog down!
@ -39,7 +39,7 @@ vec4 Colorizer(float counter, float maxSize)
void main() void main()
{ {
vec4 color = vec4(1.0); vec4 color = vec4(1.0);
float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid. float scale = 1000.0; // Makes 100x100 square grid, change this variable to make a smaller or larger grid
int value = int(scale*floor(fragTexCoord.y*scale)+floor(fragTexCoord.x*scale)); // Group pixels into boxes representing integer values int value = int(scale*floor(fragTexCoord.y*scale)+floor(fragTexCoord.x*scale)); // Group pixels into boxes representing integer values
if ((value == 0) || (value == 1) || (value == 2)) finalColor = vec4(1.0); if ((value == 0) || (value == 1) || (value == 2)) finalColor = vec4(1.0);

View file

@ -7,29 +7,29 @@ out vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
const float PI = 3.1415926535; const float PI = 3.1415926535;
void main() void main()
{ {
float aperture = 178.0; float aperture = 178.0;
float apertureHalf = 0.5 * aperture * (PI / 180.0); float apertureHalf = 0.5*aperture*(PI/180.0);
float maxFactor = sin(apertureHalf); float maxFactor = sin(apertureHalf);
vec2 uv = vec2(0); vec2 uv = vec2(0);
vec2 xy = 2.0 * fragTexCoord.xy - 1.0; vec2 xy = 2.0*fragTexCoord.xy - 1.0;
float d = length(xy); float d = length(xy);
if (d < (2.0 - maxFactor)) if (d < (2.0 - maxFactor))
{ {
d = length(xy * maxFactor); d = length(xy*maxFactor);
float z = sqrt(1.0 - d * d); float z = sqrt(1.0 - d*d);
float r = atan(d, z) / PI; float r = atan(d, z)/PI;
float phi = atan(xy.y, xy.x); float phi = atan(xy.y, xy.x);
uv.x = r * cos(phi) + 0.5; uv.x = r*cos(phi) + 0.5;
uv.y = r * sin(phi) + 0.5; uv.y = r*sin(phi) + 0.5;
} }
else else
{ {

View file

@ -13,7 +13,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
#define MAX_LIGHTS 4 #define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0 #define LIGHT_DIRECTIONAL 0
@ -37,6 +37,7 @@ struct Light {
uniform Light lights[MAX_LIGHTS]; uniform Light lights[MAX_LIGHTS];
uniform vec4 ambient; uniform vec4 ambient;
uniform vec3 viewPos; uniform vec3 viewPos;
uniform vec4 fogColor;
uniform float fogDensity; uniform float fogDensity;
void main() void main()
@ -77,10 +78,6 @@ void main()
// Fog calculation // Fog calculation
float dist = length(viewPos - fragPosition); float dist = length(viewPos - fragPosition);
// these could be parameters...
const vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0);
//const float fogDensity = 0.16;
// Exponential fog // Exponential fog
float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity)); float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity));

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -1,14 +1,22 @@
#version 330 #version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord; in vec2 fragTexCoord;
in vec4 fragColor; in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add your custom variables here
void main() void main()
{ {
vec4 texelColor = texture2D(texture0, fragTexCoord); vec4 texelColor = texture(texture0, fragTexCoord);
gl_FragColor = texelColor*colDiffuse*fragColor;
gl_FragDepth = gl_FragCoord.z; finalColor = texelColor*colDiffuse*fragColor;
gl_FragDepth = finalColor.z;
} }

View file

@ -1,5 +1,7 @@
# version 330 # version 330
#define ZERO 0
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)
in vec2 fragTexCoord; in vec2 fragTexCoord;
in vec4 fragColor; in vec4 fragColor;
@ -13,96 +15,98 @@ uniform vec3 camPos;
uniform vec3 camDir; uniform vec3 camDir;
uniform vec2 screenCenter; uniform vec2 screenCenter;
#define ZERO 0 // Output fragment color
out vec4 finalColor;
// https://learnopengl.com/Advanced-OpenGL/Depth-testing // https://learnopengl.com/Advanced-OpenGL/Depth-testing
float CalcDepth(in vec3 rd, in float Idist){ float CalcDepth(in vec3 rd, in float Idist)
{
float local_z = dot(normalize(camDir),rd)*Idist; float local_z = dot(normalize(camDir),rd)*Idist;
return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01); return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01);
} }
// https://iquilezles.org/articles/distfunctions/ // https://iquilezles.org/articles/distfunctions/
float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w)
{ {
p.x = abs(p.x); p.x = abs(p.x);
float l = length(p.xy); float l = length(p.xy);
p.xy = mat2(-c.x, c.y, p.xy = mat2(-c.x, c.y, c.y, c.x)*p.xy;
c.y, c.x)*p.xy; p.xy = vec2(((p.y > 0.0) || (p.x > 0.0))? p.x : l*sign(-c.x), (p.x>0.0)? p.y : l);
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), p.xy = vec2(p.x, abs(p.y - r)) - vec2(le, 0.0);
(p.x>0.0)?p.y:l );
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); vec2 q = vec2(length(max(p.xy, 0.0)) + min(0.0, max(p.x, p.y)), p.z);
vec2 d = abs(q) - w; vec2 d = abs(q) - w;
return min(max(d.x,d.y),0.0) + length(max(d,0.0)); return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
} }
// r = sphere's radius // r = sphere's radius
// h = cutting's plane's position // h = cutting's plane's position
// t = thickness // t = thickness
float sdSixWayCutHollowSphere( vec3 p, float r, float h, float t ) float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
{ {
// Six way symetry Transformation // Six way symetry Transformation
vec3 ap = abs(p); vec3 ap = abs(p);
if(ap.x < max(ap.y, ap.z)){ if (ap.x < max(ap.y, ap.z))
if(ap.y < ap.z) ap.xz = ap.zx; {
if (ap.y < ap.z) ap.xz = ap.zx;
else ap.xy = ap.yx; else ap.xy = ap.yx;
} }
vec2 q = vec2( length(ap.yz), ap.x ); vec2 q = vec2(length(ap.yz), ap.x);
float w = sqrt(r*r-h*h); float w = sqrt(r*r-h*h);
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : return ((h*q.x < w*q.y)? length(q - vec2(w, h)) : abs(length(q) - r)) - t;
abs(length(q)-r) ) - t;
} }
// https://iquilezles.org/articles/boxfunctions // https://iquilezles.org/articles/boxfunctions
vec2 iBox( in vec3 ro, in vec3 rd, in vec3 rad ) vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad)
{ {
vec3 m = 1.0/rd; vec3 m = 1.0/rd;
vec3 n = m*ro; vec3 n = m*ro;
vec3 k = abs(m)*rad; vec3 k = abs(m)*rad;
vec3 t1 = -n - k; vec3 t1 = -n - k;
vec3 t2 = -n + k; vec3 t2 = -n + k;
return vec2( max( max( t1.x, t1.y ), t1.z ),
min( min( t2.x, t2.y ), t2.z ) ); return vec2(max(max(t1.x, t1.y), t1.z), min(min(t2.x, t2.y), t2.z));
} }
vec2 opU( vec2 d1, vec2 d2 ) vec2 opU(vec2 d1, vec2 d2)
{ {
return (d1.x<d2.x) ? d1 : d2; return (d1.x < d2.x)? d1 : d2;
} }
vec2 map( in vec3 pos ){ vec2 map(in vec3 pos)
vec2 res = vec2( sdHorseshoe( pos-vec3(-1.0,0.08, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.5) ), 11.5 ) ; {
res = opU(res, vec2( sdSixWayCutHollowSphere( pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5 ), 4.5 )) ; vec2 res = vec2(sdHorseshoe(pos - vec3(-1.0, 0.08, 1.0), vec2(cos(1.3), sin(1.3)), 0.2, 0.3, vec2(0.03,0.5)), 11.5);
res = opU(res, vec2(sdSixWayCutHollowSphere(pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5));
return res; return res;
} }
// https://www.shadertoy.com/view/Xds3zN // https://www.shadertoy.com/view/Xds3zN
vec2 raycast( in vec3 ro, in vec3 rd ){ vec2 raycast(in vec3 ro, in vec3 rd)
vec2 res = vec2(-1.0,-1.0); {
vec2 res = vec2(-1.0, -1.0);
float tmin = 1.0; float tmin = 1.0;
float tmax = 20.0; float tmax = 20.0;
// raytrace floor plane // raytrace floor plane
float tp1 = (-ro.y)/rd.y; float tp1 = (-ro.y)/rd.y;
if( tp1>0.0 ) if (tp1 > 0.0)
{ {
tmax = min( tmax, tp1 ); tmax = min(tmax, tp1);
res = vec2( tp1, 1.0 ); res = vec2(tp1, 1.0);
} }
float t = tmin; float t = tmin;
for( int i=0; i<70 ; i++ ) for (int i = 0; i < 70 ; i++)
{ {
if(t>tmax) break; if (t > tmax) break;
vec2 h = map( ro+rd*t ); vec2 h = map(ro + rd*t);
if( abs(h.x)<(0.0001*t) ) if (abs(h.x )< (0.0001*t))
{ {
res = vec2(t,h.y); res = vec2(t, h.y);
break; break;
} }
t += h.x; t += h.x;
@ -111,67 +115,68 @@ vec2 raycast( in vec3 ro, in vec3 rd ){
return res; return res;
} }
// https://iquilezles.org/articles/rmshadows // https://iquilezles.org/articles/rmshadows
float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ) float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
{ {
// bounding volume // bounding volume
float tp = (0.8-ro.y)/rd.y; if( tp>0.0 ) tmax = min( tmax, tp ); float tp = (0.8 - ro.y)/rd.y; if (tp > 0.0) tmax = min(tmax, tp);
float res = 1.0; float res = 1.0;
float t = mint; float t = mint;
for( int i=ZERO; i<24; i++ ) for (int i = ZERO; i < 24; i++)
{ {
float h = map( ro + rd*t ).x; float h = map(ro + rd*t).x;
float s = clamp(8.0*h/t,0.0,1.0); float s = clamp(8.0*h/t, 0.0, 1.0);
res = min( res, s ); res = min(res, s);
t += clamp( h, 0.01, 0.2 ); t += clamp(h, 0.01, 0.2);
if( res<0.004 || t>tmax ) break; if ((res < 0.004) || (t > tmax)) break;
} }
res = clamp( res, 0.0, 1.0 );
res = clamp(res, 0.0, 1.0);
return res*res*(3.0-2.0*res); return res*res*(3.0-2.0*res);
} }
// https://iquilezles.org/articles/normalsSDF // https://iquilezles.org/articles/normalsSDF
vec3 calcNormal( in vec3 pos ) vec3 calcNormal(in vec3 pos)
{ {
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; vec2 e = vec2(1.0, -1.0)*0.5773*0.0005;
return normalize( e.xyy*map( pos + e.xyy ).x + return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map( pos + e.yyx ).x + e.yyx*map(pos + e.yyx).x +
e.yxy*map( pos + e.yxy ).x + e.yxy*map(pos + e.yxy).x +
e.xxx*map( pos + e.xxx ).x ); e.xxx*map(pos + e.xxx).x);
} }
// https://iquilezles.org/articles/nvscene2008/rwwtt.pdf // https://iquilezles.org/articles/nvscene2008/rwwtt.pdf
float calcAO( in vec3 pos, in vec3 nor ) float calcAO(in vec3 pos, in vec3 nor)
{ {
float occ = 0.0; float occ = 0.0;
float sca = 1.0; float sca = 1.0;
for( int i=ZERO; i<5; i++ ) for (int i = ZERO; i < 5; i++)
{ {
float h = 0.01 + 0.12*float(i)/4.0; float h = 0.01 + 0.12*float(i)/4.0;
float d = map( pos + h*nor ).x; float d = map(pos + h*nor).x;
occ += (h-d)*sca; occ += (h-d)*sca;
sca *= 0.95; sca *= 0.95;
if( occ>0.35 ) break; if (occ>0.35) break;
} }
return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ) * (0.5+0.5*nor.y);
return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y);
} }
// https://iquilezles.org/articles/checkerfiltering // https://iquilezles.org/articles/checkerfiltering
float checkersGradBox( in vec2 p ) float checkersGradBox(in vec2 p)
{ {
// filter kernel // filter kernel
vec2 w = fwidth(p) + 0.001; vec2 w = fwidth(p) + 0.001;
// analytical integral (box filter) // analytical integral (box filter)
vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w; vec2 i = 2.0*(abs(fract((p - 0.5*w)*0.5)-0.5) - abs(fract((p + 0.5*w)*0.5) - 0.5))/w;
// xor pattern // xor pattern
return 0.5 - 0.5*i.x*i.y; return (0.5 - 0.5*i.x*i.y);
} }
// https://www.shadertoy.com/view/tdS3DG // https://www.shadertoy.com/view/tdS3DG
vec4 render( in vec3 ro, in vec3 rd) vec4 render(in vec3 ro, in vec3 rd)
{ {
// background // background
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
@ -179,77 +184,78 @@ vec4 render( in vec3 ro, in vec3 rd)
// raycast scene // raycast scene
vec2 res = raycast(ro,rd); vec2 res = raycast(ro,rd);
float t = res.x; float t = res.x;
float m = res.y; float m = res.y;
if( m>-0.5 ) if (m > -0.5)
{ {
vec3 pos = ro + t*rd; vec3 pos = ro + t*rd;
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
vec3 ref = reflect( rd, nor ); vec3 ref = reflect(rd, nor);
// material // material
col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
float ks = 1.0; float ks = 1.0;
if( m<1.5 ) if (m < 1.5)
{ {
float f = checkersGradBox( 3.0*pos.xz); float f = checkersGradBox(3.0*pos.xz);
col = 0.15 + f*vec3(0.05); col = 0.15 + f*vec3(0.05);
ks = 0.4; ks = 0.4;
} }
// lighting // lighting
float occ = calcAO( pos, nor ); float occ = calcAO(pos, nor);
vec3 lin = vec3(0.0); vec3 lin = vec3(0.0);
// sun // sun
{ {
vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); vec3 lig = normalize(vec3(-0.5, 0.4, -0.6));
vec3 hal = normalize( lig-rd ); vec3 hal = normalize(lig-rd);
float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); float dif = clamp(dot(nor, lig), 0.0, 1.0);
//if( dif>0.0001 ) //if (dif>0.0001)
dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0);
spe *= dif; spe *= dif;
spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0);
//spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0); //spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0);
lin += col*2.20*dif*vec3(1.30,1.00,0.70); lin += col*2.20*dif*vec3(1.30,1.00,0.70);
lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks;
} }
// sky // sky
{ {
float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); float dif = sqrt(clamp(0.5+0.5*nor.y, 0.0, 1.0));
dif *= occ; dif *= occ;
float spe = smoothstep( -0.2, 0.2, ref.y ); float spe = smoothstep(-0.2, 0.2, ref.y);
spe *= dif; spe *= dif;
spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0);
//if( spe>0.001 ) //if (spe>0.001)
spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); spe *= calcSoftshadow(pos, ref, 0.02, 2.5);
lin += col*0.60*dif*vec3(0.40,0.60,1.15); lin += col*0.60*dif*vec3(0.40,0.60,1.15);
lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks;
} }
// back // back
{ {
float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); float dif = clamp(dot(nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
dif *= occ; dif *= occ;
lin += col*0.55*dif*vec3(0.25,0.25,0.25); lin += col*0.55*dif*vec3(0.25,0.25,0.25);
} }
// sss // sss
{ {
float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0);
dif *= occ; dif *= occ;
lin += col*0.25*dif*vec3(1.00,1.00,1.00); lin += col*0.25*dif*vec3(1.00,1.00,1.00);
} }
col = lin; col = lin;
col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
} }
return vec4(vec3( clamp(col,0.0,1.0) ),t); return vec4(vec3(clamp(col,0.0,1.0)),t);
} }
vec3 CalcRayDir(vec2 nCoord){ vec3 CalcRayDir(vec2 nCoord)
{
vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0))); vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0)));
vec3 vertical = normalize(cross(horizontal,camDir)); vec3 vertical = normalize(cross(horizontal,camDir));
return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y); return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y);
@ -257,11 +263,11 @@ vec3 CalcRayDir(vec2 nCoord){
mat3 setCamera() mat3 setCamera()
{ {
vec3 cw = normalize(camDir); vec3 cw = normalize(camDir);
vec3 cp = vec3(0.0, 1.0 ,0.0); vec3 cp = vec3(0.0, 1.0 ,0.0);
vec3 cu = normalize( cross(cw,cp) ); vec3 cu = normalize(cross(cw,cp));
vec3 cv = ( cross(cu,cw) ); vec3 cv = (cross(cu,cw));
return mat3( cu, cv, cw ); return mat3(cu, cv, cw);
} }
void main() void main()
@ -271,14 +277,15 @@ void main()
// focal length // focal length
float fl = length(camDir); float fl = length(camDir);
vec3 rd = ca * normalize( vec3(nCoord,fl) ); vec3 rd = ca*normalize(vec3(nCoord,fl));
vec3 color = vec3(nCoord/2.0 + 0.5, 0.0); vec3 color = vec3(nCoord/2.0 + 0.5, 0.0);
float depth = gl_FragCoord.z; float depth = gl_FragCoord.z;
{ {
vec4 res = render( camPos - vec3(0.0, 0.0, 0.0) , rd ); vec4 res = render(camPos - vec3(0.0, 0.0, 0.0) , rd);
color = res.xyz; color = res.xyz;
depth = CalcDepth(rd,res.w); depth = CalcDepth(rd,res.w);
} }
gl_FragColor = vec4(color , 1.0);
gl_FragDepth = depth; finalColor = vec4(color , 1.0);
gl_FragDepth = depth;
} }

View file

@ -7,75 +7,74 @@ in vec4 fragColor;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
uniform vec2 screenDims; // Dimensions of the screen
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
uniform vec2 offset; // Offset of the scale. uniform vec2 offset; // Offset of the scale
uniform float zoom; // Zoom of the scale. uniform float zoom; // Zoom of the scale
const int MAX_ITERATIONS = 255; // Max iterations to do. const int maxIterations = 255; // Max iterations to do
const float colorCycles = 2.0; // Number of times the color palette repeats. Can show higher detail for higher iteration numbers
// Square a complex number // Square a complex number
vec2 ComplexSquare(vec2 z) vec2 ComplexSquare(vec2 z)
{ {
return vec2( return vec2(z.x*z.x - z.y*z.y, z.x*z.y*2.0);
z.x * z.x - z.y * z.y,
z.x * z.y * 2.0
);
} }
// Convert Hue Saturation Value (HSV) color into RGB // Convert Hue Saturation Value (HSV) color into RGB
vec3 Hsv2rgb(vec3 c) vec3 Hsv2rgb(vec3 c)
{ {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); vec3 p = abs(fract(c.xxx + K.xyz)*6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); return c.z*mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
} }
void main() void main()
{ {
/********************************************************************************************** /**********************************************************************************************
Julia sets use a function z^2 + c, where c is a constant. Julia sets use a function z^2 + c, where c is a constant
This function is iterated until the nature of the point is determined. This function is iterated until the nature of the point is determined
If the magnitude of the number becomes greater than 2, then from that point onward If the magnitude of the number becomes greater than 2, then from that point onward
the number will get bigger and bigger, and will never get smaller (tends towards infinity). the number will get bigger and bigger, and will never get smaller (tends towards infinity)
2^2 = 4, 4^2 = 8 and so on. 2^2 = 4, 4^2 = 8 and so on
So at 2 we stop iterating. So at 2 we stop iterating
If the number is below 2, we keep iterating. If the number is below 2, we keep iterating
But when do we stop iterating if the number is always below 2 (it converges)? But when do we stop iterating if the number is always below 2 (it converges)?
That is what MAX_ITERATIONS is for. That is what maxIterations is for
Then we can divide the iterations by the MAX_ITERATIONS value to get a normalized value that we can Then we can divide the iterations by the maxIterations value to get a normalized value
then map to a color. that we can then map to a color
We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared. We use dot product (z.x*z.x + z.y*z.y) to determine the magnitude (length) squared
And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power). And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power)
*************************************************************************************************/ *************************************************************************************************/
// The pixel coordinates are scaled so they are on the mandelbrot scale // The pixel coordinates are scaled so they are on the mandelbrot scale
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
vec2 z = vec2((fragTexCoord.x + offset.x/screenDims.x)*2.5/zoom, (fragTexCoord.y + offset.y/screenDims.y)*1.5/zoom); vec2 z = vec2((fragTexCoord.x - 0.5f)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
z.x += offset.x;
z.y += offset.y;
int iterations = 0; int iterations = 0;
for (iterations = 0; iterations < MAX_ITERATIONS; iterations++) for (iterations = 0; iterations < maxIterations; iterations++)
{ {
z = ComplexSquare(z) + c; // Iterate function z = ComplexSquare(z) + c; // Iterate function
if (dot(z, z) > 4.0) break; if (dot(z, z) > 4.0) break;
} }
// Another few iterations decreases errors in the smoothing calculation. // Another few iterations decreases errors in the smoothing calculation
// See http://linas.org/art-gallery/escape/escape.html for more information. // See http://linas.org/art-gallery/escape/escape.html for more information
z = ComplexSquare(z) + c; z = ComplexSquare(z) + c;
z = ComplexSquare(z) + c; z = ComplexSquare(z) + c;
// This last part smooths the color (again see link above). // This last part smooths the color (again see link above)
float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0)); float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0));
// Normalize the value so it is between 0 and 1. // Normalize the value so it is between 0 and 1
float norm = smoothVal/float(MAX_ITERATIONS); float norm = smoothVal/float(maxIterations);
// If in set, color black. 0.999 allows for some float accuracy error. // If in set, color black. 0.999 allows for some float accuracy error
if (norm > 0.999) finalColor = vec4(0.0, 0.0, 0.0, 1.0); if (norm > 0.999) finalColor = vec4(0.0, 0.0, 0.0, 1.0);
else finalColor = vec4(Hsv2rgb(vec3(norm, 1.0, 1.0)), 1.0); else finalColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0, 1.0)), 1.0);
} }

View file

@ -3,7 +3,7 @@
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)
in vec3 fragPosition; in vec3 fragPosition;
in vec2 fragTexCoord; in vec2 fragTexCoord;
//in vec4 fragColor; in vec4 fragColor;
in vec3 fragNormal; in vec3 fragNormal;
// Input uniform values // Input uniform values
@ -13,18 +13,12 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
#define MAX_LIGHTS 4 #define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0 #define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1 #define LIGHT_POINT 1
struct MaterialProperty {
vec3 color;
int useSampler;
sampler2D sampler;
};
struct Light { struct Light {
int enabled; int enabled;
int type; int type;
@ -47,6 +41,8 @@ void main()
vec3 viewD = normalize(viewPos - fragPosition); vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0); vec3 specular = vec3(0.0);
vec4 tint = colDiffuse*fragColor;
// NOTE: Implement here your fragment shader code // NOTE: Implement here your fragment shader code
for (int i = 0; i < MAX_LIGHTS; i++) for (int i = 0; i < MAX_LIGHTS; i++)
@ -74,8 +70,8 @@ void main()
} }
} }
finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0))); finalColor = (texelColor*((tint + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
finalColor += texelColor*(ambient/10.0)*colDiffuse; finalColor += texelColor*(ambient/10.0)*tint;
// Gamma correction // Gamma correction
finalColor = pow(finalColor, vec4(1.0/2.2)); finalColor = pow(finalColor, vec4(1.0/2.2));

View file

@ -17,7 +17,7 @@ out vec2 fragTexCoord;
out vec4 fragColor; out vec4 fragColor;
out vec3 fragNormal; out vec3 fragNormal;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -18,19 +18,16 @@ out vec2 fragTexCoord;
out vec4 fragColor; out vec4 fragColor;
out vec3 fragNormal; out vec3 fragNormal;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {
// Compute MVP for current instance
mat4 mvpi = mvp*instanceTransform;
// Send vertex attributes to fragment shader // Send vertex attributes to fragment shader
fragPosition = vec3(mvpi*vec4(vertexPosition, 1.0)); fragPosition = vec3(instanceTransform*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord; fragTexCoord = vertexTexCoord;
//fragColor = vertexColor; fragColor = vec4(1.0);
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0))); fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
// Calculate final vertex position // Calculate final vertex position, note that we multiply mvp by instanceTransform
gl_Position = mvpi*vec4(vertexPosition, 1.0); gl_Position = mvp*instanceTransform*vec4(vertexPosition, 1.0);
} }

View file

@ -19,5 +19,5 @@ void main()
vec4 texelColor = texture(texture0, fragTexCoord); vec4 texelColor = texture(texture0, fragTexCoord);
vec4 texelColor2 = texture(texture1, fragTexCoord2); vec4 texelColor2 = texture(texture1, fragTexCoord2);
finalColor = texelColor * texelColor2; finalColor = texelColor*texelColor2;
} }

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -1,6 +1,6 @@
#version 330 #version 330
const int colors = 8; const int MAX_INDEXED_COLORS = 8;
// Input fragment attributes (from fragment shader) // Input fragment attributes (from fragment shader)
in vec2 fragTexCoord; in vec2 fragTexCoord;
@ -8,7 +8,8 @@ in vec4 fragColor;
// Input uniform values // Input uniform values
uniform sampler2D texture0; uniform sampler2D texture0;
uniform ivec3 palette[colors]; uniform ivec3 palette[MAX_INDEXED_COLORS];
//uniform sampler2D palette; // Alternative to ivec3, palette provided as a 256x1 texture
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
@ -16,15 +17,17 @@ out vec4 finalColor;
void main() void main()
{ {
// Texel color fetching from texture sampler // Texel color fetching from texture sampler
// NOTE: The texel is actually the GRAYSCALE index color
vec4 texelColor = texture(texture0, fragTexCoord)*fragColor; vec4 texelColor = texture(texture0, fragTexCoord)*fragColor;
// Convert the (normalized) texel color RED component (GB would work, too) // Convert the (normalized) texel color RED component (GB would work, too)
// to the palette index by scaling up from [0, 1] to [0, 255]. // to the palette index by scaling up from [0..1] to [0..255]
int index = int(texelColor.r*255.0); int index = int(texelColor.r*255.0);
ivec3 color = palette[index]; ivec3 color = palette[index];
//finalColor = texture(palette, texelColor.xy); // Alternative to ivec3
// Calculate final fragment color. Note that the palette color components // Calculate final fragment color. Note that the palette color components
// are defined in the range [0, 255] and need to be normalized to [0, 1] // are defined in the range [0..255] and need to be normalized to [0..1]
// for OpenGL to work.
finalColor = vec4(color/255.0, texelColor.a); finalColor = vec4(color/255.0, texelColor.a);
} }

View file

@ -64,16 +64,16 @@ vec3 SchlickFresnel(float hDotV,vec3 refl)
float GgxDistribution(float nDotH,float roughness) float GgxDistribution(float nDotH,float roughness)
{ {
float a = roughness * roughness * roughness * roughness; float a = roughness*roughness*roughness*roughness;
float d = nDotH * nDotH * (a - 1.0) + 1.0; float d = nDotH*nDotH*(a - 1.0) + 1.0;
d = PI * d * d; d = PI*d*d;
return a / max(d,0.0000001); return (a/max(d,0.0000001));
} }
float GeomSmith(float nDotV,float nDotL,float roughness) float GeomSmith(float nDotV,float nDotL,float roughness)
{ {
float r = roughness + 1.0; float r = roughness + 1.0;
float k = r*r / 8.0; float k = r*r/8.0;
float ik = 1.0 - k; float ik = 1.0 - k;
float ggx1 = nDotV/(nDotV*ik + k); float ggx1 = nDotV/(nDotV*ik + k);
float ggx2 = nDotL/(nDotL*ik + k); float ggx2 = nDotL/(nDotL*ik + k);
@ -84,14 +84,14 @@ vec3 ComputePBR()
{ {
vec3 albedo = texture(albedoMap,vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb; vec3 albedo = texture(albedoMap,vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb;
albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z); albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
float metallic = clamp(metallicValue, 0.0, 1.0); float metallic = clamp(metallicValue, 0.0, 1.0);
float roughness = clamp(roughnessValue, 0.0, 1.0); float roughness = clamp(roughnessValue, 0.0, 1.0);
float ao = clamp(aoValue, 0.0, 1.0); float ao = clamp(aoValue, 0.0, 1.0);
if (useTexMRA == 1) if (useTexMRA == 1)
{ {
vec4 mra = texture(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y))*useTexMRA; vec4 mra = texture(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
metallic = clamp(mra.r + metallicValue, 0.04, 1.0); metallic = clamp(mra.r + metallicValue, 0.04, 1.0);
roughness = clamp(mra.g + roughnessValue, 0.04, 1.0); roughness = clamp(mra.g + roughnessValue, 0.04, 1.0);
ao = (mra.b + aoValue)*0.5; ao = (mra.b + aoValue)*0.5;
@ -108,10 +108,10 @@ vec3 ComputePBR()
vec3 V = normalize(viewPos - fragPosition); vec3 V = normalize(viewPos - fragPosition);
vec3 emissive = vec3(0); vec3 emissive = vec3(0);
emissive = (texture(emissiveMap, vec2(fragTexCoord.x*tiling.x+offset.x, fragTexCoord.y*tiling.y+offset.y)).rgb).g * emissiveColor.rgb*emissivePower * useTexEmissive; emissive = (texture(emissiveMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb).g*emissiveColor.rgb*emissivePower*useTexEmissive;
// return N;//vec3(metallic,metallic,metallic); // return N;//vec3(metallic,metallic,metallic);
// if dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity // If dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity
vec3 baseRefl = mix(vec3(0.04), albedo.rgb, metallic); vec3 baseRefl = mix(vec3(0.04), albedo.rgb, metallic);
vec3 lightAccum = vec3(0.0); // Acumulate lighting lum vec3 lightAccum = vec3(0.0); // Acumulate lighting lum
@ -133,19 +133,19 @@ vec3 ComputePBR()
vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL); vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
// Difuse and spec light can't be above 1.0 // Difuse and spec light can't be above 1.0
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent // kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
vec3 kD = vec3(1.0) - F; vec3 kD = vec3(1.0) - F;
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light // Mult kD by the inverse of metallnes, only non-metals should have diffuse light
kD *= 1.0 - metallic; kD *= 1.0 - metallic;
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*lights[i].enabled; // Angle of light has impact on result lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*lights[i].enabled; // Angle of light has impact on result
} }
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5; vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
return ambientFinal + lightAccum*ao + emissive; return (ambientFinal + lightAccum*ao + emissive);
} }
void main() void main()
@ -154,7 +154,7 @@ void main()
// HDR tonemapping // HDR tonemapping
color = pow(color, color + vec3(1.0)); color = pow(color, color + vec3(1.0));
// Gamma correction // Gamma correction
color = pow(color, vec3(1.0/2.2)); color = pow(color, vec3(1.0/2.2));

View file

@ -4,7 +4,7 @@
in vec3 vertexPosition; in vec3 vertexPosition;
in vec2 vertexTexCoord; in vec2 vertexTexCoord;
in vec3 vertexNormal; in vec3 vertexNormal;
in vec3 vertexTangent; in vec4 vertexTangent;
in vec4 vertexColor; in vec4 vertexColor;
// Input uniform values // Input uniform values
@ -26,17 +26,17 @@ const float normalOffset = 0.1;
void main() void main()
{ {
// Compute binormal from vertex normal and tangent // Compute binormal from vertex normal and tangent
vec3 vertexBinormal = cross(vertexNormal, vertexTangent); vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz)*vertexTangent.w;
// Compute fragment normal based on normal transformations // Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel))); mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// Compute fragment position based on model transformations // Compute fragment position based on model transformations
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0f)); fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord*2.0; fragTexCoord = vertexTexCoord*2.0;
fragNormal = normalize(normalMatrix*vertexNormal); fragNormal = normalize(normalMatrix*vertexNormal);
vec3 fragTangent = normalize(normalMatrix*vertexTangent); vec3 fragTangent = normalize(normalMatrix*vertexTangent.xyz);
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal); fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
vec3 fragBinormal = normalize(normalMatrix*vertexBinormal); vec3 fragBinormal = normalize(normalMatrix*vertexBinormal);
fragBinormal = cross(fragNormal, fragTangent); fragBinormal = cross(fragNormal, fragTangent);
@ -45,4 +45,4 @@ void main()
// Calculate final vertex position // Calculate final vertex position
gl_Position = mvp*vec4(vertexPosition, 1.0); gl_Position = mvp*vec4(vertexPosition, 1.0);
} }

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800; const float renderWidth = 800;

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
float gamma = 0.6; float gamma = 0.6;
float numColors = 8.0; float numColors = 8.0;

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
void main() void main()
{ {

View file

@ -33,7 +33,7 @@ uniform vec2 resolution;
// SOFTWARE. // SOFTWARE.
// A list of useful distance function to simple primitives, and an example on how to // A list of useful distance function to simple primitives, and an example on how to
// do some interesting boolean operations, repetition and displacement. // do some interesting boolean operations, repetition and displacement
// //
// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm // More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
@ -41,38 +41,38 @@ uniform vec2 resolution;
//------------------------------------------------------------------ //------------------------------------------------------------------
float sdPlane( vec3 p ) float sdPlane(vec3 p)
{ {
return p.y; return p.y;
} }
float sdSphere( vec3 p, float s ) float sdSphere(vec3 p, float s)
{ {
return length(p)-s; return length(p)-s;
} }
float sdBox( vec3 p, vec3 b ) float sdBox(vec3 p, vec3 b)
{ {
vec3 d = abs(p) - b; vec3 d = abs(p) - b;
return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
} }
float sdEllipsoid( in vec3 p, in vec3 r ) float sdEllipsoid(in vec3 p, in vec3 r)
{ {
return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z); return (length(p/r) - 1.0)*min(min(r.x,r.y),r.z);
} }
float udRoundBox( vec3 p, vec3 b, float r ) float udRoundBox(vec3 p, vec3 b, float r)
{ {
return length(max(abs(p)-b,0.0))-r; return length(max(abs(p)-b,0.0))-r;
} }
float sdTorus( vec3 p, vec2 t ) float sdTorus(vec3 p, vec2 t)
{ {
return length( vec2(length(p.xz)-t.x,p.y) )-t.y; return length(vec2(length(p.xz)-t.x,p.y))-t.y;
} }
float sdHexPrism( vec3 p, vec2 h ) float sdHexPrism(vec3 p, vec2 h)
{ {
vec3 q = abs(p); vec3 q = abs(p);
#if 0 #if 0
@ -84,24 +84,24 @@ float sdHexPrism( vec3 p, vec2 h )
#endif #endif
} }
float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) float sdCapsule(vec3 p, vec3 a, vec3 b, float r)
{ {
vec3 pa = p-a, ba = b-a; vec3 pa = p-a, ba = b-a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); float h = clamp(dot(pa,ba)/dot(ba,ba), 0.0, 1.0);
return length( pa - ba*h ) - r; return length(pa - ba*h) - r;
} }
float sdEquilateralTriangle( in vec2 p ) float sdEquilateralTriangle( in vec2 p)
{ {
const float k = sqrt(3.0); const float k = sqrt(3.0);
p.x = abs(p.x) - 1.0; p.x = abs(p.x) - 1.0;
p.y = p.y + 1.0/k; p.y = p.y + 1.0/k;
if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0; if (p.x + k*p.y > 0.0) p = vec2(p.x - k*p.y, -k*p.x - p.y)/2.0;
p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 ); p.x += 2.0 - 2.0*clamp((p.x+2.0)/2.0, 0.0, 1.0);
return -length(p)*sign(p.y); return -length(p)*sign(p.y);
} }
float sdTriPrism( vec3 p, vec2 h ) float sdTriPrism(vec3 p, vec2 h)
{ {
vec3 q = abs(p); vec3 q = abs(p);
float d1 = q.z-h.y; float d1 = q.z-h.y;
@ -116,95 +116,95 @@ float sdTriPrism( vec3 p, vec2 h )
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
} }
float sdCylinder( vec3 p, vec2 h ) float sdCylinder(vec3 p, vec2 h)
{ {
vec2 d = abs(vec2(length(p.xz),p.y)) - h; vec2 d = abs(vec2(length(p.xz),p.y)) - h;
return min(max(d.x,d.y),0.0) + length(max(d,0.0)); return min(max(d.x,d.y),0.0) + length(max(d,0.0));
} }
float sdCone( in vec3 p, in vec3 c ) float sdCone(in vec3 p, in vec3 c)
{ {
vec2 q = vec2( length(p.xz), p.y ); vec2 q = vec2(length(p.xz), p.y);
float d1 = -q.y-c.z; float d1 = -q.y-c.z;
float d2 = max( dot(q,c.xy), q.y); float d2 = max(dot(q,c.xy), q.y);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
} }
float sdConeSection( in vec3 p, in float h, in float r1, in float r2 ) float sdConeSection(in vec3 p, in float h, in float r1, in float r2)
{ {
float d1 = -p.y - h; float d1 = -p.y - h;
float q = p.y - h; float q = p.y - h;
float si = 0.5*(r1-r2)/h; float si = 0.5*(r1-r2)/h;
float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q ); float d2 = max(sqrt(dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
} }
float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height } float sdPryamid4(vec3 p, vec3 h) // h = { cos a, sin a, height }
{ {
// Tetrahedron = Octahedron - Cube // Tetrahedron = Octahedron - Cube
float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) ); float box = sdBox(p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z));
float d = 0.0; float d = 0.0;
d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) )); d = max(d, abs(dot(p, vec3(-h.x, h.y, 0))));
d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) )); d = max(d, abs(dot(p, vec3( h.x, h.y, 0))));
d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) )); d = max(d, abs(dot(p, vec3( 0, h.y, h.x))));
d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) )); d = max(d, abs(dot(p, vec3( 0, h.y,-h.x))));
float octa = d - h.z; float octa = d - h.z;
return max(-box,octa); // Subtraction return max(-box,octa); // Subtraction
} }
float length2( vec2 p ) float length2(vec2 p)
{ {
return sqrt( p.x*p.x + p.y*p.y ); return sqrt(p.x*p.x + p.y*p.y);
} }
float length6( vec2 p ) float length6(vec2 p)
{ {
p = p*p*p; p = p*p; p = p*p*p; p = p*p;
return pow( p.x + p.y, 1.0/6.0 ); return pow(p.x + p.y, 1.0/6.0);
} }
float length8( vec2 p ) float length8(vec2 p)
{ {
p = p*p; p = p*p; p = p*p; p = p*p; p = p*p; p = p*p;
return pow( p.x + p.y, 1.0/8.0 ); return pow(p.x + p.y, 1.0/8.0);
} }
float sdTorus82( vec3 p, vec2 t ) float sdTorus82(vec3 p, vec2 t)
{ {
vec2 q = vec2(length2(p.xz)-t.x,p.y); vec2 q = vec2(length2(p.xz)-t.x,p.y);
return length8(q)-t.y; return length8(q)-t.y;
} }
float sdTorus88( vec3 p, vec2 t ) float sdTorus88(vec3 p, vec2 t)
{ {
vec2 q = vec2(length8(p.xz)-t.x,p.y); vec2 q = vec2(length8(p.xz)-t.x,p.y);
return length8(q)-t.y; return length8(q)-t.y;
} }
float sdCylinder6( vec3 p, vec2 h ) float sdCylinder6(vec3 p, vec2 h)
{ {
return max( length6(p.xz)-h.x, abs(p.y)-h.y ); return max(length6(p.xz)-h.x, abs(p.y)-h.y);
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
float opS( float d1, float d2 ) float opS(float d1, float d2)
{ {
return max(-d2,d1); return max(-d2,d1);
} }
vec2 opU( vec2 d1, vec2 d2 ) vec2 opU(vec2 d1, vec2 d2)
{ {
return (d1.x<d2.x) ? d1 : d2; return (d1.x<d2.x) ? d1 : d2;
} }
vec3 opRep( vec3 p, vec3 c ) vec3 opRep(vec3 p, vec3 c)
{ {
return mod(p,c)-0.5*c; return mod(p,c)-0.5*c;
} }
vec3 opTwist( vec3 p ) vec3 opTwist(vec3 p)
{ {
float c = cos(10.0*p.y+10.0); float c = cos(10.0*p.y+10.0);
float s = sin(10.0*p.y+10.0); float s = sin(10.0*p.y+10.0);
@ -214,110 +214,110 @@ vec3 opTwist( vec3 p )
//------------------------------------------------------------------ //------------------------------------------------------------------
vec2 map( in vec3 pos ) vec2 map(in vec3 pos)
{ {
vec2 res = opU( vec2( sdPlane( pos), 1.0 ), vec2 res = opU(vec2(sdPlane( pos), 1.0),
vec2( sdSphere( pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) ); vec2(sdSphere( pos-vec3(0.0,0.25, 0.0), 0.25), 46.9));
res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) ); res = opU(res, vec2(sdBox( pos-vec3(1.0,0.25, 0.0), vec3(0.25)), 3.0));
res = opU( res, vec2( udRoundBox( pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) ); res = opU(res, vec2(udRoundBox( pos-vec3(1.0,0.25, 1.0), vec3(0.15), 0.1), 41.0));
res = opU( res, vec2( sdTorus( pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) ); res = opU(res, vec2(sdTorus( pos-vec3(0.0,0.25, 1.0), vec2(0.20,0.05)), 25.0));
res = opU( res, vec2( sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9 ) ); res = opU(res, vec2(sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9));
res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) ); res = opU(res, vec2(sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05)),43.5));
res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) ); res = opU(res, vec2(sdCylinder( pos-vec3(1.0,0.30,-1.0), vec2(0.1,0.2)), 8.0));
res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) ); res = opU(res, vec2(sdCone( pos-vec3(0.0,0.50,-1.0), vec3(0.8,0.6,0.3)), 55.0));
res = opU( res, vec2( sdTorus82( pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) ); res = opU(res, vec2(sdTorus82( pos-vec3(0.0,0.25, 2.0), vec2(0.20,0.05)),50.0));
res = opU( res, vec2( sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) ); res = opU(res, vec2(sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05)),43.0));
res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) ); res = opU(res, vec2(sdCylinder6(pos-vec3(1.0,0.30, 2.0), vec2(0.1,0.2)), 12.0));
res = opU( res, vec2( sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) ); res = opU(res, vec2(sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05)),17.0));
res = opU( res, vec2( sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25) ),37.0 ) ); res = opU(res, vec2(sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25)),37.0));
res = opU( res, vec2( opS( udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05), res = opU(res, vec2(opS(udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05),
sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) ); sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0));
res = opU( res, vec2( opS( sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)), res = opU(res, vec2(opS(sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)),
sdCylinder( opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0 ) ); sdCylinder( opRep(vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0));
res = opU( res, vec2( 0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ) ); res = opU(res, vec2(0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0));
res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) ); res = opU(res, vec2(0.5*sdTorus(opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7));
res = opU( res, vec2( sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) ); res = opU(res, vec2(sdConeSection(pos-vec3(0.0,0.35,-2.0), 0.15, 0.2, 0.1), 13.67));
res = opU( res, vec2( sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) ); res = opU(res, vec2(sdEllipsoid(pos-vec3(1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05)), 43.17));
return res; return res;
} }
vec2 castRay( in vec3 ro, in vec3 rd ) vec2 castRay(in vec3 ro, in vec3 rd)
{ {
float tmin = 0.2; float tmin = 0.2;
float tmax = 30.0; float tmax = 30.0;
#if 1 #if 1
// bounding volume // bounding volume
float tp1 = (0.0-ro.y)/rd.y; if( tp1>0.0 ) tmax = min( tmax, tp1 ); float tp1 = (0.0-ro.y)/rd.y; if (tp1>0.0) tmax = min(tmax, tp1);
float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 ); float tp2 = (1.6-ro.y)/rd.y; if (tp2>0.0) { if (ro.y>1.6) tmin = max(tmin, tp2);
else tmax = min( tmax, tp2 ); } else tmax = min(tmax, tp2); }
#endif #endif
float t = tmin; float t = tmin;
float m = -1.0; float m = -1.0;
for( int i=0; i<64; i++ ) for (int i=0; i<64; i++)
{ {
float precis = 0.0005*t; float precis = 0.0005*t;
vec2 res = map( ro+rd*t ); vec2 res = map(ro+rd*t);
if( res.x<precis || t>tmax ) break; if (res.x<precis || t>tmax) break;
t += res.x; t += res.x;
m = res.y; m = res.y;
} }
if( t>tmax ) m=-1.0; if (t>tmax) m=-1.0;
return vec2( t, m ); return vec2(t, m);
} }
float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ) float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
{ {
float res = 1.0; float res = 1.0;
float t = mint; float t = mint;
for( int i=0; i<16; i++ ) for (int i=0; i<16; i++)
{ {
float h = map( ro + rd*t ).x; float h = map(ro + rd*t).x;
res = min( res, 8.0*h/t ); res = min(res, 8.0*h/t);
t += clamp( h, 0.02, 0.10 ); t += clamp(h, 0.02, 0.10);
if( h<0.001 || t>tmax ) break; if (h<0.001 || t>tmax) break;
} }
return clamp( res, 0.0, 1.0 ); return clamp(res, 0.0, 1.0);
} }
vec3 calcNormal( in vec3 pos ) vec3 calcNormal(in vec3 pos)
{ {
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
return normalize( e.xyy*map( pos + e.xyy ).x + return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map( pos + e.yyx ).x + e.yyx*map(pos + e.yyx).x +
e.yxy*map( pos + e.yxy ).x + e.yxy*map(pos + e.yxy).x +
e.xxx*map( pos + e.xxx ).x ); e.xxx*map(pos + e.xxx).x);
/* /*
vec3 eps = vec3( 0.0005, 0.0, 0.0 ); vec3 eps = vec3(0.0005, 0.0, 0.0);
vec3 nor = vec3( vec3 nor = vec3(
map(pos+eps.xyy).x - map(pos-eps.xyy).x, map(pos+eps.xyy).x - map(pos-eps.xyy).x,
map(pos+eps.yxy).x - map(pos-eps.yxy).x, map(pos+eps.yxy).x - map(pos-eps.yxy).x,
map(pos+eps.yyx).x - map(pos-eps.yyx).x ); map(pos+eps.yyx).x - map(pos-eps.yyx).x);
return normalize(nor); return normalize(nor);
*/ */
} }
float calcAO( in vec3 pos, in vec3 nor ) float calcAO(in vec3 pos, in vec3 nor)
{ {
float occ = 0.0; float occ = 0.0;
float sca = 1.0; float sca = 1.0;
for( int i=0; i<5; i++ ) for (int i=0; i<5; i++)
{ {
float hr = 0.01 + 0.12*float(i)/4.0; float hr = 0.01 + 0.12*float(i)/4.0;
vec3 aopos = nor * hr + pos; vec3 aopos = nor*hr + pos;
float dd = map( aopos ).x; float dd = map(aopos).x;
occ += -(dd-hr)*sca; occ += -(dd-hr)*sca;
sca *= 0.95; sca *= 0.95;
} }
return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ); return clamp(1.0 - 3.0*occ, 0.0, 1.0);
} }
// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm // http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm
float checkersGradBox( in vec2 p ) float checkersGradBox(in vec2 p)
{ {
// filter kernel // filter kernel
vec2 w = fwidth(p) + 0.001; vec2 w = fwidth(p) + 0.001;
@ -327,43 +327,43 @@ float checkersGradBox( in vec2 p )
return 0.5 - 0.5*i.x*i.y; return 0.5 - 0.5*i.x*i.y;
} }
vec3 render( in vec3 ro, in vec3 rd ) vec3 render(in vec3 ro, in vec3 rd)
{ {
vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8; vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
vec2 res = castRay(ro,rd); vec2 res = castRay(ro,rd);
float t = res.x; float t = res.x;
float m = res.y; float m = res.y;
if( m>-0.5 ) if (m>-0.5)
{ {
vec3 pos = ro + t*rd; vec3 pos = ro + t*rd;
vec3 nor = calcNormal( pos ); vec3 nor = calcNormal(pos);
vec3 ref = reflect( rd, nor ); vec3 ref = reflect(rd, nor);
// material // material
col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) ); col = 0.45 + 0.35*sin(vec3(0.05,0.08,0.10)*(m-1.0));
if( m<1.5 ) if (m<1.5)
{ {
float f = checkersGradBox( 5.0*pos.xz ); float f = checkersGradBox(5.0*pos.xz);
col = 0.3 + f*vec3(0.1); col = 0.3 + f*vec3(0.1);
} }
// lighting // lighting
float occ = calcAO( pos, nor ); float occ = calcAO(pos, nor);
vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) ); vec3 lig = normalize(vec3(cos(-0.4*runTime), sin(0.7*runTime), -0.6));
vec3 hal = normalize( lig-rd ); vec3 hal = normalize(lig-rd);
float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 ); float amb = clamp(0.5+0.5*nor.y, 0.0, 1.0);
float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); float dif = clamp(dot(nor, lig), 0.0, 1.0);
float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); float bac = clamp(dot(nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
float dom = smoothstep( -0.1, 0.1, ref.y ); float dom = smoothstep(-0.1, 0.1, ref.y);
float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 ); float fre = pow(clamp(1.0+dot(nor,rd),0.0,1.0), 2.0);
dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
dom *= calcSoftshadow( pos, ref, 0.02, 2.5 ); dom *= calcSoftshadow(pos, ref, 0.02, 2.5);
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)* float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0)*
dif * dif *
(0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 )); (0.04 + 0.96*pow(clamp(1.0+dot(hal,rd),0.0,1.0), 5.0));
vec3 lin = vec3(0.0); vec3 lin = vec3(0.0);
lin += 1.30*dif*vec3(1.00,0.80,0.55); lin += 1.30*dif*vec3(1.00,0.80,0.55);
@ -374,51 +374,51 @@ vec3 render( in vec3 ro, in vec3 rd )
col = col*lin; col = col*lin;
col += 10.00*spe*vec3(1.00,0.90,0.70); col += 10.00*spe*vec3(1.00,0.90,0.70);
col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) ); col = mix(col, vec3(0.8,0.9,1.0), 1.0-exp(-0.0002*t*t*t));
} }
return vec3( clamp(col,0.0,1.0) ); return vec3(clamp(col,0.0,1.0));
} }
mat3 setCamera( in vec3 ro, in vec3 ta, float cr ) mat3 setCamera(in vec3 ro, in vec3 ta, float cr)
{ {
vec3 cw = normalize(ta-ro); vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0); vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) ); vec3 cu = normalize(cross(cw,cp));
vec3 cv = normalize( cross(cu,cw) ); vec3 cv = normalize(cross(cu,cw));
return mat3( cu, cv, cw ); return mat3(cu, cv, cw);
} }
void main() void main()
{ {
vec3 tot = vec3(0.0); vec3 tot = vec3(0.0);
#if AA>1 #if AA>1
for( int m=0; m<AA; m++ ) for (int m=0; m<AA; m++)
for( int n=0; n<AA; n++ ) for (int n=0; n<AA; n++)
{ {
// pixel coordinates // pixel coordinates
vec2 o = vec2(float(m),float(n)) / float(AA) - 0.5; vec2 o = vec2(float(m),float(n))/float(AA) - 0.5;
vec2 p = (-resolution.xy + 2.0*(gl_FragCoord.xy+o))/resolution.y; vec2 p = (-resolution.xy + 2.0*(gl_FragCoord.xy+o))/resolution.y;
#else #else
vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y; vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y;
#endif #endif
// RAY: Camera is provided from raylib // RAY: Camera is provided from raylib
//vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x) ); //vec3 ro = vec3(-0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x));
vec3 ro = viewEye; vec3 ro = viewEye;
vec3 ta = viewCenter; vec3 ta = viewCenter;
// camera-to-world transformation // camera-to-world transformation
mat3 ca = setCamera( ro, ta, 0.0 ); mat3 ca = setCamera(ro, ta, 0.0);
// ray direction // ray direction
vec3 rd = ca * normalize( vec3(p.xy,2.0) ); vec3 rd = ca*normalize(vec3(p.xy,2.0));
// render // render
vec3 col = render( ro, rd ); vec3 col = render(ro, rd);
// gamma // gamma
col = pow( col, vec3(0.4545) ); col = pow(col, vec3(0.4545));
tot += col; tot += col;
#if AA>1 #if AA>1
@ -426,5 +426,5 @@ void main()
tot /= float(AA*AA); tot /= float(AA*AA);
#endif #endif
finalColor = vec4( tot, 1.0 ); finalColor = vec4(tot, 1.0);
} }

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values must be passed from code // NOTE: Render size values must be passed from code
const float renderWidth = 800; const float renderWidth = 800;
@ -39,7 +39,7 @@ void main()
fragColor = color; fragColor = color;
*/ */
// Scanlines method 2 // Scanlines method 2
float globalPos = (fragTexCoord.y + offset) * frequency; float globalPos = (fragTexCoord.y + offset)*frequency;
float wavePos = cos((fract(globalPos) - 0.5)*3.14); float wavePos = cos((fract(globalPos) - 0.5)*3.14);
// Texel color fetching from texture sampler // Texel color fetching from texture sampler

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
uniform vec2 resolution = vec2(800, 450); uniform vec2 resolution = vec2(800, 450);
void main() void main()
@ -20,22 +20,22 @@ void main()
float y = 1.0/resolution.y; float y = 1.0/resolution.y;
vec4 horizEdge = vec4(0.0); vec4 horizEdge = vec4(0.0);
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; horizEdge -= texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0; horizEdge -= texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; horizEdge -= texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; horizEdge += texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0; horizEdge += texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; horizEdge += texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec4 vertEdge = vec4(0.0); vec4 vertEdge = vec4(0.0);
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; vertEdge -= texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0; vertEdge -= texture(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0;
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; vertEdge -= texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; vertEdge += texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0; vertEdge += texture(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; vertEdge += texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb)); vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb));
finalColor = vec4(edge, texture2D(texture0, fragTexCoord).a); finalColor = vec4(edge, texture(texture0, fragTexCoord).a);
} }

View file

@ -7,7 +7,7 @@ in vec4 fragColor;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
#define MAX_SPOTS 3 #define MAX_SPOTS 3
@ -53,7 +53,7 @@ void main()
else else
{ {
if (d < spots[fi].inner) alpha = 0.0; if (d < spots[fi].inner) alpha = 0.0;
else alpha = (d - spots[fi].inner) / (spots[fi].radius - spots[fi].inner); else alpha = (d - spots[fi].inner)/(spots[fi].radius - spots[fi].inner);
} }
} }

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
// NOTE: Render size values should be passed from code // NOTE: Render size values should be passed from code
const float renderWidth = 800; const float renderWidth = 800;
@ -41,7 +41,7 @@ void main()
} }
tc += center; tc += center;
vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; vec4 color = texture(texture0, tc/texSize)*colDiffuse*fragColor;;
finalColor = vec4(color.rgb, 1.0);; finalColor = vec4(color.rgb, 1.0);;
} }

View file

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
uniform float secondes; uniform float seconds;
uniform vec2 size; uniform vec2 size;
@ -22,16 +22,17 @@ uniform float ampY;
uniform float speedX; uniform float speedX;
uniform float speedY; uniform float speedY;
void main() { void main()
float pixelWidth = 1.0 / size.x; {
float pixelHeight = 1.0 / size.y; float pixelWidth = 1.0/size.x;
float aspect = pixelHeight / pixelWidth; float pixelHeight = 1.0/size.y;
float aspect = pixelHeight/pixelWidth;
float boxLeft = 0.0; float boxLeft = 0.0;
float boxTop = 0.0; float boxTop = 0.0;
vec2 p = fragTexCoord; vec2 p = fragTexCoord;
p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth; p.x += cos((fragTexCoord.y - boxTop)*freqX/(pixelWidth*750.0) + (seconds*speedX))*ampX*pixelWidth;
p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight; p.y += sin((fragTexCoord.x - boxLeft)*freqY*aspect/(pixelHeight*750.0) + (seconds*speedY))*ampY*pixelHeight;
finalColor = texture(texture0, p)*colDiffuse*fragColor; finalColor = texture(texture0, p)*colDiffuse*fragColor;
} }

View file

@ -32,7 +32,7 @@ void main()
neighbourCount += fetchGol(x - 1, y); // Left neighbourCount += fetchGol(x - 1, y); // Left
neighbourCount += fetchGol(x + 1, y); // Right neighbourCount += fetchGol(x + 1, y); // Right
neighbourCount += fetchGol(x - 1, y + 1); // Bottom left neighbourCount += fetchGol(x - 1, y + 1); // Bottom left
neighbourCount += fetchGol(x, y + 1); // Bottom middle neighbourCount += fetchGol(x, y + 1); // Bottom middle
neighbourCount += fetchGol(x + 1, y + 1); // Bottom right neighbourCount += fetchGol(x + 1, y + 1); // Bottom right
if (neighbourCount == 3) setGol(x, y, 1); if (neighbourCount == 3) setGol(x, y, 1);

View file

@ -2582,9 +2582,10 @@ public static unsafe partial class Raylib
byte* fileData, byte* fileData,
int dataSize, int dataSize,
int fontSize, int fontSize,
int* fontChars, int* codepoints,
int glyphCount, int codepointsCount,
FontType type FontType type,
int* glyphCount
); );
/// <summary>Generate image font atlas using chars info</summary> /// <summary>Generate image font atlas using chars info</summary>