# 3DSnow.lua

Dec 26th, 2015
144
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. --# Main
2. -- 3D Snow
3.
4. function setup()
5.     displayMode(OVERLAY)
6.     displayMode(FULLSCREEN)
7.
8.     parameter.watch("FPS")
9.     parameter.boolean("camOrtho", false)
10.     parameter.number("timeSpeed", 0, 8, 1)
13.     parameter.number("stretch", 0, 16, 0)
14.     parameter.boolean("vortex", false)
15.     parameter.boolean("night", false)
16.
17.     instances = 300
18.     snowMesh = mesh() -- Generate a mesh with 100 triangles randomly positioned and rotated in it, with texture coordinates
19.     local v = {}
20.     local tc = {}
21.     local size = 0.5 -- Lower this to make each individual triangle smaller
22.     local hspread = 25 -- The horizontal spread of triangles within the mesh
23.     local vspread = 5 -- The vertical spread of triangles within the mesh
24.     for i = 1, 100 do
25.         local rel = {vec3(-0.5, -0.5, 0), vec3(0.5, -0.5, 0.0), vec3(0.5, 0.5, 0.0)}
26.         for k, vec in ipairs(rel) do
27.             math.randomseed(i * math.pi * 10000 * 123456789)
28.             vec = matrix()
29.             :translate((math.random() * 2 - 1) * hspread, (math.random() * 2 - 1) * vspread, (math.random() * 2 - 1) * hspread)
30.             :rotate(math.random(0, 359), 1, 0, 0):rotate(math.random(0, 359), 0, 1, 0):rotate(math.random(0, 359), 0, 0, 1)
31.             *vec3(vec.x * size, vec.y * size, vec.z * size)
32.             table.insert(v, vec)
33.         end
34.         table.insert(tc, vec2(0, 0))
35.         table.insert(tc, vec2(1, 0))
36.         table.insert(tc, vec2(1, 1))
37.     end
38.
39.     snowMesh.vertices = v
40.     snowMesh.texCoords = tc
43.     transform = snowMesh:buffer("transform")
44.     transform.instanced = true
45.     transform:resize(instances)
46.     instTint = snowMesh:buffer("tint")
47.     instTint.instanced = true
48.     instTint:resize(instances)
49.     instAlpha = snowMesh:buffer("alpha")
50.     instAlpha.instanced = true
51.     instAlpha:resize(instances)
52.
53.     for i = 1, instances do
54.         math.randomseed(i)
55.         transform[i] = matrix()
56.         instTint[i] = color(255)
57.     end
58.
59.     time = 0
60.     ts = timeSpeed
61.
62.     pos = vec3(0, -50, 0) -- Variables to handle camera movement and direction
63.     ang = vec2(1, 1):normalize()
64.     ang2 = vec2(1, 1):normalize()
65.     tpos = vec3(pos.x, pos.y, pos.z)
66.     tang = vec2(ang.x, ang.y)
67.     tang2 = vec2(ang2.x, ang2.y)
68.
69.     mId = 0
70.     lId = 0
71.
72.     zoom = 20
73.     tzoom = zoom
74. end
75.
76. function draw()
77.     if night then
78.         background(0)
79.     else
80.         background(191, 220, 255)
81.     end
82.
83.     local pmix = 0.0375 -- Smoothes the camera movement
84.     pos.x = pos.x * (1 - pmix) + tpos.x * pmix
85.     pos.y = pos.y * (1 - pmix) + tpos.y * pmix
86.     pos.z = pos.z * (1 - pmix) + tpos.z * pmix
87.     local amix = 0.1
88.     ang.x = ang.x * (1 - amix) + tang.x * amix
89.     ang.y = ang.y * (1 - amix) + tang.y * amix
90.     ang2.x = ang2.x * (1 - amix) + tang2.x * amix
91.     ang2.y = ang2.y * (1 - amix) + tang2.y * amix
92.     local zmix = 0.1
93.     zoom = zoom * (1 - zmix) + tzoom * zmix
94.     local smix = 0.05
95.     ts = ts * (1 - smix) + timeSpeed * smix
96.     time = time + DeltaTime * ts
97.
98.     if camOrtho then
99.         camera(ang.x * ang2.x * -100, ang2.y * -100, ang.y * ang2.x * -100, ang.x * ang2.x, ang2.y, ang.y * ang2.x, 0, 1, 0)
100.         local aspect = WIDTH / HEIGHT
101.         ortho(-zoom * aspect, zoom * aspect, -zoom, zoom, 0.001, 65536)
102.     else
103.         camera(pos.x, pos.y, pos.z, pos.x + ang.x * ang2.x, pos.y + ang2.y, pos.z + ang.y * ang2.x, 0, 1, 0)
104.         perspective(70, WIDTH / HEIGHT, 0.001, 65536)
105.     end
106.
109.     local step = 1
110.     local height = 20
111.     local pOffset = 1
112.     local lOffset = 0
113.     for i = 1, instances do
114.         math.randomseed(i * math.pi * 10000)
115.         local max = (instances * height * step * lOffset + height * step * (1 - lOffset))
116.         local offset = (time + i * step * pOffset) % (instances * height * step * lOffset + height * step * (1 - lOffset))
117.         transform[i] = matrix()
118.         if vortex then
119.             transform[i] = transform[i]:rotate(time * 45, 0, 1, 0)
120.         end
121.         transform[i] = transform[i]:translate(0.0, -offset * 3.0, 0.0)
122.         :translate((math.random() * 2 - 1) * hspread, (math.random() * 2 - 1) * vspread, (math.random() * 2 - 1) * hspread)
123.         :rotate(math.random(0, 359), 0, 1, 0)
124.         instAlpha[i] = math.min(1, (offset / max) * height) * math.min(1, (1 - offset / max) * height)
125.     end
126.
128.
129.     snowMesh:draw(instances)
130.
131.     collectgarbage()
132.     collectgarbage()
133.     collectgarbage()
134. end
135.
136. function touched(touch) -- Handles camera movement and direction
137.     if touch.state == BEGAN then
138.         if touch.x < WIDTH / 2 and mId == 0 then
139.             mId = touch.id
140.         elseif touch.x >= WIDTH / 2 and lId == 0 then
141.             lId = touch.id
142.         end
143.     end
144.
145.     if touch.id == mId then
146.         if camOrtho then
147.             tzoom = tzoom - touch.deltaY / 20 * (tzoom / 40 + 0.5)
148.         else
149.             local speed = 1 / 32
150.             tpos.x = tpos.x + tang:rotate(math.pi / 2).x * touch.deltaX * speed
151.             tpos.z = tpos.z + tang:rotate(math.pi / 2).y * touch.deltaX * speed
152.             tpos.x = tpos.x + tang.x * tang2.x * touch.deltaY * speed
153.             tpos.z = tpos.z + tang.y * tang2.x * touch.deltaY * speed
154.             tpos.y = tpos.y + tang2.y * touch.deltaY * speed
155.         end
156.     elseif touch.id == lId then
157.         local speed = zoom / 40 + 0.5
158.         tang = tang:rotate(math.rad(touch.deltaX / 2 * speed))
159.         tang2 = tang2:rotate(math.rad(touch.deltaY / 2 * speed))
160.         if tang2.x < 0.01 then
161.             if tang2.y < 0 then
162.                 tang2 = vec2(0.01, -1):normalize()
163.             else
164.                 tang2 = vec2(0.01, 1):normalize()
165.             end
166.         end
167.     end
168.
169.     if touch.state == ENDED or touch.state == CANCELLED then
170.         if touch.id == mId then
171.             mId = 0
172.         elseif touch.id == lId then
173.             lId = 0
174.         end
175.     end
176. end
177.
178. vert=[[
179. uniform mat4 modelViewProjection;
180.
181. attribute mat4 transform;
182. attribute vec4 position;
183. attribute vec4 color;
184. attribute mediump vec2 texCoord;
185.
186. varying lowp vec4 vColor;
187. varying mediump vec2 vTexCoord;
188.
189. void main()
190. {
191.     vColor = color;
192.     vTexCoord = texCoord;
193.     gl_Position = modelViewProjection * (transform * position);
194. }
195. ]]
196.
197. frag=[[
198. uniform sampler2D texture;
199. varying lowp vec4 vColor;
200. varying mediump vec2 vTexCoord;
201. void main()
202. {
203.     gl_FragColor = vec4(1.0);//texture2D(texture, vTexCoord) * vColor;
204. }
205. ]]
206.
207.
208. --# Primitive
209. Primitive = class()
210. -- Primitive class originally by @spacemonkey
211. -- Edited by @SkyTheCoder to add options for width, height, length, and position, also to generate texture coordinates for the cube
212.
213. --primitves gives basic mesh building for cubes and isospheres
214. --triangles are wound consistently to avoid gl_facing issues
215.
216. function Primitive:Cube(w, h, l, x, y, z)
217.     local s = 1
218.     w = w or 1
219.     h = h or w
220.     l = l or h
221.     x = x or 0
222.     y = y or 0
223.     z = z or 0
224.     local vertices = {
225.       vec3(-0.5*s, -0.5*s,  0.5*s), -- Left  bottom front
226.       vec3( 0.5*s, -0.5*s,  0.5*s), -- Right bottom front
227.       vec3( 0.5*s,  0.5*s,  0.5*s), -- Right top    front
228.       vec3(-0.5*s,  0.5*s,  0.5*s), -- Left  top    front
229.       vec3(-0.5*s, -0.5*s, -0.5*s), -- Left  bottom back
230.       vec3( 0.5*s, -0.5*s, -0.5*s), -- Right bottom back
231.       vec3( 0.5*s,  0.5*s, -0.5*s), -- Right top    back
232.       vec3(-0.5*s,  0.5*s, -0.5*s), -- Left  top    back
233.     }
234.
235.     -- now construct a cube out of the vertices above
236.     v = {
237.       -- Front
238.       vertices[1], vertices[2], vertices[3],
239.       vertices[1], vertices[3], vertices[4],
240.       -- Right
241.       vertices[2], vertices[6], vertices[7],
242.       vertices[2], vertices[7], vertices[3],
243.       -- Back
244.       vertices[6], vertices[5], vertices[8],
245.       vertices[6], vertices[8], vertices[7],
246.       -- Left
247.       vertices[5], vertices[1], vertices[4],
248.       vertices[5], vertices[4], vertices[8],
249.       -- Top
250.       vertices[4], vertices[3], vertices[7],
251.       vertices[4], vertices[7], vertices[8],
252.       -- Bottom
253.       vertices[5], vertices[6], vertices[2],
254.       vertices[5], vertices[2], vertices[1],
255.     }
256.     for i, j in ipairs(v) do
257.         v[i] = vec3(j.x * w + x, j.y * h + y, j.z * l + z)
258.     end
259.     return v
260. end
261.
262. function Primitive:CubeTexCoords(w, h, x)
263.     w = w or 1
264.     h = h or w
265.     x = x or Primitive:Cube(1)
266.     local ret = {}
267.     for i = 1, #x / 3 do
268.         table.insert(ret, vec2(0.0, 0.0))
269.         table.insert(ret, vec2(w, 0.0))
270.         table.insert(ret, vec2(w, h))
271.         table.insert(ret, vec2(0.0, 0.0))
272.         table.insert(ret, vec2(w, h))
273.         table.insert(ret, vec2(0.0, h))
274.     end
275.     return ret
276. end
277.
278. function Primitive:Sphere(w, h, l, x, y, z, depth)
279.     local s = 1
280.     w = w or 1
281.     h = h or w
282.     l = l or h
283.     x = x or 0
284.     y = y or 0
285.     z = z or 0
286.     depth = depth or 1
287.     local t = (1 + math.sqrt(5)) / 2
288.     --all the vertices of an icosohedron
289.     local vertices = {
290.             vec3(-1 , t, 0):normalize(),
291.             vec3(1 , t, 0):normalize(),
292.             vec3(-1 , -t, 0):normalize(),
293.             vec3(1 , -t, 0):normalize(),
294.
295.             vec3(0 , -1, t):normalize(),
296.             vec3(0 , 1, t):normalize(),
297.             vec3(0 , -1, -t):normalize(),
298.             vec3(0 , 1, -t):normalize(),
299.
300.             vec3(t , 0, -1):normalize(),
301.             vec3(t , 0, 1):normalize(),
302.             vec3(-t , 0, -1):normalize(),
303.             vec3(-t , 0, 1):normalize()
304.         }
305.     --20 faces
306.     icovertices = {
307.             -- 5 faces around point 0
308.             vertices[1], vertices[12], vertices[6],
309.             vertices[1], vertices[6], vertices[2],
310.             vertices[1], vertices[2], vertices[8],
311.             vertices[1], vertices[8], vertices[11],
312.             vertices[1], vertices[11], vertices[12],
313.
315.             vertices[2], vertices[6], vertices[10],
316.             vertices[6], vertices[12], vertices[5],
317.             vertices[12], vertices[11], vertices[3],
318.             vertices[11], vertices[8], vertices[7],
319.             vertices[8], vertices[2], vertices[9],
320.
321.             -- 5 faces around point 3
322.             vertices[4], vertices[10], vertices[5],
323.             vertices[4], vertices[5], vertices[3],
324.             vertices[4], vertices[3], vertices[7],
325.             vertices[4], vertices[7], vertices[9],
326.             vertices[4], vertices[9], vertices[10],
327.
329.             vertices[5], vertices[10], vertices[6],
330.             vertices[3], vertices[5], vertices[12],
331.             vertices[7], vertices[3], vertices[11],
332.             vertices[9], vertices[7], vertices[8],
333.             vertices[10], vertices[9], vertices[2]
334.         }
335.
336.     local finalVertices = {}
337.     --divide each triangle into 4 sub triangles to make an isosphere
338.     --this can be repeated (based on depth) for higher res spheres
339.     for j=1,depth do
340.         for i=1,#icovertices/3 do
341.             midpoint1 = ((icovertices[i*3-2] + icovertices[i*3-1])/2):normalize()
342.             midpoint2 = ((icovertices[i*3-1] + icovertices[i*3])/2):normalize()
343.             midpoint3 = ((icovertices[i*3] + icovertices[i*3-2])/2):normalize()
344.             --triangle 1
345.             table.insert(finalVertices,icovertices[i*3-2])
346.             table.insert(finalVertices,midpoint1)
347.             table.insert(finalVertices,midpoint3)
348.             --triangle 2
349.             table.insert(finalVertices,midpoint1)
350.             table.insert(finalVertices,icovertices[i*3-1])
351.             table.insert(finalVertices,midpoint2)
352.             --triangle 3
353.             table.insert(finalVertices,midpoint2)
354.             table.insert(finalVertices,icovertices[i*3])
355.             table.insert(finalVertices,midpoint3)
356.             --triangle 4
357.             table.insert(finalVertices,midpoint1)
358.             table.insert(finalVertices,midpoint2)
359.             table.insert(finalVertices,midpoint3)
360.         end
361.         icovertices = finalVertices
362.         finalVertices = {}
363.     end
364.     for i, j in ipairs(icovertices) do
365.         icovertices[i] = vec3(j.x * w + x, j.y * h + y, j.z * l + z)
366.     end
367.     return icovertices
368. end
369.
370.
371. --# FPS
372. FPS = 0 -- Code to calculate accurate frames per secoond
373. local frames = 0
374. local time = 0
375. tween.delay(0.001, function()
376.     local d = draw
377.     draw = function()
378.         frames = frames + 1
379.         if math.floor(ElapsedTime) ~= math.floor(time) then
380.             FPS = frames - 1
381.             frames = 1
382.         end
383.         time = ElapsedTime
384.         d()
385.     end
386. end)
390. Snow = {
391. vS = [[
392. //
393. // A basic vertex shader
394. //
395.
396. //This is the current model * view * projection matrix
397. // Codea sets it automatically
398. uniform mat4 modelViewProjection;
399.
400. uniform highp float stretch;
401.
402. //This is the current mesh vertex position, color and tex coord
403. // Set automatically
404. attribute vec4 position;
405. attribute vec4 color;
406. attribute vec2 texCoord;
407. attribute mat4 transform;
408. attribute vec4 tint;
409. attribute lowp float alpha;
410.
411. //This is an output variable that will be passed to the fragment shader
412. varying lowp vec4 vColor;
413. varying highp vec2 vTexCoord;
414. varying lowp vec4 vTint;
415. varying lowp float vAlpha;
416.
417. void main()
418. {
419.     //Pass the mesh color to the fragment shader
420.     vColor = color;
421.     vTexCoord = texCoord;
422.     vTint = tint;
423.     vAlpha = alpha;
424.
425.     vec4 offset = vec4(0.0);
426.     if (vTexCoord.xy == vec2(1.0, 1.0)) offset = vec4(0.0, stretch, 0.0, 0.0);
427.
428.     //Multiply the vertex position by our combined transform
429.     gl_Position = modelViewProjection * (transform * (position + offset));
430. }
431. ]],
432. fS = [[
433. //
434. // A basic fragment shader
435. //
436.
437. //Default precision qualifier
438. precision highp float;
439.
440. //This represents the current texture on the mesh
441. uniform lowp sampler2D texture;
442.
443. //The interpolated vertex color for this fragment
444. varying lowp vec4 vColor;
445.
446. //The interpolated texture coordinate for this fragment
447. varying highp vec2 vTexCoord;
448.
449. varying lowp vec4 vTint;
450.
451. varying lowp float vAlpha;
452.
453. void main()
454. {
455.     //Sample the texture at the interpolated coordinate
456.     //lowp vec4 col = texture2D( texture, vTexCoord ) * vColor;
457.
458.     float dist = (1.0 - pow(min(1.0, distance(vTexCoord, vec2(0.75, 0.25)) * 4.0), 3.0));
459.     if (dist <= 0.1) discard;
460.
461.     //Set the output color to the texture color
462.     gl_FragColor = vec4(vTint.rgb, vAlpha) * dist;//col;
463. }
464. ]],
465. },
467. }
468. --# Utility
469. function math.dec(x)
470.     return x - math.floor(x)
471. end
472.
473. function math.mix(a, b, x)
474.     return a * x + b * (1 - x)
475. end
476.
480.     if select("#", ...) == 1 then
481.         local data = Shaders[select(1, ...)]
482.         if data ~= nil then
484.         else
486.         end
487.     else
489.     end
490. end
RAW Paste Data

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!