Created
September 29, 2018 20:55
-
-
Save aman-tiwari/fddabe17962a473f778cb3ab1688ce28 to your computer and use it in GitHub Desktop.
basic kodelife raymarch with outlines
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 150 | |
// these are set by kodelife | |
uniform float time; | |
uniform vec2 resolution; | |
uniform vec2 mouse; | |
uniform vec3 spectrum; | |
uniform sampler2D texture0; | |
uniform sampler2D texture1; | |
uniform sampler2D texture2; | |
uniform sampler2D texture3; | |
uniform sampler2D prevFrame; | |
uniform sampler2D prevPass; | |
in VertexData | |
{ | |
vec4 v_position; | |
vec3 v_normal; | |
vec2 v_texcoord; // coordinate of the fragment, [0-1] | |
} inData; | |
// set this variable in main to the color you want to be displayed | |
out vec4 fragColor; | |
// from http://iquilezles.org/www/articles/distfunctions/distfunctions.htm | |
// signed distance function for a box with at p with sides of length s | |
float sdBox( vec3 p, vec3 b ) | |
{ | |
vec3 d = abs(p) - b; | |
return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); | |
} | |
// union two signed distance functions with a smooth join | |
// from https://www.iquilezles.org/www/articles/smin/smin.htm | |
float smin( float a, float b, float k ) | |
{ | |
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 ); | |
return mix( b, a, h ) - k*h*(1.0-h); | |
} | |
float scene(vec3 p) { | |
float sphere = length(p) - 1.0; | |
// this offsets the cube left-right | |
float box = sdBox(p - vec3(sin(time) * 2.0 + 2.0, 0.0, 0.0), vec3(0.1, 2.1, 1.0)); | |
return smin(sphere, box, 0.5); | |
} | |
// central difference approximation to normal vector of the scene | |
vec3 calcNormal(vec3 pos, float eps) { | |
const vec3 v1 = vec3( 1.0,-1.0,-1.0); | |
const vec3 v2 = vec3(-1.0,-1.0, 1.0); | |
const vec3 v3 = vec3(-1.0, 1.0,-1.0); | |
const vec3 v4 = vec3( 1.0, 1.0, 1.0); | |
return normalize( v1 * scene( pos + v1*eps ) + | |
v2 * scene( pos + v2*eps ) + | |
v3 * scene( pos + v3*eps ) + | |
v4 * scene( pos + v4*eps )); | |
} | |
vec3 calcNormal(vec3 pos) { | |
return calcNormal(pos, 0.002); | |
} | |
#define STEPS (50) | |
#define MIN_DIST (0.001) | |
// raymarching function! | |
// ro = ray origin | |
// rd = ray direction | |
// hitPoint <- will be set if we hit the surface to where we hit | |
// minDist <- will be set to the minimum distance to the surface the ray encountered | |
bool raymarch(vec3 ro, vec3 rd, | |
out vec3 hitPoint, | |
out float minDist) { | |
vec3 pos = ro; | |
minDist = 100.0; | |
for(int i = 0; i < STEPS; i++) { | |
float dist = scene(pos); | |
if(dist < MIN_DIST) { | |
hitPoint = pos + rd * dist; | |
return true; | |
} | |
pos += rd * dist; | |
minDist = min(dist, minDist); | |
} | |
return false; | |
} | |
void main(void) | |
{ | |
float aspect = resolution.x / resolution.y; | |
vec2 uv = -1.0 + 2.0 * inData.v_texcoord; | |
uv.x *= aspect; | |
vec3 rayOrigin = vec3(0.0, 0.0, -4.0); | |
vec3 rayDir = normalize(vec3(uv, 2.0)); | |
vec3 hitPos; // this will be set by raymarch to the point on the surface we hit | |
vec3 color = vec3(1.0); | |
float minDist = 100.0; // minimum distance to surface encountered | |
if(raymarch(rayOrigin, rayDir, hitPos, minDist)) { // if hit surface | |
vec3 nor = calcNormal(hitPos); | |
vec3 light = vec3(-1.0, -1.0, 0.0); | |
float diffuseIntesity = clamp(dot(nor, light), 0.0, 1.0); | |
color = mix(vec3(1.0, 0.0, 0.0), // light colour | |
vec3(0.0, 0.0, 1.0), // shadow colour | |
diffuseIntesity); | |
// uncomment below line to visualise the normals | |
//color = nor * 0.5 + 0.5; | |
} else if(minDist < 0.05) { // if near miss to surface | |
color = vec3(0.0, 0.0, 0.0); | |
} | |
fragColor = vec4(color, 1.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment