2014-09-14_21-50-06

http://glsl.heroku.com/e#1159.8

// Coffee & Tablet - @P_Malin

#ifdef GL_ES
precision highp float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

uniform sampler2D backbuffer;

#define PI 3.141592654

#define ENABLE_MONTE_CARLO
#define ENABLE_PERLIN_NOISE
#define ENABLE_REFLECTIONS
#define ENABLE_FOG
#define ENABLE_SPECULAR
#define ENABLE_POINT_LIGHT
#define ENABLE_POINT_LIGHT_FLARE

#ifdef ENABLE_MONTE_CARLO
vec4 gPixelRandom;
vec3 gRandomNormal;

void CalcPixelRandom()
{
    vec4 s1 = sin(time * 3.3422 + gl_FragCoord.xxxx * vec4(324.324234, 563.324234, 657.324234, 764.324234)) * 543.3423;
    vec4 s2 = sin(time * 1.3422 + gl_FragCoord.yyyy * vec4(567.324234, 435.324234, 432.324234, 657.324234)) * 654.5423;
    gPixelRandom = fract(2142.4 + s1 + s2);
    gRandomNormal = normalize( gPixelRandom.xyz - 0.5);
}

#endif

#ifdef ENABLE_PERLIN_NOISE

#define NOISE_TILE_SIZE 64.0
#define NOISE_TILE_COUNT 4.0

#define kNoisePersistence 2.0
#define kNoiseAmplitude 0.04

float GetNoise( const in vec2 vPos )
{
    return fract(sin(vPos.x * 324.324234) * 234.324 + sin(vPos.y * 323.324234) * 122.324);
}

float GetSmoothNoise(const in vec2 vCoord, const in float fWrap)
{
    vec2 vCoordFloor = floor(vCoord);
    vec2 vCoordFract = fract(vCoord);

    vec2 vICoordFract = 1.0 - vCoordFract;

    vec4 vCoordPacked =  vCoordFloor.xyxy;
    vCoordPacked.zw += 1.0;
    vCoordPacked = mod(vCoordPacked, fWrap);

    float tl = GetNoise( vCoordPacked.xy );
    float tr = GetNoise( vCoordPacked.zy );
    float bl = GetNoise( vCoordPacked.xw );
    float br = GetNoise( vCoordPacked.zw );

    return     tl * vICoordFract.x * vICoordFract.y
                    + tr * vCoordFract.x  * vICoordFract.y
                    + bl * vICoordFract.x * vCoordFract.y
                    + br * vCoordFract.x  * vCoordFract.y;
}

// we store the noise texture in the backbuffer alpha channel
float CalculateNoiseTexture()
{
    vec2 vTileIndex = floor(gl_FragCoord.xy / NOISE_TILE_SIZE);
    if(vTileIndex.y > 0.0)
    {
        return 1.0;
    }

    if(vTileIndex.x > NOISE_TILE_COUNT)
    {
        return 0.0;         
    }

    float fFrequency = pow(0.5, vTileIndex.x);

    float fThisNoise = GetSmoothNoise( gl_FragCoord.xy * fFrequency, NOISE_TILE_SIZE * fFrequency);

    float fSampledNoise = texture2D(backbuffer, (gl_FragCoord.xy + vec2(NOISE_TILE_SIZE, 0.0)) / resolution ).a;

    float fAmplitude = kNoiseAmplitude * pow(kNoisePersistence, vTileIndex.x);
    return fThisNoise * fAmplitude + fSampledNoise;
}

float SampleNoiseTexture( vec2 vUV )
{
    return texture2D(backbuffer, (fract(vUV) * NOISE_TILE_SIZE) / resolution ).a;
}
#else
float SampleNoiseTexture( vec2 vUV )
{
    return dot(sin(vUV * vec2(8.0,8.0)), vec2(0.5));
}
#endif

struct C_Ray
{
    vec3 vOrigin;
    vec3 vDir;
};

struct C_HitInfo
{
    vec3 vPos;
    float fDistance;
    vec3 vObjectId;
};

struct C_Material
{
    vec3 cAlbedo;
    float fR0;
    float fSmoothness;
    vec2 vParam;
};

vec3 RotateX( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( vPos.x, c * vPos.y + s * vPos.z, -s * vPos.y + c * vPos.z);

    return vResult;
}

vec3 RotateY( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.z, vPos.y, -s * vPos.x + c * vPos.z);

    return vResult;
}

vec3 RotateZ( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.y, -s * vPos.x + c * vPos.y, vPos.z);

    return vResult;
}

vec4 DistCombineUnion( const in vec4 v1, const in vec4 v2 )
{
    //if(v1.x < v2.x) return v1; else return v2;
    return mix(v1, v2, step(v2.x, v1.x));
}

vec4 DistCombineIntersect( const in vec4 v1, const in vec4 v2 )
{
    return mix(v2, v1, step(v2.x,v1.x));
}

vec4 DistCombineSubtract( const in vec4 v1, const in vec4 v2 )
{
    return DistCombineIntersect(v1, vec4(-v2.x, v2.yzw));
}

vec3 DomainRepeatXZGetTile( const in vec3 vPos, const in vec2 vRepeat, out vec2 vTile )
{
    vec3 vResult = vPos;
    vec2 vTilePos = (vPos.xz / vRepeat) + 0.5;
    vTile = floor(vTilePos + 1000.0);
    vResult.xz = (fract(vTilePos) - 0.5) * vRepeat;
    return vResult;
}

vec3 DomainRepeatXZ( const in vec3 vPos, const in vec2 vRepeat )
{
    vec3 vResult = vPos;
    vec2 vTilePos = (vPos.xz / vRepeat) + 0.5;
    vResult.xz = (fract(vTilePos) - 0.5) * vRepeat;
    return vResult;
}

vec3 DomainRepeatY( const in vec3 vPos, const in float fSize )
{
    vec3 vResult = vPos;
    vResult.y = (fract(vPos.y / fSize + 0.5) - 0.5) * fSize;
    return vResult;
}

vec3 DomainRotateSymmetry( const in vec3 vPos, const in float fSteps )
{
    float angle = atan( vPos.x, vPos.z );

    float fScale = fSteps / (PI * 2.0);
    float steppedAngle = (floor(angle * fScale + 0.5)) / fScale;

    float s = sin(-steppedAngle);
    float c = cos(-steppedAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.z,
                 vPos.y,
                -s * vPos.x + c * vPos.z);

    return vResult;
}

float GetDistanceXYTorus( const in vec3 p, const in float r1, const in float r2 )
{
    vec2 q = vec2(length(p.xy)-r1,p.z);
    return length(q)-r2;
}

float GetDistanceYZTorus( const in vec3 p, const in float r1, const in float r2 )
{
    vec2 q = vec2(length(p.yz)-r1,p.x);
    return length(q)-r2;
}

float GetDistanceCylinderY(const in vec3 vPos, const in float r)
{
    return length(vPos.xz) - r;
}

float GetDistanceBox( const in vec3 vPos, const in vec3 vSize )
{
    vec3 vDist = (abs(vPos) - vSize);
    return max(vDist.x, max(vDist.y, vDist.z));
}

float GetDistanceRoundedBox( const in vec3 vPos, const in vec3 vSize, float fRadius )
{
    vec3 vClosest = max(min(vPos, vSize), -vSize);
    return length(vClosest - vPos) - fRadius;
}

float GetDistanceMug( const in vec3 vPos )
{
    float fDistCylinderOutside = length(vPos.xz) - 1.0;
    float fDistCylinderInterior = length(vPos.xz) - 0.9;
    float fTop = vPos.y - 1.0;

    float r1 = 0.6;
    float r2 = 0.15;
    vec2 q = vec2(length(vPos.xy + vec2(1.2, -0.1))-r1,vPos.z);
    float fDistHandle = length(q)-r2;

    float fDistMug = max(max(min(fDistCylinderOutside, fDistHandle), fTop), -fDistCylinderInterior);
    return fDistMug;
}

float GetDistanceCoffee( const in vec3 vPos )
{
    float fTopCoffee = vPos.y - 0.7;
    float fDistCylinderCoffee = length(vPos.xz) - 0.95;

    float fDistCoffee = max(fTopCoffee, fDistCylinderCoffee);
    return fDistCoffee;
}

vec4 GetDistanceTablet( const in vec3 vPos )
{             
    vec3 vBevelPos = vPos - vec3(0.0, 1.71, 0.0);
    float r = 1.0;
    float fBevelDist = GetDistanceRoundedBox( vBevelPos, vec3(1.5, 1.0, 2.0), r );

    vec3 vCasePos = vPos - vec3(0.0, 0.0, 0.0);
    float fCaseDist = GetDistanceRoundedBox( vCasePos, vec3(1.5, 1.0, 2.0), 0.5 );

    vec4 vResult = vec4(max(fBevelDist, fCaseDist), 4.0, vPos.xz);

    vec4 vScreenDist = vec4(-vPos.y, 5.0, vPos.xz);
    vResult = DistCombineSubtract(vResult, vScreenDist);

    vec4 vButtonDist = vec4( length(vPos + vec3(0.0, -0.25, 2.1)) - 0.3, 5.0, vPos.xz);
    vResult = DistCombineSubtract(vResult, vButtonDist);

    return vResult;
}

// result is x=scene distance y=material or object id; zw are material specific parameters (maybe uv co-ordinates)
vec4 GetDistanceScene( const in vec3 vPos )
{           
    vec4 vResult = vec4(10000.0, -1.0, 0.0, 0.0);

    vec3 vMugDomain = vPos + vec3(2.4, 0.0, -2.0);
    vMugDomain = RotateY(vMugDomain, 1.0);

    vec4 vDistMug = vec4( GetDistanceMug(vMugDomain), 2.0, vMugDomain.xy);
    vResult = DistCombineUnion(vResult, vDistMug);

    vec4 vDistCoffee = vec4( GetDistanceCoffee(vMugDomain), 3.0, vMugDomain.xz);
    vResult = DistCombineUnion(vResult, vDistCoffee);

    vec4 vDistFloor = vec4(vPos.y + 1.0, 1.0, vPos.xz);
    vResult = DistCombineUnion(vResult, vDistFloor);

    vec3 vTabletDomain = vPos;
    vTabletDomain += vec3(-0.8, 0.7, 0.0);
    vTabletDomain = RotateY(vTabletDomain, -1.0);
    vec4 vDistTablet = GetDistanceTablet(vTabletDomain);
    vResult = DistCombineUnion(vResult, vDistTablet);

    return vResult;
}

C_Material GetObjectMaterial( const in vec3 vObjId, const in vec3 vPos )
{
    C_Material mat;

    if(vObjId.x < 1.5)
    {
        // floor
        float fBlend = SampleNoiseTexture(vPos.xz * 0.2 + vec2(0.0, sin(mod(vPos.x,4.0))));                    
        mat.fR0 = 0.02;
        mat.fSmoothness = fBlend;
        mat.cAlbedo = mix(vec3(0.7, 0.8, 0.3), vec3(0.5, 0.3, 0.1), fBlend);
    }
    else
    if(vObjId.x < 2.5)
    {
        // mug
        mat.fR0 = 0.05;
        mat.fSmoothness = 0.9;
        mat.cAlbedo = vec3(0.05, 0.35, 0.75);
    }
    else
    if(vObjId.x < 3.5)
    {
        // coffee
        mat.fR0 = 0.01;
        mat.fSmoothness = 1.0;
        mat.cAlbedo = vec3(0.5, 0.3, 0.2);
    }
    else
    if(vObjId.x < 4.5)
    {
        // tablet back
        mat.fR0 = 0.25;
        mat.fSmoothness = 0.0;
        mat.cAlbedo = vec3(0.8, 0.8, 0.8);                            
    }
    else
    {
        // tablet screen
        mat.fR0 = 0.01;
        mat.fSmoothness = 1.0;                               
        mat.cAlbedo = vec3(0.025);
    }

    return mat;
}

vec3 GetSkyGradient( const in vec3 vDir )
{
    float fBlend = vDir.y * 0.5 + 0.5;
    return mix(vec3(0.0, 0.0, 0.0), vec3(0.4, 0.9, 1.0), fBlend);
}

vec3 GetLightPos()
{
    vec3 vLightPos = vec3(0.0, 1.0, 3.0);
    #ifdef ENABLE_MONTE_CARLO         
    vLightPos += gRandomNormal * 0.2;
    #endif
    return vLightPos;
}

vec3 GetLightCol()
{
    return vec3(32.0, 6.0, 1.0);
}

vec3 GetAmbientLight(const in vec3 vNormal)
{
    return GetSkyGradient(vNormal);
}

#define kFogDensity 0.0025
void ApplyAtmosphere(inout vec3 col, const in C_Ray ray, const in C_HitInfo intersection)
{
    #ifdef ENABLE_FOG
    // fog
    float fFogAmount = exp(intersection.fDistance * -kFogDensity);
    vec3 cFog = GetSkyGradient(ray.vDir);
    col = mix(cFog, col, fFogAmount);
    #endif

    // glare from light (a bit hacky - use length of closest approach from ray to light)
    #ifdef ENABLE_POINT_LIGHT_FLARE
    vec3 vToLight = GetLightPos() - ray.vOrigin;
    float fDot = dot(vToLight, ray.vDir);
    fDot = clamp(fDot, 0.0, intersection.fDistance);

    vec3 vClosestPoint = ray.vOrigin + ray.vDir * fDot;
    float fDist = length(vClosestPoint - GetLightPos());
    col += GetLightCol() * 0.01/ (fDist * fDist);
    #endif      
}

vec3 GetSceneNormal( const in vec3 vPos )
{
    // tetrahedron normal
    float fDelta = 0.025;

    vec3 vOffset1 = vec3( fDelta, -fDelta, -fDelta);
    vec3 vOffset2 = vec3(-fDelta, -fDelta,  fDelta);
    vec3 vOffset3 = vec3(-fDelta,  fDelta, -fDelta);
    vec3 vOffset4 = vec3( fDelta,  fDelta,  fDelta);

    float f1 = GetDistanceScene( vPos + vOffset1 ).x;
    float f2 = GetDistanceScene( vPos + vOffset2 ).x;
    float f3 = GetDistanceScene( vPos + vOffset3 ).x;
    float f4 = GetDistanceScene( vPos + vOffset4 ).x;

    vec3 vNormal = vOffset1 * f1 + vOffset2 * f2 + vOffset3 * f3 + vOffset4 * f4;

    return normalize( vNormal );
}

#define kRaymarchEpsilon 0.01
#define kRaymarchMatIter 256
#define kRaymarchStartDistance 0.1

// This is an excellent resource on ray marching -> http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
void Raymarch( const in C_Ray ray, out C_HitInfo result, const float fMaxDist, const int maxIter )
{          
    result.fDistance = kRaymarchStartDistance;
    result.vObjectId.x = 0.0;

    for(int i=0;i<=kRaymarchMatIter;i++)                
    {
        result.vPos = ray.vOrigin + ray.vDir * result.fDistance;
        vec4 vSceneDist = GetDistanceScene( result.vPos );
        result.vObjectId = vSceneDist.yzw;

        // abs allows backward stepping - should only be necessary for non uniform distance functions
        if((abs(vSceneDist.x) <= kRaymarchEpsilon) || (result.fDistance >= fMaxDist) || (i > maxIter))
        {
            break;
        }                          

        result.fDistance = result.fDistance + vSceneDist.x;      
    }

    if(result.fDistance >= fMaxDist)
    {
        result.vObjectId.x = 0.0;
        result.fDistance = 1000.0;
    }
}

float GetShadow( const in vec3 vPos, const in vec3 vLightDir, const in float fLightDistance )
{
    C_Ray shadowRay;
    shadowRay.vDir = vLightDir;
    shadowRay.vOrigin = vPos;

    C_HitInfo shadowIntersect;
    Raymarch(shadowRay, shadowIntersect, fLightDistance, 32);

    return step(0.0, shadowIntersect.fDistance) * step(fLightDistance, shadowIntersect.fDistance );           
}

// http://en.wikipedia.org/wiki/Schlick's_approximation
float Schlick( const in vec3 vNormal, const in vec3 vView, const in float fR0, const in float fSmoothFactor)
{
    float fDot = dot(vNormal, -vView);
    fDot = min(max((1.0 - fDot), 0.0), 1.0);
    float fDot2 = fDot * fDot;
    float fDot5 = fDot2 * fDot2 * fDot;
    return fR0 + (1.0 - fR0) * fDot5 * fSmoothFactor;
}

float GetDiffuseIntensity(const in vec3 vLightDir, const in vec3 vNormal)
{
    return max(0.0, dot(vLightDir, vNormal));
}

float GetBlinnPhongIntensity(const in C_Ray ray, const in C_Material mat, const in vec3 vLightDir, const in vec3 vNormal)
{            
    vec3 vHalf = normalize(vLightDir - ray.vDir);
    float fNdotH = max(0.0, dot(vHalf, vNormal));

    float fSpecPower = exp2(4.0 + 6.0 * mat.fSmoothness);
    float fSpecIntensity = (fSpecPower + 2.0) * 0.125;

    return pow(fNdotH, fSpecPower) * fSpecIntensity;
}

// use distance field to evaluate ambient occlusion
float GetAmbientOcclusion(const in C_Ray ray, const in C_HitInfo intersection, const in vec3 vNormal)
{
    vec3 vPos = intersection.vPos;

    float fAmbientOcclusion = 1.0;

    float fDist = 0.0;
    for(int i=0; i<=5; i++)
    {
        fDist += 0.1;

        vec4 vSceneDist = GetDistanceScene(vPos + vNormal * fDist);

        fAmbientOcclusion *= 1.0 - max(0.0, (fDist - vSceneDist.x) * 0.2 / fDist );                                    
    }

    return fAmbientOcclusion;
}

vec3 GetObjectLighting(const in C_Ray ray, const in C_HitInfo intersection, const in C_Material material, const in vec3 vNormal, const in vec3 cReflection)
{
    vec3 cScene ;

    vec3 vSpecularReflection = vec3(0.0);
    vec3 vDiffuseReflection = vec3(0.0);

    float fAmbientOcclusion = GetAmbientOcclusion(ray, intersection, vNormal);
    vec3 vAmbientLight = GetAmbientLight(vNormal) * fAmbientOcclusion;

    vDiffuseReflection += vAmbientLight;

    vSpecularReflection += cReflection * fAmbientOcclusion;

    #ifdef ENABLE_POINT_LIGHT
    vec3 vLightPos = GetLightPos();
    vec3 vToLight = vLightPos - intersection.vPos;
    vec3 vLightDir = normalize(vToLight);
    float fLightDistance = length(vToLight);

    float fAttenuation = 1.0 / (fLightDistance * fLightDistance);

    float fShadowBias = 0.1;              
    float fShadowFactor = GetShadow( intersection.vPos + vLightDir * fShadowBias, vLightDir, fLightDistance - fShadowBias );
    vec3 vIncidentLight = GetLightCol() * fShadowFactor * fAttenuation;

    vDiffuseReflection += GetDiffuseIntensity( vLightDir, vNormal ) * vIncidentLight;                                                                                  
    vSpecularReflection += GetBlinnPhongIntensity( ray, material, vLightDir, vNormal ) * vIncidentLight;
    #endif ENABLE_POINT_LIGHT

    vDiffuseReflection *= material.cAlbedo;

    // emmissive glow from screen
    if(intersection.vObjectId.x > 4.5)
    {
        vec2 vScreenPos = intersection.vObjectId.zy * vec2(0.25, -0.3) + vec2(0.46, 0.5);

        vec2 vMul = step(vScreenPos, vec2(1.0)) * step(vec2(0.0), vScreenPos);
        float fMul = vMul.x * vMul.y * 0.8;
        vDiffuseReflection += texture2D(backbuffer, vScreenPos).xyz * fMul;
    }

    #ifdef ENABLE_SPECULAR
    float fFresnel = Schlick(vNormal, ray.vDir, material.fR0, material.fSmoothness * 0.9 + 0.1);
    cScene = mix(vDiffuseReflection , vSpecularReflection, fFresnel);
    #else
    cScene = vDiffuseReflection;
    #endif

    return cScene;
}

vec3 GetSceneColourSimple( const in C_Ray ray )
{
    C_HitInfo intersection;
    Raymarch(ray, intersection, 16.0, 32);

    vec3 cScene;

    if(intersection.vObjectId.x < 0.5)
    {
        cScene = GetSkyGradient(ray.vDir);
    }
    else
    {
        C_Material material = GetObjectMaterial(intersection.vObjectId, intersection.vPos);
        vec3 vNormal = GetSceneNormal(intersection.vPos);

        // use sky gradient instead of reflection
        vec3 cReflection = GetSkyGradient(reflect(ray.vDir, vNormal));

        // apply lighting
        cScene = GetObjectLighting(ray, intersection, material, vNormal, cReflection );
    }

    ApplyAtmosphere(cScene, ray, intersection);

    return cScene;
}

vec3 GetSceneColour( const in C_Ray ray )
{                                                           
    C_HitInfo intersection;
    Raymarch(ray, intersection, 30.0, 256);

    vec3 cScene;

    if(intersection.vObjectId.x < 0.5)
    {
        cScene = GetSkyGradient(ray.vDir);
    }
    else
    {
        C_Material material = GetObjectMaterial(intersection.vObjectId, intersection.vPos);
        vec3 vNormal = GetSceneNormal(intersection.vPos);

        #ifdef ENABLE_MONTE_CARLO
        vNormal = normalize(vNormal + gRandomNormal / (5.0 + material.fSmoothness * 200.0));
        #endif

        vec3 cReflection;
        #ifdef ENABLE_REFLECTIONS   
        {
            // get colour from reflected ray
            float fSepration = 0.05;
            C_Ray reflectRay;
            reflectRay.vDir = reflect(ray.vDir, vNormal);
            reflectRay.vOrigin = intersection.vPos + reflectRay.vDir * fSepration;

            cReflection = GetSceneColourSimple(reflectRay);                                                                          
        }
        #else
        cReflection = GetSkyGradient(reflect(ray.vDir, vNormal));                               
        #endif
        // apply lighting
        cScene = GetObjectLighting(ray, intersection, material, vNormal, cReflection );
    }

    ApplyAtmosphere(cScene, ray, intersection);

    return cScene;
}

void GetCameraRay( const in vec3 vPos, const in vec3 vForwards, const in vec3 vWorldUp, out C_Ray ray)
{
    vec2 vPixelCoord = gl_FragCoord.xy;
    #ifdef ENABLE_MONTE_CARLO
    vPixelCoord += gPixelRandom.zw;
    #endif
    vec2 vUV = ( vPixelCoord / resolution.xy );
    vec2 vViewCoord = vUV * 2.0 - 1.0;

    vViewCoord *= 0.75;

    float fRatio = resolution.x / resolution.y;

    vViewCoord.y /= fRatio;                            

    ray.vOrigin = vPos;

    vec3 vRight = normalize(cross(vForwards, vWorldUp));
    vec3 vUp = cross(vRight, vForwards);

    ray.vDir = normalize( vRight * vViewCoord.x + vUp * vViewCoord.y + vForwards);         
}

void GetCameraRayLookat( const in vec3 vPos, const in vec3 vInterest, out C_Ray ray)
{
    vec3 vForwards = normalize(vInterest - vPos);
    vec3 vUp = vec3(0.0, 1.0, 0.0);

    GetCameraRay(vPos, vForwards, vUp, ray);
}

vec3 OrbitPoint( const in float fHeading, const in float fElevation )
{
    return vec3(sin(fHeading) * cos(fElevation), sin(fElevation), cos(fHeading) * cos(fElevation));
}

vec3 Tonemap( const in vec3 cCol )
{
    // simple Reinhard tonemapping operator      
    return cCol / (1.0 + cCol);
}

void main( void )
{
    #ifdef ENABLE_MONTE_CARLO              
    CalcPixelRandom();
    #endif

    C_Ray ray;

    vec3 vCameraPos = OrbitPoint(-mouse.x * 7.0, mouse.y * PI * 0.5) * 7.0 - vec3(0.0, 0.9, 0.0);
    #ifdef ENABLE_MONTE_CARLO              
    float fDepthOfField = 0.1;
    vCameraPos += gRandomNormal * 0.05;
    #endif

    GetCameraRayLookat( vCameraPos, vec3(0.0, 0.0, 0.0), ray);
    //GetCameraRayLookat(vec3(0.0, 0.0, -5.0), vec3(0.0, 0.0, 0.0), ray);

    vec3 cScene = GetSceneColour( ray );    

    float fExposure = 2.5;
    cScene = cScene * fExposure;
    vec3 cCurr = Tonemap(cScene );

    #ifdef ENABLE_MONTE_CARLO                              
    vec3 cPrev = texture2D(backbuffer, gl_FragCoord.xy / resolution).xyz;
    // would be nice to combine before tonemap but undoing a gamma=2.0 will do instead
    cPrev = cPrev * cPrev;
    // add noise to pixel value (helps values converge)
    cPrev += (gPixelRandom.xyz - 0.5) * (1.0 / 255.0);
    cCurr = cCurr * cCurr;
    // converge speed
    vec3 cFinal = mix(cPrev, cCurr, 8.0/255.0);
    // re-apply gamma 2.0
    cFinal = sqrt(cFinal);
    #else
    vec3 cFinal = cCurr;
    #endif

    float fAlpha = 1.0;
    #ifdef ENABLE_PERLIN_NOISE
    fAlpha = CalculateNoiseTexture();          
    #endif

    gl_FragColor = vec4( cFinal, fAlpha );

    //gl_FragColor = vec4(CalculateNoiseTexture()); // output noise texture
}

2014-09-14_21-50-58

http://glsl.heroku.com/e#6254.0

// 704 Remake - @PauloFalcao
// based on Blank Slate - @P_Malin (http://glsl.heroku.com/e#2540.09)
//
// Tonight was very tired from work, and decided to do some graphics fun to clear the mind! :)
// I opened the http://glsl.heroku.com/ and saw a copy of @P_Malin framework
// I Remembered my old 704 (http://www.backtothepixel.com/demos/js/webgl/704_webgl.html)
// and thought... how it would look like if i used the 704 object...
// I loved the results!!! @P_Malin framework is awesome!!!
// Very complete, with nice variable names, really nice! :)
// Colors, and the object are the same as the original 704,
// but time is slower to give to the stuff time to cook... ;)
//

#ifdef GL_ES
precision highp float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
uniform sampler2D backbuffer;

// somehow these enable pan/zoom controls (using magic)
uniform vec2 surfaceSize;
varying vec2 surfacePosition;

float kPI = acos(0.0);
float kHalfPi = asin(1.0);
float kTwoPI = kPI * 2.0;

// Removed so that it works again
//float cos(float v) // workaround for AMD Radeon on OS X
//{ 
//  return sin(v+kHalfPi);
//}

#define ENABLE_MONTE_CARLO
#define ENABLE_REFLECTIONS
#define ENABLE_FOG
#define ENABLE_SPECULAR
#define ENABLE_POINT_LIGHT
//#define ENABLE_POINT_LIGHT_FLARE

#ifdef ENABLE_MONTE_CARLO
vec4 gPixelRandom;
vec3 gRandomNormal;

void CalcPixelRandom()
{
    // Nothing special here, just numbers generated by bashing keyboard
    vec4 s1 = sin(time * 3.3422 + gl_FragCoord.xxxx * vec4(324.324234, 563.324234, 657.324234, 764.324234)) * 543.3423;
    vec4 s2 = sin(time * 1.3422 + gl_FragCoord.yyyy * vec4(567.324234, 435.324234, 432.324234, 657.324234)) * 654.5423;
    gPixelRandom = fract(2142.4 + s1 + s2);
    gRandomNormal = normalize( gPixelRandom.xyz - 0.5);
}
#endif

struct C_Ray
{
    vec3 vOrigin;
    vec3 vDir;
};

struct C_HitInfo
{
    vec3 vPos;
    float fDistance;
    vec3 vObjectId;
};

struct C_Material
{
    vec3 cAlbedo;
    float fR0;
    float fSmoothness;
    vec2 vParam;
};

vec3 RotateX( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( vPos.x, c * vPos.y + s * vPos.z, -s * vPos.y + c * vPos.z);

    return vResult;
}

vec3 RotateY( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.z, vPos.y, -s * vPos.x + c * vPos.z);

    return vResult;
}

vec3 RotateZ( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.y, -s * vPos.x + c * vPos.y, vPos.z);

    return vResult;
}

vec4 DistCombineUnion( const in vec4 v1, const in vec4 v2 )
{
    //if(v1.x < v2.x) return v1; else return v2;
    return mix(v1, v2, step(v2.x, v1.x));
}

vec4 DistCombineIntersect( const in vec4 v1, const in vec4 v2 )
{
    return mix(v2, v1, step(v2.x,v1.x));
}

vec4 DistCombineSubtract( const in vec4 v1, const in vec4 v2 )
{
    return DistCombineIntersect(v1, vec4(-v2.x, v2.yzw));
}

vec3 DomainRepeatXZGetTile( const in vec3 vPos, const in vec2 vRepeat, out vec2 vTile )
{
    vec3 vResult = vPos;
    vec2 vTilePos = (vPos.xz / vRepeat) + 0.5;
    vTile = floor(vTilePos + 1000.0);
    vResult.xz = (fract(vTilePos) - 0.5) * vRepeat;
    return vResult;
}

vec3 DomainRepeatXZ( const in vec3 vPos, const in vec2 vRepeat )
{
    vec3 vResult = vPos;
    vec2 vTilePos = (vPos.xz / vRepeat) + 0.5;
    vResult.xz = (fract(vTilePos) - 0.5) * vRepeat;
    return vResult;
}

vec3 DomainRepeatY( const in vec3 vPos, const in float fSize )
{
    vec3 vResult = vPos;
    vResult.y = (fract(vPos.y / fSize + 0.5) - 0.5) * fSize;
    return vResult;
}

vec3 DomainRotateSymmetry( const in vec3 vPos, const in float fSteps )
{
    float angle = atan( vPos.x, vPos.z );

    float fScale = fSteps / (kTwoPI);
    float steppedAngle = (floor(angle * fScale + 0.5)) / fScale;

    float s = sin(-steppedAngle);
    float c = cos(-steppedAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.z,
                 vPos.y,
                -s * vPos.x + c * vPos.z);

    return vResult;
}

float GetDistanceXYTorus( const in vec3 p, const in float r1, const in float r2 )
{
    vec2 q = vec2(length(p.xy)-r1,p.z);
    return length(q)-r2;
}
float GetDistanceYZTorus( const in vec3 p, const in float r1, const in float r2 )
{
    vec2 q = vec2(length(p.yz)-r1,p.x);
    return length(q)-r2;
}
float GetDistanceCylinderY(const in vec3 vPos, const in float r)
{
    return length(vPos.xz) - r;
}
float GetDistanceBox( const in vec3 vPos, const in vec3 vSize )
{
    vec3 vDist = (abs(vPos) - vSize);
    return max(vDist.x, max(vDist.y, vDist.z));
}

float GetDistanceRoundedBox( const in vec3 vPos, const in vec3 vSize, float fRadius )
{
    vec3 vClosest = max(min(vPos, vSize), -vSize);
    return length(vClosest - vPos) - fRadius;
}

// result is x=scene distance y=material or object id; zw are material specific parameters (maybe uv co-ordinates)
vec4 GetDistanceScene( const in vec3 vPos )
{          
    vec4 vResult = vec4(10000.0, -1.0, 0.0, 0.0);

    float oP=length(vPos);
    vec3 vSphereDomain=vPos;
    float tt=time*0.05+10.0;
    vSphereDomain.x=sin(vSphereDomain.x)+sin(tt);
    vSphereDomain.z=sin(vSphereDomain.z)+cos(tt);

    vec4 vDistSphere = vec4( length(length(vSphereDomain))-1.5-sin(oP-tt*4.0), 2.0, vSphereDomain.xy);

    vResult = DistCombineUnion(vResult, vDistSphere);

    vec4 vDistFloor = vec4(vPos.y + 1.0, 1.0, vPos.xz);
    vResult = DistCombineUnion(vResult, vDistFloor);

    return vResult;
}

C_Material GetObjectMaterial( const in vec3 vObjId, const in vec3 vPos )
{
    C_Material mat;

    if(vObjId.x < 1.5)
    {
        // floor
        mat.fR0 = 0.01;
        mat.fSmoothness = 0.0;
        if (fract(vPos.x*.5)>.5)
            if (fract(vPos.z*.5)>.5)
                mat.cAlbedo=vec3(0,0,0);
            else
                mat.cAlbedo=vec3(1,1,1);
            else
            if (fract(vPos.z*.5)>.5)
                mat.cAlbedo = vec3(1,1,1);
            else
                mat.cAlbedo = vec3(0,0,0);
    }
    else
    if(vObjId.x < 2.5)
    {
        // sphere
        mat.fR0 = 0.5;
        mat.fSmoothness = 0.9;
        float tt=time*0.05+10.0;
        float d=length(vPos);
        mat.cAlbedo = vec3((sin(d*.25-tt*4.0)+1.0)/2.0,(sin(tt)+1.0)/2.0,(sin(d-tt*4.0)+1.0)/2.0);
    }

    return mat;
}
vec3 GetSkyGradient( const in vec3 vDir )
{
    float fBlend = vDir.y * 0.5 + 0.5;
    return mix(vec3(0.0, 0.0, 0.0), vec3(0.5, 0.6, 0.7), fBlend);
}
vec3 GetLightPos()
{
    vec3 vLightPos = vec3(2.0, 9.0, 2.0);
    #ifdef ENABLE_MONTE_CARLO        
    vLightPos += gRandomNormal * 0.2;
    #endif
    return vLightPos;
}
vec3 GetLightCol()
{
    return vec3(32.0, 6.0, 1.0) * 10.0;
}

vec3 GetAmbientLight(const in vec3 vNormal)
{
    return GetSkyGradient(vNormal);
}

#define kFogDensity 0.035
void ApplyAtmosphere(inout vec3 col, const in C_Ray ray, const in C_HitInfo intersection)
{
    #ifdef ENABLE_FOG
    // fog
    float fFogAmount = exp(intersection.fDistance * -kFogDensity);
    vec3 cFog = GetSkyGradient(ray.vDir);
    col = mix(cFog, col, fFogAmount);
    #endif

    // glare from light (a bit hacky - use length of closest approach from ray to light)
    #ifdef ENABLE_POINT_LIGHT_FLARE
    vec3 vToLight = GetLightPos() - ray.vOrigin;
    float fDot = dot(vToLight, ray.vDir);
    fDot = clamp(fDot, 0.0, intersection.fDistance);

    vec3 vClosestPoint = ray.vOrigin + ray.vDir * fDot;
    float fDist = length(vClosestPoint - GetLightPos());
    col += GetLightCol() * 0.01/ (fDist * fDist);
    #endif     
}
vec3 GetSceneNormal( const in vec3 vPos )
{
    // tetrahedron normal
    float fDelta = 0.025;

    vec3 vOffset1 = vec3( fDelta, -fDelta, -fDelta);
    vec3 vOffset2 = vec3(-fDelta, -fDelta,  fDelta);
    vec3 vOffset3 = vec3(-fDelta,  fDelta, -fDelta);
    vec3 vOffset4 = vec3( fDelta,  fDelta,  fDelta);

    float f1 = GetDistanceScene( vPos + vOffset1 ).x;
    float f2 = GetDistanceScene( vPos + vOffset2 ).x;
    float f3 = GetDistanceScene( vPos + vOffset3 ).x;
    float f4 = GetDistanceScene( vPos + vOffset4 ).x;

    vec3 vNormal = vOffset1 * f1 + vOffset2 * f2 + vOffset3 * f3 + vOffset4 * f4;

    return normalize( vNormal );
}

#define kRaymarchEpsilon 0.01
#define kRaymarchMatIter 256
#define kRaymarchStartDistance 0.1
// This is an excellent resource on ray marching -> http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
void Raymarch( const in C_Ray ray, out C_HitInfo result, const float fMaxDist, const int maxIter )
{         
    result.fDistance = kRaymarchStartDistance;
    result.vObjectId.x = 0.0;

    for(int i=0;i<=kRaymarchMatIter;i++)               
    {
        result.vPos = ray.vOrigin + ray.vDir * result.fDistance;
        vec4 vSceneDist = GetDistanceScene( result.vPos );
        result.vObjectId = vSceneDist.yzw;

        // abs allows backward stepping - should only be necessary for non uniform distance functions
        if((abs(vSceneDist.x) <= kRaymarchEpsilon) || (result.fDistance >= fMaxDist) || (i > maxIter))
        {
            break;
        }                         

        result.fDistance = result.fDistance + vSceneDist.x;     
    }

    if(result.fDistance >= fMaxDist)
    {
        result.vPos = ray.vOrigin + ray.vDir * result.fDistance;
        result.vObjectId.x = 0.0;
        result.fDistance = 1000.0;
    }
}

float GetShadow( const in vec3 vPos, const in vec3 vLightDir, const in float fLightDistance )
{
    C_Ray shadowRay;
    shadowRay.vDir = vLightDir;
    shadowRay.vOrigin = vPos;

    C_HitInfo shadowIntersect;
    Raymarch(shadowRay, shadowIntersect, fLightDistance, 32);

    return step(0.0, shadowIntersect.fDistance) * step(fLightDistance, shadowIntersect.fDistance );          
}

// http://en.wikipedia.org/wiki/Schlick's_approximation
float Schlick( const in vec3 vNormal, const in vec3 vView, const in float fR0, const in float fSmoothFactor)
{
    float fDot = dot(vNormal, -vView);
    fDot = min(max((1.0 - fDot), 0.0), 1.0);
    float fDot2 = fDot * fDot;
    float fDot5 = fDot2 * fDot2 * fDot;
    return fR0 + (1.0 - fR0) * fDot5 * fSmoothFactor;
}

float GetDiffuseIntensity(const in vec3 vLightDir, const in vec3 vNormal)
{
    return max(0.0, dot(vLightDir, vNormal));
}

float GetBlinnPhongIntensity(const in C_Ray ray, const in C_Material mat, const in vec3 vLightDir, const in vec3 vNormal)
{           
    vec3 vHalf = normalize(vLightDir - ray.vDir);
    float fNdotH = max(0.0, dot(vHalf, vNormal));

    float fSpecPower = exp2(4.0 + 6.0 * mat.fSmoothness);
    float fSpecIntensity = (fSpecPower + 2.0) * 0.125;

    return pow(fNdotH, fSpecPower) * fSpecIntensity;
}

// use distance field to evaluate ambient occlusion
float GetAmbientOcclusion(const in C_Ray ray, const in C_HitInfo intersection, const in vec3 vNormal)
{
    vec3 vPos = intersection.vPos;

    float fAmbientOcclusion = 1.0;

    float fDist = 0.0;
    for(int i=0; i<=5; i++)
    {
        fDist += 0.1;

        vec4 vSceneDist = GetDistanceScene(vPos + vNormal * fDist);

        fAmbientOcclusion *= 1.0 - max(0.0, (fDist - vSceneDist.x) * 0.2 / fDist );                                   
    }

    return fAmbientOcclusion;
}

vec3 GetObjectLighting(const in C_Ray ray, const in C_HitInfo intersection, const in C_Material material, const in vec3 vNormal, const in vec3 cReflection)
{
    vec3 cScene ;

    vec3 vSpecularReflection = vec3(0.0);
    vec3 vDiffuseReflection = vec3(0.0);

    float fAmbientOcclusion = GetAmbientOcclusion(ray, intersection, vNormal);
    vec3 vAmbientLight = GetAmbientLight(vNormal) * fAmbientOcclusion;

    vDiffuseReflection += vAmbientLight;

    vSpecularReflection += cReflection * fAmbientOcclusion;

    #ifdef ENABLE_POINT_LIGHT
    vec3 vLightPos = GetLightPos();
    vec3 vToLight = vLightPos - intersection.vPos;
    vec3 vLightDir = normalize(vToLight);
    float fLightDistance = length(vToLight);

    float fAttenuation = 1.0 / (fLightDistance * fLightDistance);

    float fShadowBias = 0.1;             
    float fShadowFactor = GetShadow( intersection.vPos + vLightDir * fShadowBias, vLightDir, fLightDistance - fShadowBias );
    vec3 vIncidentLight = GetLightCol() * fShadowFactor * fAttenuation;

    vDiffuseReflection += GetDiffuseIntensity( vLightDir, vNormal ) * vIncidentLight;                                                                                 
    vSpecularReflection += GetBlinnPhongIntensity( ray, material, vLightDir, vNormal ) * vIncidentLight;
    #endif ENABLE_POINT_LIGHT

    vDiffuseReflection *= material.cAlbedo;              

    #ifdef ENABLE_SPECULAR
    float fFresnel = Schlick(vNormal, ray.vDir, material.fR0, material.fSmoothness * 0.9 + 0.1);
    cScene = mix(vDiffuseReflection , vSpecularReflection, fFresnel);
    #else
    cScene = vDiffuseReflection;
    #endif

    return cScene;
}

vec3 GetSceneColourSimple( const in C_Ray ray )
{
    C_HitInfo intersection;
    Raymarch(ray, intersection, 16.0, 32);

    vec3 cScene;

    if(intersection.vObjectId.x < 0.5)
    {
        cScene = GetSkyGradient(ray.vDir);
    }
    else
    {
        C_Material material = GetObjectMaterial(intersection.vObjectId, intersection.vPos);
        vec3 vNormal = GetSceneNormal(intersection.vPos);

        // use sky gradient instead of reflection
        vec3 cReflection = GetSkyGradient(reflect(ray.vDir, vNormal));

        // apply lighting
        cScene = GetObjectLighting(ray, intersection, material, vNormal, cReflection );
    }

    ApplyAtmosphere(cScene, ray, intersection);

    return cScene;
}

vec3 GetSceneColour( const in C_Ray ray )
{                                                           
    C_HitInfo intersection;
    Raymarch(ray, intersection, 60.0, 256);

    vec3 cScene;

    if(intersection.vObjectId.x < 0.5)
    {
        cScene = GetSkyGradient(ray.vDir);
    }
    else
    {
        C_Material material = GetObjectMaterial(intersection.vObjectId, intersection.vPos);
        vec3 vNormal = GetSceneNormal(intersection.vPos);

        #ifdef ENABLE_MONTE_CARLO
        vNormal = normalize(vNormal + gRandomNormal / (5.0 + material.fSmoothness * 200.0));
        #endif

        vec3 cReflection;
        #ifdef ENABLE_REFLECTIONS    
        {
            // get colour from reflected ray
            float fSepration = 0.05;
            C_Ray reflectRay;
            reflectRay.vDir = reflect(ray.vDir, vNormal);
            reflectRay.vOrigin = intersection.vPos + reflectRay.vDir * fSepration;

            cReflection = GetSceneColourSimple(reflectRay);                                                                         
        }
        #else
        cReflection = GetSkyGradient(reflect(ray.vDir, vNormal));                               
        #endif
        // apply lighting
        cScene = GetObjectLighting(ray, intersection, material, vNormal, cReflection );
    }

    ApplyAtmosphere(cScene, ray, intersection);

    return cScene;
}

void GetCameraRay( const in vec3 vPos, const in vec3 vForwards, const in vec3 vWorldUp, out C_Ray ray)
{
    vec2 vPixelCoord = gl_FragCoord.xy;
    #ifdef ENABLE_MONTE_CARLO
    vPixelCoord += gPixelRandom.zw;
    #endif
    vec2 vUV = ( vPixelCoord / resolution.xy );
    vec2 vViewCoord = vUV * 2.0 - 1.0;

    vViewCoord *= 0.75;

    float fRatio = resolution.x / resolution.y;

    vViewCoord.y /= fRatio;                           

    ray.vOrigin = vPos;

    vec3 vRight = normalize(cross(vForwards, vWorldUp));
    vec3 vUp = cross(vRight, vForwards);

    ray.vDir = normalize( vRight * vViewCoord.x + vUp * vViewCoord.y + vForwards);        
}

void GetCameraRayLookat( const in vec3 vPos, const in vec3 vInterest, out C_Ray ray)
{
    vec3 vForwards = normalize(vInterest - vPos);
    vec3 vUp = vec3(0.0, 1.0, 0.0);

    GetCameraRay(vPos, vForwards, vUp, ray);
}

vec3 OrbitPoint( const in float fHeading, const in float fElevation )
{
    return vec3(sin(fHeading) * cos(fElevation), sin(fElevation), cos(fHeading) * cos(fElevation));
}

vec3 Gamma( const in vec3 cCol )
{
    return cCol * cCol;
}

vec3 InvGamma( const in vec3 cCol )
{
    return sqrt(cCol);
}

vec3 Tonemap( const in vec3 cCol )
{
    // simple Reinhard tonemapping operator     
    vec3 vResult = cCol / (1.0 + cCol);

    return Gamma(vResult);
}

vec3 InvTonemap( const in vec3 cCol )
{
    vec3 vResult = cCol;
    vResult = clamp(vResult, 0.01, 0.99);
    vResult = InvGamma(vResult);
    return - (vResult / (vResult - 1.0));
}

void main( void )
{
    #ifdef ENABLE_MONTE_CARLO             
    CalcPixelRandom();
    #endif

    C_Ray ray;

    const float fCamreaInitialHeading = 0.5;
    const float fCamreaInitialElevation = 0.5;
    const float fCamreaInitialDist = 20.0;
    const float fCameraHeight = 0.01;
    const float fOrbitSpeed = 1.0;

    // This magic stolen from other 3d pan/zoom examples
    float fZoom = surfaceSize.y * 0.5 + 0.4;

    vec2 vCenterPosition = (0.5 - ( gl_FragCoord.xy / resolution )) * surfaceSize + surfacePosition;
    float fHeading = vCenterPosition.x * fOrbitSpeed + fCamreaInitialHeading;
    float fElevation = (vCenterPosition.y * fOrbitSpeed + fCamreaInitialElevation);

    vec3 vCameraPos = OrbitPoint(fHeading, fElevation) * fCamreaInitialDist * fZoom;

    vCameraPos += vec3(0.0, -fCameraHeight, 0.0);
    #ifdef ENABLE_MONTE_CARLO             
    float fDepthOfField = 0.1;
    vCameraPos += gRandomNormal * fDepthOfField;
    #endif

    GetCameraRayLookat( vCameraPos, vec3(0.0, 0.0, 0.0), ray);
    //GetCameraRayLookat(vec3(0.0, 0.0, -5.0), vec3(0.0, 0.0, 0.0), ray);

    vec3 cScene = GetSceneColour( ray );   

    float fExposure = 3.5;
    cScene = cScene * fExposure;

    #ifdef ENABLE_MONTE_CARLO                              
    vec3 cPrev = texture2D(backbuffer, gl_FragCoord.xy / resolution).xyz;
    // add noise to pixel value (helps values converge)
    cPrev += (gPixelRandom.xyz - 0.5) * (1.0 / 255.0);
    cPrev = InvTonemap(cPrev);
    // converge speep
    float fBlend = 0.1;
    vec3 cFinal = mix(cPrev, cScene, fBlend);
    #else
    vec3 cFinal = cScene;
    #endif

    cFinal = Tonemap(cFinal);

    float fAlpha = 1.0;

    gl_FragColor = vec4( cFinal, fAlpha );
}
Tags : #shader

오랜만에 Processing을 해보려니 극악한 IDE환경에 Sublime text가 너무 그리워져 이것을 해결할 수 있는 방법을 찾아보았다.

processing-sublime

그 해결책은 바로 Sublime text의 processing-sublime 플러그인. 내가 이미 쓰고있었다…(읭?)
맥과 윈도우, 리눅스가 방법이 다 다른데 맥용은 아래와 같다. 윈도우나 리눅스는 위의 github페이지 참고.

##OSX에서 설치방법##

  1. sublime text에서 processing-sublime플러그인을 설치.
  2. processing에서 Tools -> Install “processing-java”를 눌러 설치
  3. Sublime text에서 Tools – Build system – Processing을 선택
  4. 원하는 PDE파일을 Sublime text에서 열고 Command + B 키를 누르면 실행된다.

이 때 할때마다 자바창이 계속 뜨는 문제가 생기는데 이를 해결하려면 다음과 같이 할 수 있다.

  1. Sublime Text의 Preferences – Browse Packages를 눌러 나오는 폴더 목록중에 Processing로 들어간다.
  2. Processing.sublime-build파일을 열어 수정한다.

두번째 줄에

"cmd": ["processing-java", "--sketch=$file_path", "--output=$file_path/build-tmp", "--run", "--force"],

부분이 있는데, 이 부분을 통째로 다음과 같이 바꾼다.

"shell": true,
"cmd": ["killall -v java; processing-java --sketch=$file_path --output=$file_path/build-tmp --run --force"],

이렇게 하면 빌드할 때마다 java를 종료시키기 때문에 processing과 비슷한 환경에서 개발이 가능하다.

Tags : #processing #sublime text

terminal에서 이미지들을 gif나 mov으로 변환하기

a0.jpg ~ a60.jpg를 animation.gif나 animation.mov로 변환하고 싶을 때는 어떻게 하면 될까?

convert -delay 5 -loop 0 a*.jpg animation.gif
convert -delay 5 animation.mov

사용법은 이렇게 간단하지만 imagemagick이라는 플러그인과 ffmpeg라는 플러그인이 필요하다.
아마도 저 명령어를 했을때 에러가 난다면 없을 가능성이 높은데, 없다면 brew를 이용해 설치할 수 있다.

brew install imagemagick
brew install ffmpeg

brew가 없다면 검색해서 brew를 설치하도록. 이상.

참고포스팅

Convert an image sequence to a movie
Creating Animated GIFs from the Command Line in Mac OS X Using Convert

more 1. animation gif나 mp4를 업로드 할 수 있는 공유 사이트

Gfycat

Tags : #terminal

에버노트 웹 클리퍼

https://chrome.google.com/webstore/detail/evernote-web-clipper/pioclpoplcdbaefihamjohnefbikjilc
에버노트 전용 크롬 클리어 프로그램인데 상당히 잘 만들어졌습니다.
크롬을 이용하다 이 버튼을 누르면 커서키를 움직이면서 웹페이지의 일부분만 에버노트에 저장할수가 있는데요.
이때 어떤 노트에 저장할지, 태그는 뭘로 할지 선택할 수가 있고, 많은 노트가 쌓여 있으면 자동으로 어떤 노트에 들어가면 좋을지 자동으로 보여줍니다.

1

grab it을 활용

Grab it 은 screen floating앱입니다. 간단하게 말하자면 화면을 캡쳐하면 화면에 둥둥 떠있는데 이걸 이미지로 저장하기도 하고 클립보드에 옮겨 포토샵이나 에버노트에 불이기도 합니다.
이런 앱이 몇가지가 있는데 grab it이 저에겐 제일 맞는것 같더라구요.
grab it – mac app store https://itunes.apple.com/kr/app/grabit/id450166997?mt=12
grab it 작동 동영상 https://www.youtube.com/watch?v=27vksXJc_Gw
맥용 플로팅 이미지 캡처 소프트웨어 4종 비교 http://macnews.tistory.com/1190

전 주로 화면을 에버노트에 저장하고 싶거나, 혹은 화면일부를 참고하고 싶을 때 이 어플을 이용합니다.

2

에버노트 세팅

별로 특별한건 아닌데 제가 주로 쓰는 방법을 알려드리면.
에버노트로 붙여넣기 할 때 서식 없이 붙여넣기를 하려면 alt + command + V
이미 쓴 글의 서식을 단순화 시킬때는 shift + command + F
가로선을 삽입할 때는 command + shift + H (윈도우에서는 control + shift + -)
글씨를 크게 할 때는 command +, (-)

pdf 저장 기능

pdf를 에버노트의 글쓰기 창에 던져놓으면 pdf가 들어가 집니다. 본문 검색도 됩니다.

이미지 ocr 기능

심지어 이미지 안의 글씨도 인식해서 검색결과에 나옵니다.

에버노트의 공유 url복사를 누르면 이 페이지처럼 링크가 생성되는데

링크를 가진 모든 사람들이 페이지를 볼수있고, 페이지가 자동으로 동기화 되기 때문에 이처럼 간편하게 쓰기 좋네요.
에버노트에 정리한 오늘 스터디 링크:
https://www.evernote.com/shard/s22/sh/780a1fa7-e483-4d9d-b9af-ff57057df1a2/b9ff1114a01b30c168a7a96a70f497bf
정말 대충대충 넣어놓습니다.

code highter

에버노트에 소스코드를 붙여넣으면 전혀 이쁘지가 않는데 아래와 같은 사이트를 통해 소스 하일라이팅을 시키고 그걸 복사해서
붙여넣기 할 수 있습니다.
http://hilite.me/
GLSL을 선택하고 맘에드는 스타일을 선택해서 highlight하시면 됩니다.
3

이미지에 주석달거나 붙여넣은 이미지 축소하기

이미지 축소는 가장 필요했던 기능인데 방금찾았네요.
이미지에 우클릭하기 ‘이미지에 주석달기’를 누릅니다.
이 메뉴에서 사각형을 그린다거나 화살표를 추가할수도 있구요.
저 표시된 버튼을 누르고 상단에서 크기조절을 누르면 이미지 조절이 됩니다.
4

뭐 많은 기능이 있겠지만 저는 일단 에버노트에서는 이정도만 쓰는것 같습니다.
생각해보면 전 에버노트와 simplenote라는 어플을 같이 쓰는데요.
http://simplenote.com/

심플노트는 완전 텍스트 기반 에디턴데, 프리웨어에 깔끔하고, ios – mac – android 완벽 동기화를 자랑하는 어플입니다.
그래서 저는 주로 뭔가 기억할 것들은 simplenote에, 이미지를 첨부한 내용이라던가 웹에서 클리핑한 내용 등등은 에버노트에 저장해두는 편입니다.

Tags : #evernote #tip

http://glsl.heroku.com/e#19378.0

precision highp float;
uniform vec2 resolution;
uniform float time;
uniform vec2 mouse;

float hash11(float p) {
    return fract(sin(p)*45768.23);
}

float hash21(vec2 p) {
    return fract(sin(p.x * 15.23 + p.y * 32.12) * 45768.23);
}

float hash31(vec3 p) {
    return fract(sin(p.x *15.23 + p.y * 35.87 + p.z * 75.53) * 45768.23);
}

vec2 hash22(vec2 p) {
    mat2 m = mat2(15.23, 32.12, 71.23, 152.31);
    return fract(sin(m*p)*45768.23);
}

vec3 hash33(vec3 p) {
    mat3 m = mat3(15.23, 35.11, 70.24, 151.22, 301.11 , 612.23, 1345.17, 2678.98, 5371.13);
    return fract(sin(m*p)*45768.23);
}

float value_noise(vec3 p) {
    vec3 g = floor(p);
    vec3 f = fract(p);
    float fbl = hash31(g + vec3(0.0, 0.0, 0.0));
    float fbr = hash31(g + vec3(1.0, 0.0, 0.0));
    float ftl = hash31(g + vec3(0.0, 1.0, 0.0));
    float ftr = hash31(g + vec3(1.0, 1.0, 0.0));
    float bbl = hash31(g + vec3(0.0, 0.0, 1.0));
    float bbr = hash31(g + vec3(1.0, 0.0, 1.0));
    float btl = hash31(g + vec3(0.0, 1.0, 1.0));
    float btr = hash31(g + vec3(1.0, 1.0, 1.0));
    
    float fb = mix(fbl, fbr, f.x);
    float ft = mix(ftl, ftr, f.x);
    float fres = mix(fb, ft, f.y);
    float bb = mix(bbl, bbr, f.x);
    float bt = mix(btl, btr, f.x);
    float bres = mix(bb, bt, f.y);
    
    float res = mix(fres, bres, f.z);
    return res;
}

float sdPlane(in vec3 p) {
    return p.y + value_noise(p);
    // return p.y;
}

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

float map(in vec3 p) {
    float d = sdPlane(p);
    d = min(d, sdSphere(p - vec3(0.0, 0.25, 0.0), 0.25)); // find surface compare 
    return d;
}

vec3 calcNormal(in vec3 p) {
    // calculate all surface`s normal
    vec3 e = vec3(0.001, 0.0, 0.0);
    vec3 nor = vec3(
        map(p + e.xyy) - map(p - e.xyy),
        map(p + e.yxy) - map(p - e.yxy),
        map(p + e.yyx) - map(p - e.yyx)
    );
    return normalize(nor);
}

float castRay(in vec3 cameraPosition, in vec3 renderVector, in float maxt) {
    // find surface
    float precis = 0.001;
    float h = precis * 2.0;
    float t = 0.0;
    for(int i = 0; i < 60; i++) {
        if(abs(h) < precis || t > maxt) continue;
        h = map(cameraPosition + renderVector * t);
        t += h;
    }
    return t;
}

float softshadow(in vec3 cameraPosition, in vec3 renderVector, in float mint, in float maxt, in float k) {
    float sh = 1.0;
    float t = mint;
    float h = 0.0;
    for(int i = 0; i < 30; i++) {
        if(t > maxt) continue;
        h = map(cameraPosition + renderVector * t);
        sh = min(sh, k * h / t);
        t += h;
    }
    return sh;
}

vec3 render(in vec3 cameraPosition, in vec3 renderVector) {
    vec3 col = vec3(1.0);
    float distanceFromCamera = castRay(cameraPosition, renderVector, 20.0); // distance camera to target
    vec3 pos = cameraPosition + renderVector * distanceFromCamera; //surface`s point?
    vec3 nor = calcNormal(pos); // calculate all surface`s normal
    vec3 lig = normalize(vec3(-0.4, 0.7, 0.5)); // light`s vector
    float dif = clamp(dot(lig, nor), 0.0, 1.0); // light`s strenght -> color
    float spec = pow(clamp(dot(reflect(renderVector, nor), lig), 0.0, 1.0), 16.0);
    float sh = softshadow(pos, lig, 0.02, 20.0, 7.0);
    col = col * (dif + spec) * sh;
    return col;
}

void main() {
    vec2 uv = gl_FragCoord.xy / resolution.xy;
    vec2 p = uv * 2.0 - 1.0;
    p.x *= resolution.x / resolution.y;
    // vec3 cameraPosition = vec3(1.0, 1.0, 3.0); //camera ray origin
    vec3 cameraPosition = vec3( mouse.x*4.0, 1.0, 3.0); //camera ray origin
    vec3 targetOrigin = vec3(0.0, 0.0, 0.0); //target
    vec3 eyeToTarget = normalize(targetOrigin - cameraPosition); //eye to target vector
    vec3 upVector = vec3(0.0, 1.0, 0.0); //up vector
    vec3 targetUpVector = normalize(cross(eyeToTarget, upVector)); // target`s right coorenderVector 
    vec3 targetRightVector = normalize(cross(targetUpVector, eyeToTarget)); // target`s up coorenderVector  
    vec3 renderVector = normalize(p.x * targetUpVector + p.y * targetRightVector + mouse.y*2.5 * eyeToTarget); //viewer`s vector
    vec3 col = render(cameraPosition, renderVector);
    
    gl_FragColor = vec4(col, 1.0);
}
Tags : #shader

2014-08-23_08-23-53

Sublime Text를 쓰다보면 이런 에러가 뜰때가 가끔 있는데, 파일 인코딩이 UTF-8이 아닌 다른 것(위의 상황에서는 GBK)으로 되어 있을 때 한글을 입력하고 저장하려고 할 때 생기는 에러다. 인코딩을 UTF-8로 바꾸고 저장하면 해결이 되는 부분인데, 그 전에 position 9997을 어떻게 찾는지 궁금해서 찾아보았더니, 파이썬 코드로 간단히 몇줄을 넣으면 표시가 된단다.

파일 이름은 아무것이나 좋고 (Preferences > Browse Packages > User)에다 확장자를 py로 저장하면 Sublime Text의 좌측 하단에 바로 표시가 된다.

2014-08-23_08-37-02

import sublime, sublime_plugin

class PositionListener(sublime_plugin.EventListener):
  def on_selection_modified(self,view):
    text = "Position: "
    sels = view.sel()
    for s in sels:
        text += " " + str(s.begin())
        if not s.empty():
            text += "-" + str(s.end()) + " "
    view.set_status('exact_pos', text)

출처 : http://stackoverflow.com/questions/12943594/is-it-possible-to-show-the-exact-position-in-sublime-text-2

Tags : #sublime text

GLSL Heroku의 셰이더 모음
계속 업데이트 예정

http://glsl.heroku.com/e#19224.0

039f49f29b201d6ea672de862d798c14

#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

float rand(vec2 v){
    return fract(sin(dot(v.xy,vec2(33.9898,78.233))) * 43758.56);
}
void main( void ) {

    vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / resolution.y ;
    float c = 0.0;
    for(int i = 0; i < 30; i++){
        float f = float(i);
        p += 
        c += max(0.5 - length(vec2(rand(vec2(f, 1.0)), rand(vec2(-1.0, f))) * 2.0 - 1.0 - p), 0.0);
    }
    gl_FragColor = vec4(vec3(smoothstep(0.1, 0.6, c), smoothstep(0.4, 1.0, c), smoothstep(0.8, 1.0, c)), 1.0 );

}

http://glsl.heroku.com/e#19097.0

2014-08-23_02-01-15

#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

