sointu toimii!
This commit is contained in:
363
shader_test.glsl
Normal file
363
shader_test.glsl
Normal file
@ -0,0 +1,363 @@
|
||||
#version 330
|
||||
|
||||
precision mediump float;
|
||||
|
||||
float EPS = 0.0001;
|
||||
float PI = 3.14159265359;
|
||||
float FLT_MAX = 900.;
|
||||
|
||||
uniform float u_time;
|
||||
uniform vec2 u_resolution;
|
||||
|
||||
layout(location = 1) out vec4 my_fragColor;
|
||||
|
||||
const int maxIterations = 64;
|
||||
const float stepScale = 1.;
|
||||
const float stopThreshold = .005;
|
||||
|
||||
float fov = .6;
|
||||
float nearClip = 0.;
|
||||
float farClip = 80.;
|
||||
|
||||
struct Light {
|
||||
vec3 position;
|
||||
float intensity;
|
||||
vec3 color;
|
||||
};
|
||||
|
||||
struct Surface {
|
||||
float dist;
|
||||
vec3 position;
|
||||
vec3 baseColor;
|
||||
vec3 normal;
|
||||
vec3 emissiveColor;
|
||||
};
|
||||
|
||||
struct Hit {
|
||||
Surface surface;
|
||||
Surface near;
|
||||
};
|
||||
|
||||
float saturate(float s) {
|
||||
return clamp(s, 0., 1.);
|
||||
}
|
||||
|
||||
float distanceToLine(vec3 origin, vec3 dir, vec3 point) {
|
||||
vec3 pointToOrigin = point - origin;
|
||||
float pointToOriginLength = length(pointToOrigin);
|
||||
vec3 pointToOriginNorm = normalize(pointToOrigin);
|
||||
float theta = dot(dir, pointToOriginNorm);
|
||||
return pointToOriginLength * sqrt(1. - theta * theta);
|
||||
}
|
||||
|
||||
mat4 scale(vec3 s) {
|
||||
mat4 m = mat4(
|
||||
s.x, 0., 0., 0.,
|
||||
0., s.y, 0., 0.,
|
||||
0., 0., s.z, 0.,
|
||||
0., 0., 0., 1.
|
||||
);
|
||||
return inverse(m);
|
||||
}
|
||||
|
||||
mat4 rotateX(float angle) {
|
||||
return inverse(mat4(
|
||||
1., 0., 0., 0.,
|
||||
0., cos(angle), -sin(angle), 0.,
|
||||
0., sin(angle), cos(angle), 0.,
|
||||
0., 0., 0., 1.
|
||||
));
|
||||
}
|
||||
|
||||
mat4 rotateY(float angle) {
|
||||
return inverse(mat4(
|
||||
cos(angle), 0., sin(angle), 0.,
|
||||
0., 1., 0., 0.,
|
||||
-sin(angle), 0., cos(angle), 0.,
|
||||
0., 0., 0., 1.
|
||||
));
|
||||
}
|
||||
|
||||
mat4 rotateZ(float angle) {
|
||||
return inverse(mat4(
|
||||
cos(angle), -sin(angle), 0., 0.,
|
||||
sin(angle), cos(angle), 0., 0.,
|
||||
0., 0., 1., 0.,
|
||||
0., 0., 0., 1.
|
||||
));
|
||||
}
|
||||
|
||||
mat4 translate(vec3 p) {
|
||||
return inverse(mat4(
|
||||
1., 0., 0., p.x,
|
||||
0., 1., 0., p.y,
|
||||
0., 0., 1., p.z,
|
||||
0., 0., 0., 1.
|
||||
));
|
||||
}
|
||||
|
||||
float sphere(vec3 p, float size) {
|
||||
return length(p) - size;
|
||||
}
|
||||
|
||||
float box(vec3 p, vec3 size) {
|
||||
vec3 d = abs(p) - size;
|
||||
return length(max(d, 0.)) + min(max(d.x, max(d.y, d.z)), 0.);
|
||||
}
|
||||
|
||||
float tube2(vec2 p, float size) {
|
||||
return length(p) - size;
|
||||
}
|
||||
|
||||
float box2(vec2 p, float size) {
|
||||
return length(max(abs(p) - size, 0.));
|
||||
}
|
||||
|
||||
float cylindar(vec3 p, vec3 c) {
|
||||
return length(p.xz - c.xy) - c.z;
|
||||
}
|
||||
|
||||
float displacement(vec3 p, vec3 power) {
|
||||
return sin(power.x * p.x) * sin(power.y * p.y) * sin(power.z * p.z);
|
||||
}
|
||||
|
||||
vec3 repeat(vec3 p, float c) {
|
||||
return mod(p, c) - c * .5;
|
||||
}
|
||||
|
||||
float smin(float a, float b, float k) {
|
||||
float res = exp(-k * a) + exp(-k * b);
|
||||
return -log(res) / k;
|
||||
}
|
||||
|
||||
float scene(vec3 p) {
|
||||
vec3 _p = p;
|
||||
|
||||
_p = (vec4(_p, 1.)).xyz;
|
||||
|
||||
return min(
|
||||
sphere((vec4(p, 1.) * translate(vec3(-.7, 0., 0.))).xyz, .5),
|
||||
box((vec4(p, 1.) * translate(vec3(.7, 0., 0))).xyz, vec3(.45))
|
||||
);
|
||||
}
|
||||
|
||||
float calcAO(vec3 p, vec3 n) {
|
||||
float k = 1.;
|
||||
float occ = 0.;
|
||||
for(int i = 0; i < 5; i++) {
|
||||
float len = .15 * (float(i) + 1.);
|
||||
float distance = scene(n * len + p);
|
||||
occ += (len - distance) * k;
|
||||
k *= .5;
|
||||
}
|
||||
return clamp(1. - occ, 0., 1.);
|
||||
}
|
||||
|
||||
vec3 getNormal(vec3 p) {
|
||||
const float e = EPS;
|
||||
return normalize(vec3(
|
||||
scene(p + vec3(e, 0.0, 0.0)) - scene(p + vec3(-e, 0.0, 0.0)),
|
||||
scene(p + vec3(0.0, e, 0.0)) - scene(p + vec3(0.0, -e, 0.0)),
|
||||
scene(p + vec3(0.0, 0.0, e)) - scene(p + vec3(0.0, 0.0, -e))
|
||||
));
|
||||
}
|
||||
|
||||
Surface near(Surface needle, Surface target) {
|
||||
if(needle.dist < 0. || needle.dist < target.dist) {
|
||||
return needle;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
Hit rayMarching(vec3 origin, vec3 dir, float start, float end) {
|
||||
Surface cs; // current surface
|
||||
cs.dist = -1.;
|
||||
|
||||
Surface ns; // near surface
|
||||
ns.dist = FLT_MAX;
|
||||
|
||||
Hit hit;
|
||||
|
||||
float sceneDist = 0.;
|
||||
float rayDepth = start;
|
||||
|
||||
for(int i = 0; i < maxIterations; i++) {
|
||||
sceneDist = scene(origin + dir * rayDepth);
|
||||
|
||||
// cache near distance
|
||||
if(sceneDist < ns.dist) {
|
||||
ns.dist = sceneDist;
|
||||
}
|
||||
|
||||
if((sceneDist < stopThreshold) || (rayDepth >= end)) {
|
||||
break;
|
||||
}
|
||||
rayDepth += sceneDist * stepScale;
|
||||
cs.dist = rayDepth;
|
||||
}
|
||||
|
||||
if (sceneDist >= stopThreshold) {
|
||||
rayDepth = end;
|
||||
}
|
||||
|
||||
cs.dist = rayDepth;
|
||||
hit.surface = cs;
|
||||
hit.near = ns;
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
float getSpecular(vec3 position, vec3 normal, Light light, float diffuse, vec3 cameraPos) {
|
||||
vec3 lightDir = light.position - position;
|
||||
vec3 ref = reflect(-normalize(lightDir), normal);
|
||||
float specular = 0.;
|
||||
if(diffuse > 0.) {
|
||||
specular = max(0., dot(ref, normalize(cameraPos - normal)));
|
||||
float specularPower = 32.;
|
||||
specular = pow(specular, specularPower) * light.intensity;
|
||||
}
|
||||
return specular;
|
||||
}
|
||||
|
||||
vec3 lighting(Surface surface, vec3 cameraPos) {
|
||||
vec3 position = surface.position;
|
||||
|
||||
vec3 color = vec3(0.);
|
||||
vec3 sceneColor = vec3(0.);
|
||||
vec3 normal = getNormal(position);
|
||||
|
||||
vec3 objColor = vec3(.4, .4, .4);
|
||||
vec3 specularColor = vec3(.6, .6, .6);
|
||||
|
||||
Light directionalLight;
|
||||
directionalLight.position = vec3(5., 5., 5.);
|
||||
directionalLight.intensity = .8;
|
||||
directionalLight.color = vec3(.4, .4, .4);
|
||||
|
||||
Light pointLight;
|
||||
pointLight.position = vec3(5., 5., 5.);
|
||||
pointLight.intensity = .8;
|
||||
pointLight.color = vec3(.5, .5, .5);
|
||||
|
||||
Light ambientLight;
|
||||
ambientLight.color = vec3(.1, .1, .1);
|
||||
ambientLight.intensity = .3;
|
||||
|
||||
// directional light
|
||||
float dDiffuse = max(0., dot(normal, normalize(directionalLight.position)));
|
||||
dDiffuse *= directionalLight.intensity;
|
||||
vec3 dDiffuseColor = dDiffuse * directionalLight.color * objColor;
|
||||
float dSpecular = getSpecular(position, normal, directionalLight, dDiffuse, cameraPos);
|
||||
vec3 dSpecularColor = dSpecular * specularColor;
|
||||
|
||||
// point light
|
||||
vec3 pLightDir = pointLight.position - position;
|
||||
float pDiffuse = max(0., dot(normal, normalize(pLightDir)));
|
||||
vec3 pDiffuseColor = pDiffuse * pointLight.color * objColor;
|
||||
float d = distance(pointLight.position, position);
|
||||
vec3 k = vec3(.05, .9, .06);
|
||||
float attenuation = 1. / (k.x + (k.y * d) + (k.z * d * d));
|
||||
pDiffuse *= pointLight.intensity;
|
||||
pDiffuse *= attenuation;
|
||||
float pSpecular = getSpecular(position, normal, pointLight, pDiffuse, cameraPos);
|
||||
pSpecular *= attenuation;
|
||||
vec3 pSpecularColor = pSpecular * specularColor;
|
||||
|
||||
// ambient
|
||||
vec3 ambientColor = ambientLight.color * ambientLight.intensity * objColor;
|
||||
float ao = calcAO(position, normal);
|
||||
|
||||
vec3 diffuse = dDiffuseColor + pDiffuseColor;
|
||||
vec3 specular = dSpecularColor + pSpecularColor;
|
||||
vec3 ambient = ambientColor * ao;
|
||||
|
||||
// color += objColor * diffuse + specular + ambient * ao;
|
||||
color += objColor * diffuse + ambient * ao;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec3 emissiveLight(Light light, Surface surface, vec3 rayOrigin, vec3 rayDirection) {
|
||||
vec3 eyeDirection = rayOrigin + rayDirection;
|
||||
|
||||
float lightEmissive = pow(distanceToLine(eyeDirection, rayDirection, light.position) + .95, -2.);
|
||||
|
||||
float c = dot(surface.normal, normalize(light.position - surface.position));
|
||||
c = clamp(c, 0., 1.);
|
||||
float em = 0.;
|
||||
|
||||
em = c + (1. - c) * step(farClip, surface.dist);
|
||||
|
||||
return lightEmissive * light.color * light.intensity * em;
|
||||
}
|
||||
|
||||
vec3 emissiveLighting(Surface surface, vec3 rayOrigin, vec3 rayDirection) {
|
||||
vec3 eyeDirection = rayOrigin + rayDirection;
|
||||
vec3 normal = surface.normal;
|
||||
|
||||
Light pointLightRed;
|
||||
pointLightRed.color = vec3(1., .1, .1);
|
||||
pointLightRed.intensity = 1.;
|
||||
pointLightRed.position = vec3(cos(u_time * 1.4) * 2., sin(u_time * 1.4) * 2., 0.);
|
||||
|
||||
Light pointLightGreen;
|
||||
pointLightGreen.color = vec3(.1, 1., .1);
|
||||
pointLightGreen.intensity = 1.;
|
||||
pointLightGreen.position = vec3(cos(u_time * 1.6) * 2., 0., sin(u_time * 1.6) * 2.);
|
||||
|
||||
Light pointLightBlue;
|
||||
pointLightBlue.color = vec3(.1, .1, 1.);
|
||||
pointLightBlue.intensity = 1.;
|
||||
pointLightBlue.position = vec3(0., sin(u_time * 1.8) * 2., cos(u_time * 1.8) * 2.);
|
||||
|
||||
|
||||
vec3 color = vec3(0.);
|
||||
color += emissiveLight(pointLightRed, surface, rayOrigin, rayDirection);
|
||||
color += emissiveLight(pointLightGreen, surface, rayOrigin, rayDirection);
|
||||
color += emissiveLight(pointLightBlue, surface, rayOrigin, rayDirection);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
/*vec2 aspect = vec2(u_resolution.x / u_resolution.y, 1.);
|
||||
vec2 screenCoord = (2. * gl_FragCoord.xy / u_resolution.xy - 1.) * aspect;
|
||||
// vec2 mouse = u_mouse.xy / u_resolution.xy - .5;
|
||||
|
||||
// camera settings
|
||||
vec3 lookAt = vec3(0., 0., 0.);
|
||||
vec3 cameraPos = vec3(0.,0., 5.);
|
||||
|
||||
// camera vectors
|
||||
vec3 forward = normalize(lookAt - cameraPos);
|
||||
vec3 right = normalize(cross(forward, vec3(0., 1., 0.)));
|
||||
vec3 up = normalize(cross(right, forward));
|
||||
|
||||
// raymarch
|
||||
vec3 rayOrigin = cameraPos;
|
||||
vec3 rayDirection = normalize(forward + fov * screenCoord.x * right + fov * screenCoord.y * up);
|
||||
Hit hit = rayMarching(rayOrigin, rayDirection, nearClip, farClip);
|
||||
Surface surface = hit.surface;
|
||||
Surface near = hit.near;
|
||||
|
||||
surface.position = rayOrigin + rayDirection * surface.dist;
|
||||
|
||||
// color
|
||||
vec3 sceneColor = vec3(0.);
|
||||
|
||||
// no hit or too far
|
||||
if(surface.dist >= farClip) {
|
||||
vec3 bgColor = vec3(0.);
|
||||
sceneColor = bgColor;
|
||||
} else {
|
||||
sceneColor += lighting(surface, cameraPos);
|
||||
}
|
||||
|
||||
surface.normal = getNormal(surface.position);
|
||||
sceneColor += emissiveLighting(surface, rayOrigin, rayDirection);
|
||||
*/
|
||||
|
||||
// my_fragColor = vec4(sceneColor, 1.);
|
||||
my_fragColor = vec4(vec3(0., 1., 0.), 1.);
|
||||
}
|
||||
Reference in New Issue
Block a user