Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML GLSL] Shader Wody

Ostatnio zmodyfikowano wczoraj o godz. 22:31
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
[SFML GLSL] Shader Wody
» 2024-10-24 12:20:59
Witam. Znalazłem pewien Shader, który mi się spodobał.
https://www.shadertoy.com/view/Mt2SzR
Chciałbym go przepisać na SFML 2.X GLSL. Skopiowałem Shader i zmieniłem kilka rzeczy - tak żeby SFML 2.X nie wyrzucał błędu. Ostatecznie Shader nie działa tak jak powinien. Czy to ja gdzieś błąd zrobiłem czy faktycznie Shader nie działa tak jak pokazuje na shadertoy ?


uniform vec2 resolution;
uniform float time;

float random(float x) {
 
    return fract(sin(x) * 10000.);
         
}

float noise(vec2 p) {

    return random(p.x + p.y * 10000.);
           
}

vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); }
vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); }
vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); }
vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); }

float smoothNoise(vec2 p) {

    vec2 interp = smoothstep(0., 1., fract(p));
    float s = mix(noise(sw(p)), noise(se(p)), interp.x);
    float n = mix(noise(nw(p)), noise(ne(p)), interp.x);
    return mix(s, n, interp.y);
       
}

float fractalNoise(vec2 p) {

    float x = 0.;
    x += smoothNoise(p      );
    x += smoothNoise(p * 2. ) / 2.;
    x += smoothNoise(p * 4. ) / 4.;
    x += smoothNoise(p * 8. ) / 8.;
    x += smoothNoise(p * 16.) / 16.;
    x /= 1. + 1./2. + 1./4. + 1./8. + 1./16.;
    return x;
           
}

float movingNoise(vec2 p) {
 
    float x = fractalNoise(p + time);
    float y = fractalNoise(p - time);
    return fractalNoise(p + vec2(x, y));  
   
}

float nestedNoise(vec2 p) {
   
    float x = movingNoise(p);
    float y = movingNoise(p + 100.);
    return movingNoise(p + vec2(x, y));
   
}
void main()
{
    vec2 uv = gl_TexCoord[0].xy / resolution.xy;
    float n = nestedNoise(uv * 6.);
    gl_FragColor = vec4(mix(vec3(.4, .6, 1.), vec3(.1, .2, 1.), n), 1.);
}
 
P-181747
tBane
Temat założony przez niniejszego użytkownika
» 2024-10-24 12:26:16
Gdy ustawiłem
float n = nestedNoise(uv * 25600.);
 to wtedy woda zaczęła przypominać tą z https://www.shadertoy.com. Gdzie zrobiłem błąd ?
Ale dostrzełem błąd - co dwa chunki(512px) shader tak jakby się resetuje. Wie ktoś z jakiego powodu nie ma płynnego przejścia i skąd to wywnioskować ?

P-181748
tBane
Temat założony przez niniejszego użytkownika
» 2024-10-24 13:00:50
Eksperymentowałem z różnymi wielkościami tekstury i nic to nie dało :-/
P-181749
tBane
Temat założony przez niniejszego użytkownika
» 2024-10-24 19:21:44
Jak na razie mój Shader prezentuje się następująco:

C/C++
shader->setUniform( "time", currentTime.asSeconds() );
sf::Vector2f resolution( 1280, 720 );
shader->setUniform( "resolution", resolution );



uniform vec2 resolution;
uniform float time;

float random(float x) {
 
    return fract(sin(x) * 10000.);
         
}

float noise(vec2 p) {

    return random(p.x + p.y * 10000.);
           
}

vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); }
vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); }
vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); }
vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); }

float smoothNoise(vec2 p) {

    vec2 interp = smoothstep(0., 1., fract(p));
    float s = mix(noise(sw(p)), noise(se(p)), interp.x);
    float n = mix(noise(nw(p)), noise(ne(p)), interp.x);
    return mix(s, n, interp.y);
       
}

float fractalNoise(vec2 p) {

    float x = 0.;
    x += smoothNoise(p      );
    x += smoothNoise(p * 2. ) / 2.;
    x += smoothNoise(p * 4. ) / 4.;
    x += smoothNoise(p * 8. ) / 8.;
    x += smoothNoise(p * 16.) / 16.;

    x /= 1. + 1./2. + 1./4. + 1./8. + 1./16.;
    return x;
           
}

float movingNoise(vec2 p) {
 
    float x = fractalNoise(p + time);
    float y = fractalNoise(p - time);
    return fractalNoise(p + vec2(x, y));  
   
}

float nestedNoise(vec2 p) {
   
    float x = movingNoise(p);
    float y = movingNoise(p + 100.);
    return movingNoise(p + vec2(x, y));
   
}
void main()
{
    vec2 uv = gl_TexCoord[0].xy / resolution.xy;
    float n = nestedNoise(uv * 25600);
    gl_FragColor = vec4(mix(vec3(.4, .6, 1.), vec3(.1, .2, 1.), n), 1.);
}
P-181751
pekfos
» 2024-10-24 22:05:54
    vec2 uv = gl_TexCoord[0].xy / resolution.xy;
    float n = nestedNoise(uv * 25600);
Pewny jesteś użycia tu współrzędnych tekstury? W zasadzie przerobiłem tylko to i wydaje się działać.
C/C++
#include <SFML/Graphics.hpp>
#include <cmath>

const std::string VertexShader = R"( varying vec2 worldPos; void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; worldPos = gl_ModelViewMatrix * gl_Vertex; gl_FrontColor = gl_Color; } )";

const std::string WaterFragmentShader = R"( uniform vec2 resolution; uniform float time; varying vec2 worldPos; float random(float x) { return fract(sin(x) * 10000.); } float noise(vec2 p) { return random(p.x + p.y * 10000.); } vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); } vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); } vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); } vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); } float smoothNoise(vec2 p) { vec2 interp = smoothstep(0., 1., fract(p)); float s = mix(noise(sw(p)), noise(se(p)), interp.x); float n = mix(noise(nw(p)), noise(ne(p)), interp.x); return mix(s, n, interp.y); } float fractalNoise(vec2 p) { float x = 0.; x += smoothNoise(p ); x += smoothNoise(p * 2. ) / 2.; x += smoothNoise(p * 4. ) / 4.; x += smoothNoise(p * 8. ) / 8.; x += smoothNoise(p * 16.) / 16.; x /= 1. + 1./2. + 1./4. + 1./8. + 1./16.; return x; } float movingNoise(vec2 p) { float x = fractalNoise(p + time); float y = fractalNoise(p - time); return fractalNoise(p + vec2(x, y)); } float nestedNoise(vec2 p) { float x = movingNoise(p); float y = movingNoise(p + 100.); return movingNoise(p + vec2(x, y)); } void main() { vec2 uv = worldPos.xy * 0.05; float n = nestedNoise(uv); gl_FragColor = vec4(mix(vec3(.4, .6, 1.), vec3(.1, .2, 1.), n), 1.); } )";




int main()
{
   
int tilesx = 128, tilesy = 96;
   
sf::RenderWindow okno( sf::VideoMode( tilesx * 10, tilesy * 10 ), "Kurs SFML 2.0 - http://cpp0x.pl" );
   
   
sf::Image img;
   
img.create( 10, 10 );
   
for( int i = 0; i < img.getSize().x; ++i )
   
for( int j = 0; j < img.getSize().y; ++j )
       
 img.setPixel( i, j, sf::Color( i * 25, j * 25, 0 ) );
   
   
sf::Texture tex;
   
tex.loadFromImage( img );
   
   
sf::Shader shader;
   
if( !shader.loadFromMemory( VertexShader, WaterFragmentShader ) )
       
 return 1;
   
   
sf::Clock stoper;
   
   
while( okno.isOpen() )
   
{
       
sf::Event event;
       
while( okno.pollEvent( event ) )
       
{
           
if( event.type == sf::Event::Closed )
               
 okno.close();
           
           
if( event.type == sf::Event::Resized )
           
{
               
tilesx = event.size.width / 10;
               
tilesy = event.size.height / 10;
               
               
auto view = okno.getView();
               
view.setSize( event.size.width, event.size.height );
               
view.setCenter( event.size.width / 2, event.size.height / 2 );
               
okno.setView( view );
           
}
           
        }
       
okno.clear();
       
       
sf::VertexArray va( sf::Quads, tilesx * tilesy * 4 );
       
for( int i = 0, k = 0; i < tilesx; ++i )
       
for( int j = 0; j < tilesy; ++j )
       
{
           
sf::Vector2f pos( i * 10, j * 10 ), off( 0, 0 );
           
va[ k ].position = pos + off; va[ k ].texCoords = off; k++; off.x = 10;
           
va[ k ].position = pos + off; va[ k ].texCoords = off; k++; off.y = 10;
           
va[ k ].position = pos + off; va[ k ].texCoords = off; k++; off.x = 0;
           
va[ k ].position = pos + off; va[ k ].texCoords = off; k++;
       
}
       
       
shader.setUniform( "time", stoper.getElapsedTime().asSeconds() );
       
shader.setUniform( "resolution", sf::Vector2f( tilesx * 10, tilesy * 10 ) );
       
       
sf::RenderStates rs;
       
rs.texture = & tex;
       
rs.shader = & shader;
       
okno.draw( va, rs );
       
       
okno.display();
   
}
}
Rozdzielczość była w oryginale używana do uzyskania znormalizowanego uv. Tu dałem współrzędne świata jako uv i jak na razie nie widzę problemów. Możesz rozciągnąć okno żeby sprawdzić większą albo mniejszą mapę. Kafelki mają 10x10, jak wykomentujesz użycie shadera w rs to będzie widać strukturę mapy.
P-181752
« 1 »
  Strona 1 z 1