Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pink shaders in Unity 2019. Solution? (Not using a custom pipeline) #17

Open
01GOD opened this issue Aug 22, 2019 · 0 comments
Open

Pink shaders in Unity 2019. Solution? (Not using a custom pipeline) #17

01GOD opened this issue Aug 22, 2019 · 0 comments

Comments

@01GOD
Copy link

01GOD commented Aug 22, 2019

Been trying to convert a shadertoy, but shaderman output a pink shader in Unity. Here is the shader. Thanks in advance for a solution!:
https://www.shadertoy.com/view/llVXRd

// --------------------------------------------------------
// HG_SDF
// https://www.shadertoy.com/view/Xs3GRB
// --------------------------------------------------------

void pR(inout vec2 p, float a) {
p = cos(a)*p + sin(a)*vec2(p.y, -p.x);
}

float pReflect(inout vec3 p, vec3 planeNormal, float offset) {
float t = dot(p, planeNormal)+offset;
if (t < 0.) {
p = p - (2.*t)*planeNormal;
}
return sign(t);
}

float smax(float a, float b, float r) {
float m = max(a, b);
if ((-a < r) && (-b < r)) {
return max(m, -(r - sqrt((r+a)(r+a) + (r+b)(r+b))));
} else {
return m;
}
}

// --------------------------------------------------------
// Icosahedron domain mirroring
// Adapted from knighty https://www.shadertoy.com/view/MsKGzw
// --------------------------------------------------------

#define PI 3.14159265359

vec3 facePlane;
vec3 uPlane;
vec3 vPlane;

int Type=5;
vec3 nc;
vec3 pab;
vec3 pbc;
vec3 pca;

void initIcosahedron() {//setup folding planes and vertex
float cospin=cos(PI/float(Type)), scospin=sqrt(0.75-cospin*cospin);
nc=vec3(-0.5,-cospin,scospin);//3rd folding plane. The two others are xz and yz planes
pbc=vec3(scospin,0.,0.5);//No normalization in order to have 'barycentric' coordinates work evenly
pca=vec3(0.,scospin,cospin);
pbc=normalize(pbc); pca=normalize(pca);//for slightly better DE. In reality it's not necesary to apply normalization :)
pab=vec3(0,0,1);

facePlane = pca;
uPlane = cross(vec3(1,0,0), facePlane);
vPlane = vec3(1,0,0);

}

void pModIcosahedron(inout vec3 p) {
p = abs(p);
pReflect(p, nc, 0.);
p.xy = abs(p.xy);
pReflect(p, nc, 0.);
p.xy = abs(p.xy);
pReflect(p, nc, 0.);
}

// --------------------------------------------------------
// Triangle tiling
// Adapted from mattz https://www.shadertoy.com/view/4d2GzV
// --------------------------------------------------------

const float sqrt3 = 1.7320508075688772;
const float i3 = 0.5773502691896258;

const mat2 cart2hex = mat2(1, 0, i3, 2. * i3);
const mat2 hex2cart = mat2(1, 0, -.5, .5 * sqrt3);

#define PHI (1.618033988749895)
#define TAU 6.283185307179586

struct TriPoints {
vec2 a;
vec2 b;
vec2 c;
vec2 center;
vec2 ab;
vec2 bc;
vec2 ca;
};

TriPoints closestTriPoints(vec2 p) {
vec2 pTri = cart2hex * p;
vec2 pi = floor(pTri);
vec2 pf = fract(pTri);

float split1 = step(pf.y, pf.x);
float split2 = step(pf.x, pf.y);

vec2 a = vec2(split1, 1);
vec2 b = vec2(1, split2);
vec2 c = vec2(0, 0);

a += pi;
b += pi;
c += pi;

a = hex2cart * a;
b = hex2cart * b;
c = hex2cart * c;

vec2 center = (a + b + c) / 3.;

vec2 ab = (a + b) / 2.;
vec2 bc = (b + c) / 2.;
vec2 ca = (c + a) / 2.;

return TriPoints(a, b, c, center, ab, bc, ca);

}

// --------------------------------------------------------
// Geodesic tiling
// --------------------------------------------------------

struct TriPoints3D {
vec3 a;
vec3 b;
vec3 c;
vec3 center;
vec3 ab;
vec3 bc;
vec3 ca;
};

vec3 intersection(vec3 n, vec3 planeNormal, float planeOffset) {
float denominator = dot(planeNormal, n);
float t = (dot(vec3(0), planeNormal ) + planeOffset) / -denominator;
return n * t;
}

//// Edge length of an icosahedron with an inscribed sphere of radius of 1
//float edgeLength = 1. / ((sqrt(3.) / 12.) * (3. + sqrt(5.)));
//// Inner radius of the icosahedron's face
//float faceRadius = (1./6.) * sqrt(3.) * edgeLength;
float faceRadius = 0.3819660112501051;

// 2D coordinates on the icosahedron face
vec2 icosahedronFaceCoordinates(vec3 p) {
vec3 pn = normalize(p);
vec3 i = intersection(pn, facePlane, -1.);
return vec2(dot(i, uPlane), dot(i, vPlane));
}

// Project 2D icosahedron face coordinates onto a sphere
vec3 faceToSphere(vec2 facePoint) {
return normalize(facePlane + (uPlane * facePoint.x) + (vPlane * facePoint.y));
}

TriPoints3D geodesicTriPoints(vec3 p, float subdivisions) {
// Get 2D cartesian coordiantes on that face
vec2 uv = icosahedronFaceCoordinates(p);

// Get points on the nearest triangle tile
float uvScale = subdivisions / faceRadius / 2.;
TriPoints points = closestTriPoints(uv * uvScale);

// Project 2D triangle coordinates onto a sphere 
vec3 a = faceToSphere(points.a / uvScale);
vec3 b = faceToSphere(points.b / uvScale);
vec3 c = faceToSphere(points.c / uvScale);
vec3 center = faceToSphere(points.center / uvScale);
vec3 ab = faceToSphere(points.ab / uvScale);
vec3 bc = faceToSphere(points.bc / uvScale);
vec3 ca = faceToSphere(points.ca / uvScale);

return TriPoints3D(a, b, c, center, ab, bc, ca);

}

// --------------------------------------------------------
// Spectrum colour palette
// IQ https://www.shadertoy.com/view/ll2GD3
// --------------------------------------------------------

vec3 pal( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d ) {
return a + bcos( 6.28318(c*t+d) );
}

vec3 spectrum(float n) {
return pal( n, vec3(0.5,0.5,0.5),vec3(0.5,0.5,0.5),vec3(1.0,1.0,1.0),vec3(0.0,0.33,0.67) );
}

// --------------------------------------------------------
// Model/Camera Rotation
// --------------------------------------------------------

mat3 sphericalMatrix(float theta, float phi) {
float cx = cos(theta);
float cy = cos(phi);
float sx = sin(theta);
float sy = sin(phi);
return mat3(
cy, -sy * -sx, -sy * cx,
0, cx, sx,
sy, cy * -sx, cy * cx
);
}

mat3 mouseRotation(bool enable, vec2 xy) {
if (enable) {
vec2 mouse = iMouse.xy / iResolution.xy;

    if (mouse.x != 0. && mouse.y != 0.) {
        xy.x = mouse.x;
        xy.y = mouse.y;
    }
}
float rx, ry;

rx = (xy.y + .5) * PI;
ry = (-xy.x) * 2. * PI;

return sphericalMatrix(rx, ry);

}

mat3 modelRotation() {
mat3 m = mouseRotation(MOUSE_CONTROL==1, MODEL_ROTATION);
return m;
}

mat3 cameraRotation() {
mat3 m = mouseRotation(MOUSE_CONTROL==2, CAMERA_ROTATION);
return m;
}

// --------------------------------------------------------
// Animation
// --------------------------------------------------------

const float SCENE_DURATION = 6.;
const float CROSSFADE_DURATION = 2.;

float time;

struct HexSpec {
float roundTop;
float roundCorner;
float height;
float thickness;
float gap;
};

HexSpec newHexSpec(float subdivisions) {
return HexSpec(
.05 / subdivisions,
.1 / subdivisions,
2.,
2.,
.005
);
}

