Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Haskell
Wiki community
Recent changes
Random page
HaskellWiki
Search
Search
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Glome tutorial
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Special pages
Page information
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Textures, Lighting=== In Glome, textures are not associated with individual geometric primitives. Instead, it uses a container object called "Tex": <haskell>Tex (SolidItem t m) (Texture tag mat)</haskell> The SolidItem is the thing that we want to apply the texture to, and the Texture is the texture itself. A texture, in turn, is a function that takes a ray and it's corresponding ray intersection and returns a material. The shader's job is to take the material and ray intersection data and figure out what color to render it. It's possible to define your own material types, but most of the time you'll want to use the one provided by Shader.hs: <haskell> data Material t = Surface Color Flt Flt Flt Flt Flt Bool | -- color, alpha, ambient, diffuse, specular, shine, dielectric Reflect Flt | -- amount Refract Flt Flt | -- amount, ior Warp (SolidItem t (Material t)) (SolidItem t (Material t)) [Light] (Ray -> Rayint t (Material t) -> Ray) | -- frame, scene, ctx, xfm AdditiveLayers [Material t] | Blend (Material t) (Material t) Flt </haskell> A "Surface" defines basic surface properties like ambient, diffuse, and specular illumination. "Reflect" is used for reflective surfaces (like mirrors), and Refract is used for refraction (not currently implemented). AdditiveLayers is used to layer multiple Materials and add the colors together, while Blend allows you to create a weighted mixture of two layers. Often, we might want to texture a single object by itself: <haskell> m_matte :: Color -> M m_matte c = (Surface c 1 0.03 1 0 0 False) matte :: Color -> T matte c = (\_ _ -> m_matte c) Tex (sphere (Vec 0 0 0) 1) (matte (Color 1 0 0)) </haskell> This produces a red ball. Or we could texture a whole group of objects at once by wrapping a "tex" around a whole group (or bih) of objects. A textured object is just a regular object, so what happens if we apply another Texture? <haskell>Tex (Tex (sphere (Vec 0 0 0) 1) (matte (Color 1 0 0))) (matte (Color 0 1 0))</haskell> You might think this will produce a green ball, but in fact it produces a red one. The rule here is that the innermost texture has highest priority. Applying a texture to a large group of objects applies that texture only to the objects that don't already have a texture. An exception is if the inner texture returns an alpha value less than one (i.e. it's at least partially transparent), in which case the outer texture is applied underneath the inner texture. Textures can have very complicated behavior, since they can act conditionally on all the data the ray tracer returns. <haskell> type Texture tag mat = Ray -> Rayint tag mat -> mat data Rayint tag mat = RayHit { ridepth' :: !Flt, ripos :: !Vec, rinorm :: !Vec, riray :: !Ray, riuvw :: !Vec, ritex :: [Texture tag mat], ritag :: [tag] } | RayMiss deriving Show </haskell> The most useful field here is "ripos" which is the XYZ coordinates of the location of the ray intersection. Most textures won't need to access the other fields. Note that a ray can miss it's target object, in which case the value of the Rayint is "RayMiss". In general, a texture shouldn't need to worry about that case, since Glome wouldn't be evaluating the texture if the ray missed the object. When creating textures, it may be necessary to add some random variation to make it more interesting to look at. For this, "perlin" is a Perlin noise function, defined in "SolidTexture.hs". Perlin noise is a well-known and efficient algorithm for generating a three dimensional splotchy pattern that is a very useful building block for defining more complex textures. One caveat about using Tex is that the Bih constructor treats a Tex (and all the objects it contain) as a monolithic object. So, if a Tex contains many objects (or even just a few), you might want to use "bih" instead of "group" on the children, even if you're running "bih" at the root of the scene. Along with Tex, Glome provides a Tag type which behaves similarly to Tex except that the tag type is left up to the application. Tags aren't directly useful for rendering, but they can be very handy for other computational geometry tasks if you need to have some way to know exactly what a ray hit.
Summary:
Please note that all contributions to HaskellWiki are considered to be released under simple permissive license (see
HaskellWiki:Copyrights
for details). If you don't want your writing to be edited mercilessly and redistributed at will, then don't submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!
Cancel
Editing help
(opens in new window)
Toggle limited content width