Skip to content

Instantly share code, notes, and snippets.

@nagadomi
Last active May 6, 2023 20:09
Show Gist options
  • Save nagadomi/beb656d90370e9cd471d1a3be56b8621 to your computer and use it in GitHub Desktop.
Save nagadomi/beb656d90370e9cd471d1a3be56b8621 to your computer and use it in GitHub Desktop.
conversion of eeVR shader to MSL using https://github.com/septag/glslcc
#version 450
layout (location = POSITION) in vec3 aVertexPosition;
layout (location = TEXCOORD0) in vec2 aVertexTextureCoord;
layout (location = TEXCOORD0) out vec2 vTexCoord;
void main() {
vTexCoord = aVertexTextureCoord;
gl_Position = vec4(aVertexPosition, 1);
}
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float2 vTexCoord [[user(locn2)]];
float4 gl_Position [[position]];
};
struct main0_in
{
float2 aVertexTextureCoord [[attribute(0)]];
float3 aVertexPosition [[attribute(1)]];
};
vertex main0_out main0(main0_in in [[stage_in]])
{
main0_out out = {};
out.vTexCoord = in.aVertexTextureCoord;
out.gl_Position = float4(in.aVertexPosition, 1.0);
return out;
}
#version 450
precision mediump float;
#define PI 3.1415926535897932384626
#define FOVFRAC 0.500000
#define SIDEFRAC 0.500000
#define TBFRAC 0.500000
#define HCLIP 3.141593
#define VCLIP 3.141593
#define HMARGIN 0.095877
#define VMARGIN 0.095877
#define EXTRUSION 0.000000
#define INTRUSION 0.000000
const float INVSIDEFRAC = 1 / SIDEFRAC;
const float TBHTEXSCALE = 1 / (TBFRAC - INTRUSION);
const float HTEXSCALE = 1 / (1 + 2 * EXTRUSION + 2 * HMARGIN);
const float VTEXSCALE = 1 / (1 + 2 * EXTRUSION + 2 * VMARGIN);
const float ACTUALHMARGIN = HMARGIN * HTEXSCALE;
const float ACTUALVMARGIN = VMARGIN * VTEXSCALE;
vec2 tr(vec2 src, vec2 offset, vec2 scale)
{
return (src + offset) * scale;
}
vec2 tr(vec2 src, vec2 offset, float scale)
{
return (src + offset) * scale;
}
vec2 tr(vec2 src, float offset, float scale)
{
return tr(src, vec2(offset, offset), scale);
}
vec2 to_uv(float x, float y)
{
return tr(vec2(x, y), 1.0, 0.5);
}
vec2 apply_side_margin(vec2 src)
{
return tr(src, vec2(0, VMARGIN), vec2(1, VTEXSCALE));
}
vec2 to_uv_right(vec3 pt)
{
return apply_side_margin(to_uv(-pt.z/pt.x, pt.y/pt.x) * vec2(INVSIDEFRAC, 1));
}
vec2 to_uv_left(vec3 pt)
{
return apply_side_margin(tr(to_uv(-pt.z/pt.x, -pt.y/pt.x), vec2(SIDEFRAC - 1, 0), vec2(INVSIDEFRAC, 1)));
}
vec2 to_uv_top(vec3 pt)
{
return tr(to_uv(pt.x/pt.y, -pt.z/pt.y), vec2(0, -INTRUSION), vec2(1, TBHTEXSCALE));
}
vec2 to_uv_bottom(vec3 pt)
{
return tr(to_uv(-pt.x/pt.y, -pt.z/pt.y), vec2(0, TBFRAC - 1), vec2(1, TBHTEXSCALE));
}
vec2 apply_margin(vec2 src)
{
return tr(src, vec2(HMARGIN + EXTRUSION, VMARGIN + EXTRUSION), vec2(HTEXSCALE, VTEXSCALE));
}
vec2 to_uv_front(vec3 pt)
{
return apply_margin(to_uv(pt.x/pt.z, pt.y/pt.z));
}
vec2 to_uv_back(vec3 pt)
{
return apply_margin(to_uv(pt.x/pt.z, -pt.y/pt.z));
}
float atan2(in float y, in float x)
{
return x == 0.0 ? sign(y) * 0.5 * PI : atan(y, x);
}
layout (binding = 0) uniform sampler2D cubeLeftImage;
layout (binding = 1) uniform sampler2D cubeRightImage;
layout (binding = 2) uniform sampler2D cubeBottomImage;
layout (binding = 3) uniform sampler2D cubeTopImage;
layout (binding = 4) uniform sampler2D cubeBackImage;
layout (binding = 5) uniform sampler2D cubeFrontImage;
layout (location = TEXCOORD0) in vec2 vTexCoord;
layout (location = COLOR0) out vec4 fragColor;
void main() {
// Calculate the pointing angle
float azimuth = FOVFRAC * PI * vTexCoord.x;
float elevation = 0.5 * PI * vTexCoord.y;
// Calculate the position on unit sphere
vec3 pt;
pt.x = cos(elevation) * sin(azimuth);
pt.y = sin(elevation);
pt.z = cos(elevation) * cos(azimuth);
// Select the correct pixel
// left or right
float lor = step(abs(pt.y), abs(pt.x)) * step(abs(pt.z), abs(pt.x));
// top or bottom
float tob = (1 - lor) * step(abs(pt.z), abs(pt.y));
// front or back
float fob = (1 - lor) * (1 - tob);
float right = step(0, pt.x);
float up = step(0, pt.y);
float front = step(0, pt.z);
float over45 = step(0.25 * PI, abs(azimuth));
float over135 = step(0.75 * PI, abs(azimuth));
{
float angle;
angle = (fob + tob) * (1 - over45) * front * abs(pt.x/pt.z) * 0.25 * PI;
angle += (lor + tob) * over45 * (1 - over135) * right * (2 - pt.z/pt.x) * 0.25 * PI;
angle += (lor + tob) * over45 * (1 - over135) * (1 - right) * (pt.z/pt.x + 2) * 0.25 * PI;
angle += (fob + tob) * over135 * (1 - front) * (4 - abs(pt.x/pt.z)) * 0.25 * PI;
if(angle > HCLIP*0.5) discard;
}
{
float near_horizon = step(abs(pt.y), abs(pt.z));
float angle;
angle = (fob + lor * near_horizon) * abs(pt.y/pt.z) * 0.25 * PI;
angle += (tob + lor * (1 - near_horizon)) * (2 - abs(pt.z/pt.y)) * 0.25 * PI;
if(angle > VCLIP*0.5) discard;
}
vec2 right_uv = to_uv_right(pt);
fragColor += lor * right * texture(cubeRightImage, right_uv);
vec2 left_uv = to_uv_left(pt);
fragColor += lor * (1 - right) * texture(cubeLeftImage, left_uv);
fragColor += tob * up * texture(cubeTopImage, to_uv_top(pt));
fragColor += tob * (1 - up) * texture(cubeBottomImage, to_uv_bottom(pt));
{
vec2 uv = to_uv_front(pt);
fragColor += fob * front * texture(cubeFrontImage, uv);
{
float in_range = step(0, uv.x) * (1 - step(1, uv.x));
float alpha = in_range * front * lor * right * smoothstep(1.0, 0.0, clamp((uv.x - 1 + ACTUALHMARGIN) / ACTUALHMARGIN, 0.0, 1.0));
fragColor = mix(fragColor, texture(cubeFrontImage, uv), alpha);
alpha = in_range * front * lor * (1 - right) * smoothstep(0.0, 1.0, clamp(uv.x / ACTUALHMARGIN, 0.0, 1.0));
fragColor = mix(fragColor, texture(cubeFrontImage, uv), alpha);
}
{
float in_range = step(0, uv.y) * (1 - step(1, uv.y));
float alpha = in_range * front * tob * up * smoothstep(1.0, 0.0, clamp((uv.y - 1 + ACTUALVMARGIN) / ACTUALVMARGIN, 0.0, 1.0));
fragColor = mix(fragColor, texture(cubeFrontImage, uv), alpha);
alpha = in_range * front * tob * (1 - up) * smoothstep(0.0, 1.0, clamp(uv.y / ACTUALVMARGIN, 0.0, 1.0));
fragColor = mix(fragColor, texture(cubeFrontImage, uv), alpha);
}
}
{
float range = over45 * (1 - over135);
float alpha = range * right * tob * up * smoothstep(1.0, 0.0, clamp((right_uv.y - 1 + ACTUALVMARGIN) / ACTUALVMARGIN, 0.0, 1.0));
fragColor = mix(fragColor, texture(cubeRightImage, right_uv), alpha);
alpha = range * right * tob * (1 - up) * smoothstep(0.0, 1.0, clamp(right_uv.y / ACTUALVMARGIN, 0.0, 1.0));
fragColor = mix(fragColor, texture(cubeRightImage, right_uv), alpha);
alpha = range * (1 - right) * tob * up * smoothstep(1.0, 0.0, clamp((left_uv.y - 1 + ACTUALVMARGIN) / ACTUALVMARGIN, 0.0, 1.0));
fragColor = mix(fragColor, texture(cubeLeftImage, left_uv), alpha);
alpha = range * (1 - right) * tob * (1 - up) * smoothstep(0.0, 1.0, clamp(left_uv.y / ACTUALVMARGIN, 0.0, 1.0));
fragColor = mix(fragColor, texture(cubeLeftImage, left_uv), alpha);
}
}
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 fragColor [[color(10)]];
};
struct main0_in
{
float2 vTexCoord [[user(locn2)]];
};
static inline __attribute__((always_inline))
float2 tr(thread const float2& src, thread const float2& offset, thread const float& scale)
{
return (src + offset) * scale;
}
static inline __attribute__((always_inline))
float2 tr(thread const float2& src, thread const float& offset, thread const float& scale)
{
float2 param = src;
float2 param_1 = float2(offset, offset);
float param_2 = scale;
return tr(param, param_1, param_2);
}
static inline __attribute__((always_inline))
float2 to_uv(thread const float& x, thread const float& y)
{
float2 param = float2(x, y);
float param_1 = 1.0;
float param_2 = 0.5;
return tr(param, param_1, param_2);
}
static inline __attribute__((always_inline))
float2 tr(thread const float2& src, thread const float2& offset, thread const float2& scale)
{
return (src + offset) * scale;
}
static inline __attribute__((always_inline))
float2 apply_side_margin(thread const float2& src)
{
float2 param = src;
float2 param_1 = float2(0.0, 0.095876999199390411376953125);
float2 param_2 = float2(1.0, 0.839099347591400146484375);
return tr(param, param_1, param_2);
}
static inline __attribute__((always_inline))
float2 to_uv_right(thread const float3& pt)
{
float param = (-pt.z) / pt.x;
float param_1 = pt.y / pt.x;
float2 param_2 = to_uv(param, param_1) * float2(2.0, 1.0);
return apply_side_margin(param_2);
}
static inline __attribute__((always_inline))
float2 to_uv_left(thread const float3& pt)
{
float param = (-pt.z) / pt.x;
float param_1 = (-pt.y) / pt.x;
float2 param_2 = to_uv(param, param_1);
float2 param_3 = float2(-0.5, 0.0);
float2 param_4 = float2(2.0, 1.0);
float2 param_5 = tr(param_2, param_3, param_4);
return apply_side_margin(param_5);
}
static inline __attribute__((always_inline))
float2 to_uv_top(thread const float3& pt)
{
float param = pt.x / pt.y;
float param_1 = (-pt.z) / pt.y;
float2 param_2 = to_uv(param, param_1);
float2 param_3 = float2(0.0, -0.0);
float2 param_4 = float2(1.0, 2.0);
return tr(param_2, param_3, param_4);
}
static inline __attribute__((always_inline))
float2 to_uv_bottom(thread const float3& pt)
{
float param = (-pt.x) / pt.y;
float param_1 = (-pt.z) / pt.y;
float2 param_2 = to_uv(param, param_1);
float2 param_3 = float2(0.0, -0.5);
float2 param_4 = float2(1.0, 2.0);
return tr(param_2, param_3, param_4);
}
static inline __attribute__((always_inline))
float2 apply_margin(thread const float2& src)
{
float2 param = src;
float2 param_1 = float2(0.095876999199390411376953125);
float2 param_2 = float2(0.839099347591400146484375);
return tr(param, param_1, param_2);
}
static inline __attribute__((always_inline))
float2 to_uv_front(thread const float3& pt)
{
float param = pt.x / pt.z;
float param_1 = pt.y / pt.z;
float2 param_2 = to_uv(param, param_1);
return apply_margin(param_2);
}
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> cubeRightImage [[texture(0)]], texture2d<float> cubeLeftImage [[texture(1)]], texture2d<float> cubeTopImage [[texture(2)]], texture2d<float> cubeBottomImage [[texture(3)]], texture2d<float> cubeFrontImage [[texture(4)]], sampler cubeRightImageSmplr [[sampler(0)]], sampler cubeLeftImageSmplr [[sampler(1)]], sampler cubeTopImageSmplr [[sampler(2)]], sampler cubeBottomImageSmplr [[sampler(3)]], sampler cubeFrontImageSmplr [[sampler(4)]])
{
main0_out out = {};
float azimuth = 1.57079637050628662109375 * in.vTexCoord.x;
float elevation = 1.57079637050628662109375 * in.vTexCoord.y;
float3 pt;
pt.x = cos(elevation) * sin(azimuth);
pt.y = sin(elevation);
pt.z = cos(elevation) * cos(azimuth);
float lor = step(abs(pt.y), abs(pt.x)) * step(abs(pt.z), abs(pt.x));
float tob = (1.0 - lor) * step(abs(pt.z), abs(pt.y));
float fob = (1.0 - lor) * (1.0 - tob);
float right = step(0.0, pt.x);
float up = step(0.0, pt.y);
float front = step(0.0, pt.z);
float over45 = step(0.785398185253143310546875, abs(azimuth));
float over135 = step(2.35619449615478515625, abs(azimuth));
float angle = (((((fob + tob) * (1.0 - over45)) * front) * abs(pt.x / pt.z)) * 0.25) * 3.1415927410125732421875;
angle += (((((((lor + tob) * over45) * (1.0 - over135)) * right) * (2.0 - (pt.z / pt.x))) * 0.25) * 3.1415927410125732421875);
angle += (((((((lor + tob) * over45) * (1.0 - over135)) * (1.0 - right)) * ((pt.z / pt.x) + 2.0)) * 0.25) * 3.1415927410125732421875);
angle += ((((((fob + tob) * over135) * (1.0 - front)) * (4.0 - abs(pt.x / pt.z))) * 0.25) * 3.1415927410125732421875);
if (angle > 1.570796489715576171875)
{
discard_fragment();
}
float near_horizon = step(abs(pt.y), abs(pt.z));
float angle_1 = (((fob + (lor * near_horizon)) * abs(pt.y / pt.z)) * 0.25) * 3.1415927410125732421875;
angle_1 += ((((tob + (lor * (1.0 - near_horizon))) * (2.0 - abs(pt.z / pt.y))) * 0.25) * 3.1415927410125732421875);
if (angle_1 > 1.570796489715576171875)
{
discard_fragment();
}
float3 param = pt;
float2 right_uv = to_uv_right(param);
out.fragColor += (cubeRightImage.sample(cubeRightImageSmplr, right_uv) * (lor * right));
float3 param_1 = pt;
float2 left_uv = to_uv_left(param_1);
out.fragColor += (cubeLeftImage.sample(cubeLeftImageSmplr, left_uv) * (lor * (1.0 - right)));
float3 param_2 = pt;
out.fragColor += (cubeTopImage.sample(cubeTopImageSmplr, to_uv_top(param_2)) * (tob * up));
float3 param_3 = pt;
out.fragColor += (cubeBottomImage.sample(cubeBottomImageSmplr, to_uv_bottom(param_3)) * (tob * (1.0 - up)));
float3 param_4 = pt;
float2 uv = to_uv_front(param_4);
out.fragColor += (cubeFrontImage.sample(cubeFrontImageSmplr, uv) * (fob * front));
float in_range = step(0.0, uv.x) * (1.0 - step(1.0, uv.x));
float alpha = (((in_range * front) * lor) * right) * smoothstep(1.0, 0.0, fast::clamp(((uv.x - 1.0) + 0.0804503262042999267578125) / 0.0804503262042999267578125, 0.0, 1.0));
out.fragColor = mix(out.fragColor, cubeFrontImage.sample(cubeFrontImageSmplr, uv), float4(alpha));
alpha = (((in_range * front) * lor) * (1.0 - right)) * smoothstep(0.0, 1.0, fast::clamp(uv.x / 0.0804503262042999267578125, 0.0, 1.0));
out.fragColor = mix(out.fragColor, cubeFrontImage.sample(cubeFrontImageSmplr, uv), float4(alpha));
float in_range_1 = step(0.0, uv.y) * (1.0 - step(1.0, uv.y));
float alpha_1 = (((in_range_1 * front) * tob) * up) * smoothstep(1.0, 0.0, fast::clamp(((uv.y - 1.0) + 0.0804503262042999267578125) / 0.0804503262042999267578125, 0.0, 1.0));
out.fragColor = mix(out.fragColor, cubeFrontImage.sample(cubeFrontImageSmplr, uv), float4(alpha_1));
alpha_1 = (((in_range_1 * front) * tob) * (1.0 - up)) * smoothstep(0.0, 1.0, fast::clamp(uv.y / 0.0804503262042999267578125, 0.0, 1.0));
out.fragColor = mix(out.fragColor, cubeFrontImage.sample(cubeFrontImageSmplr, uv), float4(alpha_1));
float range = over45 * (1.0 - over135);
float alpha_2 = (((range * right) * tob) * up) * smoothstep(1.0, 0.0, fast::clamp(((right_uv.y - 1.0) + 0.0804503262042999267578125) / 0.0804503262042999267578125, 0.0, 1.0));
out.fragColor = mix(out.fragColor, cubeRightImage.sample(cubeRightImageSmplr, right_uv), float4(alpha_2));
alpha_2 = (((range * right) * tob) * (1.0 - up)) * smoothstep(0.0, 1.0, fast::clamp(right_uv.y / 0.0804503262042999267578125, 0.0, 1.0));
out.fragColor = mix(out.fragColor, cubeRightImage.sample(cubeRightImageSmplr, right_uv), float4(alpha_2));
alpha_2 = (((range * (1.0 - right)) * tob) * up) * smoothstep(1.0, 0.0, fast::clamp(((left_uv.y - 1.0) + 0.0804503262042999267578125) / 0.0804503262042999267578125, 0.0, 1.0));
out.fragColor = mix(out.fragColor, cubeLeftImage.sample(cubeLeftImageSmplr, left_uv), float4(alpha_2));
alpha_2 = (((range * (1.0 - right)) * tob) * (1.0 - up)) * smoothstep(0.0, 1.0, fast::clamp(left_uv.y / 0.0804503262042999267578125, 0.0, 1.0));
out.fragColor = mix(out.fragColor, cubeLeftImage.sample(cubeLeftImageSmplr, left_uv), float4(alpha_2));
return out;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment