~shockham/Physo

b315600e854e07532fe13d211c01f588e970c414 — shockham 4 years ago 2445c94
More shading more fun
1 files changed, 94 insertions(+), 14 deletions(-)

M src/shaders/frag.glsl
M src/shaders/frag.glsl => src/shaders/frag.glsl +94 -14
@@ 11,6 11,34 @@ uniform float time;
varying vec3 vposition;
varying vec3 vcolor;

const mat2 m2 = mat2(  0.80,  0.60,
                      -0.60,  0.80 );


//---------------------------------------------------------------
// value noise, and its analytical derivatives
//---------------------------------------------------------------
float hash1( vec2 p )
{
    p  = 50.0*fract( p*0.3183099 );
    return fract( p.x*p.y*(p.x+p.y) );
}


float noise( in vec2 x )
{
    vec2 p = floor(x);
    vec2 w = fract(x);
    vec2 u = w*w*w*(w*(w*6.0-15.0)+10.0);

    float a = hash1(p+vec2(0,0));
    float b = hash1(p+vec2(1,0));
    float c = hash1(p+vec2(0,1));
    float d = hash1(p+vec2(1,1));

    return -1.0+2.0*( a + (b-a)*u.x + (c-a)*u.y + (a - b - c + d)*u.x*u.y );
}

//------------------------------------------------------------------------------
// Distance field functions
//------------------------------------------------------------------------------


@@ 20,21 48,55 @@ float sdPlane(in vec3 p) {
}

float sdSphere(in vec3 p, float s) {
    return length(p) - s;
    return (length(p) - s);
}

float sdTorus(in vec3 p, in vec2 t) {
    return length(vec2(length(p.xz) - t.x, p.y)) - t.y;
}

float sdTerrain(in vec3 p) {
    return (p.y + 0.3) - (cos(p.z * 5.0) * cos(p.x * 5.0)) / 5.0;
}

float sdNoiseTerrain(in vec2 x) {
    float f = 1.9;
    float s = 0.55;
    float a = 0.0;
    float b = 0.5;
    for( int i=0; i<4; i++ )
    {
        float n = noise(x);
        a += b*n;
        b *= s;
        x = f*m2*x;
    }
	return a;
}

vec2 opUnion(vec2 d1, vec2 d2) {
    return d1.x < d2.x ? d1 : d2;
}
vec2 opSmoothUnion(vec2 d1, vec2 d2, float k) {
    float h = clamp(0.5 + 0.5*(d2.x-d1.x)/k, 0.0, 1.0);
    return mix(d2, d1, h) - k*h*(1.0-h);
}

float opDisp(vec3 p, float amt) {
    return sin(amt*p.x)*sin(amt*p.y)*sin(amt*p.z);
}

vec2 scene(in vec3 position) {
    vec2 scene = opUnion(
          vec2(sdPlane(position), 1.0),
          vec2(sdSphere(position - vec3(0.0, 0.4, 0.0), 0.4), 12.0)
        //vec2(position.y - sdNoiseTerrain(position.xz), 1.0),
        vec2(sdPlane(position), 1.0),
        opUnion(
            vec2(sdSphere(position - vec3(-1.0, 0.4, 0.0), 0.4), 10.0),
            opUnion(
                vec2(sdSphere(position - vec3(1.0, 0.4, 0.0), 0.4), 14.0),
                vec2(sdSphere(position - vec3(0.0, 0.4, 0.0), 0.4), 12.0)
            )
        )
    );
    return scene;
}


@@ 46,7 108,7 @@ vec2 scene(in vec3 position) {
float shadow(in vec3 origin, in vec3 direction) {
    float hit = 1.0;
    float t = 0.02;
    

    for (int i = 0; i < 1000; i++) {
        float h = scene(origin + direction * t).x;
        if (h < 0.001) return 0.0;


@@ 62,7 124,7 @@ vec2 traceRay(in vec3 origin, in vec3 direction) {
    float material = -1.0;

    float t = 0.02;
    

    for (int i = 0; i < 1000; i++) {
        vec2 hit = scene(origin + direction * t);
        if (hit.x < 0.002 || t > 20.0) break;


@@ 183,7 245,7 @@ vec3 OECF_sRGBFast(const vec3 linear) {
float floorColor(vec3 pos) {
    float cbSize = 10.0;//2.0 + 6.0 * cos(time);
    return mod(
        floor(cbSize * pos.z) + floor(cbSize * pos.x), 
        floor(cbSize * pos.z) + floor(cbSize * pos.x),
        2.0 * sin(time / 20.0)
    );
}


@@ 219,17 281,35 @@ vec3 render(in vec3 origin, in vec3 direction, out float distance) {
        float intensity = 2.0;
        float indirectIntensity = 0.64;

        if (material < 4.0)  {
        if (material < 4.0) {
            // Checkerboard floor
            float f = floorColor(position);
            float f = floorColor(position) * distance;
            baseColor = 0.4 + f * vec3(0.2);
            roughness = 0.1;
        } else if (material < 11.0) {
            // Metallic objects
            baseColor = vec3(0.0, 0.7, 0.8);
            //roughness = 1.2;
            //roughness = 0.4 + (sin(time) / 2.0);
            //metallic = 1.0 + (cos(time) / 2.0);
            roughness = 1.4;
            metallic = -1.0;
        } else if (material < 13.0) {
            // Metallic objects
            baseColor = vec3(0.0, 0.7, 0.8);
            //roughness = 1.2;
            //roughness = 0.4 + (sin(time) / 2.0);
            //metallic = 1.0 + (cos(time) / 2.0);
            roughness = 0.2;
            metallic = 0.2;
        } else if (material < 16.0) {
            // Metallic objects
            baseColor = vec3(0.0, 0.7, 0.8);
            //roughness = 1.2;
            roughness = 0.4 + (sin(time) / 2.0);
            metallic = 1.0 + cos(time);
            //roughness = 0.4 + (sin(time) / 2.0);
            //metallic = 1.0 + (cos(time) / 2.0);
            roughness = -1.4;
            metallic = 1.0;
        }

        float linearRoughness = roughness * roughness;


@@ 295,10 375,10 @@ void main() {

    // Camera position and "look at"
    vec3 origin = vec3(0.0, 0.6, 0.0);
    vec3 target = vec3(0.0);
    vec3 target = vec3(0.0, 0.3, 0.0);

    origin.x += 1.7 * cos(time * 0.2);
    origin.z += 1.7 * sin(time * 0.2);
    origin.x += 4.0 * cos(time * 0.2);
    origin.z += 4.0 * sin(time * 0.2);

    mat3 toWorld = setCamera(origin, target, 0.0);
    vec3 direction = toWorld * normalize(vec3(p.xy, 2.0));


@@ 311,7 391,7 @@ void main() {
    color = Tonemap_ACES(color);

    // Exponential distance fog
    color = mix(color, 0.8 * vec3(0.7, 0.8, 1.0), 1.0 - exp2(-0.011 * distance * distance));
    color = mix(color, vec3(1.0), 1.0 - exp2(-0.011 * distance * distance));

    // Gamma compression
    color = OECF_sRGBFast(color);