uniform sampler2D u_Texture0; uniform sampler2D u_Texture1; uniform sampler2D u_Texture2; // https://github.com/tokoik/fisheye ... // https://stackoverflow.com/questions/39352533/android-opengl-es-textured-half-sphere ??? 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; // 0: NORMAL, 1:WIDE uniform float u_aspect; // 스크린 AR void main(void) { vec2 fc = v_TexCoords0.st; float PI = 3.14159265359; if (u_mode == 1) { // Pin Cushion Dewarp // --- 파라미터 조절 --- // STRENGTH_X: 좌우(가로) 방향으로 펴는 강도 float STRENGTH_X_TOP = 0.27; float STRENGTH_X_BOTTOM = 0.47; // STRENGTH_Y: 상하(세로) 방향으로 펴는 강도 float STRENGTH_Y_TOP = 0.85; float STRENGTH_Y_BOTTOM = 0.5; // ZOOM: 전체 확대/축소 비율 float ZOOM = 1.08; // 2. 중심을 중앙으로 이동 [-0.5, 0.5] vec2 centeredUV = fc - 0.5; // 3. 화면 비율(Aspect Ratio) 보정 // 가로가 긴 화면에서 원이 타원이 되지 않도록 X좌표를 보정합니다. centeredUV.x *= u_aspect; // 4. 중심으로부터의 거리(반지름) 제곱 계산 float r2 = dot(centeredUV, centeredUV); // 5. Y축 강도 보간 계수 (t) 계산 // uv.y는 [0.0 (바닥) ~ 1.0 (천장)] 범위를 가지며, 이를 보간 계수로 사용합니다. float t = 1.0- fc.y; // 6. X축 강도 선형 보간 // 하단(t=0.0)에서 STRENGTH_X_BOTTOM, 상단(t=1.0)에서 STRENGTH_X_TOP float current_STRENGTH_X = mix(STRENGTH_X_BOTTOM, STRENGTH_X_TOP, t); // 7. Y축 강도 선형 보간 // 하단(t=0.0)에서 STRENGTH_Y_BOTTOM, 상단(t=1.0)에서 STRENGTH_Y_TOP float current_STRENGTH_Y = mix(STRENGTH_Y_BOTTOM, STRENGTH_Y_TOP, t); // 5. 왜곡 보정 (X, Y 개별 적용) // r2(중심에서의 거리)에 따라 보정하되, 축별로 다른 강도를 곱합니다. float factorX = 1.0 / (1.0 + current_STRENGTH_X * r2); float factorY = 1.0 / (1.0 + current_STRENGTH_Y * r2); // 6. 보정된 좌표 계산 (ZOOM 적용 포함) // X축에는 factorX, Y축에는 factorY를 각각 곱해줍니다. vec2 distortedUV = centeredUV * vec2(factorX, factorY) * ZOOM; // 7. 화면 비율 복원 distortedUV.x /= u_aspect; // 8. 좌표 범위를 다시 [0, 1]로 복귀 fc = distortedUV + 0.5; if(fc.x < 0.0 || fc.y < 0.0 || fc.x > 1.0 || fc.y > 1.0) { gl_FragColor = vec4(0.0,0.0,0.0,1.0); return; } } else // 일반모드 { // ZOOM CLIP if (fc.x < 0.0 || fc.x > 1.0) { gl_FragColor = vec4(0.0,0.0,0.0,1.0); return; } } 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); }