266 lines
8.8 KiB
GLSL
266 lines
8.8 KiB
GLSL
// precision highp float;
|
|
uniform sampler2D u_Texture0;
|
|
uniform sampler2D u_Texture1;
|
|
uniform sampler2D u_Texture2;
|
|
varying vec2 v_TexCoords0;
|
|
varying vec2 v_TexCoords1;
|
|
varying vec2 v_TexCoords2;
|
|
|
|
#define v_TexCoords1 v_TexCoords0
|
|
#define v_TexCoords2 v_TexCoords0
|
|
#define v_TexCoords3 v_TexCoords0
|
|
|
|
uniform float u_opacity;
|
|
uniform mat4 u_colorMatrix;
|
|
|
|
uniform int u_mode;
|
|
uniform float u_angle;
|
|
uniform int u_flip;
|
|
uniform float u_effectiveWidth;
|
|
uniform float u_clipBound;
|
|
uniform float u_screenWidth;
|
|
uniform float u_screenHeight;
|
|
uniform float u_realScreenWidth;
|
|
|
|
void main(void)
|
|
{
|
|
vec2 fc = v_TexCoords0.st;
|
|
float PI = 3.141592;
|
|
|
|
float sw = u_screenWidth;
|
|
float rsw = u_realScreenWidth;
|
|
float sh = u_screenHeight;
|
|
// 구분선 픽셀 크기
|
|
float pw = (2.0 / u_realScreenWidth);// * u_effectiveWidth;
|
|
float ph = (2.0 / u_screenHeight);
|
|
|
|
float tmin = 0.2;
|
|
float tmax = 0.43;
|
|
|
|
const vec4 lineColor = vec4(0.796875,0.59765625,0.19921875,1.0);
|
|
|
|
// VR + PANORAMA
|
|
if(u_mode == 2 || u_mode == 3)
|
|
{
|
|
float R = u_effectiveWidth / 2.0 * 0.96;//0.5;
|
|
float Cfx = u_effectiveWidth / 2.0;
|
|
float Cfy = 0.5;
|
|
|
|
float He = 1.0;
|
|
float We = u_effectiveWidth;
|
|
|
|
float Xe = 1.0-fc.x; // flip h
|
|
float Ye = 1.0-fc.y; // upside down
|
|
|
|
if(u_mode == 3){
|
|
if(Ye > 0.62) {
|
|
gl_FragColor = vec4(0.0,0.0,0.0,1.0);
|
|
return;
|
|
}
|
|
Ye = (Ye / 0.62);
|
|
}
|
|
|
|
float r = Ye/He*R;
|
|
float theta = Xe/We*2.0*PI;// - (u_angle * 3.0); // TOP_DOWN_2D_360
|
|
float Xf = Cfx+r*sin(theta);
|
|
float Yf = Cfy+r*cos(theta);
|
|
|
|
fc = vec2(Xf,Yf);
|
|
}
|
|
else if(u_mode == 1) // PANORAMA 4CH
|
|
{
|
|
// 4분할 모드 (가로 라인 위치는 u_effectiveWidth 반영)
|
|
float hw = u_effectiveWidth / 2.0;
|
|
|
|
if(abs(hw - fc.x) < pw || abs(0.5 - fc.y) < ph) {
|
|
gl_FragColor = lineColor;//
|
|
return;
|
|
}
|
|
|
|
fc.y = 1.0 - fc.y;
|
|
float R = u_effectiveWidth / 2.0 * 0.99;
|
|
float Cfx = u_effectiveWidth / 2.0;
|
|
float Cfy = 0.5;
|
|
|
|
float We = u_effectiveWidth;
|
|
|
|
float Xe = 1.0-fc.x; // flip h
|
|
float Ye = 1.0-fc.y; // upside down
|
|
|
|
// 세로 분할 선
|
|
if(fc.y < 0.5) // bottom AREA
|
|
{
|
|
/*
|
|
Ye = 1.0-Ye;
|
|
float r = (((Ye * (tmax - tmin)) / 0.5) + tmin); // (fmax - fmin) = 0.5
|
|
float theta = Xe/We*PI+(PI/2.0); // 1/2
|
|
theta += PI;
|
|
float Xf = Cfx+r*sin(theta);
|
|
float Yf = Cfy+r*cos(theta);
|
|
fc = vec2(Xf,Yf);
|
|
*/
|
|
// Ye가 0.0일 때 안쪽(tmin), 0.5일 때 바깥쪽(tmax)이 되도록 매핑
|
|
// 상하를 뒤집으려면 0.5 - fc.y를 사용하여 좌표 진행 방향을 반대로 바꿉니다.
|
|
float Ye_flipped = 0.5 - fc.y;
|
|
float r = (((Ye_flipped * (tmax - tmin)) / 0.5) + tmin);
|
|
/*
|
|
float theta = Xe/We*PI+(PI/2.0);
|
|
theta += PI;
|
|
float Xf = Cfx+r*sin(theta);
|
|
float Yf = Cfy+r*cos(theta);
|
|
fc = vec2(Xf,Yf);
|
|
*/
|
|
// 2. 좌우 반전 추가
|
|
// Xe가 (1.0 - fc.x)이므로, 이를 다시 반전시키려면
|
|
// We(효과 너비)에서 Xe를 뺀 값을 사용하거나 fc.x를 직접 활용합니다.
|
|
float Xe_flipped = We - Xe;
|
|
|
|
// 3. 반전된 Xe_flipped를 사용하여 theta 계산
|
|
float theta = Xe_flipped / We * PI + (PI / 2.0);
|
|
theta += PI;
|
|
|
|
float Xf = Cfx + r * sin(theta);
|
|
float Yf = Cfy + r * cos(theta);
|
|
fc = vec2(Xf, Yf);
|
|
}
|
|
else // top AREA 180 ~ 360
|
|
{
|
|
Ye = 1.0-Ye-0.5;
|
|
//float r = ((Ye*R) * 2.0) * clip_y + offset_y; //
|
|
float r = (((Ye * (tmax - tmin)) / 0.5) + tmin); // (fmax - fmin) = 0.5
|
|
float theta = Xe/We*PI+(PI/2.0); // 1/2
|
|
float Xf = Cfx+r*sin(theta);
|
|
float Yf = Cfy+r*cos(theta);
|
|
fc = vec2(Xf,Yf);
|
|
}
|
|
}
|
|
else if(u_mode == 4) // 5CH 모드
|
|
{
|
|
float left_area_ratio = 0.5;
|
|
float left_area_width = u_effectiveWidth * left_area_ratio;//min(sh / sw,0.5) * u_effectiveWidth;
|
|
|
|
if(abs(left_area_width - fc.x) < pw) {
|
|
gl_FragColor = lineColor;
|
|
return;
|
|
}
|
|
|
|
// 5분할 모드
|
|
float rx = fc.x;
|
|
float ry = fc.y;
|
|
|
|
float R = u_effectiveWidth / 2.0 * 0.99;
|
|
float Cfx = u_effectiveWidth / 2.0;
|
|
float Cfy = 0.5;
|
|
float We = u_effectiveWidth;
|
|
|
|
// 우측 (5채널)
|
|
if (rx < left_area_width) {
|
|
// 1:1 영역 은 보장됨
|
|
float target_area = 0.4;
|
|
float tx = rx * (1.0 / left_area_width) * target_area + ((1.0-target_area) * 0.5);
|
|
float ty = ry * target_area + ((1.0-target_area) * 0.5);
|
|
fc = vec2(tx,ty);
|
|
} else {
|
|
// 우측 4분할 (실제로는 2분할)
|
|
// 나머지 영역 의
|
|
// 좌우(abs(fc.x - h_center) < pw)
|
|
// 상하( abs(fc.y - 0.5) < ph) 라인 그리기
|
|
float h_center = (left_area_ratio + ((1.0 - left_area_ratio) * 0.5)) * u_effectiveWidth;
|
|
if(abs(h_center - rx) < pw || abs(ry - 0.5) < ph) {
|
|
gl_FragColor = lineColor;
|
|
return;
|
|
}
|
|
// 4채널 모드와 동일
|
|
float R = u_effectiveWidth / 2.0 * 0.99;
|
|
float Cfx = u_effectiveWidth / 2.0;
|
|
float Cfy = 0.5;
|
|
|
|
float We = u_effectiveWidth;
|
|
|
|
// ry 는 1.0 - left_area_width
|
|
rx = (1.0 - (rx - left_area_width) / (1.0 - left_area_width));
|
|
|
|
if(ry > 0.5) // bottom AREA
|
|
{
|
|
|
|
|
|
/*
|
|
ry = 1.0 - ((ry - 0.5) * 2.0); // ry 는 0.5~1.0 이므로 0.0~1.0으로 변환
|
|
float r = ((((ry * R) * (tmax - tmin)) / 0.5) + tmin);
|
|
|
|
float theta = rx/We*PI+(PI/2.0); // 1/2
|
|
theta += PI;
|
|
float Xf = Cfx+r*sin(theta);
|
|
float Yf = Cfy+r*cos(theta);
|
|
fc = vec2(Xf,Yf);
|
|
*/
|
|
/*
|
|
// --- 수정 부분 ---
|
|
// 기존: ry = 1.0 - ((ry - 0.5) * 2.0); -> 중앙이 1.0, 하단끝이 0.0
|
|
// 변경: 아래 식은 중앙(0.5)일 때 0.0, 하단끝(1.0)일 때 1.0이 됩니다.
|
|
ry = (ry - 0.5) * 2.0;
|
|
|
|
float r = ((((ry * R) * (tmax - tmin)) / 0.5) + tmin);
|
|
float theta = rx / We * PI + (PI / 2.0);
|
|
theta += PI;
|
|
float Xf = Cfx + r * sin(theta);
|
|
float Yf = Cfy + r * cos(theta);
|
|
fc = vec2(Xf, Yf);
|
|
*/
|
|
// 1. 상하 반전 처리 (기존 유지: 중앙 0.5일 때 r 최소, 바닥 1.0일 때 r 최대)
|
|
ry = (ry - 0.5) * 2.0;
|
|
float r = ((((ry * R) * (tmax - tmin)) / 0.5) + tmin);
|
|
|
|
// 2. 좌우 반전 추가
|
|
// rx 값을 1.0에서 빼줌으로써 좌우를 뒤집습니다.
|
|
float rx_flipped = 1.0 - rx;
|
|
|
|
// 3. 반전된 rx_flipped를 사용하여 theta 계산
|
|
float theta = rx_flipped / We * PI + (PI / 2.0);
|
|
theta += PI;
|
|
|
|
float Xf = Cfx + r * sin(theta);
|
|
float Yf = Cfy + r * cos(theta);
|
|
fc = vec2(Xf, Yf);
|
|
}
|
|
else // top AREA 180 ~ 360
|
|
{
|
|
ry = 1.0 - (ry * 2.0); // ry 는 0.0~0.5 이므로 0.0~1.0으로 변환
|
|
float r = ((((ry * R) * (tmax - tmin)) / 0.5) + tmin);
|
|
|
|
float theta = rx/We*PI+(PI/2.0); // 1/2 = ANGLE
|
|
float Xf = Cfx+r*sin(theta);
|
|
float Yf = Cfy+r*cos(theta);
|
|
fc = vec2(Xf,Yf);
|
|
}
|
|
|
|
}
|
|
}
|
|
else // FISH EYE
|
|
{
|
|
// ZOOM CLIP
|
|
if (fc.x < 0.0 || fc.x > 1.0) {
|
|
gl_FragColor = vec4(0.0,0.0,0.0,1.0);
|
|
return;
|
|
}
|
|
fc.x *= u_effectiveWidth;
|
|
|
|
// 1. 중앙 85%의 시작점 (버릴 영역의 크기: 15% / 2 = 7.5%)
|
|
float START_UV = 0.075;
|
|
|
|
// 2. 텍스처의 85% 영역 크기
|
|
float SCALE_RANGE = 1.0 - 2.0 * START_UV; // 0.85
|
|
|
|
// 3. 출력 UV (0.0~1.0)를 원본 텍스처의 중앙 85% 영역으로 매핑
|
|
// New_UV = TexCoords * (0.85) + 0.075
|
|
fc = fc * SCALE_RANGE + START_UV;
|
|
}
|
|
|
|
gl_FragColor = clamp(u_colorMatrix
|
|
* vec4(texture2D(u_Texture0, fc).r,
|
|
texture2D(u_Texture1, fc).r,
|
|
texture2D(u_Texture2, fc).r,
|
|
1.0), 0.0, 1.0);
|
|
|
|
}
|