<commit_before>** Phong

#+BEGIN_SRC c :noweb-ref phong-vs
  void main(){
      vec4 worldPos = model * vec4(position, 1.0);
      vec4 eyePos = view * worldPos;
      vEyePos = eyePos.xyz;
      vNormal = (normalMat * vec4(normal, 0.0)).xyz;
      vLightPos = (view * vec4(lightPos, 1.0)).xyz;
      vCol = normal * 0.5 + 0.5;
      gl_Position = proj * eyePos;
  }
#+END_SRC

#+BEGIN_SRC c :noweb-ref phong-fs
  vec3 ambientColor = vec3(0.1, 0.1, 0.1);
  vec3 diffuseColor = vCol;
  vec3 specularColor = vec3(1.0, 1.0, 1.0);

  float phong(vec3 L, vec3 E, vec3 N) {
    vec3 R = reflect(-L, N);
    return dot(R, E);
  }

  float blinnPhong(vec3 L, vec3 E, vec3 N) {
    vec3 halfVec = normalize(L + E);
    return dot(halfVec, N);
  }

  void main() {
    vec3 L = normalize(vLightPos - vEyePos);
    vec3 E = normalize(-vEyePos);
    vec3 N = normalize(vNormal);

    float NdotL = max(0.0, (dot(N, L) + wrap) / (1.0 + wrap));
    vec3 color = ambientColor + NdotL * diffuseColor;

    float specular = 0.0;
    if (useBlinnPhong)
      specular = blinnPhong(L, E, N);
    else
      specular = phong(L, E, N);

    color += max(pow(specular, shininess), 0.0) * specularColor;

    gl_FragColor = vec4(color, 1.0);
  }
#+END_SRC

** Demo

#+BEGIN_SRC clojure :noweb-ref demo :noweb yes
  (def vs "
   <<phong-vs>>")

  (def fs "
   <<phong-fs>>")
#+END_SRC

#+BEGIN_SRC clojure :noweb-ref demo
  (defn ^:export demo
    []
    (enable-console-print!)
    (let [gl (gl/gl-context "main")
          shader (sh/make-shader-from-spec
                  gl {:vs vs
                      :fs fs
                      :uniforms {:view :mat4
                                 :proj :mat4
                                 :model :mat4
                                 :normalMat :mat4
                                 :shininess :float
                                 :lightPos :vec3
                                 :useBlinnPhong :bool
                                 :wrap :float}
                      :attribs {:position :vec3
                                :normal :vec3}
                      :varying {:vNormal :vec3
                                :vEyePos :vec3
                                :vLightPos :vec3
                                :vCol :vec3}})
          ;; mesh (-> (s/sphere 0.5) (g/as-mesh {:res 20}))
          ma (-> (a/aabb 1) (g/as-mesh))
          mb (-> (s/sphere 1) (g/as-mesh {:res 10}))
          mc (-> (s/sphere 0.9) (g/as-mesh {:res 10}))
          mesh (-> ma
                   (csg/mesh->csg)
                   (csg/intersect (csg/mesh->csg mb))
                   (csg/subtract (csg/mesh->csg mc))
                   (csg/csg->mesh)
                   (g/center)
                   ;;(g/transform (g/scale M44 0.5))
                   ;;(sd/catmull-clark)
                   )
          floor (-> (a/aabb [2 0.1 2])
                    (g/center (vec3 0 -0.5 0))
                    (g/as-mesh {:flags :n}))
          mesh (g/into mesh floor)
          spec (gl/as-webgl-buffer-spec mesh {:tessellate true :fnormals true})
          _ (prn (:num-vertices spec))
          model {:shader shader
                 :attribs (buf/make-attribute-buffers
                           gl gl/static-draw
                           {:position {:data (:vertices spec) :size 3}
                            :normal {:data (:normals spec) :size 3}})
                 :uniforms {}
                 :mode gl/triangles
                 :count (:num-vertices spec)}
          timer (atom 0)]
      (anim/animate
       (fn [t]
         (let [view (-> (mat/look-at (vec3 0 0 2) (vec3) (vec3 0 1 0))
                        (g/rotate-y (* t 0.5)))
               proj (gl/perspective (gl/get-viewport-rect gl) 45 0.1 100.0)
               tx1 (-> M44 (g/translate 0 0 0) (g/rotate-x (* 0 0.15)))
               tx1inv (-> tx1 (g/invert) (g/transpose))
               light-pos (vec3 (* 0.2 (Math/sin t)) 1 0)]
           (gl/clear-depth-buffer gl 1)
           (gl/clear-color-buffer gl 0 0 0 1.0)
           (.enable gl gl/depth-test)
           (.enable gl gl/cull-face)
           (.cullFace gl gl/back)
           (buf/draw-arrays
            gl (merge model
                      {:uniforms {:model tx1
                                  :normalMat tx1inv
                                  :view view
                                  :proj proj
                                  :lightPos light-pos
                                  :shininess 4
                                  :useBlinnPhong 1}}))
           (set! (.-textContent (.getElementById js/document "fps")) (str (/ 1 (- t @timer)) "fps"))
           (reset! timer t)
           true)))
      {:ctx gl
       :shader shader}))

  (demo)
#+END_SRC


** Complete namespace definition

#+BEGIN_SRC clojure :tangle ../babel/test/thi/ng/geom/webgl/example01.cljs :noweb yes :mkdirp yes :padline no
(ns thi.ng.geom.webgl.example01
  (:require
    [thi.ng.geom.webgl.core :as gl]
    [thi.ng.geom.webgl.arrays :as arrays]
    [thi.ng.geom.webgl.animator :as anim]
    [thi.ng.geom.webgl.buffers :as buf]
    [thi.ng.geom.webgl.shaders :as sh]
    [thi.ng.geom.webgl.utils :as u]
    [thi.ng.geom.core :as g]
    [thi.ng.geom.core.vector :as v :refer [vec2 vec3]]
    [thi.ng.geom.core.matrix :as mat :refer [M44]]
    [thi.ng.geom.types]
    [thi.ng.geom.aabb :as a]
    [thi.ng.geom.sphere :as s]
    [thi.ng.geom.gmesh]
    [thi.ng.geom.mesh.csg :as csg]
    [thi.ng.geom.mesh.subdivision :as sd]
    [thi.ng.common.error :as err])
  (:require-macros
    [thi.ng.macromath.core :as mm]))

  <<demo>>
#+END_SRC<commit_msg>update demo to use shader preset<commit_after>
** Demo

#+BEGIN_SRC clojure :noweb-ref demo
  (defn ^:export demo
    []
    (enable-console-print!)
    (let [gl (gl/gl-context "main")
          shader (sh/make-shader-from-spec gl phong/shader-spec)
          ;; mesh (-> (s/sphere 0.5) (g/as-mesh {:res 20}))
          ma (-> (a/aabb 1) (g/as-mesh))
          mb (-> (s/sphere 1) (g/as-mesh {:res 10}))
          mc (-> (s/sphere 0.9) (g/as-mesh {:res 10}))
          mesh (-> ma
                   (csg/mesh->csg)
                   (csg/intersect (csg/mesh->csg mb))
                   (csg/subtract (csg/mesh->csg mc))
                   (csg/csg->mesh)
                   (g/center)
                   ;;(g/transform (g/scale M44 0.5))
                   ;;(sd/catmull-clark)
                   )
          floor (-> (a/aabb [2 0.1 2])
                    (g/center (vec3 0 -0.5 0))
                    (g/as-mesh {:flags :n}))
          mesh (g/into mesh floor)
          spec (gl/as-webgl-buffer-spec mesh {:tessellate true :fnormals true})
          _ (prn (:num-vertices spec))
          model {:shader shader
                 :attribs (buf/make-attribute-buffers
                           gl gl/static-draw
                           {:position {:data (:vertices spec) :size 3}
                            :normal {:data (:normals spec) :size 3}})
                 :uniforms {}
                 :mode gl/triangles
                 :count (:num-vertices spec)}
          timer (atom 0)]
      (anim/animate
       (fn [t]
         (let [y (m/map-interval (Math/sin (* t 0.5)) -1 1 0 2)
               view (-> (mat/look-at (vec3 0 y 2) (vec3) (vec3 0 1 0))
                        (g/rotate-y (* t 0.5))) 
               proj (gl/perspective (gl/get-viewport-rect gl) 45 0.1 100.0)
               tx1 (-> M44 (g/translate 0 0 0) (g/rotate-x (* 0 0.15)))
               tx1inv (-> tx1 (g/invert) (g/transpose))
               light-pos (vec3 (* 0.2 (Math/sin t)) 1 0)]
           (gl/clear-depth-buffer gl 1)
           (gl/clear-color-buffer gl 0.95 0.97 1.0 1.0)
           (.enable gl gl/depth-test)
           (.enable gl gl/cull-face)
           (.cullFace gl gl/back)
           (buf/draw-arrays
            gl (merge model
                      {:uniforms {:model tx1
                                  :normalMat tx1inv
                                  :view view
                                  :proj proj
                                  :lightPos light-pos
                                  :shininess 4
                                  :useBlinnPhong true}}))
           (set! (.-textContent (.getElementById js/document "fps")) (str (/ 1 (- t @timer)) "fps"))
           (reset! timer t)
           true)))
      {:ctx gl
       :shader shader}))

  (demo)
#+END_SRC


** Complete namespace definition

#+BEGIN_SRC clojure :tangle ../babel/test/thi/ng/geom/webgl/example01.cljs :noweb yes :mkdirp yes :padline no
(ns thi.ng.geom.webgl.example01
  (:require
    [thi.ng.geom.webgl.core :as gl]
    [thi.ng.geom.webgl.arrays :as arrays]
    [thi.ng.geom.webgl.animator :as anim]
    [thi.ng.geom.webgl.buffers :as buf]
    [thi.ng.geom.webgl.shaders :as sh]
    [thi.ng.geom.webgl.shaders.phong :as phong]
    [thi.ng.geom.webgl.utils :as u]
    [thi.ng.geom.core :as g]
    [thi.ng.geom.core.vector :as v :refer [vec2 vec3]]
    [thi.ng.geom.core.matrix :as mat :refer [M44]]
    [thi.ng.geom.types]
    [thi.ng.geom.aabb :as a]
    [thi.ng.geom.sphere :as s]
    [thi.ng.geom.gmesh]
    [thi.ng.geom.mesh.csg :as csg]
    [thi.ng.geom.mesh.subdivision :as sd]
    [thi.ng.common.math.core :as m]
    [thi.ng.common.error :as err])
  (:require-macros
    [thi.ng.macromath.core :as mm]))

  <<demo>>
#+END_SRC
{'fraction_non_alphanumeric': 0.14527533747589458, 'fraction_numerical': 0.02581958431540604, 'mean_word_length': 1.3644883485309016, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 19, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1967156', 'n_tokens_mistral': 3531, 'n_tokens_neox': 3206, 'n_words': 761}