LYGIA Shader Library

raymarch (lygia/lighting/raymarch)

Raymarching template where it needs to define a vec4 raymarchMap( in vec3 pos )

Dependencies:

Use:

<vec4> raymarch(<mat4> viewMatrix, <vec2> st)
<vec4> raymarch(<mat4> viewMatrix, <vec2> st, out <float> eyeDepth)
<vec4> raymarch(<mat4> viewMatrix, <vec2> st, out <float> eyeDepth, out <Material> mat)
<vec4> raymarch(<vec3> cameraPosition, <vec3> lookAt, <vec2> st)
<vec4> raymarch(<vec3> cameraPosition, <vec3> lookAt, <vec2> st, out <float> eyeDepth)
<vec4> raymarch(<vec3> cameraPosition, <vec3> lookAt, <vec2> st, out <float> eyeDepth, out <Material> mat)

Check it on Github



#ifndef RAYMARCH_RENDER_FNC
#define RAYMARCH_RENDER_FNC raymarchDefaultRender
#endif

#ifndef RAYMARCH_VOLUME_RENDER_FNC
#define RAYMARCH_VOLUME_RENDER_FNC raymarchVolume
#endif

#ifndef RAYMARCH_CAMERA_FOV
#define RAYMARCH_CAMERA_FOV 60.0
#endif

#ifndef FNC_RAYMARCH
#define FNC_RAYMARCH

#if defined(RAYMARCH_MULTISAMPLE)
const float RAYMARCH_MULTISAMPLE_FACTOR = 1.0/float(RAYMARCH_MULTISAMPLE);
#endif

vec4 raymarch(mat4 viewMatrix, vec2 st, out float eyeDepth, out Material mat) {

    float fov = 1.0 / tan(RAYMARCH_CAMERA_FOV * DEG2RAD * 0.5);
    vec3 camera = viewMatrix[3].xyz;
    vec3 cameraForward = viewMatrix[2].xyz;
    mat3 viewMatrix3 = toMat3(viewMatrix);

#if defined(RAYMARCH_MULTISAMPLE)

    #if defined(RAYMARCH_AOV)
    Material matAcc;
    materialZero(matAcc);
    #endif

    vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
    eyeDepth = 0.0;

    vec2 pixel = 1.0/RESOLUTION;
    vec2 offset = rotate( vec2(0.5, 0.0), EIGHTH_PI);

    for (int i = 0; i < RAYMARCH_MULTISAMPLE; i++) {
        vec3 rayDirection = viewMatrix3 * normalize(vec3((st + offset * pixel)*2.0-1.0, fov));

        float sampleDepth = 0.0;
        float dist = 0.0;

        vec4 opaque = RAYMARCH_RENDER_FNC(camera, rayDirection, cameraForward, dist, sampleDepth, mat);
        #ifdef RAYMARCH_VOLUME
        color += vec4(RAYMARCH_VOLUME_RENDER_FNC(camera, rayDirection, st, dist, opaque.rgb), opaque.a);
        #else
        color += opaque;
        #endif

        eyeDepth += sampleDepth;

        #if defined(RAYMARCH_AOV)
        materialAdd(matAcc, mat, matAcc);
        #endif

        offset = rotate(offset, HALF_PI);
    }

    eyeDepth *= RAYMARCH_MULTISAMPLE_FACTOR;

    #if defined(RAYMARCH_AOV)  
        materialMultiply(matAcc, RAYMARCH_MULTISAMPLE_FACTOR, mat);
    #endif

    return color * RAYMARCH_MULTISAMPLE_FACTOR;

#else // Single sample

    vec3 rayDirection = viewMatrix3 * normalize(vec3(st*2.0-1.0, fov));
    float dist = 0.0;

    vec4 opaque = RAYMARCH_RENDER_FNC( camera, rayDirection, cameraForward, dist, eyeDepth, mat);
    #ifdef RAYMARCH_VOLUME
        vec4 color = vec4(RAYMARCH_VOLUME_RENDER_FNC(camera, rayDirection, st, dist, opaque.rgb), opaque.a);
    #else
        vec4 color = opaque;
    #endif

    return color;

#endif
}

vec4 raymarch(mat4 viewMatrix, vec2 st, out float eyeDepth) {
    Material mat;
    materialZero(mat);
    return raymarch(viewMatrix, st, eyeDepth, mat);
}

vec4 raymarch(mat4 viewMatrix, vec2 st) {
    float eyeDepth = 0.0;
    return raymarch(viewMatrix, st, eyeDepth);
}

vec4 raymarch(vec3 cameraPosition, vec3 cameraLookAt, vec2 st, out float eyeDepth, out Material mat) {
    mat4 viewMatrix = lookAtView(cameraPosition, cameraLookAt);
    return raymarch(viewMatrix, st, eyeDepth, mat);
}

vec4 raymarch(vec3 cameraPosition, vec3 cameraLookAt, vec2 st, out float eyeDepth) {
    mat4 viewMatrix = lookAtView(cameraPosition, cameraLookAt);
    return raymarch(viewMatrix, st, eyeDepth);
}

vec4 raymarch(vec3 cameraPosition, vec3 cameraLookAt, vec2 st) {
    mat4 viewMatrix = lookAtView(cameraPosition, cameraLookAt);
    return raymarch(viewMatrix, st);
}

#endif

Dependencies:

Use:

