GLSL 프래그먼트 셰이더로 이런 종류의 리플을 구현하는 방법은 무엇입니까?


11

그래서 나는 이미 반사 부분을 구현했습니다.

uniform sampler2D texture;
uniform vec2 resolution;
uniform vec3 overlayColor;

void main()
{
vec2 uv = gl_FragCoord.xy / resolution.xy;

if (uv.y > 0.3)// is air - no reflection or effect
{
    gl_FragColor = texture2D(texture, vec2(uv.x, uv.y));
}
else
{
    // Compute the mirror effect.
    vec4 color = texture2D(texture, vec2(uv.x, 0.6 - uv.y));
    // 
    vec4 finalColor = vec4(mix(color.rgb, overlayColor, 0.25), 1.0);
    gl_FragColor = finalColor;
}
}

출처

이제 문제는 이러한 파문이 어떻게 구현 되는가입니다.


3
이것은 완전한 답은 아니지만 일련의 힌트입니다. 효과를 "애니메이션"하려면 시간과 같은 변수가 필요합니다. 이 time값을 사용 uv.xy하면 (sin(time),cos(time))오프셋 벡터를 사용하여를 이동할 수 있습니다 . 물론 사인 및 코사인 오프셋의 진폭을 파악해야합니다. uv.y먼저 첫 번째 오프셋으로 시작 하고 효과를 더 조정할 수있는 방법을 봅니다.
teodron

이 힌트에 대해 대단히 감사합니다. @LeFauve의 구현을 시도한 후에 이것이 필요한 것으로 나타났습니다.
cepro

답변:


11

나는 teodron이 제안한 것을 구현하려고 노력했다.

void main()
{
    vec2 uv = gl_FragCoord.xy / resolution.xy;
    float sepoffset = 0.005*cos(iGlobalTime*3.0);
    if (uv.y > 0.3 + sepoffset)// is air - no reflection or effect
    {
        gl_FragColor = texture2D(texture, vec2(uv.x, -uv.y));
    }
    else
    {
        // Compute the mirror effect.
        float xoffset = 0.005*cos(iGlobalTime*3.0+200.0*uv.y);
        //float yoffset = 0.05*(1.0+cos(iGlobalTime*3.0+50.0*uv.y));
        float yoffset = ((0.3 - uv.y)/0.3) * 0.05*(1.0+cos(iGlobalTime*3.0+50.0*uv.y));
        vec4 color = texture2D(texture, vec2(uv.x+xoffset , -1.0*(0.6 - uv.y+ yoffset)));
        // 
        //vec4 finalColor = vec4(mix(color.rgb, overlayColor, 0.25), 1.0);
        gl_FragColor = color;
    }
}

꽤 가깝게 보이지만 (기본 이미지 없이는 알기가 어렵지만) 매개 변수를 조정할 수 있습니다.

https://www.shadertoy.com/view/Xll3R7 에서 실제로 볼 수 있습니다.

일부 비고 :

  • 이미지를 뒤집어 놓은 이후 y 좌표를 뒤집어 야했지만 resolution.xy에 전달한 내용에 따라 달라질 수 있습니다. 결과가 반전되면 uv.y를 반전하십시오.
  • 유니폼 선언을 변경하여 셰이더 토이와 작동합니다. 이러한 변경 사항은 무시해도됩니다.
  • 그러나 시간을 제공하는 유니폼을 추가하고 iGlobalTime (초 단위 시간) 대신 사용해야합니다.
  • 예제에 효과가있는 것처럼 보이기 때문에 조수 효과를 추가했지만 말하기가 어렵습니다 (sepoffset 변수 참조). 마음에 들지 않으면 제거 할 수 있습니다
  • 오버레이 색상이 좋지 않아서 제거했습니다. 예에 하나도 없었습니다.
  • 취향에 맞게 효과를 조정하려면 :
    • iGlobalTime의 요소를 변경하여 효과의 속도를 높이거나 낮추십시오 (원하는 경우 각 요소를 개별적으로 변경할 수 있음, x 움직임을 가속화하고 y 움직임을 느리게하자)
    • cos () 인수를 변경하여 효과를 증폭 / 감소

편집 : @ cepro의 수정 사항을 포함하도록 yoffset을 변경했습니다.


1
상당한 노력! +1
teodron

3
도와 주셔서 감사합니다 :). 이것은 실제로 매우 가까운 결과를 제공합니다. 그러나 나는 그것이 마지막 성분 하나를 놓친다고 생각합니다. 그림에서 잔물결이 카메라에 가까울수록 (화면 하단) 더 커집니다 (수직으로 뻗어 있음). uv.y로 y 오프셋을 조정해야할까요? float yoffset = ((0.3-uv.y) /0.3) * 0.05 * (1.0 + cos (iGlobalTime * 3.0 + 50.0 * uv.y)) ;. 나는 이것을 시도했고 나는 결과와 비슷하다.
cepro

@cepro에 가까운 파문을 잘 잡습니다. 나는 그것을 놓쳤다
LeFauve

IMO 수정 된 웨이브 pettern에 문제가 있습니다. 파도가 증가하는 동안, 그들은 이상한 "미러링 된"패턴을 가지고 있습니다 (최신 Chrome의 GTX 680).
Mario
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.