Snippets

Joseph Chow Fbo ping-pong example

Created by Joseph Chow
(ns mxtapes.fbotest5
  (:require
    [thi.ng.geom.matrix :refer [M44]]
    [matchstick.buffer :as buffer]
    [matchstick.core :as mscore]
    [thi.ng.typedarrays.core :as arrays]
    [thi.ng.math.core :as math]
    [mxtapes.globals :as globals]
    [thi.ng.geom.gl.buffers :as buf]
    [matchstick.SimpleGeometry :as sgeometry]
    [matchstick.shaders.basicshaders :as bshaders]
    [matchstick.shaders.shadervars :as svars]
    [thi.ng.geom.gl.shaders :as sh]
    [thi.ng.geom.gl.core :as gl]
    [thi.ng.geom.gl.webgl.constants :as glc]
    [thi.ng.geom.gl.camera :as cam]
    [thi.ng.geom.core :as g]
    [thi.ng.geom.gl.fx :as fx]
    [thi.ng.color.core :as col]
    [thi.ng.geom.vector :refer [vec3]]
    [matchstick.shaders.noise.curlnoise :as cnoise]
    [thi.ng.geom.vector :as vec]
    [thi.ng.geom.vector :as v]))



(def particleOrigins (arrays/float32 (* 128 128 4)))
(dotimes [i (aget particleOrigins "length")]
  (aset particleOrigins i (* (- (math/random) 0.5) 128)))

(def fbo-size 128)
(def rt1_tex (buffer/DataTextureFloat globals/gl particleOrigins))
(def rt2_tex (buffer/DataTextureFloat globals/gl particleOrigins))
(def rt3_tex (buffer/DataTextureFloat globals/gl particleOrigins))

(def rt1 (buf/make-fbo-with-attachments globals/gl {:tex rt1_tex
                                                    :width 128
                                                    :height 128
                                                    :depth? false}))


(def rt2 (buf/make-fbo-with-attachments globals/gl {:tex rt2_tex
                                                    :width 128
                                                    :height 128
                                                    :depth? false}))

(def rt3 (buf/make-fbo-with-attachments globals/gl {:tex rt3_tex
                                                    :width 128
                                                    :height 128
                                                    :depth? false}))
(def simshader

  "Defines a complete basic color shader spec"
  {:vs       (str "void main() {
              vec3 c = color;
              vec3 n = normal;
              vUv = uv;"
                  "gl_Position =  model * vec4(position, 1.0);"
                  "}")

   :fs       (str
               cnoise/curlNoise
              "void main (){"
              "vec2 uv = gl_FragCoord.xy / resolution;"
              "vec4 oPos = texture2D( originTexture , vUv );"
              "vec4 pos  = texture2D( destinationTexture , vUv );"
              "vec3 vel = pos.xyz - oPos.xyz;"

              "vec3 curl = curlNoise( pos.xyz * noiseSize );"

              "vel += curl;"
              "vel *= .97;"

              "vec3 p = pos.xyz + vel;"
              "gl_FragColor = vec4( p , 1. );"
              ;;"gl_FragColor = vec4(1.0,1.0,0.0,1.0);"
               "}")
   :uniforms {:proj               :mat4
              :model              [:mat4 M44]
              :noiseSize          [:float 0.1]
              :resolution         [:vec2 (v/vec2 js/window.innerWidth js/window.innerHeight)]
              :originTexture      [:sampler2D 1]
              :destinationTexture [:sampler2D 2]}
   :attribs  {:position :vec3
              :normal   :vec3
              :color    :vec3
              :uv       :vec2}
   :varying  {:vUv :vec2}
   :state    {:depth-test false}})
(def rendershader
  "Defines the rendering shader used in the render stage of ping-ponging
  set the texture uniform with the texture that you expect to receive from the simulation state"
  {:vs       (str "void main() {
              vec3 c = color;
              vec3 n = normal;
              vUv = uv;"
                  "vPosition = position;"
                  "gl_Position =  proj * view * model * vec4(position, 1.0);"
                  "}")
   :fs       (str "void main() {
                vec2 uv = gl_FragCoord.xy / resolution;
                //gl_FragColor = vec4(uv,0.0,1.0);
                 vec4 oPos = texture2D(tpos,vUv);
                gl_FragColor = oPos;
             }")

   :uniforms {:proj       :mat4
              :view       :mat4
              :model      [:mat4 M44]
              :resolution [:vec2 (v/vec2 js/window.innerWidth js/window.innerHeight)]
              :tpos       [:sampler2D 0]}
   :attribs  {:position :vec3
              :normal   :vec3
              :color    :vec3
              :uv       :vec2}
   :varying  {:vUv       :vec2
              :vPosition :vec3}
   :state    {}})

(def simquad (-> (sgeometry/init-quad globals/gl)
                 (assoc :shader (sh/make-shader-from-spec globals/gl simshader))))

(def model (-> (sgeometry/init-quad globals/gl)
               (assoc :shader (sh/make-shader-from-spec globals/gl rendershader))))


(defn drawquad []
  (gl/draw-with-shader
    globals/gl
    simquad))

(defn render []
  (gl/draw-with-shader
    globals/gl
    (-> model
        (cam/apply globals/camera))))

(def timer 0)
(def output nil)
(defn draw [t]

  (let [flipFlop (mod timer 3)]

    (if (= flipFlop 0)
      (do
        (gl/bind rt3)
        (doto globals/gl
          (gl/set-viewport 0 0 fbo-size fbo-size) )

        (gl/bind rt1_tex 1)
        (gl/bind rt2_tex 2)

        (drawquad)
        (gl/unbind rt1_tex)
        (gl/unbind rt2_tex)
        (gl/unbind rt3)
        (set! output rt3_tex)
        ))


    (if (= flipFlop 1)
      (do
        (gl/bind rt1)
        (doto globals/gl
          (gl/set-viewport 0 0 fbo-size fbo-size))
        (gl/bind rt2_tex 1)
        (gl/bind rt3_tex 2)


        (drawquad)
        (gl/unbind rt2_tex)
        (gl/unbind rt3_tex)
        (gl/unbind rt1)
        (set! output rt1_tex)
        ))

    (if (= flipFlop 2)
      (do
        (gl/bind rt2)
        (doto globals/gl
          (gl/set-viewport 0 0 fbo-size fbo-size))
        (gl/bind rt3_tex 1)
        (gl/bind rt1_tex 2)


        (drawquad)
        (gl/unbind rt3_tex)
        (gl/unbind rt1_tex)
        (gl/unbind rt2)
        (set! output rt2_tex)
        ))

    )

  (mscore/reset-viewport globals/gl)
  (gl/bind output 0)
  (render)
  (gl/unbind output)
  (set! timer (inc timer))
  )

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.