<float4> raymarch(<float4x4> viewMatrix, <float2> st)
<float4> raymarch(<float4x4> viewMatrix, <float2> st, out <float> eyeDepth)
<float4> raymarch(<float4x4> viewMatrix, <float2> st, out <float> eyeDepth, out <Material> mat)
<float4> raymarch(<float3> cameraPosition, <float3> lookAt, <float2> st)
<float4> raymarch(<float3> cameraPosition, <float3> lookAt, <float2> st, out <float> eyeDepth)
<float4> raymarch(<float3> cameraPosition, <float3> lookAt, <float2> st, out <float> eyeDepth, out <Material> mat)

Check it on Github



#ifndef RAYMARCH_RENDER_FNC
#define RAYMARCH_RENDER_FNC raymarchDefaultRender
#endif

#ifndef RAYMARCH_VOLUME_RENDER_FNC
#define RAYMARCH_VOLUME_RENDER_FNC raymarchVolume
#endif

#ifndef RESOLUTION
#define RESOLUTION _ScreenParams.xy
#endif

#ifndef RAYMARCH_CAMERA_FOV
#define RAYMARCH_CAMERA_FOV 60.0
#endif

#ifndef FNC_RAYMARCH
#define FNC_RAYMARCH

#if defined(RAYMARCH_MULTISAMPLE)
static const float RAYMARCH_MULTISAMPLE_FACTOR = 1.0/float(RAYMARCH_MULTISAMPLE);
#endif

float4 raymarch(float4x4 viewMatrix, float2 st, out float eyeDepth, out Material mat) {

    float fov = 1.0 / tan(RAYMARCH_CAMERA_FOV * DEG2RAD * 0.5);
    float3 camera = float3(viewMatrix._m03, viewMatrix._m13, viewMatrix._m23);
    float3 cameraForward = float3(viewMatrix._m02, viewMatrix._m12, viewMatrix._m22);

#if defined(RAYMARCH_MULTISAMPLE)

    #if defined(RAYMARCH_AOV)
    Material matAcc;
    materialZero(matAcc);
    #endif

    float4 color = float4(0.0, 0.0, 0.0, 0.0);
    eyeDepth = 0.0;

    float2 pixel = 1.0/RESOLUTION;
    float2 offset = rotate( float2(0.5, 0.0), EIGHTH_PI);

    for (int i = 0; i < RAYMARCH_MULTISAMPLE; i++) {
        float3 rayDirection = mul((float3x3)viewMatrix, normalize(float3((st + offset * pixel)*2.0-1.0, fov)));

        float sampleDepth = 0.0;
        float dist = 0.0;

        float4 opaque = RAYMARCH_RENDER_FNC(camera, rayDirection, cameraForward, dist, sampleDepth, mat);
        #ifdef RAYMARCH_VOLUME
        color += float4(RAYMARCH_VOLUME_RENDER_FNC(camera, rayDirection, st, dist, opaque.rgb), opaque.a);
        #else
        color += opaque;
        #endif

        eyeDepth += sampleDepth;

        #if defined(RAYMARCH_AOV)
            // Accumulate material properties
            materialAdd(matAcc, mat, matAcc);
        #endif

        offset = rotate(offset, HALF_PI);
    }

    eyeDepth *= RAYMARCH_MULTISAMPLE_FACTOR;

    #if defined(RAYMARCH_AOV)
        // Average material
        materialMultiply(matAcc, RAYMARCH_MULTISAMPLE_FACTOR, mat);
    #endif

    return color * RAYMARCH_MULTISAMPLE_FACTOR;

#else // Single sample

    float3 rayDirection = mul((float3x3)viewMatrix, normalize(float3(st * 2.0 - 1.0, fov)));
    float dist = 0.0;

    float4 opaque = RAYMARCH_RENDER_FNC(camera, rayDirection, cameraForward, dist, eyeDepth, mat);
    #ifdef RAYMARCH_VOLUME
        float4 color = float4(RAYMARCH_VOLUME_RENDER_FNC(camera, rayDirection, st, dist, opaque.rgb), opaque.a);
    #else
        float4 color = opaque;
    #endif

    return color;

#endif
}

float4 raymarch(float4x4 viewMatrix, float2 st, out float eyeDepth) {
    Material mat;
    materialZero(mat);
    return raymarch(viewMatrix, st, eyeDepth, mat);
}

float4 raymarch(float4x4 viewMatrix, float2 st) {
    float eyeDepth = 0.0;
    return raymarch(viewMatrix, st, eyeDepth);
}

float4 raymarch(float3 cameraPosition, float3 cameraLookAt, float2 st, out float eyeDepth, out Material mat) {
    float4x4 viewMatrix = lookAtView(cameraPosition, cameraLookAt);
    return raymarch(viewMatrix, st, eyeDepth, mat);
}

float4 raymarch(float3 cameraPosition, float3 cameraLookAt, float2 st, out float eyeDepth) {
    float4x4 viewMatrix = lookAtView(cameraPosition, cameraLookAt);
    return raymarch(viewMatrix, st, eyeDepth);
}

float4 raymarch(float3 cameraPosition, float3 cameraLookAt, float2 st) {
    float4x4 viewMatrix = lookAtView(cameraPosition, cameraLookAt);
    return raymarch(viewMatrix, st);
}

#endif

Examples

Licenses

LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.

Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).

It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.

Get the latest news and releases

Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository