Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 460
- out vec4 FragColor;
- in vec2 texcoord;
- #define PI 3.1415926f
- uniform sampler2D background;
- uniform int textureWidth;
- uniform int textureHeight;
- uniform int backType;
- uniform samplerBuffer VertexSampler0;
- uniform vec3 origin;
- uniform vec3 front;
- uniform vec3 right;
- uniform vec3 up;
- uniform float fov;
- uniform float scale;
- uniform float width;
- uniform float height;
- struct DirectionalLight
- {
- float strength;
- vec3 color;
- float lightDist;
- vec3 dir;
- };
- struct World
- {
- vec3 skyColor;
- vec3 floorColor;
- vec3 horizonColor;
- float horizonAngle;
- };
- uniform DirectionalLight dirLight;
- uniform World world;
- struct Octree
- {
- vec3 color;
- vec3 pos;
- float size;
- int children[8];
- vec3 bounds[2];
- bool isLeaf;
- bool isEmpty;
- };
- struct Ray
- {
- vec3 orig, dir;
- vec3 invdir;
- int sign[3];
- };
- Octree load(int pos)
- {
- int id = pos/4;
- vec4 v1 = texelFetch(VertexSampler0, id + 0);
- vec4 v2 = texelFetch(VertexSampler0, id + 1);
- vec4 v3 = texelFetch(VertexSampler0, id + 2);
- vec4 v4 = texelFetch(VertexSampler0, id + 3);
- vec4 v5 = texelFetch(VertexSampler0, id + 4);
- vec4 v6 = texelFetch(VertexSampler0, id + 5);
- Octree oc;
- oc.pos = v1.xyz;
- oc.size = v1.w;
- oc.color = vec3(v2.x, v2.y, v2.z);
- oc.bounds[0] = vec3(v2.w, v3.xy);
- oc.bounds[1] = vec3(v3.zw, v4.x);
- oc.children[0] = int(v4.y);
- oc.children[1] = int(v4.z);
- oc.children[2] = int(v4.w);
- oc.children[3] = int(v5.x);
- oc.children[4] = int(v5.y);
- oc.children[5] = int(v5.z);
- oc.children[6] = int(v5.w);
- oc.children[7] = int(v6.x);
- oc.isLeaf = v6.y > 0;
- oc.isEmpty = v6.z > 0;
- return oc;
- }
- struct Contact
- {
- vec3 position;
- vec3 normal;
- };
- int iterativeHitNode(Ray r)
- {
- int buf[1000];
- int front = 0;
- int rear = 0;
- buf[front++] = 0;
- int closest = -1;
- while (front != rear)
- {
- if(front >= 1000)
- return -1;
- Octree node = load(buf[rear++]);
- Octree closestNode = load(closest);
- if(node.isLeaf && (closest == -1 || (sqDist(node.pos, r.orig) <= sqDist(closestNode.pos, r.orig))))
- {
- closest = buf[rear - 1];
- }
- if(node.isEmpty)
- continue;
- for (int i = 0; i < 8; ++i)
- {
- if(node.children[i] == -1)
- continue;
- Octree child = load(node.children[i]);
- if(node.children[i] != -1 && AABBtest(child, r))
- {
- buf[front++] = node.children[i];
- }
- }
- }
- return closest;
- }
- vec3 getImageBackground(vec3 from, vec3 direction)
- {
- float theta = atan(direction.y, direction.x) * 180 / PI + 180;
- float alpha = atan(direction.z, sqrt(direction.x * direction.x + direction.y * direction.y)) * 180 / PI + 90;
- float x = textureWidth * theta / 360;
- float y = textureHeight * alpha / 180;
- vec2 pos = vec2( 1 - x/textureWidth, 1 - y/textureHeight);
- return texture(background, pos).xyz;
- }
- vec3 getBackground(vec3 from, vec3 direction)
- {
- if(backType == 0)
- return getSkyBackground(from, direction);
- else if(backType == 1)
- {
- return getImageBackground(from, direction);
- }
- return vec3(0);
- }
- vec3 multiplyColors(vec3 color1, vec3 otherColor)
- {
- return vec3(otherColor.x * color1.x, otherColor.y * color1.y, otherColor.z * color1.z);
- }
- void main()
- {
- float px = texcoord.x*width - width * 0.5f;
- float py = texcoord.y*height - height * 0.5f;
- Ray r = initRay(front + right * px * scale + up * py * scale, origin);
- int res = iterativeHitNode(r);
- if(res != -1)
- {
- Octree oc = load(res);
- Contact c = cubeHit(r.dir, r.orig, oc.pos, oc.size*0.5f);
- float slope = abs(dot(dirLight.dir, c.normal));
- vec3 color = multiplyColors(oc.color, dirLight.color) * slope * dirLight.strength;
- vec3 shadowPos = c.position + c.normal*0.001f;
- Ray shadowRay = initRay(-dirLight.dir, shadowPos);
- int shadowHit = iterativeHitNode(shadowRay);
- if(shadowHit != -1)
- color = color*0.1f;
- FragColor = vec4(color, 1);
- }
- else
- {
- FragColor = vec4(getBackground(r.orig, r.dir), 1);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement