| 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.);
 }
 
 | 
|  | 
| 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ć ? | 
|  | 
| 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 :-/ | 
|  | 
| 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: 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.);
 }
 
 | 
|  | 
| 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ć. #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. | 
|  | 
| tBane Temat założony przez niniejszego użytkownika | » 2024-10-25 11:22:41 Ok. Rozumiem. Dzięki za pomoc. Jeszcze dodałem efekt pikselizacji. void main(){
 vec2 coords = worldPos.xy / resolution;
 float pixelFactor = 0.0078125;
 vec2 pixelCoord = floor( coords / pixelFactor ) * pixelFactor;
 float n = nestedNoise( pixelCoord * 25.60 );
 vec3 color = mix( vec3( .4, .6, 1. ), vec3( .1, .2, 1. ), n );
 vec3 darkcolor = color * 0.7;
 gl_FragColor = vec4( darkcolor, 1. );
 }
 
 | 
|  | 
| tBane Temat założony przez niniejszego użytkownika | » 2024-11-01 19:49:46 Mam jeszcze jeden BUG polegający na tym, że gdy przemieszczam się po mapie to tak samo przemieszcza się "woda w palecie". Chciałbym aby była renderowana "względem palety" a nie "względem świata". // water2.fraguniform sampler2D texture;
 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()
 {
 vec4 texcolor = texture2D(texture, gl_TexCoord[0].xy);
 if(texcolor.x == 127./255. && texcolor.y == 127./255. && texcolor.z == 127./255. && texcolor.w == 1.0) {
 vec2 coords = worldPos.xy/resolution;
 float pixelationFactor = 0.00390625;
 vec2 pixelCoord = floor(coords / pixelationFactor) * pixelationFactor;
 float n = nestedNoise(pixelCoord * 25.60);
 vec3 color = mix(vec3(.4, .6, 1.), vec3(.05, .1, 1.), n);
 vec3 darkcolor = color * 0.7;
 gl_FragColor = vec4(darkcolor, 1.);
 }else{
 gl_FragColor = texcolor;
 }
 }
 | 
|  | 
| pekfos | » 2024-11-01 22:11:39 Tak samo wyświetlasz wodę w obu przypadkach, więc działa tak samo. Możesz dodać parametr do shadera by rozróżnić te przypadki. | 
|  | 
| « 1 »  2 |