Created
September 9, 2021 03:39
-
-
Save moniquelive/a8f518851f5291314afb98201db26f2f to your computer and use it in GitHub Desktop.
Nosso primeiro shader em ELM WebGL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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