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.