daily pastebin goal
53%
SHARE
TWEET

Grass Codea Simulation

sp4cemonkey Mar 28th, 2013 214 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Grass
  2.  
  3. -- Use this function to perform your initial setup
  4. function setup()
  5.     displayMode(FULLSCREEN)
  6.     field = mesh()
  7.     --field.shader = shader("Documents:Grass")
  8.     field.shader = shader(GrassShader.vertexShader, GrassShader.fragmentShader)
  9.     bladeWidth = 0.15
  10.     bladeHeight = 1.5
  11.     midWeight = 0.2
  12.     size = vec2(30,30)
  13.     touchScale = 10
  14.     numBlades = 10000
  15.    
  16.     field.shader.bladeHeight = bladeHeight
  17.     createField(field, size,numBlades)
  18.     generateTouchMesh(size)
  19.     --pressureZones are x,y then radius and finally type (1 = round pushout)
  20.     field.shader.pressureZone = vec4(-1000,-1000,0,0)
  21.    
  22.     campos = vec2(0,45)
  23.    
  24.     imageTouchSurface = image(WIDTH/touchScale,HEIGHT/touchScale)
  25.     currentPressurePoint = 1
  26.     pressurePoints = {}
  27.     pressurePoints[1] = vec4(-1000,-1000,0,0)
  28. end
  29.  
  30. function generateTouchMesh(size)
  31.     --make a square the same footprint as our field to read touch against
  32.     touchMesh = mesh()
  33.     touchMesh:resize(6)
  34.     touchMesh.vertices = {
  35.         vec3(-size.x/2, 0, -size.y/2),
  36.         vec3(-size.x/2, 0, size.y/2),
  37.         vec3(size.x/2, 0, -size.y/2),
  38.         vec3(-size.x/2, 0, size.y/2),
  39.         vec3(size.x/2, 0, size.y/2),
  40.         vec3(size.x/2, 0, -size.y/2)
  41.     }
  42.     touchMesh.texCoords = {
  43.         vec2(0,0),
  44.         vec2(0,1),
  45.         vec2(1,0),
  46.         vec2(0,1),
  47.         vec2(1,1),
  48.         vec2(1,0)
  49.     }
  50.     touchMesh:setColors(color(255,255,255,255))
  51.     --call out for out texture
  52.     touchMesh.texture = generateCoordTexture(vec2(100,100))
  53. end
  54.  
  55. function generateCoordTexture(resolution)
  56.     tex = image(resolution.x, resolution.y)
  57.     for x=1,resolution.x do
  58.         for y=1, resolution.y do
  59.             tex:set(x,y,x/resolution.x*255,y/resolution.y*255,0)
  60.         end
  61.     end
  62.     return tex
  63. end
  64.  
  65. function createField(field, size, blades)
  66.     --data is a vec4 that encode x as weight and y as height from base z and w represent x,y on the field
  67.     dataBuffer = field:buffer("data")
  68.     for i=1,blades do
  69.         pos = vec3(math.random() * size.x - (size.x/2), 0, math.random() * size.y - (size.y/2))
  70.         createBlade(field, pos, pos + vec3(0,bladeHeight,0))    
  71.     end
  72. end
  73.  
  74. function createBlade(field, baseLocation, topLocation)
  75.     local firstVertex = field.size + 1
  76.     field:resize(firstVertex+11)
  77.     local bladeRotation = math.random(360)
  78.     --setup our vertex locations
  79.     --2d vertex positions
  80.     v2d = vec2(bladeWidth/2,0):rotate(math.rad(bladeRotation))
  81.     midLocation = (baseLocation + topLocation)/2
  82.     --calculate the vertices
  83.     --base corners
  84.     v1 = vec3(v2d.x+baseLocation.x,baseLocation.y, v2d.y+baseLocation.z)
  85.     v2 = vec3(-v2d.x+baseLocation.x, baseLocation.y, -v2d.y+baseLocation.z)
  86.     --mid corners
  87.     v3 = vec3((v2d.x)+midLocation.x, midLocation.y, (v2d.x)+midLocation.z)
  88.     v4 = vec3(-(v2d.x)+midLocation.x, midLocation.y, -(v2d.x)+midLocation.z)
  89.     --point
  90.     v5 = vec3(v2d.x/2+topLocation.x,topLocation.y, v2d.y/2+topLocation.z)
  91.     v6 = vec3(-v2d.x/2+topLocation.x, topLocation.y, -v2d.y/2+topLocation.z)
  92.    
  93.     basecol = color(86, 153, 96, 255)
  94.     midcol = color(63, 163, 78, 255)
  95.     topcol = color(12, 229, 8, 255)
  96.     field:vertex(firstVertex, v1)
  97.     field:vertex(firstVertex+1, v2)
  98.     field:vertex(firstVertex+2, v3)
  99.     normal = (v2-v1):normalize():cross((v3-v1):normalize()):normalize()
  100.     field:normal(firstVertex, normal)
  101.     field:normal(firstVertex+1, normal)
  102.     field:normal(firstVertex+2, normal)
  103.     field:normal(firstVertex+3, normal)
  104.     field:normal(firstVertex+4, normal)
  105.     field:normal(firstVertex+5, normal)
  106.     field:normal(firstVertex+6, normal)
  107.     field:normal(firstVertex+7, normal)
  108.     field:normal(firstVertex+8, normal)
  109.     field:normal(firstVertex+9, normal)
  110.     field:normal(firstVertex+10, normal)
  111.     field:normal(firstVertex+11, normal)    
  112.     field:vertex(firstVertex+3, v3)
  113.     field:vertex(firstVertex+4, v4)
  114.     field:vertex(firstVertex+5, v2)
  115.     field:vertex(firstVertex+6, v3)
  116.     field:vertex(firstVertex+7, v4)
  117.     field:vertex(firstVertex+8, v5)
  118.     field:vertex(firstVertex+9, v4)
  119.     field:vertex(firstVertex+10, v5)
  120.     field:vertex(firstVertex+11, v6)
  121.     field:color(firstVertex, basecol)
  122.     field:color(firstVertex+1, basecol)
  123.     field:color(firstVertex+2, midcol)
  124.     field:color(firstVertex+3, midcol)
  125.     field:color(firstVertex+4, midcol)
  126.     field:color(firstVertex+5, basecol)
  127.     field:color(firstVertex+6, midcol)
  128.     field:color(firstVertex+7, midcol)
  129.     field:color(firstVertex+8, topcol)
  130.     field:color(firstVertex+9, midcol)
  131.     field:color(firstVertex+10, topcol)
  132.     field:color(firstVertex+11, topcol)
  133.     dataBuffer[firstVertex] = vec4(0, 0, baseLocation.x, baseLocation.z)
  134.     dataBuffer[firstVertex+1] = vec4(0, 0, baseLocation.x, baseLocation.z)
  135.     dataBuffer[firstVertex+2] = vec4(midWeight, midLocation.y - baseLocation.y, baseLocation.x, baseLocation.z)
  136.     dataBuffer[firstVertex+3] = vec4(midWeight, midLocation.y - baseLocation.y, baseLocation.x, baseLocation.z)
  137.     dataBuffer[firstVertex+4] = vec4(midWeight, midLocation.y - baseLocation.y, baseLocation.x, baseLocation.z)
  138.     dataBuffer[firstVertex+5] = vec4(0, 0, baseLocation.x, baseLocation.z)
  139.     dataBuffer[firstVertex+6] = vec4(midWeight, midLocation.y - baseLocation.y, baseLocation.x, baseLocation.z)
  140.     dataBuffer[firstVertex+7] = vec4(midWeight, midLocation.y - baseLocation.y, baseLocation.x, baseLocation.z)
  141.     dataBuffer[firstVertex+8] = vec4(1, topLocation.y - baseLocation.y, baseLocation.x, baseLocation.z)
  142.     dataBuffer[firstVertex+9] = vec4(midWeight, midLocation.y - baseLocation.y, baseLocation.x, baseLocation.z)
  143.     dataBuffer[firstVertex+10] = vec4(1, topLocation.y - baseLocation.y, baseLocation.x, baseLocation.z)
  144.     dataBuffer[firstVertex+11] = vec4(1, topLocation.y - baseLocation.y, baseLocation.x, baseLocation.z)
  145. end
  146.  
  147. function touched(touch)
  148.     if touch.state == BEGAN or touch.state == MOVING then
  149.         r,g,b,a = imageTouchSurface:get(touch.x/touchScale, touch.y/touchScale)
  150.         r = r / 255 * size.x - size.x/2
  151.         g = g / 255 * size.y - size.y/2
  152.         if math.abs(r-pressurePoints[currentPressurePoint].x) + math.abs(g-pressurePoints[currentPressurePoint].y) > 1 then
  153.             currentPressurePoint = (currentPressurePoint + 1)%20
  154.             pressurePoints[currentPressurePoint] = vec4(r,g,3,ElapsedTime)
  155.             if currentPressurePoint == 1 then
  156.                 field.shader.pressureZone1 = pressurePoints[currentPressurePoint]
  157.             elseif currentPressurePoint == 2 then
  158.                 field.shader.pressureZone2 = pressurePoints[currentPressurePoint]
  159.             elseif currentPressurePoint == 3 then
  160.                 field.shader.pressureZone3 = pressurePoints[currentPressurePoint]
  161.             elseif currentPressurePoint == 4 then
  162.                 field.shader.pressureZone4 = pressurePoints[currentPressurePoint]
  163.             elseif currentPressurePoint == 5 then
  164.                 field.shader.pressureZone5 = pressurePoints[currentPressurePoint]
  165.             elseif currentPressurePoint == 6 then
  166.                 field.shader.pressureZone6 = pressurePoints[currentPressurePoint]
  167.             elseif currentPressurePoint == 7 then
  168.                 field.shader.pressureZone7 = pressurePoints[currentPressurePoint]
  169.             elseif currentPressurePoint == 8 then
  170.                 field.shader.pressureZone8 = pressurePoints[currentPressurePoint]
  171.             elseif currentPressurePoint == 9 then
  172.                 field.shader.pressureZone9 = pressurePoints[currentPressurePoint]
  173.             elseif currentPressurePoint == 10 then
  174.                 field.shader.pressureZone10 = pressurePoints[currentPressurePoint]
  175.             elseif currentPressurePoint == 11 then
  176.                 field.shader.pressureZone11 = pressurePoints[currentPressurePoint]
  177.             elseif currentPressurePoint == 12 then
  178.                 field.shader.pressureZone12 = pressurePoints[currentPressurePoint]
  179.             elseif currentPressurePoint == 13 then
  180.                 field.shader.pressureZone13 = pressurePoints[currentPressurePoint]
  181.             elseif currentPressurePoint == 14 then
  182.                 field.shader.pressureZone14 = pressurePoints[currentPressurePoint]
  183.             elseif currentPressurePoint == 15 then
  184.                 field.shader.pressureZone15 = pressurePoints[currentPressurePoint]
  185.             elseif currentPressurePoint == 16 then
  186.                 field.shader.pressureZone16 = pressurePoints[currentPressurePoint]
  187.             elseif currentPressurePoint == 17 then
  188.                 field.shader.pressureZone17 = pressurePoints[currentPressurePoint]
  189.             elseif currentPressurePoint == 18 then
  190.                 field.shader.pressureZone18 = pressurePoints[currentPressurePoint]
  191.             elseif currentPressurePoint == 19 then
  192.                 field.shader.pressureZone19 = pressurePoints[currentPressurePoint]
  193.             elseif currentPressurePoint == 20 then
  194.                 field.shader.pressureZone20 = pressurePoints[currentPressurePoint]
  195.             end
  196.         end
  197.     end
  198. end
  199.  
  200. -- This function gets called once every frame
  201. function draw()
  202.     campos = campos:rotate(math.rad(0.2))
  203.     output.clear()
  204.     print(1/DeltaTime)
  205.     field.shader.time = ElapsedTime
  206.  
  207.     setContext(imageTouchSurface)
  208.     background(40, 40, 50)
  209.     camera(campos.x,30,campos.y, 0,0,0)
  210.     perspective()
  211.     touchMesh:draw()
  212.     setContext()
  213.     background(40,40,50)
  214.     camera(campos.x,30,campos.y, 0,0,0)
  215.     perspective()
  216.    
  217.     field.shader.vEyePosition = vec3(campos.x, 20, campos.y)
  218.     field.shader.vLightPosition = vec3(10,80,20)
  219.     field.shader.mInvModel = modelMatrix():inverse():transpose()
  220.        
  221.     field:draw()
  222. end
  223.  
  224. GrassShader = {
  225. vertexShader = [[
  226. //
  227. // A basic vertex shader
  228. //
  229.  
  230. //This is the current model * view * projection matrix
  231. // Codea sets it automatically
  232. uniform mat4 modelViewProjection;
  233.  
  234. uniform vec4 pressureZone1;
  235. uniform vec4 pressureZone2;
  236. uniform vec4 pressureZone3;
  237. uniform vec4 pressureZone4;
  238. uniform vec4 pressureZone5;
  239. uniform vec4 pressureZone6;
  240. uniform vec4 pressureZone7;
  241. uniform vec4 pressureZone8;
  242. uniform vec4 pressureZone9;
  243. uniform vec4 pressureZone10;
  244. uniform vec4 pressureZone11;
  245. uniform vec4 pressureZone12;
  246. uniform vec4 pressureZone13;
  247. uniform vec4 pressureZone14;
  248. uniform vec4 pressureZone15;
  249. uniform vec4 pressureZone16;
  250. uniform vec4 pressureZone17;
  251. uniform vec4 pressureZone18;
  252. uniform vec4 pressureZone19;
  253. uniform vec4 pressureZone20;
  254.  
  255. uniform float time;
  256. uniform highp mat4 mInvModel;
  257. uniform mediump vec3 vEyePosition;
  258. uniform mediump vec3 vLightPosition;
  259.  
  260. //This is the current mesh vertex position, color and tex coord
  261. // Set automatically
  262. attribute vec4 position;
  263. attribute vec4 color;
  264. attribute vec3 normal;
  265. attribute vec4 data;
  266.  
  267. //This is an output variable that will be passed to the fragment shader
  268. varying lowp vec4 vColor;
  269. varying highp vec3 lightDirection;
  270. varying mediump vec3 eyeDirection;
  271. varying mediump vec3 vNormal;
  272.  
  273. /// 2D Noise by Ian McEwan, Ashima Arts.
  274. vec3 mod289(vec3 x) {
  275.     return x - floor(x * (1.0 / 289.0)) * 289.0;
  276. }
  277.  
  278. vec2 mod289(vec2 x) {
  279.     return x - floor(x * (1.0 / 289.0)) * 289.0;
  280. }
  281.  
  282. vec3 permute(vec3 x) {
  283.     return mod289(((x*34.0)+1.0)*x);
  284. }
  285.  
  286. float snoise (vec2 v) {
  287.     const vec4 C = vec4(
  288.         0.211324865405187, // (3.0-sqrt(3.0))/6.0
  289.         0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
  290.         -0.577350269189626, // -1.0 + 2.0 * C.x
  291.         0.024390243902439); // 1.0 / 41.0
  292.         // First corner
  293.     vec2 i = floor(v + dot(v, C.yy) );
  294.     vec2 x0 = v - i + dot(i, C.xx);
  295.     // Other corners
  296.     vec2 i1;
  297.     i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
  298.     vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1;
  299.     // Permutations
  300.     i = mod289(i);
  301.     // Avoid truncation effects in permutation
  302.     vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 ));
  303.     vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
  304.     m = m*m ;
  305.     m = m*m ;
  306.     // Gradients: 41 points uniformly over a line, mapped onto a diamond.
  307.     // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
  308.     vec3 x = 2.0 * fract(p * C.www) - 1.0;
  309.     vec3 h = abs(x) - 0.5;
  310.     vec3 ox = floor(x + 0.5);
  311.     vec3 a0 = x - ox;
  312.     // Normalise gradients implicitly by scaling m
  313.     // Approximation of: m *= inversesqrt( a0*a0 + h*h );
  314.     m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
  315.     // Compute final noise value at P
  316.     vec3 g;
  317.     g.x = a0.x * x0.x + h.x * x0.y;
  318.     g.yz = a0.yz * x12.xz + h.yz * x12.yw;
  319.     return 60.0 * dot(m, g);
  320. }
  321.  
  322. vec2 applyPressure(vec4 pressureZone)
  323. {    
  324.     float radius = length(pressureZone.xy - data.zw);
  325.     if (radius < pressureZone.z) {
  326.         float factor;
  327.         if (time < pressureZone.w + 2.5) {
  328.             if (time < pressureZone.w + 0.5) {
  329.                 factor = 1.0 - (pressureZone.w + 0.5 - time)/0.5;
  330.             }
  331.             else {
  332.                 factor = 1.0 - (time - pressureZone.w - 0.5)/2.0;
  333.             }
  334.             return (normalize(data.zw - pressureZone.xy) *
  335.                 (1.0 - radius/pressureZone.z)) * factor * 2.0;
  336.         }
  337.     }  
  338.     return vec2(0,0);
  339. }
  340.  
  341. void main()
  342. {
  343.     //convert the positions of the eye and light from world space to object space and then make a vector from position for ADS lighting
  344.     lightDirection = ((vec4(vLightPosition,1) * mInvModel) - position).xyz;
  345.     eyeDirection = ((vec4(vEyePosition,1) * mInvModel) - position).xyz;
  346.    
  347.     //Pass the mesh color to the fragment shader
  348.     vColor = color;
  349.    
  350.     //apply force by weight
  351.     vec2 deformation = vec2(snoise(vec2(data.z/15.0+time/2.0,data.w/15.0+time/2.0)),
  352.         snoise(vec2(data.z/15.0+time/2.0+5000.0,data.w/15.0+time/2.0+5000.0)));
  353.    
  354.     //apply pressureZone
  355.    
  356.     deformation = deformation + applyPressure(pressureZone1);
  357.     deformation = deformation + applyPressure(pressureZone2);
  358.     deformation = deformation + applyPressure(pressureZone3);
  359.     deformation = deformation + applyPressure(pressureZone4);
  360.     deformation = deformation + applyPressure(pressureZone5);
  361.     deformation = deformation + applyPressure(pressureZone6);
  362.     deformation = deformation + applyPressure(pressureZone7);
  363.     deformation = deformation + applyPressure(pressureZone8);
  364.     deformation = deformation + applyPressure(pressureZone9);
  365.     deformation = deformation + applyPressure(pressureZone10);
  366.     deformation = deformation + applyPressure(pressureZone11);
  367.     deformation = deformation + applyPressure(pressureZone12);
  368.     deformation = deformation + applyPressure(pressureZone13);
  369.     deformation = deformation + applyPressure(pressureZone14);
  370.     deformation = deformation + applyPressure(pressureZone15);
  371.     deformation = deformation + applyPressure(pressureZone16);
  372.     deformation = deformation + applyPressure(pressureZone17);
  373.     deformation = deformation + applyPressure(pressureZone18);
  374.     deformation = deformation + applyPressure(pressureZone19);
  375.     deformation = deformation + applyPressure(pressureZone20);
  376.     deformation = deformation * data.x;
  377.     //limit the force length max to length from root
  378.     if (length(deformation) > (data.y*0.99)) {
  379.         deformation = normalize(deformation)*(data.y*0.99);
  380.     }
  381.     //calculate the vertical adjustment to retain length with deformation
  382.     float heightReduction = -(data.y-sqrt(pow(data.y,2.0) - pow(length(deformation),2.0)));
  383.    
  384.     vec4 positionModification = vec4(deformation.x,
  385.         heightReduction, deformation.y,0);
  386.        
  387.     //adjust the normal by the deformation for lighting
  388.     float defHorLength = length(deformation);
  389.     vec2 defHorDirection = normalize(deformation);
  390.    
  391.     //normal and color to fragment
  392.     //normals should be adjusted for pressure...
  393.     vNormal = normal;
  394.     if (data.y > 0.1) {
  395.     vNormal = normalize(normal + vec3(-defHorDirection.x*heightReduction/data.y,
  396.             defHorLength/data.y,
  397.             -defHorDirection.y*heightReduction/data.y));
  398.     }
  399.     //Multiply the vertex position by our combined transform
  400.     gl_Position = modelViewProjection * (position + positionModification);
  401. }
  402. ]],
  403. fragmentShader = [[
  404. precision lowp float;
  405.  
  406. uniform lowp sampler2D texture;
  407. //uniform lowp sampler2D bumpMap;
  408.  
  409. varying lowp vec4 vColor;
  410. varying mediump vec3 lightDirection;
  411. varying mediump vec3 eyeDirection;
  412. varying mediump vec3 vNormal;
  413.  
  414. const float c_zero = 0.0;
  415. const float c_one = 1.0;
  416. const float c_two = 2.0;
  417.  
  418. void main()
  419. {
  420.     //if (!gl_FrontFacing) discard;
  421.    
  422.     vec3 curNormal = normalize(vNormal);
  423.    
  424.     lowp vec4 curCol = vColor;    
  425.    
  426.     vec3 vLightDirection = normalize(normalize(lightDirection));
  427.     vec3 vCameraDirection = normalize(eyeDirection);
  428.  
  429.    
  430.     lowp vec4 vAmbientColor = curCol * 0.2;
  431.    
  432.     // Calculate Diffuse intensity
  433.     float fDiffuseIntensity = max(max( c_zero, dot( curNormal, vLightDirection )), dot(-curNormal, vLightDirection));
  434.  
  435.     lowp vec4 vDiffuseColor = curCol * fDiffuseIntensity;
  436.    
  437.     vAmbientColor.a = c_one;
  438.     vDiffuseColor.a = c_one;
  439.     //Set the output color to the texture color
  440.     gl_FragColor = vAmbientColor + vDiffuseColor;
  441.     //gl_FragColor = curCol;
  442. }
  443.  
  444. ]]
  445. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top