-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathcompute_shader.cljs
149 lines (131 loc) · 4.24 KB
/
compute_shader.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
(ns ^:figwheel-always game.client.compute_shader
(:require
[cljs.pprint :as pprint]
[com.stuartsierra.component :as component]
[promesa.core :as p]
[cats.core :as m]
[game.client.common :as common :refer [new-jsobj list-item data unique-id]]
[game.client.ground-local :as ground]
[game.client.config :as config]
[game.client.math :as math]
[game.client.gamma_ext :as ge :refer [get-name]]
[game.client.scene :as scene]
[game.client.engine2_explosion :as engine2_explosion]
[gamma.api :as g]
[gamma.program :as gprogram]
[clojure.string :as string])
(:require-macros [game.shared.macros :as macros :refer [defcom]]))
(def precision "precision mediump float;\n")
(def fake-if-template "
TYPE fake_if(bool test, TYPE arg1, TYPE arg2) {
return test ? arg1 : arg2;
}
")
(def swizzle-by-index "
float swizzle_by_index(vec4 arg, float index) {
if (index == 0.0) {
return arg.x;
} else {
if (index == 1.0) {
return arg.y;
} else {
if (index == 2.0) {
return arg.z;
} else {
return arg.w;
}
}
}
}
")
(def fake-if
(apply str
(map #(string/replace fake-if-template "TYPE" (name %)) [:float :vec2 :vec3 :vec4])))
(def preamble
(str
precision
swizzle-by-index
fake-if))
(def vertex-position (g/attribute "position" :vec3))
(def vertex-normal (g/attribute "normal" :vec3))
(def vertex-uv (g/attribute "uv" :vec2))
(def projection-matrix (g/uniform "projectionMatrix" :mat4))
(def model-view-matrix (g/uniform "modelViewMatrix" :mat4))
; v-uv.x subrange of 0 to 1 according to texture index
(def v-uv (g/varying "vUV" :vec2 :mediump))
; v-uv-normalized from 0 to 1
(def v-uv-normalized (g/varying "vUVNormalized" :vec2 :mediump))
(def u-copy-rt-scale (g/uniform "uCopyRTScale" :vec4))
(def t-copy-rt (g/uniform "tCopyRT" :sampler2D))
; COPY SHADER
; copy render target for debugging to screen
(def copy-vertex-shader
{
v-uv vertex-uv
(g/gl-position)
(->
(g/* projection-matrix model-view-matrix)
(g/* (g/vec4 vertex-position 1)))})
(def copy-fragment-shader
{
(g/gl-frag-color)
(g/div
(g/texture2D t-copy-rt v-uv)
u-copy-rt-scale)})
; (g/gl-frag-color) (g/abs (g/texture2D t-copy-rt v-uv))})
(def copy-shader
(gprogram/program
{
:vertex-shader copy-vertex-shader
:fragment-shader copy-fragment-shader}))
(def copy-shader-vs
(str preamble (:glsl (:vertex-shader copy-shader))))
(def copy-shader-fs
(str preamble (:glsl (:fragment-shader copy-shader))))
(defn get-compute-shader
[component config]
(let
[
screen-width (-> js/window .-innerWidth)
screen-height (-> js/window .-innerHeight)
plane (new js/THREE.PlaneBufferGeometry screen-width screen-height)
placeholder-material (new js/THREE.MeshBasicMaterial)
quad-target (new js/THREE.Mesh plane placeholder-material)
_ (-> quad-target .-position .-z (set! -500))
scene-render-target (new js/THREE.Scene)
camera-ortho (new js/THREE.OrthographicCamera (/ screen-width -2) (/ screen-width 2) (/ screen-height 2) (/ screen-height -2) -10000 10000)
_ (-> camera-ortho .-position .-z (set! 100))
_ (-> scene-render-target (.add camera-ortho))
_ (-> scene-render-target (.add quad-target))
copy-uniforms #js {}
_
(doto copy-uniforms
(aset
(get-name u-copy-rt-scale)
#js { :value (new js/THREE.Vector4 1 1 1 1)})
(aset
(get-name t-copy-rt)
#js { :value nil}))
copy-material
(new js/THREE.RawShaderMaterial
#js
{
:uniforms copy-uniforms
:vertexShader copy-shader-vs
:fragmentShader copy-shader-fs})]
(-> component
(assoc :quad quad-target)
(assoc :scene scene-render-target)
(assoc :camera camera-ortho)
(assoc :copy-material copy-material))))
(defcom
new-compute-shader
[config]
[quad scene camera copy-material]
(fn [component]
(if
(= (:start-count component) 0)
(get-compute-shader component config)
component))
(fn [component]
component))