// Animation 1

float animSubdivisions1() {
return mix(2.4, 3.4, cos(time * PI) * .5 + .5);
}

HexSpec animHex1(vec3 hexCenter, float subdivisions) {
HexSpec spec = newHexSpec(subdivisions);

float offset = time * 3. * PI;
offset -= subdivisions;
float blend = dot(hexCenter, pca);
blend = cos(blend * 30. + offset) * .5 + .5;
spec.height = mix(1.75, 2., blend);

spec.thickness = spec.height;

return spec;

}

// Animation 2

float animSubdivisions2() {
return mix(1., 2.3, sin(time * PI/2.) * .5 + .5);
}

HexSpec animHex2(vec3 hexCenter, float subdivisions) {
HexSpec spec = newHexSpec(subdivisions);

float blend = hexCenter.y;
spec.height = mix(1.6, 2., sin(blend * 10. + time * PI) * .5 + .5);

spec.roundTop = .02 / subdivisions;
spec.roundCorner = .09 / subdivisions;
spec.thickness = spec.roundTop * 4.;
spec.gap = .01;

return spec;

}

// Animation 3

float animSubdivisions3() {
return 5.;
}

HexSpec animHex3(vec3 hexCenter, float subdivisions) {
HexSpec spec = newHexSpec(subdivisions);

float blend = acos(dot(hexCenter, pab)) * 10.;
blend = cos(blend + time * PI) * .5 + .5;
spec.gap = mix(.01, .4, blend) / subdivisions;

spec.thickness = spec.roundTop * 2.;

return spec;

}

// Transition between animations

float sineInOut(float t) {
return -0.5 * (cos(PI * t) - 1.0);
}

float transitionValues(float a, float b, float c) {
#ifdef LOOP
#if LOOP == 1
return a;
#endif
#if LOOP == 2
return b;
#endif
#if LOOP == 3
return c;
#endif
#endif
float t = time / SCENE_DURATION;
float scene = floor(mod(t, 3.));
float blend = fract(t);
float delay = (SCENE_DURATION - CROSSFADE_DURATION) / SCENE_DURATION;
blend = max(blend - delay, 0.) / (1. - delay);
blend = sineInOut(blend);
float ab = mix(a, b, blend);
float bc = mix(b, c, blend);
float cd = mix(c, a, blend);
float result = mix(ab, bc, min(scene, 1.));
result = mix(result, cd, max(scene - 1., 0.));
return result;
}

HexSpec transitionHexSpecs(HexSpec a, HexSpec b, HexSpec c) {
float roundTop = transitionValues(a.roundTop, b.roundTop, c.roundTop);
float roundCorner = transitionValues(a.roundCorner, b.roundCorner, c.roundCorner);
float height = transitionValues(a.height, b.height, c.height);
float thickness = transitionValues(a.thickness, b.thickness, c.thickness);
float gap = transitionValues(a.gap, b.gap, c.gap);
return HexSpec(roundTop, roundCorner, height, thickness, gap);
}

// --------------------------------------------------------
// Modelling
// --------------------------------------------------------

const vec3 FACE_COLOR = vec3(.9,.9,1.);
const vec3 BACK_COLOR = vec3(.1,.1,.15);
const vec3 BACKGROUND_COLOR = vec3(.0, .005, .03);

struct Model {
float dist;
vec3 albedo;
float glow;
};

Model hexModel(
vec3 p,
vec3 hexCenter,
vec3 edgeA,
vec3 edgeB,
HexSpec spec
) {
float d;

float edgeADist = dot(p, edgeA) + spec.gap;
float edgeBDist = dot(p, edgeB) - spec.gap;
float edgeDist = smax(edgeADist, -edgeBDist, spec.roundCorner);

float outerDist = length(p) - spec.height;
d = smax(edgeDist, outerDist, spec.roundTop);

float innerDist = length(p) - spec.height + spec.thickness;
d = smax(d, -innerDist, spec.roundTop);

vec3 color;

float faceBlend = (spec.height - length(p)) / spec.thickness;
faceBlend = clamp(faceBlend, 0., 1.);
color = mix(FACE_COLOR, BACK_COLOR, step(.5, faceBlend));

vec3 edgeColor = spectrum(dot(hexCenter, pca) * 5. + length(p) + .8);    
float edgeBlend = smoothstep(-.04, -.005, edgeDist);
color = mix(color, edgeColor, edgeBlend); 

return Model(d, color, edgeBlend);

}