void main(void)
{
    vec2 uv = -1.0 + 2.0*gl_FragCoord.xy / resolution.xy;
    uv.x *=  resolution.x / resolution.y;

    // background    
    vec3 color = vec3(0.8 + 0.2*uv.y);

    // bubbles  
    for( int i=0; i<20; i++ )
    {
        // bubble seeds
        float pha =      sin(float(i)*546.13+1.0)*0.5 + 0.5;
        float siz = pow( sin(float(i)*651.74+5.0)*0.5 + 0.5, 4.0 );
        float pox =      sin(float(i)*321.55+4.1) * resolution.x / resolution.y;

        // buble size, position and color
        float rad = 0.1 + 0.5*siz;
        vec2  pos = vec2( pox, -1.0-rad + (2.0+2.0*rad)*mod(pha+0.1*time*(0.2+0.8*siz),1.0));
        float dis = length( uv - pos );
        vec3  col = mix( vec3(0.94,0.3,0.0), vec3(0.1,0.4,0.8), 0.5+0.5*sin(float(i)*1.2+1.9));

        // render
        float f = length(uv-pos)/rad;
        f = sqrt(clamp(1.0-f*f,0.0,1.0));
        color -= col.zyx *(1.0-smoothstep( rad*0.95, rad, dis )) * f;
    }

    // vigneting    
    color *= sqrt(1.5-0.5*length(uv));

    gl_FragColor = vec4(color,1.0);
}

http://glsl.heroku.com/e#19318.0

3e8d4eb6e8695484044984ff6daa58b6

#ifdef GL_ES
precision mediump float;
#endif

#define STEPS 50
#define LIGHTPASSES 8
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

vec2 c = vec2(0.5,0.5*resolution.y/resolution.x);
vec3 wallColor = vec3(1.,1.,1.);

/*by Olivier de Schaetzen (citiral)
haven't really seen anything like this before, so either I don't check enough shaders or I might have made something original once ;)
*/

//random function not by me, found it somewhere on the internet!
float rand(vec2 n)
{
  return 1. * 
     fract(sin(dot(n.xy, vec2(12.898, 78.33)))* 43758.5453);
}

vec3 getColor(vec2 p)
{   
    //if (p.x >= 0.1 && p.x <= 0.19 && p.y >= 0.1 && p.y <= 0.19) {
    //  return wallColor;
    //}

    vec2 pp = p;
    vec2 ppp = p;

    p.x += sin(time*10.)*0.04;
    p.y += cos(time*10.)*0.04;
    if (length(p-c) <= 0.01) {
        return wallColor;   
    }

    pp.x += cos(time*5.)*0.08;
    pp.y += sin(time*5.)*0.08;
    if (length(pp-c) <= 0.02) {
        return wallColor;   
    }

    ppp.x += sin(time*2.5)*0.15;
    ppp.y += cos(time*2.5)*0.15;
    if (length(ppp-c) <= 0.02) {
        return wallColor;   
    }

    return vec3(0.3,0.3,0.3);
}

vec3 getLighting(vec2 p, vec2 lp)
{
    vec2 sp = p;
    vec2 v = (lp-p)/float(STEPS);

    for (int i = 0 ; i < STEPS ; i++) {
        if (getColor(sp) == wallColor) {
            return length(p-lp)/vec3(1.,1.,1.) + 1./length(p-lp)*0.075*vec3(1.0,0.5*(sin(time)+0.1),0.7);
        }
        sp += v;
    }

    return vec3(1.0,1.0,1.0)+1./length(p-lp)*0.075*vec3(1.0,0.5*(sin(time)+1.),0.6);
}

vec3 blendLighting(vec2 p, vec2 lp)
{   
    vec2 r;
    vec3 c = vec3(0.,0.,0.);

    for (int i = 1 ; i <= LIGHTPASSES ; i++) {
        r = vec2(rand(sin(time*float(i))+p.xy)*0.03-0.015,rand(cos(time*float(i))+p.yx)*0.03-0.015);
        c += getLighting(p,lp+r)/float(LIGHTPASSES);
    }

    return c;
}

void main( void ) {

    vec2 p = gl_FragCoord.xy/resolution.xy;
    vec2 lp = mouse.xy;
    p.y *= resolution.y/resolution.x;
    lp.y *= resolution.y/resolution.x;  

    gl_FragColor = vec4(getColor(p)*blendLighting(p,lp),1.);
}

http://glsl.heroku.com/e#18740.0

4002d4389cee443f4e443f75cb10c4bb

#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

float noise(vec3 p) //Thx to Las^Mercury
{
    vec3 i = floor(p);
    vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
    vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
    a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
    a.xy = mix(a.xz, a.yw, f.y);
    return mix(a.x, a.y, f.z);
}

float sphere(vec3 p, vec4 spr)
{
    return length(spr.xyz-p) - spr.w;
}

float flame(vec3 p)
{
    float d = sphere(p*vec3(1.,.5,1.), vec4(.0,-1.,.0,1.));
    return d + (noise(p+vec3(.0,time*2.,.0)) + noise(p*3.)*.5)*.25*(p.y) ;
}

float scene(vec3 p)
{
    return min(100.-length(p) , abs(flame(p)) );
}

vec4 raymarch(vec3 org, vec3 dir)
{
    float d = 0.0, glow = 0.0, eps = 0.02;
    vec3  p = org;
    bool glowed = false;

    for(int i=0; i<64; i++)
    {
        d = scene(p) + eps;
        p += d * dir;
        if( d>eps )
        {
            if(flame(p) < .0)
                glowed=true;
            if(glowed)
                glow = float(i)/64.;
        }
    }
    return vec4(p,glow);
}

void main()
{
    vec2 v = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
    v.x *= resolution.x/resolution.y;

    vec3 org = vec3(0., -2., 4.);
    vec3 dir = normalize(vec3(v.x*1.6, -v.y, -1.5));

    vec4 p = raymarch(org, dir);
    float glow = p.w;

    vec4 col = mix(vec4(1.,.5,.1,1.), vec4(0.1,.5,1.,1.), p.y*.02+.4);

    gl_FragColor = mix(vec4(0.), col, pow(glow*2.,4.));
    //gl_FragColor = mix(vec4(1.), mix(vec4(1.,.5,.1,1.),vec4(0.1,.5,1.,1.),p.y*.02+.4), pow(glow*2.,4.));

}

http://glsl.heroku.com/e#9824.11

2014-08-23_11-11-20

// water turbulence effect by @joltz0r 2013-07-04, improved 2013-07-07

// let the fluidity flow in psychedelic --@joltz0r
#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
varying vec2 surfacePosition;

#define MAX_ITER 32
void main( void ) {

    vec2 p = surfacePosition*4.0;
    vec2 i = p;
    float c = 0.0;
    float inten = 1.0;

    for (int n = 0; n < MAX_ITER; n++) {
        float t = time * (1.0 - (1.0 / float(n+1)));
        i = (p + vec2(
            cos(t - i.x) + sin(t + i.y), 
            sin(t - i.y) + cos(t + i.x)
        )) - (i - (1.0 / vec2(n+1)));
        c += 1.0/length((p*i) / vec2(
            sin(i.x + t)/inten,
            cos(i.y + t)/inten
            )
        );
    }
    c /= float(MAX_ITER);

    gl_FragColor = vec4(vec3(c)*vec3(0.95, 0.97, 1.8), 1.0);
}

http://glsl.heroku.com/e#18182.0

2014-08-24_16-52-51

#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 resolution;

void main()
{

    vec2 uv = (gl_FragCoord.xy/resolution.xy)-.5;

    float time = time * .1 + ((.25+.05*sin(time*.1))/(length(uv.xy)+.07))* 2.2;
    float si = sin(time);
    float co = cos(time);
    mat2 ma = mat2(co, si, -si, co);

    float c = 0.0;
    float v1 = 0.0;
    float v2 = 0.0;

    for (int i = 0; i < 100; i++)
    {
        float s = float(i) * .035;
        vec3 p = s * vec3(uv, 0.0);
        p.xy *= ma;
        p += vec3(.22,.3, s-1.5-sin(time*.13)*.1);
        for (int i = 0; i < 8; i++)
        {
            p = abs(p) / dot(p,p) - 0.659;
        }
        v1 += dot(p,p)*.0015 * (1.8+sin(length(uv.xy*13.0)+.5-time*.2));
        v2 += dot(p,p)*.0015 * (1.5+sin(length(uv.xy*13.5)+2.2-time*.3));
        c = length(p.xy*.5) * .35;
    }

    float len = length(uv);
    v1 *= smoothstep(.7, .0, len);
    v2 *= smoothstep(.6, .0, len);

    float re = clamp(c, 0.0, 1.0);
    float gr = clamp((v1+c)*.25, 0.0, 1.0);
    float bl = clamp(v2, 0.0, 1.0);
    vec3 col = vec3(re, gr, bl) + smoothstep(0.15, .0, len) * .9;

    gl_FragColor=vec4(col, 1.0);
}

http://glsl.heroku.com/e#19082.0

2014-08-27_16-31-17 2

// Blank Slate - Work in progress @P_Malin

// added pan/zoom - hard work stolen from other shaders, thanks @emackey

#ifdef GL_ES
precision highp float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

// somehow these enable pan/zoom controls (using magic)
uniform vec2 surfaceSize;
varying vec2 surfacePosition;

float kPI = acos(0.0);
float kHalfPi = asin(1.0);
float kTwoPI = kPI * 2.0;
/*
float cos(float v) // workaround for AMD Radeon on OS X
{ 
    return sin(v+kHalfPi);
}
*/

//#define ENABLE_MONTE_CARLO
#define ENABLE_REFLECTIONS
#define ENABLE_FOG
#define ENABLE_SPECULAR
#define ENABLE_POINT_LIGHT
#define ENABLE_POINT_LIGHT_FLARE

#ifdef ENABLE_MONTE_CARLO
vec4 gPixelRandom;
vec3 gRandomNormal;

void CalcPixelRandom()
{
    // Nothing special here, just numbers generated by bashing keyboard
    vec4 s1 = sin(time * 3.3422 + gl_FragCoord.xxxx * vec4(324.324234, 563.324234, 657.324234, 764.324234)) * 543.3423;
    vec4 s2 = sin(time * 1.3422 + gl_FragCoord.yyyy * vec4(567.324234, 435.324234, 432.324234, 657.324234)) * 654.5423;
    gPixelRandom = fract(2142.4 + s1 + s2);
    gRandomNormal = normalize( gPixelRandom.xyz - 0.5);
}
#endif

struct C_Ray
{
    vec3 vOrigin;
    vec3 vDir;
};

struct C_HitInfo
{
    vec3 vPos;
    float fDistance;
    vec3 vObjectId;
};

struct C_Material
{
    vec3 cAlbedo;
    float fR0;
    float fSmoothness;
    vec2 vParam;
};

vec3 RotateX( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( vPos.x, c * vPos.y + s * vPos.z, -s * vPos.y + c * vPos.z);

    return vResult;
}

vec3 RotateY( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.z, vPos.y, -s * vPos.x + c * vPos.z);

    return vResult;
}

vec3 RotateZ( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.y, -s * vPos.x + c * vPos.y, vPos.z);

    return vResult;
}

vec4 DistCombineUnion( const in vec4 v1, const in vec4 v2 )
{
    //if(v1.x < v2.x) return v1; else return v2;
    return mix(v1, v2, step(v2.x, v1.x));
}

vec4 DistCombineIntersect( const in vec4 v1, const in vec4 v2 )
{
    return mix(v2, v1, step(v2.x,v1.x));
}

vec4 DistCombineSubtract( const in vec4 v1, const in vec4 v2 )
{
    return DistCombineIntersect(v1, vec4(-v2.x, v2.yzw));
}

vec3 DomainRepeatXZGetTile( const in vec3 vPos, const in vec2 vRepeat, out vec2 vTile )
{
    vec3 vResult = vPos;
    vec2 vTilePos = (vPos.xz / vRepeat) + 0.5;
    vTile = floor(vTilePos + 1000.0);
    vResult.xz = (fract(vTilePos) - 0.5) * vRepeat;
    return vResult;
}

vec3 DomainRepeatXZ( const in vec3 vPos, const in vec2 vRepeat )
{
    vec3 vResult = vPos;
    vec2 vTilePos = (vPos.xz / vRepeat) + 0.5;
    vResult.xz = (fract(vTilePos) - 0.5) * vRepeat;
    return vResult;
}

vec3 DomainRepeatY( const in vec3 vPos, const in float fSize )
{
    vec3 vResult = vPos;
    vResult.y = (fract(vPos.y / fSize + 0.5) - 0.5) * fSize;
    return vResult;
}

vec3 DomainRotateSymmetry( const in vec3 vPos, const in float fSteps )
{
    float angle = atan( vPos.x, vPos.z );

    float fScale = fSteps / (kTwoPI);
    float steppedAngle = (floor(angle * fScale + 0.5)) / fScale;

    float s = sin(-steppedAngle);
    float c = cos(-steppedAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.z,
                 vPos.y,
                -s * vPos.x + c * vPos.z);

    return vResult;
}

float GetDistanceXYTorus( const in vec3 p, const in float r1, const in float r2 )
{
    vec2 q = vec2(length(p.xy)-r1,p.z);
    return length(q)-r2;
}
float GetDistanceYZTorus( const in vec3 p, const in float r1, const in float r2 )
{
    vec2 q = vec2(length(p.yz)-r1,p.x);
    return length(q)-r2;
}
float GetDistanceCylinderY(const in vec3 vPos, const in float r)
{
    return length(vPos.xz) - r;
}
float GetDistanceBox( const in vec3 vPos, const in vec3 vSize )
{
    vec3 vDist = (abs(vPos) - vSize);
    return max(vDist.x, max(vDist.y, vDist.z));
}

float GetDistanceRoundedBox( const in vec3 vPos, const in vec3 vSize, float fRadius )
{
    vec3 vClosest = max(min(vPos, vSize), -vSize);
    return length(vClosest - vPos) - fRadius;
}

// result is x=scene distance y=material or object id; zw are material specific parameters (maybe uv co-ordinates)
vec4 GetDistanceScene( const in vec3 vPos )
{          
    vec4 vResult = vec4(10000.0, -1.0, 0.0, 0.0);

    vec3 vSphereDomain = DomainRepeatXZ(vPos, vec2(5.0, 5.0));

    vec4 vDistSphere = vec4( length(vSphereDomain) - 1.0, 2.0, vSphereDomain.xy);

    vResult = DistCombineUnion(vResult, vDistSphere);

    vec4 vDistFloor = vec4(vPos.y + 1.0, 1.0, vPos.xz);
    vResult = DistCombineUnion(vResult, vDistFloor);

    return vResult;
}

C_Material GetObjectMaterial( const in vec3 vObjId, const in vec3 vPos )
{
    C_Material mat;

    if(vObjId.x < 1.5)
    {
        // floor
        mat.fR0 = 0.1;
        mat.fSmoothness = 0.01;
        mat.cAlbedo = vec3(0, 0, 0);
    }
    else
    if(vObjId.x < 2.5)
    {
        // sphere
        mat.fR0 = 0.05;
        mat.fSmoothness = 0.9;
        mat.cAlbedo = vec3(1, 1, 1);
    }

    return mat;
}
vec3 GetSkyGradient( const in vec3 vDir )
{
    float fBlend = vDir.y * 0.5 + 0.5;
    return mix(vec3(0.0, 0.0, 0.0), vec3(0.4, 0.9, 1.0), fBlend);
}
vec3 GetLightPos()
{
    vec3 vLightPos = vec3(0.0, 1.0, 3.0);
    #ifdef ENABLE_MONTE_CARLO        
    vLightPos += gRandomNormal * 0.2;
    #endif
    return vLightPos;
}
vec3 GetLightCol()
{
    return vec3(14.0, 14.0, 10.0) * 10.0;
}

vec3 GetAmbientLight(const in vec3 vNormal)
{
    return GetSkyGradient(vNormal);
}

#define kFogDensity 0.1
void ApplyAtmosphere(inout vec3 col, const in C_Ray ray, const in C_HitInfo intersection)
{
    #ifdef ENABLE_FOG
    // fog
    float fFogAmount = exp(intersection.fDistance * -kFogDensity);
    vec3 cFog = GetSkyGradient(ray.vDir);
    col = mix(cFog, col, fFogAmount);
    #endif

    // glare from light (a bit hacky - use length of closest approach from ray to light)
    #ifdef ENABLE_POINT_LIGHT_FLARE
    vec3 vToLight = GetLightPos() - ray.vOrigin;
    float fDot = dot(vToLight, ray.vDir);
    fDot = clamp(fDot, 0.0, intersection.fDistance);

    vec3 vClosestPoint = ray.vOrigin + ray.vDir * fDot;
    float fDist = length(vClosestPoint - GetLightPos());
    col += GetLightCol() * 0.01/ (fDist * fDist);
    #endif     
}
vec3 GetSceneNormal( const in vec3 vPos )
{
    // tetrahedron normal
    float fDelta = 0.025;

    vec3 vOffset1 = vec3( fDelta, -fDelta, -fDelta);
    vec3 vOffset2 = vec3(-fDelta, -fDelta,  fDelta);
    vec3 vOffset3 = vec3(-fDelta,  fDelta, -fDelta);
    vec3 vOffset4 = vec3( fDelta,  fDelta,  fDelta);

    float f1 = GetDistanceScene( vPos + vOffset1 ).x;
    float f2 = GetDistanceScene( vPos + vOffset2 ).x;
    float f3 = GetDistanceScene( vPos + vOffset3 ).x;
    float f4 = GetDistanceScene( vPos + vOffset4 ).x;

    vec3 vNormal = vOffset1 * f1 + vOffset2 * f2 + vOffset3 * f3 + vOffset4 * f4;

    return normalize( vNormal );
}

#define kRaymarchEpsilon 0.01
#define kRaymarchMatIter 256
#define kRaymarchStartDistance 0.1
// This is an excellent resource on ray marching -> http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
void Raymarch( const in C_Ray ray, out C_HitInfo result, const float fMaxDist, const int maxIter )
{         
    result.fDistance = kRaymarchStartDistance;
    result.vObjectId.x = 0.0;

    for(int i=0;i<=kRaymarchMatIter;i++)               
    {
        result.vPos = ray.vOrigin + ray.vDir * result.fDistance;
        vec4 vSceneDist = GetDistanceScene( result.vPos );
        result.vObjectId = vSceneDist.yzw;

        // abs allows backward stepping - should only be necessary for non uniform distance functions
        if((abs(vSceneDist.x) <= kRaymarchEpsilon) || (result.fDistance >= fMaxDist) || (i > maxIter))
        {
            break;
        }                         

        result.fDistance = result.fDistance + vSceneDist.x;     
    }

    if(result.fDistance >= fMaxDist)
    {
        result.vPos = ray.vOrigin + ray.vDir * result.fDistance;
        result.vObjectId.x = 0.0;
        result.fDistance = 1000.0;
    }
}

float GetShadow( const in vec3 vPos, const in vec3 vLightDir, const in float fLightDistance )
{
    C_Ray shadowRay;
    shadowRay.vDir = vLightDir;
    shadowRay.vOrigin = vPos;

    C_HitInfo shadowIntersect;
    Raymarch(shadowRay, shadowIntersect, fLightDistance, 32);

    return step(0.0, shadowIntersect.fDistance) * step(fLightDistance, shadowIntersect.fDistance );          
}

// http://en.wikipedia.org/wiki/Schlick's_approximation
float Schlick( const in vec3 vNormal, const in vec3 vView, const in float fR0, const in float fSmoothFactor)
{
    float fDot = dot(vNormal, -vView);
    fDot = min(max((1.0 - fDot), 0.0), 1.0);
    float fDot2 = fDot * fDot;
    float fDot5 = fDot2 * fDot2 * fDot;
    return fR0 + (1.0 - fR0) * fDot5 * fSmoothFactor;
}

float GetDiffuseIntensity(const in vec3 vLightDir, const in vec3 vNormal)
{
    return max(0.0, dot(vLightDir, vNormal));
}

float GetBlinnPhongIntensity(const in C_Ray ray, const in C_Material mat, const in vec3 vLightDir, const in vec3 vNormal)
{           
    vec3 vHalf = normalize(vLightDir - ray.vDir);
    float fNdotH = max(0.0, dot(vHalf, vNormal));

    float fSpecPower = exp2(4.0 + 6.0 * mat.fSmoothness);
    float fSpecIntensity = (fSpecPower + 2.0) * 0.125;

    return pow(fNdotH, fSpecPower) * fSpecIntensity;
}

// use distance field to evaluate ambient occlusion
float GetAmbientOcclusion(const in C_Ray ray, const in C_HitInfo intersection, const in vec3 vNormal)
{
    vec3 vPos = intersection.vPos;

    float fAmbientOcclusion = 1.0;

    float fDist = 0.0;
    for(int i=0; i<=5; i++)
    {
        fDist += 0.1;

        vec4 vSceneDist = GetDistanceScene(vPos + vNormal * fDist);

        fAmbientOcclusion *= 1.0 - max(0.0, (fDist - vSceneDist.x) * 0.2 / fDist );                                   
    }

    return fAmbientOcclusion;
}

vec3 GetObjectLighting(const in C_Ray ray, const in C_HitInfo intersection, const in C_Material material, const in vec3 vNormal, const in vec3 cReflection)
{
    vec3 cScene ;

    vec3 vSpecularReflection = vec3(0.0);
    vec3 vDiffuseReflection = vec3(0.0);

    float fAmbientOcclusion = GetAmbientOcclusion(ray, intersection, vNormal);
    vec3 vAmbientLight = GetAmbientLight(vNormal) * fAmbientOcclusion;

    vDiffuseReflection += vAmbientLight;

    vSpecularReflection += cReflection * fAmbientOcclusion;

    #ifdef ENABLE_POINT_LIGHT
    vec3 vLightPos = GetLightPos();
    vec3 vToLight = vLightPos - intersection.vPos;
    vec3 vLightDir = normalize(vToLight);
    float fLightDistance = length(vToLight);

    float fAttenuation = 1.0 / (fLightDistance * fLightDistance);

    float fShadowBias = 0.1;             
    float fShadowFactor = GetShadow( intersection.vPos + vLightDir * fShadowBias, vLightDir, fLightDistance - fShadowBias );
    vec3 vIncidentLight = GetLightCol() * fShadowFactor * fAttenuation;

    vDiffuseReflection += GetDiffuseIntensity( vLightDir, vNormal ) * vIncidentLight;                                                                                 
    vSpecularReflection += GetBlinnPhongIntensity( ray, material, vLightDir, vNormal ) * vIncidentLight;
    #endif ENABLE_POINT_LIGHT

    vDiffuseReflection *= material.cAlbedo;              

    #ifdef ENABLE_SPECULAR
    float fFresnel = Schlick(vNormal, ray.vDir, material.fR0, material.fSmoothness * 0.9 + 0.1);
    cScene = mix(vDiffuseReflection , vSpecularReflection, fFresnel);
    #else
    cScene = vDiffuseReflection;
    #endif

    return cScene;
}

vec3 GetSceneColourSimple( const in C_Ray ray )
{
    C_HitInfo intersection;
    Raymarch(ray, intersection, 16.0, 32);

    vec3 cScene;

    if(intersection.vObjectId.x < 0.5)
    {
        cScene = GetSkyGradient(ray.vDir);
    }
    else
    {
        C_Material material = GetObjectMaterial(intersection.vObjectId, intersection.vPos);
        vec3 vNormal = GetSceneNormal(intersection.vPos);

        // use sky gradient instead of reflection
        vec3 cReflection = GetSkyGradient(reflect(ray.vDir, vNormal));

        // apply lighting
        cScene = GetObjectLighting(ray, intersection, material, vNormal, cReflection );
    }

    ApplyAtmosphere(cScene, ray, intersection);

    return cScene;
}

vec3 GetSceneColour( const in C_Ray ray )
{                                                           
    C_HitInfo intersection;
    Raymarch(ray, intersection, 30.0, 256);

    vec3 cScene;

    if(intersection.vObjectId.x < 0.5)
    {
        cScene = GetSkyGradient(ray.vDir);
    }
    else
    {
        C_Material material = GetObjectMaterial(intersection.vObjectId, intersection.vPos);
        vec3 vNormal = GetSceneNormal(intersection.vPos);

        #ifdef ENABLE_MONTE_CARLO
        vNormal = normalize(vNormal + gRandomNormal / (5.0 + material.fSmoothness * 200.0));
        #endif

        vec3 cReflection;
        #ifdef ENABLE_REFLECTIONS    
        {
            // get colour from reflected ray
            float fSepration = 0.05;
            C_Ray reflectRay;
            reflectRay.vDir = reflect(ray.vDir, vNormal);
            reflectRay.vOrigin = intersection.vPos + reflectRay.vDir * fSepration;

            cReflection = GetSceneColourSimple(reflectRay);                                                                         
        }
        #else
        cReflection = GetSkyGradient(reflect(ray.vDir, vNormal));                               
        #endif
        // apply lighting
        cScene = GetObjectLighting(ray, intersection, material, vNormal, cReflection );
    }

    ApplyAtmosphere(cScene, ray, intersection);

    return cScene;
}

void GetCameraRay( const in vec3 vPos, const in vec3 vForwards, const in vec3 vWorldUp, out C_Ray ray)
{
    vec2 vPixelCoord = gl_FragCoord.xy;
    #ifdef ENABLE_MONTE_CARLO
    vPixelCoord += gPixelRandom.zw;
    #endif
    vec2 vUV = ( vPixelCoord / resolution.xy );
    vec2 vViewCoord = vUV * 2.0 - 1.0;

    vViewCoord *= 0.75;

    float fRatio = resolution.x / resolution.y;

    vViewCoord.y /= fRatio;                           

    ray.vOrigin = vPos;

    vec3 vRight = normalize(cross(vForwards, vWorldUp));
    vec3 vUp = cross(vRight, vForwards);

    ray.vDir = normalize( vRight * vViewCoord.x + vUp * vViewCoord.y + vForwards);        
}

void GetCameraRayLookat( const in vec3 vPos, const in vec3 vInterest, out C_Ray ray)
{
    vec3 vForwards = normalize(vInterest - vPos);
    vec3 vUp = vec3(0.0, 1.0, 0.0);

    GetCameraRay(vPos, vForwards, vUp, ray);
}

vec3 OrbitPoint( const in float fHeading, const in float fElevation )
{
    return vec3(sin(fHeading) * cos(fElevation), sin(fElevation), cos(fHeading) * cos(fElevation));
}

vec3 Gamma( const in vec3 cCol )
{
    return cCol * cCol;
}

vec3 InvGamma( const in vec3 cCol )
{
    return sqrt(cCol);
}

vec3 Tonemap( const in vec3 cCol )
{
    // simple Reinhard tonemapping operator     
    vec3 vResult = cCol / (1.0 + cCol);

    return Gamma(vResult);
}

vec3 InvTonemap( const in vec3 cCol )
{
    vec3 vResult = cCol;
    vResult = clamp(vResult, 0.01, 0.99);
    vResult = InvGamma(vResult);
    return - (vResult / (vResult - 1.0));
}

void main( void )
{
    #ifdef ENABLE_MONTE_CARLO             
    CalcPixelRandom();
    #endif

    C_Ray ray;

    const float fCamreaInitialHeading = 2.5;
    const float fCamreaInitialElevation = 0.4;
    const float fCamreaInitialDist = 7.0;
    const float fCameraHeight = 0.9;
    const float fOrbitSpeed = 1.0;

    // This magic stolen from other 3d pan/zoom examples
    float fZoom = surfaceSize.y * 0.5 + 0.4;

    vec2 vCenterPosition = (0.5 - ( gl_FragCoord.xy / resolution )) * surfaceSize + surfacePosition;
    float fHeading = vCenterPosition.x * fOrbitSpeed + fCamreaInitialHeading;
    float fElevation = (vCenterPosition.y * fOrbitSpeed + fCamreaInitialElevation);

    vec3 vCameraPos = OrbitPoint(fHeading, fElevation) * fCamreaInitialDist * fZoom;

    vCameraPos += vec3(mouse.x*5., mouse.y*5., 0.0);

    vCameraPos += vec3(0.0, -fCameraHeight, 0.0);
    #ifdef ENABLE_MONTE_CARLO             
    float fDepthOfField = 0.025;
    vCameraPos += gRandomNormal * fDepthOfField;
    #endif

    GetCameraRayLookat( vCameraPos, vec3(0.0, 0.0, 0.0), ray);
    //GetCameraRayLookat(vec3(0.0, 0.0, -5.0), vec3(0.0, 0.0, 0.0), ray);

    vec3 cScene = GetSceneColour( ray );   

    float fExposure = 2.5;
    cScene = cScene * fExposure;

    #ifdef ENABLE_MONTE_CARLO                              
    vec3 cPrev = texture2D(backbuffer, gl_FragCoord.xy / resolution).xyz;
    // add noise to pixel value (helps values converge)
    cPrev += (gPixelRandom.xyz - 0.5) * (1.0 / 255.0);
    cPrev = InvTonemap(cPrev);
    // converge speed
    float fBlend = 0.1;
    vec3 cFinal = mix(cPrev, cScene, fBlend);
    #else
    vec3 cFinal = cScene;
    #endif

    cFinal = Tonemap(cFinal);

    float fAlpha = 1.0;

    gl_FragColor = vec4( cFinal, fAlpha );
}

http://glsl.heroku.com/e#19075.0

2014-08-27_16-31-33 2

// Blank Slate - Work in progress @P_Malin

// added pan/zoom - hard work stolen from other shaders, thanks @emackey

#ifdef GL_ES
precision highp float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

// somehow these enable pan/zoom controls (using magic)
uniform vec2 surfaceSize;
varying vec2 surfacePosition;

float kPI = acos(0.0);
float kHalfPi = asin(1.0);
float kTwoPI = kPI * 2.0;
/*
float cos(float v) // workaround for AMD Radeon on OS X
{ 
    return sin(v+kHalfPi);
}
*/

//#define ENABLE_MONTE_CARLO
#define ENABLE_REFLECTIONS
#define ENABLE_FOG
#define ENABLE_SPECULAR
#define ENABLE_POINT_LIGHT
#define ENABLE_POINT_LIGHT_FLARE

#ifdef ENABLE_MONTE_CARLO
vec4 gPixelRandom;
vec3 gRandomNormal;

void CalcPixelRandom()
{
    // Nothing special here, just numbers generated by bashing keyboard
    vec4 s1 = sin(time * 3.3422 + gl_FragCoord.xxxx * vec4(324.324234, 563.324234, 657.324234, 764.324234)) * 543.3423;
    vec4 s2 = sin(time * 1.3422 + gl_FragCoord.yyyy * vec4(567.324234, 435.324234, 432.324234, 657.324234)) * 654.5423;
    gPixelRandom = fract(2142.4 + s1 + s2);
    gRandomNormal = normalize( gPixelRandom.xyz - 0.5);
}
#endif

struct C_Ray
{
    vec3 vOrigin;
    vec3 vDir;
};

struct C_HitInfo
{
    vec3 vPos;
    float fDistance;
    vec3 vObjectId;
};

struct C_Material
{
    vec3 cAlbedo;
    float fR0;
    float fSmoothness;
    vec2 vParam;
};

vec3 RotateX( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( vPos.x, c * vPos.y + s * vPos.z, -s * vPos.y + c * vPos.z);

    return vResult;
}

vec3 RotateY( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.z, vPos.y, -s * vPos.x + c * vPos.z);

    return vResult;
}

vec3 RotateZ( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle);
    float c = cos(fAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.y, -s * vPos.x + c * vPos.y, vPos.z);

    return vResult;
}

vec4 DistCombineUnion( const in vec4 v1, const in vec4 v2 )
{
    //if(v1.x < v2.x) return v1; else return v2;
    return mix(v1, v2, step(v2.x, v1.x));
}

vec4 DistCombineIntersect( const in vec4 v1, const in vec4 v2 )
{
    return mix(v2, v1, step(v2.x,v1.x));
}

vec4 DistCombineSubtract( const in vec4 v1, const in vec4 v2 )
{
    return DistCombineIntersect(v1, vec4(-v2.x, v2.yzw));
}

vec3 DomainRepeatXZGetTile( const in vec3 vPos, const in vec2 vRepeat, out vec2 vTile )
{
    vec3 vResult = vPos;
    vec2 vTilePos = (vPos.xz / vRepeat) + 0.5;
    vTile = floor(vTilePos + 1000.0);
    vResult.xz = (fract(vTilePos) - 0.5) * vRepeat;
    return vResult;
}

vec3 DomainRepeatXZ( const in vec3 vPos, const in vec2 vRepeat )
{
    vec3 vResult = vPos;
    vec2 vTilePos = (vPos.xz / vRepeat) + 0.5;
    vResult.xz = (fract(vTilePos) - 0.5) * vRepeat;
    return vResult;
}

vec3 DomainRepeatY( const in vec3 vPos, const in float fSize )
{
    vec3 vResult = vPos;
    vResult.y = (fract(vPos.y / fSize + 0.5) - 0.5) * fSize;
    return vResult;
}

vec3 DomainRotateSymmetry( const in vec3 vPos, const in float fSteps )
{
    float angle = atan( vPos.x, vPos.z );

    float fScale = fSteps / (kTwoPI);
    float steppedAngle = (floor(angle * fScale + 0.5)) / fScale;

    float s = sin(-steppedAngle);
    float c = cos(-steppedAngle);

    vec3 vResult = vec3( c * vPos.x + s * vPos.z,
                 vPos.y,
                -s * vPos.x + c * vPos.z);

    return vResult;
}

float GetDistanceXYTorus( const in vec3 p, const in float r1, const in float r2 )
{
    vec2 q = vec2(length(p.xy)-r1,p.z);
    return length(q)-r2;
}
float GetDistanceYZTorus( const in vec3 p, const in float r1, const in float r2 )
{
    vec2 q = vec2(length(p.yz)-r1,p.x);
    return length(q)-r2;
}
float GetDistanceCylinderY(const in vec3 vPos, const in float r)
{
    return length(vPos.xz) - r;
}
float GetDistanceBox( const in vec3 vPos, const in vec3 vSize )
{
    vec3 vDist = (abs(vPos) - vSize);
    return max(vDist.x, max(vDist.y, vDist.z));
}

float GetDistanceRoundedBox( const in vec3 vPos, const in vec3 vSize, float fRadius )
{
    vec3 vClosest = max(min(vPos, vSize), -vSize);
    return length(vClosest - vPos) - fRadius;
}

// result is x=scene distance y=material or object id; zw are material specific parameters (maybe uv co-ordinates)
vec4 GetDistanceScene( const in vec3 vPos )
{          
    vec4 vResult = vec4(10000.0, -1.0, 0.0, 0.0);

    vec3 vSphereDomain = DomainRepeatXZ(vPos, vec2(5.0, 5.0));

    vec4 vDistSphere = vec4( length(vSphereDomain) - 1.0, 2.0, vSphereDomain.xy);

    vResult = DistCombineUnion(vResult, vDistSphere);

    vec4 vDistFloor = vec4(vPos.y + 1.0, 1.0, vPos.xz);
    vResult = DistCombineUnion(vResult, vDistFloor);

    return vResult;
}

C_Material GetObjectMaterial( const in vec3 vObjId, const in vec3 vPos )
{
    C_Material mat;

    if(vObjId.x < 1.5)
    {
        // floor
        mat.fR0 = 0.02;
        mat.fSmoothness = 0.0;
        mat.cAlbedo = vec3(0.7, 0.8, 0.3);
    }
    else
    if(vObjId.x < 2.5)
    {
        // sphere
        mat.fR0 = 0.05;
        mat.fSmoothness = 0.9;
        mat.cAlbedo = vec3(0.05, 0.35, 0.75);
    }

    return mat;
}
vec3 GetSkyGradient( const in vec3 vDir )
{
    float fBlend = vDir.y * 0.5 + 0.5;
    return mix(vec3(0.0, 0.0, 0.0), vec3(0.4, 0.9, 1.0), fBlend);
}
vec3 GetLightPos()
{
    vec3 vLightPos = vec3(0.0, 1.0, 3.0);
    #ifdef ENABLE_MONTE_CARLO        
    vLightPos += gRandomNormal * 0.2;
    #endif
    return vLightPos;
}
vec3 GetLightCol()
{
    return vec3(32.0, 6.0, 1.0) * 10.0;
}

vec3 GetAmbientLight(const in vec3 vNormal)
{
    return GetSkyGradient(vNormal);
}

#define kFogDensity 0.0025
void ApplyAtmosphere(inout vec3 col, const in C_Ray ray, const in C_HitInfo intersection)
{
    #ifdef ENABLE_FOG
    // fog
    float fFogAmount = exp(intersection.fDistance * -kFogDensity);
    vec3 cFog = GetSkyGradient(ray.vDir);
    col = mix(cFog, col, fFogAmount);
    #endif

    // glare from light (a bit hacky - use length of closest approach from ray to light)
    #ifdef ENABLE_POINT_LIGHT_FLARE
    vec3 vToLight = GetLightPos() - ray.vOrigin;
    float fDot = dot(vToLight, ray.vDir);
    fDot = clamp(fDot, 0.0, intersection.fDistance);

    vec3 vClosestPoint = ray.vOrigin + ray.vDir * fDot;
    float fDist = length(vClosestPoint - GetLightPos());
    col += GetLightCol() * 0.01/ (fDist * fDist);
    #endif     
}
vec3 GetSceneNormal( const in vec3 vPos )
{
    // tetrahedron normal
    float fDelta = 0.025;

    vec3 vOffset1 = vec3( fDelta, -fDelta, -fDelta);
    vec3 vOffset2 = vec3(-fDelta, -fDelta,  fDelta);
    vec3 vOffset3 = vec3(-fDelta,  fDelta, -fDelta);
    vec3 vOffset4 = vec3( fDelta,  fDelta,  fDelta);

    float f1 = GetDistanceScene( vPos + vOffset1 ).x;
    float f2 = GetDistanceScene( vPos + vOffset2 ).x;
    float f3 = GetDistanceScene( vPos + vOffset3 ).x;
    float f4 = GetDistanceScene( vPos + vOffset4 ).x;

    vec3 vNormal = vOffset1 * f1 + vOffset2 * f2 + vOffset3 * f3 + vOffset4 * f4;

    return normalize( vNormal );
}

#define kRaymarchEpsilon 0.01
#define kRaymarchMatIter 256
#define kRaymarchStartDistance 0.1
// This is an excellent resource on ray marching -> http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
void Raymarch( const in C_Ray ray, out C_HitInfo result, const float fMaxDist, const int maxIter )
{         
    result.fDistance = kRaymarchStartDistance;
    result.vObjectId.x = 0.0;

    for(int i=0;i<=kRaymarchMatIter;i++)               
    {
        result.vPos = ray.vOrigin + ray.vDir * result.fDistance;
        vec4 vSceneDist = GetDistanceScene( result.vPos );
        result.vObjectId = vSceneDist.yzw;

        // abs allows backward stepping - should only be necessary for non uniform distance functions
        if((abs(vSceneDist.x) <= kRaymarchEpsilon) || (result.fDistance >= fMaxDist) || (i > maxIter))
        {
            break;
        }                         

        result.fDistance = result.fDistance + vSceneDist.x;     
    }

    if(result.fDistance >= fMaxDist)
    {
        result.vPos = ray.vOrigin + ray.vDir * result.fDistance;
        result.vObjectId.x = 0.0;
        result.fDistance = 1000.0;
    }
}

float GetShadow( const in vec3 vPos, const in vec3 vLightDir, const in float fLightDistance )
{
    C_Ray shadowRay;
    shadowRay.vDir = vLightDir;
    shadowRay.vOrigin = vPos;

    C_HitInfo shadowIntersect;
    Raymarch(shadowRay, shadowIntersect, fLightDistance, 32);

    return step(0.0, shadowIntersect.fDistance) * step(fLightDistance, shadowIntersect.fDistance );          
}

// http://en.wikipedia.org/wiki/Schlick's_approximation
float Schlick( const in vec3 vNormal, const in vec3 vView, const in float fR0, const in float fSmoothFactor)
{
    float fDot = dot(vNormal, -vView);
    fDot = min(max((1.0 - fDot), 0.0), 1.0);
    float fDot2 = fDot * fDot;
    float fDot5 = fDot2 * fDot2 * fDot;
    return fR0 + (1.0 - fR0) * fDot5 * fSmoothFactor;
}

float GetDiffuseIntensity(const in vec3 vLightDir, const in vec3 vNormal)
{
    return max(0.0, dot(vLightDir, vNormal));
}

float GetBlinnPhongIntensity(const in C_Ray ray, const in C_Material mat, const in vec3 vLightDir, const in vec3 vNormal)
{           
    vec3 vHalf = normalize(vLightDir - ray.vDir);
    float fNdotH = max(0.0, dot(vHalf, vNormal));

    float fSpecPower = exp2(4.0 + 6.0 * mat.fSmoothness);
    float fSpecIntensity = (fSpecPower + 2.0) * 0.125;

    return pow(fNdotH, fSpecPower) * fSpecIntensity;
}

// use distance field to evaluate ambient occlusion
float GetAmbientOcclusion(const in C_Ray ray, const in C_HitInfo intersection, const in vec3 vNormal)
{
    vec3 vPos = intersection.vPos;

    float fAmbientOcclusion = 1.0;

    float fDist = 0.0;
    for(int i=0; i<=5; i++)
    {
        fDist += 0.1;

        vec4 vSceneDist = GetDistanceScene(vPos + vNormal * fDist);

        fAmbientOcclusion *= 1.0 - max(0.0, (fDist - vSceneDist.x) * 0.2 / fDist );                                   
    }

    return fAmbientOcclusion;
}

vec3 GetObjectLighting(const in C_Ray ray, const in C_HitInfo intersection, const in C_Material material, const in vec3 vNormal, const in vec3 cReflection)
{
    vec3 cScene ;

    vec3 vSpecularReflection = vec3(0.0);
    vec3 vDiffuseReflection = vec3(0.0);

    float fAmbientOcclusion = GetAmbientOcclusion(ray, intersection, vNormal);
    vec3 vAmbientLight = GetAmbientLight(vNormal) * fAmbientOcclusion;

    vDiffuseReflection += vAmbientLight;

    vSpecularReflection += cReflection * fAmbientOcclusion;

    #ifdef ENABLE_POINT_LIGHT
    vec3 vLightPos = GetLightPos();
    vec3 vToLight = vLightPos - intersection.vPos;
    vec3 vLightDir = normalize(vToLight);
    float fLightDistance = length(vToLight);

    float fAttenuation = 1.0 / (fLightDistance * fLightDistance);

    float fShadowBias = 0.1;             
    float fShadowFactor = GetShadow( intersection.vPos + vLightDir * fShadowBias, vLightDir, fLightDistance - fShadowBias );
    vec3 vIncidentLight = GetLightCol() * fShadowFactor * fAttenuation;

    vDiffuseReflection += GetDiffuseIntensity( vLightDir, vNormal ) * vIncidentLight;                                                                                 
    vSpecularReflection += GetBlinnPhongIntensity( ray, material, vLightDir, vNormal ) * vIncidentLight;
    #endif ENABLE_POINT_LIGHT

    vDiffuseReflection *= material.cAlbedo;              

    #ifdef ENABLE_SPECULAR
    float fFresnel = Schlick(vNormal, ray.vDir, material.fR0, material.fSmoothness * 0.9 + 0.1);
    cScene = mix(vDiffuseReflection , vSpecularReflection, fFresnel);
    #else
    cScene = vDiffuseReflection;
    #endif

    return cScene;
}

vec3 GetSceneColourSimple( const in C_Ray ray )
{
    C_HitInfo intersection;
    Raymarch(ray, intersection, 16.0, 32);

    vec3 cScene;

    if(intersection.vObjectId.x < 0.5)
    {
        cScene = GetSkyGradient(ray.vDir);
    }
    else
    {
        C_Material material = GetObjectMaterial(intersection.vObjectId, intersection.vPos);
        vec3 vNormal = GetSceneNormal(intersection.vPos);

        // use sky gradient instead of reflection
        vec3 cReflection = GetSkyGradient(reflect(ray.vDir, vNormal));

        // apply lighting
        cScene = GetObjectLighting(ray, intersection, material, vNormal, cReflection );
    }

    ApplyAtmosphere(cScene, ray, intersection);

    return cScene;
}

vec3 GetSceneColour( const in C_Ray ray )
{                                                           
    C_HitInfo intersection;
    Raymarch(ray, intersection, 30.0, 256);

    vec3 cScene;

    if(intersection.vObjectId.x < 0.5)
    {
        cScene = GetSkyGradient(ray.vDir);
    }
    else
    {
        C_Material material = GetObjectMaterial(intersection.vObjectId, intersection.vPos);
        vec3 vNormal = GetSceneNormal(intersection.vPos);

        #ifdef ENABLE_MONTE_CARLO
        vNormal = normalize(vNormal + gRandomNormal / (5.0 + material.fSmoothness * 200.0));
        #endif

        vec3 cReflection;
        #ifdef ENABLE_REFLECTIONS    
        {
            // get colour from reflected ray
            float fSepration = 0.05;
            C_Ray reflectRay;
            reflectRay.vDir = reflect(ray.vDir, vNormal);
            reflectRay.vOrigin = intersection.vPos + reflectRay.vDir * fSepration;

            cReflection = GetSceneColourSimple(reflectRay);                                                                         
        }
        #else
        cReflection = GetSkyGradient(reflect(ray.vDir, vNormal));                               
        #endif
        // apply lighting
        cScene = GetObjectLighting(ray, intersection, material, vNormal, cReflection );
    }

    ApplyAtmosphere(cScene, ray, intersection);

    return cScene;
}

void GetCameraRay( const in vec3 vPos, const in vec3 vForwards, const in vec3 vWorldUp, out C_Ray ray)
{
    vec2 vPixelCoord = gl_FragCoord.xy;
    #ifdef ENABLE_MONTE_CARLO
    vPixelCoord += gPixelRandom.zw;
    #endif
    vec2 vUV = ( vPixelCoord / resolution.xy );
    vec2 vViewCoord = vUV * 2.0 - 1.0;

    vViewCoord *= 0.75;

    float fRatio = resolution.x / resolution.y;

    vViewCoord.y /= fRatio;                           

    ray.vOrigin = vPos;

    vec3 vRight = normalize(cross(vForwards, vWorldUp));
    vec3 vUp = cross(vRight, vForwards);

    ray.vDir = normalize( vRight * vViewCoord.x + vUp * vViewCoord.y + vForwards);        
}

void GetCameraRayLookat( const in vec3 vPos, const in vec3 vInterest, out C_Ray ray)
{
    vec3 vForwards = normalize(vInterest - vPos);
    vec3 vUp = vec3(0.0, 1.0, 0.0);

    GetCameraRay(vPos, vForwards, vUp, ray);
}

vec3 OrbitPoint( const in float fHeading, const in float fElevation )
{
    return vec3(sin(fHeading) * cos(fElevation), sin(fElevation), cos(fHeading) * cos(fElevation));
}

vec3 Gamma( const in vec3 cCol )
{
    return cCol * cCol;
}

vec3 InvGamma( const in vec3 cCol )
{
    return sqrt(cCol);
}

vec3 Tonemap( const in vec3 cCol )
{
    // simple Reinhard tonemapping operator     
    vec3 vResult = cCol / (1.0 + cCol);

    return Gamma(vResult);
}

vec3 InvTonemap( const in vec3 cCol )
{
    vec3 vResult = cCol;
    vResult = clamp(vResult, 0.01, 0.99);
    vResult = InvGamma(vResult);
    return - (vResult / (vResult - 1.0));
}

void main( void )
{
    #ifdef ENABLE_MONTE_CARLO             
    CalcPixelRandom();
    #endif

    C_Ray ray;

    const float fCamreaInitialHeading = 2.5;
    const float fCamreaInitialElevation = 0.4;
    const float fCamreaInitialDist = 7.0;
    const float fCameraHeight = 0.9;
    const float fOrbitSpeed = 1.0;

    // This magic stolen from other 3d pan/zoom examples
    float fZoom = surfaceSize.y * 0.5 + 0.4;

    vec2 vCenterPosition = (0.5 - ( gl_FragCoord.xy / resolution )) * surfaceSize + surfacePosition;
    float fHeading = vCenterPosition.x * fOrbitSpeed + fCamreaInitialHeading;
    float fElevation = (vCenterPosition.y * fOrbitSpeed + fCamreaInitialElevation);

    vec3 vCameraPos = OrbitPoint(fHeading, fElevation) * fCamreaInitialDist * fZoom;

    vCameraPos += vec3(mouse.x*5., mouse.y*5., 0.0);

    vCameraPos += vec3(0.0, -fCameraHeight, 0.0);
    #ifdef ENABLE_MONTE_CARLO             
    float fDepthOfField = 0.025;
    vCameraPos += gRandomNormal * fDepthOfField;
    #endif

    GetCameraRayLookat( vCameraPos, vec3(0.0, 0.0, 0.0), ray);
    //GetCameraRayLookat(vec3(0.0, 0.0, -5.0), vec3(0.0, 0.0, 0.0), ray);

    vec3 cScene = GetSceneColour( ray );   

    float fExposure = 2.5;
    cScene = cScene * fExposure;

    #ifdef ENABLE_MONTE_CARLO                              
    vec3 cPrev = texture2D(backbuffer, gl_FragCoord.xy / resolution).xyz;
    // add noise to pixel value (helps values converge)
    cPrev += (gPixelRandom.xyz - 0.5) * (1.0 / 255.0);
    cPrev = InvTonemap(cPrev);
    // converge speed
    float fBlend = 0.1;
    vec3 cFinal = mix(cPrev, cScene, fBlend);
    #else
    vec3 cFinal = cScene;
    #endif

    cFinal = Tonemap(cFinal);

    float fAlpha = 1.0;

    gl_FragColor = vec4( cFinal, fAlpha );
}

< http://glsl.heroku.com/e#19432.1 >

2014-08-27_16-44-29

//shader from https://www.shadertoy.com/view/XsfXWH
//I just copied

#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

// ray marching
const int max_iterations = 128;
const float stop_threshold = 0.01;
const float grad_step = 0.05;
const float clip_far = 1000.0;

// math
const float PI = 3.14159265359;
const float DEG_TO_RAD = PI / 180.0;

mat3 roty( float angle ) {
    float c = cos( angle );
    float s = sin( angle );

    return mat3(
        c  , 0.0, -s  ,
        0.0, 1.0, 0.0,
        s  , 0.0, c  
    );
}

mat3 rotzx( vec2 angle ) {
    vec2 c = cos( angle );
    vec2 s = sin( angle );

    return
    mat3(
        c.y, s.y, 0.0,
        -s.y, c.y, 0.0,
        0.0, 0.0, 1.0
    ) *
    mat3(
        1.0, 0.0, 0.0,
        0.0, c.x, s.x ,
        0.0, -s.x, c.x
    );
}

// distance function
float dist_sphere( vec3 pos, float r ) {
    return length( pos ) - r;
}

float dist_box( vec3 pos, vec3 size ) {
    return length( max( abs( pos ) - size, 0.0 ) );
}

float dist_cone( vec3 p, float r, float h )
{
    vec2 c = normalize( vec2( h, r ) );
    float q = length(p.xy);
    return max( dot(c,vec2(q,p.z)), -(p.z + h) );
}

float dist_capsule( vec3 p, vec3 a, vec3 b, float r )
{
    vec3 pa = p - a, ba = b - a;
    float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
    return length( pa - ba*h ) - r;
}

vec2 princess( vec3 p ) {
    p = vec3( p.x,abs(p.y),p.z );

    // hat
    float d0 = dist_cone( roty( radians( 70.0  ) ) * ( p - vec3( -3.4, 0.0, 2.04 ) ), 0.97, 3.3 );
    // skirt
    float d1 = dist_cone( roty( radians( -10.0 ) ) * ( p - vec3( 0.03, 0.0, -0.1 ) ), 1.6, 2.6 );
    // head
    float d2 = dist_sphere( p + vec3( 0.0, 0.0, -0.8 ), 1.0 );
    // neck
    float d3 = dist_capsule( p, vec3( 0.0, 0.0, -0.5 ), vec3( 0.0, 0.0, 1.0 ), 0.18 );
    // legs
    float d4 = dist_capsule( p + vec3( 0.0, -0.4, 0.0 ), vec3( 0.0, 0.0, -4.6 ), vec3( 0.0, 0.0, -2.0 ), 0.15 );
    // feet
    float d5 = dist_cone( roty( -90.0 * DEG_TO_RAD ) * ( p + vec3( -0.53, -0.4, 4.58 ) ), 0.16, 0.5 );

    float g0 = min( min( d0, d1 ), min( d4, d5 ) );

    float d = g0;
    float id = 1.0;

    if ( d > d3 ) { d = d3; id = 0.0; }
    if ( d > d2 ) { d = d2; id = step( 0.2, p.x ); }

    return vec2( d, id );
}

// distance
vec2 dist_field( vec3 p ) {
    return princess( p + vec3( 0.0, 0.0, -0.85 ) );
}

// gradient
vec3 gradient( vec3 pos ) {
    const vec3 dx = vec3( grad_step, 0.0, 0.0 );
    const vec3 dy = vec3( 0.0, grad_step, 0.0 );
    const vec3 dz = vec3( 0.0, 0.0, grad_step );
    return normalize (
        vec3(
            dist_field( pos + dx ).x - dist_field( pos - dx ).x,
            dist_field( pos + dy ).x - dist_field( pos - dy ).x,
            dist_field( pos + dz ).x - dist_field( pos - dz ).x         
        )
    );
}

// ray marching
vec2 ray_marching( vec3 origin, vec3 dir, float start, float end ) {
    float depth = start;
    for ( int i = 0; i < max_iterations; i++ ) {
        vec2 hit = dist_field( origin + dir * depth );
        if ( hit.x < stop_threshold ) {
            return hit;
        }
        depth += hit.x;
        if ( depth >= end) {
            break;
        }
    }
    return vec2( end, -1.0 );
}

// othogonal ray direction
vec3 ray_dir( float fov, vec2 size, vec2 pos ) {
    vec2 xy = pos - size * 0.5;

    float cot_half_fov = tan( ( 90.0 - fov * 0.5 ) * DEG_TO_RAD );  
    float z = size.y * 0.5 * cot_half_fov;

    return normalize( vec3( xy, -z ) );
}

vec3 EvalPixel( vec2 pix ) {
    // default ray dir
    vec3 dir = ray_dir( 45.0, resolution.xy, pix );

    // default ray origin
    vec3 eye = vec3( 0.0, 0.0, 13.0 );

    // rotate camera
    mat3 rot = rotzx( vec2( 70.0 * DEG_TO_RAD, 0.7 * time ) );
    dir = rot * dir;
    eye = rot * eye;

    // ray marching
    vec2 hit = ray_marching( eye, dir, 0.0, clip_far );
    if ( hit.x >= clip_far ) {
        return mix( vec3( 0.0, 0.3, 0.4 ), vec3( 0.17, 0.7, 0.7 ), gl_FragCoord.y / resolution.y );
    }

    // shading
    return vec3( hit.y );
}

void main(void)
{
    vec3 color = vec3( 0.0 );

#if 1
    color += EvalPixel( gl_FragCoord.xy                    );
    color += EvalPixel( gl_FragCoord.xy + vec2( 0.5, 0.0 ) );
    color += EvalPixel( gl_FragCoord.xy + vec2( 0.0, 0.5 ) );
    color += EvalPixel( gl_FragCoord.xy + vec2( 0.5, 0.5 ) );

    color *= 0.25;
#else
    color = EvalPixel( gl_FragCoord.xy );
#endif 

    gl_FragColor = vec4( color, 1.0 );
}
Tags : #shader

How To Track & Display Post Views Count in WordPress Without a Plugin

ID;    
    }
    wpb_set_post_views($post_id);
}
add_action( 'wp_head', 'wpb_track_post_views');

/*********************************CODE-3********************************************
* @Author: Boutros AbiChedid 
* @Date:   January 16, 2012
* @Websites: http://bacsoftwareconsulting.com/ ; http://blueoliveonline.com/
* @Description: Adds a Non-Sortable 'Views' Columnn to the Post Tab in WP dashboard.
* This code requires CODE-1(and CODE-2) as a prerequesite.
* Code is browser and JavaScript independent.
* @Tested on: WordPress version 3.2.1
***********************************************************************************/
 
//Gets the  number of Post Views to be used later.
function get_PostViews($post_ID){
    $count_key = 'wpb_post_views_count';
    //Returns values of the custom field with the specified key from the specified post.
    $count = get_post_meta($post_ID, $count_key, true);
 
    return $count;
}
 
//Function that Adds a 'Views' Column to your Posts tab in WordPress Dashboard.
function post_column_views($newcolumn){
    //Retrieves the translated string, if translation exists, and assign it to the 'default' array.
    $newcolumn['post_views'] = __('Views');
    return $newcolumn;
}
 
//Function that Populates the 'Views' Column with the number of views count.
function post_custom_column_views($column_name, $id){
     
    if($column_name === 'post_views'){
        // Display the Post View Count of the current post.
        // get_the_ID() - Returns the numeric ID of the current post.
        echo get_PostViews(get_the_ID());
    }
}
//Hooks a function to a specific filter action.
//applied to the list of columns to print on the manage posts screen.
add_filter('manage_posts_columns', 'post_column_views');
 
//Hooks a function to a specific action. 
//allows you to add custom columns to the list post/custom post type pages.
//'10' default: specify the function's priority.
//and '2' is the number of the functions' arguments.
add_action('manage_posts_custom_column', 'post_custom_column_views',10,2);
?>

Tags : #wordpress

셰이더 Shader는 무엇인가

Shader 온라인 툴들

Intro to Pixel Shaders in Three.js

Tags : #shader

ssodelta의 첫 포스트
Generating Images from Regular Expressions
http://ssodelta.wordpress.com/2014/03/24/generating-images-from-regular-expressions/
요는 정규식의 방식을 이용해서 프렉탈 이미지를 만들수 있다는것

dln385가 reddit에 올린 그의 버전
img
(reddit:http://www.reddit.com/r/compsci/comments/21f5f0/regex_fractals/)

dln385가 올린 소스코드
http://www.reddit.com/r/compsci/comments/21ife7/regex_fractals_source_code/

dln385는 자바로 구현한것처럼 보이고, 뒤따라 많은 사람들이 시도했다.

Tags : #generative art #regex

actelion_gradient06
vimeo : https://vimeo.com/27495725
이것을 보고 한번 따라해보려고 한 것이 시작이었다. Touchdesigner에서 3D모델을 불러와 버텍스에 점을 찍거나 파티클을 생성하는건 되었는데, 위와같은 모양이 나오지 않아서 생각해보니 위의 이미지는 버텍스와 버텍스 사이에 무수히 많은 점들을 배치한 것이다. 내가 했던 방식들은 버텍스에만 좌표가 있기 때문에 평면은 텅텅 비어버리는 것.
꼭 해내고야 말겠다는 생각으로 찾는중.

8월 20일

Poligon to point cloud Mesh to point cloud whatever…

ROME

[browser-shot width=”300″ url=”http://www.ro.me/tech/”]
와우 이건 정말 멋지다! 

http://www.ro.me/tech/turbulent-point-cloud

shoe1
대박이다!!

Andor Salga

 Andor Salga’s Processing.JS Web IDE

2014-08-20_09-13-34

http://www.chromeexperiments.com/detail/undulating-monkey/

large

POINT CLOUD LIBRARY

이걸 찾았는데 왠지 아닌것 같고…
http://pointclouds.org/documentation/tutorials/walkthrough.php#visualization
이런기능들? 즉, 수집된 포인트클라우드를 이용하거나 메쉬로 바꾸는 등의 일을 하는것 같다..

curve 

[browser-shot width=”300″ url=”https://www.sfdm.scad.edu/faculty/mkesson/vsfx319/wip/best_winter2011/ali_jafargholi/project_5.html”]

8월 21일

나는 계속 구글에서 ‘vertex to point cloud’로 검색을 해 왔는데, ‘scattering on surface’로 찾아보라는 조언을 듣고 찾아봤더니 정말 결과가 나온다.
일단 TD에서는 surface를 scattering하는 방법은 없고, 후디니에서 3D파일을 불러와서 scatter SOP을 이용하거나 Blender를 이용해서 일단 좌표 변환하는 방법이 있다.
블랜더를 사용해본적이 없기 때문에 이번주는 공부를 좀 해봐야할것 같다.

Tags : #idea

워드프레스를 설치할때 계정의 root에 설치하면 상관없지만 다른 폴더가 있을 경우 지저분해 보일 가능성이 있다. 그래서 wordpress라는 폴더에다 설치하곤 하는데 그럴 경우 사이트 주소에

http://example.com/wordpress

처럼 보기 싫게 되는 경우가 있다. 이럴 때

/wordpress부분을 감추려면 어떻게 해야 할까.

우선 관리자의 설정 메뉴에 들어가보면 워드프레스 주소와 사이트 주소가 같이 되어 있을것이다.

ex) http://example.com/wordpress

여기에서 사이트 주소를

http://example.com

로 바꿔준다. 그리고 한가지 중요한 것은 /wordpress에 들어있던 index.php를 /에 복사한 다음 내용을 수정해 주어야 한다.

<?php
/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );

이런식으로 되어있는데.

require( dirname( __FILE__ ) . '/wp-blog-header.php' );

이 부분을 해당 url로 바꾸어준다.
즉 이런식으로.

require( './wordpress/wp-blog-header.php' );
Tags : #wordpress