-- elm install elm-explorations/linear-algebra -- elm install elm-explorations/webgl import Browser import Browser.Events as E import Html exposing (Html) import Html.Attributes exposing (width, height, style) import Math.Matrix4 as Mat4 exposing (Mat4) import Math.Vector3 as Vec3 exposing (Vec3, vec3) import WebGL -- MAIN main =  Browser.element  { init = init  , view = view  , update = update  , subscriptions = subscriptions  } -- MODEL type alias Model =  Float init : () -> (Model, Cmd Msg) init () =  ( 0, Cmd.none ) -- UPDATE type Msg  = TimeDelta Float update : Msg -> Model -> (Model, Cmd Msg) update msg currentTime =  case msg of  TimeDelta delta ->  ( delta + currentTime, Cmd.none ) -- SUBSCRIPTIONS subscriptions : Model -> Sub Msg subscriptions _ =  E.onAnimationFrameDelta TimeDelta -- VIEW view : Model -> Html msg view t =  WebGL.toHtml  [ width 400, height 400, style "display" "block"  ]  [ WebGL.entity vertexShader fragmentShader mesh { perspective = perspective (t / 1000) }  ] perspective : Float -> Mat4 perspective t =  Mat4.mul  (Mat4.makePerspective 45 1 0.01 100)  (Mat4.makeLookAt (vec3 (4 * cos t) 0 (4 * sin t)) (vec3 0 0 0) (vec3 0 1 0)) -- MESH type alias Vertex =  { position : Vec3  , color : Vec3  } mesh : WebGL.Mesh Vertex mesh =  WebGL.triangles  [ ( Vertex (vec3 0 0 0) (vec3 1 0 0)  , Vertex (vec3 1 1 0) (vec3 0 1 0)  , Vertex (vec3 1 -1 0) (vec3 0 0 1)  )  ] -- SHADERS type alias Uniforms =  { perspective : Mat4  } vertexShader : WebGL.Shader Vertex Uniforms { vcolor : Vec3 } vertexShader =  [glsl|  attribute vec3 position;  attribute vec3 color;  uniform mat4 perspective;  varying vec3 vcolor;  void main () {  gl_Position = perspective * vec4(position, 1.0);  vcolor = color;  }  |] fragmentShader : WebGL.Shader {} Uniforms { vcolor : Vec3 } fragmentShader =  [glsl|  precision mediump float;  varying vec3 vcolor;  void main () {  gl_FragColor = vec4(vcolor, 1.0);  }  |]