Skip to content

Instantly share code, notes, and snippets.

@moniquelive
Created September 9, 2021 03:39
Show Gist options
  • Save moniquelive/a8f518851f5291314afb98201db26f2f to your computer and use it in GitHub Desktop.
Save moniquelive/a8f518851f5291314afb98201db26f2f to your computer and use it in GitHub Desktop.
Nosso primeiro shader em ELM WebGL
-- Render a spinning cube.
--
-- Dependencies:
-- 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 angle =
case msg of
TimeDelta dt ->
( angle + dt / 5000, Cmd.none )
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions _ =
E.onAnimationFrameDelta TimeDelta
-- VIEW
view : Model -> Html Msg
view angle =
WebGL.toHtmlWith
[ WebGL.clearColor 0 0 0 1
, WebGL.depth 1
, WebGL.alpha True ]
[ width 400, height 400, style "display" "block"
]
[ WebGL.entity vertexShader fragmentShader cubeMesh (uniforms angle)
]
type alias Uniforms =
{ rotation : Mat4
, perspective : Mat4
, camera : Mat4
, angle : Float
}
uniforms : Float -> Uniforms
uniforms angle =
{ rotation =
Mat4.mul
(Mat4.makeRotate (3 * angle) (vec3 0 1 0))
(Mat4.makeRotate (2 * angle) (vec3 1 0 0))
, perspective = Mat4.makePerspective 45 1 0.01 100
, camera = Mat4.makeLookAt (vec3 0 0 5) (vec3 0 0 0) (vec3 0 1 0)
, angle = angle
}
-- MESH
type alias Vertex =
{ color : Vec3
, position : Vec3
}
cubeMesh : WebGL.Mesh Vertex
cubeMesh =
let
rft = vec3 1 1 1
lft = vec3 -1 1 1
lbt = vec3 -1 -1 1
rbt = vec3 1 -1 1
rbb = vec3 1 -1 -1
rfb = vec3 1 1 -1
lfb = vec3 -1 1 -1
lbb = vec3 -1 -1 -1
in
WebGL.triangles <| List.concat <|
[ face (vec3 115 210 22 ) (vec3 52 101 164) (vec3 237 212 0 ) (vec3 204 0 0 ) rft rfb rbb rbt -- green
, face (vec3 52 101 164) (vec3 237 212 0 ) (vec3 204 0 0 ) (vec3 117 80 123) rft rfb lfb lft -- blue
, face (vec3 237 212 0 ) (vec3 204 0 0 ) (vec3 117 80 123) (vec3 245 121 0 ) rft lft lbt rbt -- yellow
, face (vec3 204 0 0 ) (vec3 117 80 123) (vec3 245 121 0 ) (vec3 115 210 22 ) rfb lfb lbb rbb -- red
, face (vec3 117 80 123) (vec3 245 121 0 ) (vec3 115 210 22 ) (vec3 52 101 164) lft lfb lbb lbt -- purple
, face (vec3 245 121 0 ) (vec3 115 210 22 ) (vec3 52 101 164) (vec3 237 212 0 ) rbt rbb lbb lbt -- orange
]
face : Vec3 -> Vec3 -> Vec3 -> Vec3 -> Vec3 -> Vec3 -> Vec3 -> Vec3 -> List ( Vertex, Vertex, Vertex )
face c1 c2 c3 c4 a b c d =
let
vertex cc position =
Vertex (Vec3.scale (1 / 255) cc) position
in
[ ( vertex c1 a, vertex c2 b, vertex c3 c )
, ( vertex c3 c, vertex c4 d, vertex c1 a )
]
-- SHADERS
vertexShader : WebGL.Shader Vertex Uniforms { vcolor : Vec3 }
vertexShader =
[glsl|
attribute vec3 position;
attribute vec3 color;
uniform mat4 perspective;
uniform mat4 camera;
uniform mat4 rotation;
uniform float angle;
varying vec3 vcolor;
void main () {
vec3 p = vec3(
cos(radians(160.0*angle))*position.x,
sin(radians(160.0*angle+cos(10.0*angle)*120.0))*position.y,
cos(radians(160.0*angle+240.0))*position.z);
gl_Position = perspective * camera * rotation * vec4(p, 1.0);
float x = cos(10.0*angle);
float y = sin(10.0*angle);
//gl_Position = vec4(x,y,1.0, 1.0) * gl_Position;
vcolor = color;
}
|]
fragmentShader : WebGL.Shader {} Uniforms { vcolor : Vec3 }
fragmentShader =
[glsl|
//precision mediump float;
precision highp float;
uniform float angle;
varying vec3 vcolor;
void main () {
/*vec3 c = vec3(
cos(radians(160.0*angle)) * vcolor.r,
sin(radians(160.0*angle)) * vcolor.g,
cos(radians(160.0*angle)) * vcolor.b);*/
vec3 c = vcolor;
gl_FragColor = 0.8 * vec4(c, 1); //abs(cos(radians(160.0*angle))));
}
|]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment