• Products
    • Isadora
    • Get It
    • ADD-ONS
    • IzzyCast
    • Get It
  • Forum
  • Help
  • Werkstatt
  • Newsletter
  • Impressum
  • Dsgvo
  • Press
  • Isadora
  • Get It
  • ADD-ONS
  • IzzyCast
  • Get It
  • Press
  • Dsgvo
  • Impressum

Navigation

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Popular
    • Tags

    [ANSWERED] GPU Displace actor

    How To... ?
    8
    11
    3812
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • jhoepffner
      jhoepffner last edited by Woland

      Following some demands concerning a GPU displace actor, I propose a first shader. Its a little bit primitive but it works as waited.

      Feel free to adapt it, you can add a color sensibility. If you have a alpha layer in input 1 and you need to output it, its necessary to premultiply the alpha layer (not made here).

      /*

      a Displace Shader Actor

      proposed by Jacques Hoepffner

      after isadora Werkstatt 2017

      [MFC EDIT] Please note that this will not give the same results as Isadora's built in displace actor.

      */

      // 2 texture inputs

      uniform sampler2D tex0;

      uniform sampler2D tex1;

      // offset input

      // ISADORA_FLOAT_PARAM(offsetX, offx, 0.0, 10.0, 5.0, "offset on X");

      // ISADORA_FLOAT_PARAM(offsetY, offy, 0.0, 10.0, 5.0, "offset on Y");

      uniform float offsetX;

      uniform float offsetY;

      uniform vec2 resolution;

      vec2 coord = gl_FragCoord.xy/resolution.xy;

      void main(void) {

      // displace  tex0 pixels, according to the brightness of tex1 pixels

      coord.x = coord.x + texture2D(tex1, coord).x * offsetX /10.0;

      coord.y = coord.y + texture2D(tex1, coord).y * offsetY /10.0;

      vec4 color = texture2D(tex0, coord);

      gl_FragColor = color;

      }

      Jacques Hoepffner http://hoepffner.info
      GigaByte 550b / Ryzen 7 3800X / Ram 64 Go / RTX 3090 24 Go / SSD 2 To / raid0 32 To
      MBP 13' i5 2.6 Ghz 16 Go / Intel Iris / macOs 10.11.6 / izzy 2.6.1 + 3.0.3b2
      MBP 15' i7 2.6 Ghz 16 Go / GTX 650M 1Go/ MacOs10.13.3 / Izzy 2.6.1
      MSI GS65 i7 3.6 Ghz 32 Go / GTX 1070 8 Go / Windows 10 / Izzy 3.0.3b2

      1 Reply Last reply Reply Quote 1
      • jfg
        jfg last edited by

        Jacques,

        thank you very much. Works fantastic.

        best

        Jean-François

        • Izzy 3.2.6
        - MacBook Pro M1 Max 16" 64GB RAM, Mac OS 15.3.2 Sequoia
        - Mac Pro 5.1 middle 2012 (3,33 GHz 6-Core Intel Xeon, 32GB RAM, Radeon RX 580 8 GB ),
        Mac OS 10.14.6 (Mojave)
        - Mac mini Pro M4, Mac OS 15.3.2 Sequoia

        • A range of deployable older Macs
          Located in Bremen, Germany
        1 Reply Last reply Reply Quote 0
        • DusX
          DusX Tech Staff last edited by

          This is fantastic!

          One note, simply by changing the comments for the Isadora params to a range of -10.0,10.0 for the offset x and y, 

          the shader works perfectly with both positive and negative offsets :)

          // ISADORA_FLOAT_PARAM(offsetX, offx, -10.0, 10.0, 5.0, "offset on X");

          // ISADORA_FLOAT_PARAM(offsetY, offy, -10.0, 10.0, 5.0, "offset on Y");

          Troikatronix Technical Support

          • New Support Ticket Link: https://support.troikatronix.com/support/tickets/new
          • My Add-ons: https://troikatronix.com/add-ons/?u=dusx
          • Profession Services: https://support.troikatronix.com/support/solutions/articles/13000109444-professional-services

          Running: Win 11 64bit, i7, M.2 PCIe SSD's, 32gb DDR4, nVidia GTX 4070 | located in Ontario Canada.

          1 Reply Last reply Reply Quote 0
          • mark
            mark last edited by mark

            Dear @jhoepffner 

            Thank you for this. But, I need to point out the following:

            This will not give the same results as Isadora's Displace actor.

            I have edited your code to add a comment to indicate this to avoid confusion among the users. In fact, your algorithm is much closer to the functionality of the Scanner actor.

            The code for the displace actor looks something like this.

            float brightness_of_displace_pixel = (calculate brightness of displace texture, 0.0 to 1.0)
            float dst_pixel_x = (cos(angle) + 1.0)/2.0 * displace_amount * brightness_of_displace_pixel;
            float dst_pixel_y = (sin(angle) + 1.0)/2.0 * displace_amount * brightness_of_displace_pixel;

            But here is where you encounter the problem. You want to write to the pixel at texture0[dst_pixel_x][dst_pixel_y], but you can't do that – you can only output to the current pixel as defined by the gl_FragCoord.xy built-in variable. (The inability to write to an arbitrary pixel within a Shader is covered by this Stack Overflow post.) Writing to an arbitrary pixel on the CPU is easy because it's just a two dimensional array.

            Jacques, if you have an idea of how to accomplish the functionality of the Displace actor, please share it with me. The Stack Overflow post suggets the idea of an array of points that equals the resolution of the image in both dimensions. I suppose you could analyze the brightness of the image, output the x coordinate to one texture and then the y coordinate to a second texture, and then use those two textures to modulate the vertices. But I'm sorry to admit that this is a bit beyond my skill level with shaders.

            Best Wishes,
            Mark

            Media Artist & Creator of Isadora
            Macintosh SE-30, 32 Mb RAM, MacOS 7.6, Dual Floppy Drives

            1 Reply Last reply Reply Quote 0
            • mark
              mark last edited by mark

              Dear All,

              Here is a version that accepts a displace amount from 0 to 100 and an angle between 0 and 360.

              /*

              a Displace Shader Actor
              proposed by Jacques Hoepffner
              after isadora Werkstatt 2017

              updated by Mark Coniglio to move the pixels based
              on an a displace amount and an angle instead of
              separate x/y inputs

              this version also calculates the actual greyscale
              brightness of the pixel using standard a conversion
              algorithm

              Note that this code will not produce the same results
              as the built-in Isadora Displace actor.

              */

              // greyscale weights for RGB to gray conversion
              const vec4 sGrayScaleWeights = vec4(0.3086, 0.6094, 0.0820, 0.0);

              // used to convert from degrees to radians
              const float sDegreesToRadians = 0.01745329252;

              // 2 texture inputs
              uniform sampler2D tex0;
              uniform sampler2D tex1;

              // ISADORA_FLOAT_PARAM(amount, amtt, 0.0, 100.0, 50.0, "Displace amount.");
              uniform float amount;

              // ISADORA_FLOAT_PARAM(angle, angl, 0.0, 360.0, 0.0, "Displace angle");
              uniform float angle;

              void main(void) {

              float radians = (angle/360.0) * sDegreesToRadians;

              vec2 offset_max = vec2( (sin(radians) + 1.0) / 2.0, (cos(radians) + 1.0) / 2.0 );

              // displace tex0 pixels, according to the brightness of tex1 pixels

              vec4 c1 = texture2D(tex1, gl_TexCoord[0].st);
              vec4 greyColor = c1 * sGrayScaleWeights;
              float luminance = greyColor.r + greyColor.g + greyColor.b;

              vec2 src_coord = gl_TexCoord[0].st + offset_max * luminance * (amount/100.0);
              vec4 color = texture2D(tex0, src_coord);

              gl_FragColor = color;

              }

              Media Artist & Creator of Isadora
              Macintosh SE-30, 32 Mb RAM, MacOS 7.6, Dual Floppy Drives

              CitizenJoe 1 Reply Last reply Reply Quote 2
              • CitizenJoe
                CitizenJoe @mark last edited by

                @mark

                I get these errors when I compile your code, above:

                FRAG 0(2) : error C0000:-1 syntax error, unexpected '*' at token "*"
                FRAG 0(29) : warning C1503:-1 undefined variable "sGrayScaleWeights"

                Thanks,

                Hugh

                Hugh in Winnipeg - All test machines, Win10/11 Pro, 64 bit, OS SSD and separate data SSD.
                Dell 7560, i9 11950H, 64 gigs, NVIDIA RTX A4000 w/8 GB GDDR6

                Woland 1 Reply Last reply Reply Quote 0
                • Woland
                  Woland Tech Staff @CitizenJoe last edited by Woland

                  @citizenjoe

                  ChatGPT to the rescue :)
                  Disclaimer: I have no idea if this still does what it's supposed to, but the result looks cool and it compiles so ¯\_(ツ)_/¯

                  /*
                  a Displace Shader Actor
                  proposed by Jacques Hoepffner
                  after isadora Werkstatt 2017
                  updated by Mark Coniglio to move the pixels based
                  on an a displace amount and an angle instead of
                  separate x/y inputs
                  this version also calculates the actual greyscale
                  brightness of the pixel using standard a conversion
                  algorithm
                  Note that this code will not produce the same results
                  as the built-in Isadora Displace actor.
                  */
                  // greyscale weights for RGB to gray conversion
                  const vec4 sGrayScaleWeights = vec4(0.3086, 0.6094, 0.0820, 0.0);
                  // used to convert from degrees to radians
                  const float sDegreesToRadians = 0.01745329252 * 2.0 * 3.14159265359 / 360.0;
                  // 2 texture inputs
                  uniform sampler2D tex0;
                  uniform sampler2D tex1;
                  // ISADORA_FLOAT_PARAM(amount, amtt, 0.0, 100.0, 50.0, "Displace amount.");
                  uniform float amount;
                  // ISADORA_FLOAT_PARAM(angle, angl, 0.0, 360.0, 0.0, "Displace angle");
                  uniform float angle;
                  void main(void) {
                      float radians = angle * sDegreesToRadians;
                      vec2 offset_max = vec2(sin(radians), cos(radians));
                      // displace tex0 pixels, according to the brightness of tex1 pixels
                      vec4 c1 = texture2D(tex1, gl_TexCoord[0].st);
                      float luminance = dot(c1.rgb, sGrayScaleWeights.rgb);
                  
                  vec2 src_coord = gl_TexCoord[0].st + offset_max * luminance * (amount/100.0);
                  vec4 color = texture2D(tex0, src_coord);
                  
                  gl_FragColor = color;
                  

                  }

                  TroikaTronix Technical Support
                  New Support Ticket: https://support.troikatronix.com/support/tickets/new
                  Support Policy: https://support.troikatronix.com/support/solutions/articles/13000064762
                  Add-Ons: https://troikatronix.com/add-ons/ & https://troikatronix.com/add-ons/?u=woland
                  Professional Services: https://support.troikatronix.com/support/solutions/articles/13000109444

                  | Isadora Version: all of them | Mac Pro (Late 2013), macOS 10.14.6, 3.5GHz 6-core, 1TB SSD, 64GB RAM, Dual AMD FirePro D700s |

                  Woland 1 Reply Last reply Reply Quote 0
                  • Woland
                    Woland Tech Staff @Woland last edited by

                    Here's another version where the angle input works a bit better I think:

                    /*
                    a Displace Shader Actor
                    proposed by Jacques Hoepffner
                    after isadora Werkstatt 2017
                    updated by Mark Coniglio to move the pixels based
                    on a displace amount and an angle instead of
                    separate x/y inputs
                    this version also calculates the actual greyscale
                    brightness of the pixel using standard a conversion
                    algorithm
                    Note that this code will not produce the same results
                    as the built-in Isadora Displace actor.
                    */
                    // greyscale weights for RGB to gray conversion
                    const vec3 sGrayScaleWeights = vec3(0.3086, 0.6094, 0.0820);
                    // used to convert from degrees to radians
                    const float sDegreesToRadians = 0.01745329252;
                    // 2 texture inputs
                    uniform sampler2D tex0;
                    uniform sampler2D tex1;
                    // ISADORA_FLOAT_PARAM(amount, amtt, 0.0, 100.0, 50.0, "Displace amount.");
                    uniform float amount;
                    // ISADORA_FLOAT_PARAM(angle, angl, 0.0, 360.0, 0.0, "Displace angle");
                    uniform float angle;
                    void main(void) {
                        // Convert angle to radians
                        float radians = angle * sDegreesToRadians;
                        // Calculate offset direction based on angle
                        vec2 offset_direction = vec2(sin(radians), cos(radians));
                        // Sample the brightness from tex1
                        vec4 c1 = texture2D(tex1, gl_TexCoord[0].st);
                    
                    // Convert the sampled color to luminance
                    float luminance = dot(c1.rgb, sGrayScaleWeights);
                    
                    // Calculate the displacement offset
                    vec2 displacement = offset_direction * (luminance - 0.5) * (amount / 100.0);
                    
                    // Calculate the source coordinates in tex0
                    vec2 src_coord = gl_TexCoord[0].st + displacement;
                    // Sample the color from tex0 at the displaced coordinates
                    vec4 color = texture2D(tex0, src_coord);
                    // Output the final color
                    gl_FragColor = color;
                    

                    }

                    TroikaTronix Technical Support
                    New Support Ticket: https://support.troikatronix.com/support/tickets/new
                    Support Policy: https://support.troikatronix.com/support/solutions/articles/13000064762
                    Add-Ons: https://troikatronix.com/add-ons/ & https://troikatronix.com/add-ons/?u=woland
                    Professional Services: https://support.troikatronix.com/support/solutions/articles/13000109444

                    | Isadora Version: all of them | Mac Pro (Late 2013), macOS 10.14.6, 3.5GHz 6-core, 1TB SSD, 64GB RAM, Dual AMD FirePro D700s |

                    crystalhorizon 1 Reply Last reply Reply Quote 0
                    • dbini
                      dbini last edited by

                      I needed to do some Displacing yesterday and the CPU Displace was too heavy. I found a workaround using the displace function of Rutt Etra actor and setting the Draw Mode to Image Plane. It's pretty Displacey.  

                      John Collingswood
                      taikabox.com
                      2019 MBPT 2.6GHZ i7 OSX15.3.2 16GB
                      plus an old iMac and assorted Mac Minis for installations

                      Woland 1 Reply Last reply Reply Quote 2
                      • Woland
                        Woland Tech Staff @dbini last edited by

                        @dbini said:

                        Draw Mode [...] Image Plane [...] Pretty Displacey

                         Thanks for the band name ideas :)

                        TroikaTronix Technical Support
                        New Support Ticket: https://support.troikatronix.com/support/tickets/new
                        Support Policy: https://support.troikatronix.com/support/solutions/articles/13000064762
                        Add-Ons: https://troikatronix.com/add-ons/ & https://troikatronix.com/add-ons/?u=woland
                        Professional Services: https://support.troikatronix.com/support/solutions/articles/13000109444

                        | Isadora Version: all of them | Mac Pro (Late 2013), macOS 10.14.6, 3.5GHz 6-core, 1TB SSD, 64GB RAM, Dual AMD FirePro D700s |

                        1 Reply Last reply Reply Quote 2
                        • crystalhorizon
                          crystalhorizon Beta Platinum @Woland last edited by

                          @woland said:

                          /* a Displace Shader Actor proposed by Jacques Hoepffner after isadora Werkstatt 2017 updated by Mark Coniglio to move the pixels based on a displace amount and an angle instead of separate x/y inputs this version also calculates the actual greyscale brightness of the pixel using standard a conversion algorithm Note that this code will not produce the same results as the built-in Isadora Displace actor. */ // greyscale weights for RGB to gray conversion const vec3 sGrayScaleWeights = vec3(0.3086, 0.6094, 0.0820); // used to convert from degrees to radians const float sDegreesToRadians = 0.01745329252; // 2 texture inputs uniform sampler2D tex0; uniform sampler2D tex1; // ISADORA_FLOAT_PARAM(amount, amtt, 0.0, 100.0, 50.0, "Displace amount."); uniform float amount; // ISADORA_FLOAT_PARAM(angle, angl, 0.0, 360.0, 0.0, "Displace angle"); uniform float angle; void main(void) { // Convert angle to radians float radians = angle * sDegreesToRadians; // Calculate offset direction based on angle vec2 offset_direction = vec2(sin(radians), cos(radians)); // Sample the brightness from tex1 vec4 c1 = texture2D(tex1, gl_TexCoord[0].st); // Convert the sampled color to luminance float luminance = dot(c1.rgb, sGrayScaleWeights); // Calculate the displacement offset vec2 displacement = offset_direction * (luminance - 0.5) * (amount / 100.0); // Calculate the source coordinates in tex0 vec2 src_coord = gl_TexCoord[0].st + displacement; // Sample the color from tex0 at the displaced coordinates vec4 color = texture2D(tex0, src_coord); // Output the final color gl_FragColor = color; }

                           Thanks for the code Impro

                          Alexander Nantschev | http://www.crystalhorizon.at | located in Vienna Austria

                          1 Reply Last reply Reply Quote 2
                          • First post
                            Last post