// checks to see which intersection is closer
Model opU( Model m1, Model m2 ){
if (m1.dist < m2.dist) {
return m1;
} else {
return m2;
}
}

Model geodesicModel(vec3 p) {

pModIcosahedron(p);

float subdivisions = transitionValues(
    animSubdivisions1(),
    animSubdivisions2(),
    animSubdivisions3()
);
TriPoints3D points = geodesicTriPoints(p, subdivisions);
    
vec3 edgeAB = normalize(cross(points.center, points.ab));
vec3 edgeBC = normalize(cross(points.center, points.bc));
vec3 edgeCA = normalize(cross(points.center, points.ca));

Model model, part;
HexSpec spec;

spec = transitionHexSpecs(
    animHex1(points.b, subdivisions),
    animHex2(points.b, subdivisions),
    animHex3(points.b, subdivisions)
);
part = hexModel(p, points.b, edgeAB, edgeBC, spec);
model = part;

spec = transitionHexSpecs(
    animHex1(points.c, subdivisions),
    animHex2(points.c, subdivisions),
    animHex3(points.c, subdivisions)
);
part = hexModel(p, points.c, edgeBC, edgeCA, spec);
model = opU(model, part);

spec = transitionHexSpecs(
    animHex1(points.a, subdivisions),
    animHex2(points.a, subdivisions),
    animHex3(points.a, subdivisions)
);
part = hexModel(p, points.a, edgeCA, edgeAB, spec);
model = opU(model, part);

return model;

}

Model map( vec3 p ){
mat3 m = modelRotation();
p *= m;
#ifndef LOOP
pR(p.xz, time * PI/16.);
#endif
Model model = geodesicModel(p);
return model;
}

// --------------------------------------------------------
// LIGHTING
// Adapted from IQ https://www.shadertoy.com/view/Xds3zN
// --------------------------------------------------------

vec3 doLighting(Model model, vec3 pos, vec3 nor, vec3 ref, vec3 rd) {
vec3 lightPos = normalize(vec3(.5,.5,-1.));
vec3 backLightPos = normalize(vec3(-.5,-.3,1));
vec3 ambientPos = vec3(0,1,0);

vec3  lig = lightPos;
float amb = clamp((dot(nor, ambientPos) + 1.) / 2., 0., 1.);
float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
float bac = pow(clamp(dot(nor, backLightPos), 0., 1.), 1.5);
float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );

vec3 lin = vec3(0.0);
lin += 1.20 * dif * vec3(.9);
lin += 0.80 * amb * vec3(.5, .7, .8);
lin += 0.30 * bac * vec3(.25);
lin += 0.20 * fre * vec3(1);

vec3 albedo = model.albedo;
vec3 col = mix(albedo * lin, albedo, model.glow);    

return col;

}

// --------------------------------------------------------
// Ray Marching
// Adapted from cabbibo https://www.shadertoy.com/view/Xl2XWt
// --------------------------------------------------------

const float MAX_TRACE_DISTANCE = 8.; // max trace distance
const float INTERSECTION_PRECISION = .001; // precision of the intersection
const int NUM_OF_TRACE_STEPS = 100;
const float FUDGE_FACTOR = .9; // Default is 1, reduce to fix overshoots

struct CastRay {
vec3 origin;
vec3 direction;
};

struct Ray {
vec3 origin;
vec3 direction;
float len;
};

struct Hit {
Ray ray;
Model model;
vec3 pos;
bool isBackground;
vec3 normal;
vec3 color;
};

vec3 calcNormal( in vec3 pos ){
vec3 eps = vec3( 0.001, 0.0, 0.0 );
vec3 nor = vec3(
map(pos+eps.xyy).dist - map(pos-eps.xyy).dist,
map(pos+eps.yxy).dist - map(pos-eps.yxy).dist,
map(pos+eps.yyx).dist - map(pos-eps.yyx).dist );
return normalize(nor);
}

Hit raymarch(CastRay castRay){

float currentDist = INTERSECTION_PRECISION * 2.0;
Model model;

Ray ray = Ray(castRay.origin, castRay.direction, 0.);

for( int i=0; i< NUM_OF_TRACE_STEPS ; i++ ){
    if (currentDist < INTERSECTION_PRECISION || ray.len > MAX_TRACE_DISTANCE) {
        break;
    }
    model = map(ray.origin + ray.direction * ray.len);
    currentDist = model.dist;
    ray.len += currentDist * FUDGE_FACTOR;
}

bool isBackground = false;
vec3 pos = vec3(0);
vec3 normal = vec3(0);
vec3 color = vec3(0);

if (ray.len > MAX_TRACE_DISTANCE) {
    isBackground = true;
} else {
    pos = ray.origin + ray.direction * ray.len;
    normal = calcNormal(pos);
}

return Hit(ray, model, pos, isBackground, normal, color);

}

// --------------------------------------------------------
// Rendering
// --------------------------------------------------------

void shadeSurface(inout Hit hit){

vec3 color = BACKGROUND_COLOR;

if (hit.isBackground) {
    hit.color = color;
    return;
}

vec3 ref = reflect(hit.ray.direction, hit.normal);

#ifdef DEBUG
    color = hit.normal * 0.5 + 0.5;
#else 
    color = doLighting(
        hit.model,
        hit.pos,
        hit.normal,
        ref,
        hit.ray.direction
    );
#endif

hit.color = color;

}

vec3 render(Hit hit){
shadeSurface(hit);
return hit.color;
}

// --------------------------------------------------------
// Camera
// https://www.shadertoy.com/view/Xl2XWt
// --------------------------------------------------------

mat3 calcLookAtMatrix( in vec3 ro, in vec3 ta, in float roll )
{
vec3 ww = normalize( ta - ro );
vec3 uu = normalize( cross(ww,vec3(sin(roll),cos(roll),0.0) ) );
vec3 vv = normalize( cross(uu,ww));
return mat3( uu, vv, ww );
}

void doCamera(out vec3 camPos, out vec3 camTar, out float camRoll, in float time, in vec2 mouse) {
float dist = 5.5;
camRoll = 0.;
camTar = vec3(0,0,0);
camPos = vec3(0,0,-dist);
camPos *= cameraRotation();
camPos += camTar;
}

// --------------------------------------------------------
// Gamma
// https://www.shadertoy.com/view/Xds3zN
// --------------------------------------------------------

const float GAMMA = 2.2;

vec3 gamma(vec3 color, float g) {
return pow(color, vec3(g));
}

vec3 linearToScreen(vec3 linearRGB) {
return gamma(linearRGB, 1.0 / GAMMA);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
time = iTime;

#ifdef LOOP
    #if LOOP == 1
        time = mod(time, 2.);   
    #endif
    #if LOOP == 2
        time = mod(time, 4.);   
    #endif
    #if LOOP == 3
        time = mod(time, 2.);
	#endif
#endif

initIcosahedron();

vec2 p = (-iResolution.xy + 2.0*fragCoord.xy)/iResolution.y;
vec2 m = iMouse.xy / iResolution.xy;

vec3 camPos = vec3( 0., 0., 2.);
vec3 camTar = vec3( 0. , 0. , 0. );
float camRoll = 0.;

// camera movement
doCamera(camPos, camTar, camRoll, iTime, m);

// camera matrix
mat3 camMat = calcLookAtMatrix( camPos, camTar, camRoll );  // 0.0 is the camera roll

// create view ray
vec3 rd = normalize( camMat * vec3(p.xy,2.0) ); // 2.0 is the lens length

Hit hit = raymarch(CastRay(camPos, rd));

vec3 color = render(hit);

#ifndef DEBUG
    color = linearToScreen(color);
#endif

fragColor = vec4(color,1.0);

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant