JSFiddle - React, Tailwind, and code Playground

by realhunts

HTML

<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>
const mobile = ( navigator.userAgent.match(/Android/i)
      || navigator.userAgent.match(/webOS/i)
      || navigator.userAgent.match(/iPhone/i)
      || navigator.userAgent.match(/BlackBerry/i)
      || navigator.userAgent.match(/Windows Phone/i)
      );
function randInt(min, max) {
    return Math.round(Math.random() * Math.abs(max - min) + min);
  }
function createGrass(scene, sourceMesh){

//Variables for blade mesh
var joints = 5;
var n = .5
var w_ = 0.12*n;
var h_ = .5*n;

//Patch side length
var width = 120;

//Number of blades
var instances = 5000;
if(mobile){
	instances = 5000;
	width = 120;
}

function multiplyQuaternions(q1, q2){
  x =  q1.x * q2.w + q1.y * q2.z - q1.z * q2.y + q1.w * q2.x;
  y = -q1.x * q2.z + q1.y * q2.w + q1.z * q2.x + q1.w * q2.y;
  z =  q1.x * q2.y - q1.y * q2.x + q1.z * q2.w + q1.w * q2.z;
  w = -q1.x * q2.x - q1.y * q2.y - q1.z * q2.z + q1.w * q2.w;
  return new THREE.Vector4(x, y, z, w);
}

//************** Shader sources **************
var vertexSource = `
precision mediump float;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
attribute vec3 position;
attribute vec3 offset;
attribute vec2 uv;
attribute vec4 orientation;
attribute float halfRootAngleSin;
attribute float halfRootAngleCos;
attribute float stretch;
uniform float time;
varying vec2 vUv;
varying float frc;

//WEBGL-NOISE FROM https://github.com/stegu/webgl-noise

//Description : Array and textureless GLSL 2D simplex noise function. Author : Ian McEwan, Ashima Arts. Maintainer : stegu Lastmod : 20110822 (ijm) License : Copyright (C) 2011 Ashima Arts. All rights reserved. Distributed under the MIT License. See LICENSE file. https://github.com/ashima/webgl-noise https://github.com/stegu/webgl-noise

vec3 mod289(vec3 x) {return x - floor(x * (1.0 / 289.0)) * 289.0;} vec2 mod289(vec2 x) {return x - floor(x...

JavaScript

// a basic three.js scene

var container, renderer, scene, camera, controls;

init();
animate();

function init() {

    // renderer
    renderer = new THREE.WebGLRenderer({
        antialias: false
    });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0xccccff);
    container = document.createElement('div');
    document.body.appendChild(container);
    container.appendChild(renderer.domElement);

    // scene
    scene = new THREE.Scene();

    // camera
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
    camera.position.set(0, 200, 800);
    camera.lookAt(scene.position);

    // (camera) controls
    // mouse controls: left button to rotate, 
    //    mouse wheel to zoom, right button to pan
    controls = new THREE.OrbitControls(camera, renderer.domElement);

    // light    
    var light = new THREE.PointLight(0xffffff);
    light.position.set(100, 250, 250);
    scene.add(light);

    // mesh
    var sphereGeometry = new THREE.SphereGeometry(100, 32, 16);
    var sphereMaterial = new THREE.MeshLambertMaterial({
        color: 0xff0000
    });
    var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
    sphere.position.y = 100;
    scene.add(sphere);

    var planeGeometry = new THREE.PlaneGeometry(500, 500, 10, 10);
    var planeMaterial = new THREE.MeshLambertMaterial({
        color: 0x888888,
        side: THREE.DoubleSide
    });
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.rotation.x = -Math.PI / 2;
    scene.add(plane);


          var ground_geo = new THREE.PlaneGeometry(12, 12, 40, 40);
          ground_geo.rotateX(-Math.PI / 2)
        
          var grass = new createGrass(scene, new THREE.Mesh(ground_geo))
          grass.scale.set(40, 40, 40)
       
    // events
    window.addEventListener('resize', onWindowResize, false);

}

function onWindowResize(event) {
    camera.aspect = window.innerWidth /...