Skip to content

Commit

Permalink
README updates
Browse files Browse the repository at this point in the history
  • Loading branch information
davesmith00000 committed Sep 25, 2023
1 parent bf43dc3 commit 79616fb
Showing 1 changed file with 44 additions and 48 deletions.
92 changes: 44 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,50 +31,6 @@ Scala-CLI
//> using lib "io.indigoengine::ultraviolet:x.y.z"
```

## Using Ultraviolet with Scala 3.3.0

Ultraviolet (up to 0.1.1) was built against Scala 3.2.x, but does work with Scala 3.3.0 with one minor caveat: The thing to know is that calling external inlined functions doesn't work the way it used to anymore, and will produce errors that complain about illegal forward references.

Being able to call external inlined functions is important, because it's one of the main ways the Ultraviolet achieves code reuse.

Here is a simple example. Given an object called `Importable` like this:

```scala
object Importable:
inline def addOne = (i: Int) => i + 1
```

## In Scala 3.2.x

This used to work:

```scala
import Importable.*

inline def fragment: Shader[FragEnv, Int] =
Shader { _ =>
val value = 10
addOne(value)
}
```

## Scala 3.3.x

Unfortunately the way inlines are represented in the AST has now changed, and the old method does not work anymore. Luckily there is a simple workaround. All we have to do is create a local proxy with the same signature that delegates to the original function:

```scala
import Importable.*

inline def fragment: Shader[FragEnv, Int] =
Shader { _ =>
val proxy: Int => Int = addOne
val value = 10
proxy(value)
}
```

With this small change, we can continue to reuse code between shaders as before. Indeed the compiled output will be identical to how it was before.

## TL;DR: What is a Shader / Ultraviolet / basic programmer intuition

If you've stumbled across this repo and have no idea what all this shader stuff is about:
Expand Down Expand Up @@ -136,10 +92,6 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord )

Pretty similar! And in fact, converting GLSL examples to Scala + Ultraviolet tends to be quite a straightforward and mechanical process. Much work has been done to make the syntax feel the same or better.

## Status: "It works on my machine"

Ultraviolet is in early stage development. It appears to be working well but there will be many, many corner cases that haven't been found yet. Please report bugs and issues!

## Motivation

This project is motivated from two needs:
Expand Down Expand Up @@ -411,3 +363,47 @@ Here, 'external' means 'not inside the body of your shader'.
- A def that is essentially a call by reference val such as `inline def x = 1.0f` will have it's value inlined.
- A def that is a function, laid out like a method e.g. `inline def foo(c: Int): Int = c + 1` will be inlined.
- A def that is an anonymous function will be embedded with a new name and will work exactly as you'd expect, i.e. `inline def foo: Int => Int = c => c + 1`

## Using Ultraviolet with Scala > 3.3.0

Ultraviolet (up to 0.1.1) was built against Scala 3.2.x, but does work with Scala 3.3.0 with one minor caveat: The thing to know is that calling external inlined functions doesn't work the way it used to anymore, and will produce errors that complain about illegal forward references.

Being able to call external inlined functions is important, because it's one of the main ways the Ultraviolet achieves code reuse.

Here is a simple example. Given an object called `Importable` like this:

```scala
object Importable:
inline def addOne = (i: Int) => i + 1
```

## In Scala 3.2.x

This used to work:

```scala
import Importable.*

inline def fragment: Shader[FragEnv, Int] =
Shader { _ =>
val value = 10
addOne(value)
}
```

## Scala 3.3.x

Unfortunately the way inlines are represented in the AST has now changed, and the old method does not work anymore. Luckily there is a simple workaround. All we have to do is create a local proxy with the same signature that delegates to the original function:

```scala
import Importable.*

inline def fragment: Shader[FragEnv, Int] =
Shader { _ =>
val proxy: Int => Int = addOne
val value = 10
proxy(value)
}
```

With this small change, we can continue to reuse code between shaders as before. Indeed the compiled output will be identical to how it was before.

0 comments on commit 79616fb

Please sign in to comment.