Sometimes the reflection in the mirror is more real than the object itself ...
- Lewis Carroll (Alice in the looking glass)
#version 430 core
layout( local_size_x = 32, local_size_y = 32 ) in;
layout(binding = 0, rgba8) uniform image2D IMG;
layout(binding = 1, std430) buffer InSphere {vec4 Shape_obj[];};
layout(binding = 2, std430) buffer InSphere_color {vec4 Sphere_color[];};
uniform vec2 u_InvScreenSize;
uniform float u_ScreenRatio;
uniform vec3 u_LightPosition;
uniform vec3 u_CameraPosition;
//
const vec3 ray00 = vec3(-1*u_ScreenRatio,-1, -1.2);
const vec3 ray01 = vec3(-1*u_ScreenRatio,+1, -1.2);
const vec3 ray10 = vec3(+1*u_ScreenRatio,-1, -1.2);
const vec3 ray11 = vec3(+1*u_ScreenRatio,+1, -1.2);
const ivec2 size = imageSize(IMG);
const mat3 mat_rotate = mat3(-0.5, -0.86602540378443864676372317075294, 0, 0.86602540378443864676372317075294, -0.5, 0, 0, 0, 1);
struct plane {
vec3 v_plane;
vec3 n_plane;
vec3 p_plane;
};
//
plane m[3];
int last_plane;
//----------------------------------------------------------
float ray_intersect_sphere(vec3 orig, vec3 dir, vec4 Shape_obj) {
vec3 l = Shape_obj.xyz - orig;
float tca = dot(l,dir);
float d2 = dot(l,l) - tca * tca;
if (d2 > Shape_obj.w * Shape_obj.w) {return 0;}
float thc = sqrt(Shape_obj.w * Shape_obj.w - d2);
float t0 = tca - thc;
float t1 = tca + thc;
if (t0 < 0) {t0 = t1;}
if (t0 < 0) {return 0;}
return t0;
}
//---------------------------------------------------------
'float ray_intersect_plane(in vec3 orig, in vec3 dir, inout plane p) {
vec3 tested_direction = p.v_plane - orig;
float k = dot(tested_direction, p.v_plane) / dot(dir, p.v_plane);
if (k>=0) {
vec3 p0 = orig + dir * k;
// z
if ((p0.z>-80)&&(p0.z<3)) {
p.p_plane = p0;
return length(p0-orig);
}
}
return 1000000;
}'+
//---------------------------------------------------------
bool all_obj(inout vec3 loc_eye, inout vec3 dir, inout vec3 c) {
float min_len = 1000000;
uint near_id = 0;
float len;
float min_len2 = 1000000;
int near_id2 = -1;
for (int i=0; i<3; i++) {
if (i!=last_plane) {
len = ray_intersect_plane(loc_eye, dir, m[i]);
if (len<min_len2) {
min_len2 = len;
near_id2 = i;
}
}
}
//
if (near_id2>=0) {
loc_eye = m[near_id2].p_plane;
dir = reflect(dir, m[near_id2].n_plane);
last_plane =near_id2;
return true;
}
for (uint i=0; i<Shape_obj.length(); i++) {
len = ray_intersect_sphere(loc_eye, dir, Shape_obj[i]);
if ((len>0)&&(len<min_len)) {
min_len = len;
near_id = i;
}
}
//
if (min_len>=1000000) {return false;}
vec3 hit = loc_eye + dir * min_len;
vec3 Normal = normalize(hit - Shape_obj[near_id].xyz);
vec3 to_light = u_LightPosition - hit;
float to_light_len = length(to_light);
vec3 light_dir = normalize(to_light);
float diffuse_light = max(dot(light_dir, Normal), 0.0);
c = min(c + Sphere_color[near_id].xyz * (diffuse_light*0.8+0.2),1);
return false;
}
//---------------------------------------------------------
void main(void) {
if (gl_GlobalInvocationID.x >= size.x || gl_GlobalInvocationID.y >= size.y) return;
const vec2 pos = gl_GlobalInvocationID.xy * u_InvScreenSize.xy;
vec3 dir = normalize(mix(mix(ray00, ray01, pos.y), mix(ray10, ray11, pos.y), pos.x));
vec3 c = vec3(0, 0, 0);
//
vec3 eye = vec3(u_CameraPosition);
//
m[0].v_plane = vec3(0,-5,0);
m[0].n_plane = vec3(0,1,0);
m[1].v_plane = mat_rotate * m[0].v_plane;
m[1].n_plane = mat_rotate * m[0].n_plane;
m[2].v_plane = mat_rotate * m[1].v_plane;
m[2].n_plane = mat_rotate * m[1].n_plane;
//
for (int i=0; i<20; i++) {
if (!all_obj(eye, dir, c)) {break;}
}
//
imageStore(IMG, ivec2(gl_GlobalInvocationID.xy), vec4(c,1));
}
// #version 330 core layout (location = 0) in vec4 a_Position; uniform mat4 u_MVP; out vec4 v_Color; out vec2 v_TexCoords; void main() { v_TexCoords = a_Position.zw; gl_Position = u_MVP * vec4(a_Position.xy, 0, 1); } // #version 330 core precision mediump float; varying vec2 v_TexCoords; uniform sampler2D u_Texture; void main(){ gl_FragColor = texture(u_Texture, v_TexCoords); }
Source: https://habr.com/ru/post/461351/
All Articles