Coder Social home page Coder Social logo

purplekingdomgames / ultraviolet Goto Github PK

View Code? Open in Web Editor NEW
57.0 57.0 2.0 1.74 MB

Scala 3 to GLSL transpiler library

License: MIT License

Scala 97.41% Shell 0.12% GLSL 1.65% HTML 0.70% Nix 0.12%
gamedev glsl indigo scala scala3 scala3-metaprogramming shaders ultraviolet webgl

ultraviolet's People

Contributors

davesmith00000 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

arcilli fblto

ultraviolet's Issues

Check that matrices support the `*` operator

In this example we multiply two matricies together, then multiply a vec4 by that, and swizzle.

vec2 scaleCoordsWithOffset(vec2 texcoord, vec2 offset){
  mat4 transform = translate2d(offset) * scale2d(FRAME_SIZE);
  return (transform * vec4(texcoord, 1.0, 1.0)).xy;
}

Here is the standard transform:

  mat4 transform = 
    translate2d(POSITION) *
    rotate2d(-1.0 * ROTATION) *
    scale2d(SIZE * SCALE) *
    translate2d(-(REF / SIZE) + 0.5) *
    scale2d(vec2(1.0, -1.0) * FLIP);

  gl_Position = u_projection * u_baseTransform * transform * VERTEX;

Check that inline shaders can take arguments

All the shader tests currently (I think) are like this:

inline def fragment: Shader[Env, vec4] = ???

But it would be super handy to be able to do either of these, too, as it unlocks things like the ability to use inline if (removing the need for the GLSL ifdef pre-processor):

inline def fragment(maxCount: Int): Shader[Env, vec4] = ???
inline def fragment: Int => Shader[Env, vec4] = maxCount => ???

Add missing functions (stubs or real)

  • fract
  • mix
  • max
  • min
  • dot
  • clamp
  • length
  • cos
  • sin
  • tan
  • atan
  • atan2 // Not a thing.
  • mod
  • floor
  • //- e.g. -sin(1.0)
  • normalize
  • pow
  • distance
  • abs
  • ops: + - / *
  • step
  • smoothstep
  • Boolean ops: && || < > <= >= ==
  • texture2D
  • reflect
  • textureCube
  • ceil
  • round
  • transpose

Possible bug: If statements assigned to a val

They currently allow for a simple values to be assigned like:

val x = if x < 10 then 5 else 15

But I have a suspicion that if the body was a Block then you'd get undesirable output.

Create 'enviroments'

I'd like to be able to do this:

import ultraviolet.environments.indigo.fragment.*

This would provide all the standard things available to an indigo fragment shader.

More missing functions...

  • type radians (type degrees)
  • type degrees (type radians)
  • type asin (type x)
  • type acos (type x)
  • type exp (type x)
  • type log (type x)
  • type exp2 (type x)
  • type log2 (type x)
  • type inversesqrt (type x)
  • type sign (type x)
  • mat matrixCompMult (mat x, mat y)
  • type faceforward (type N, type I, type Nref)
  • type refract (type I, type N,float eta)
  • bvec lessThan(vec x, vec y)
  • bvec lessThanEqual(vec x, vec y)
  • bvec greaterThan(vec x, vec y)
  • bvec greaterThanEqual(vec x, vec y)
  • bvec equal(vec x, vec y)
  • bvec notEqual(vec x, vec y)
  • bool any(bvec x)
  • bool all(bvec x)
  • bvec not(bvec x)
  • type dFdx( type x )
  • type dFdy( type x )
  • type fwidth( type p )

Is there a way to support returning Tuples from functions?

GLSL has no notion of Product types*. In GLSL, this isn't a problem because it's procedural and you can just assign multiple outputs to variables, or using the function argument out keyword.

However this makes things difficult for the functional programmer who'd like to be able to return more than one value from a function.

One solution might be to allow things like this:

def foo(): (Float, Float, Float) =
  (1.0f, 2.0f, 3.0f)

val (x, y, z) = foo()

Which just becomes:

float x;
float y;
float z;
void foo(){
  x=1.0;
  y=2.0;
  z=3.0;
}

It would need to error if the function does anything else.

*UPDATE: Initial assert isn't quite right, there are structs.

Add some sort of playground

Some way to add the ultraviolet lib to a project and kick out shaders for different platform flavours (webgl2, indigo, shadertoy) and also so generate a run a simple indigo project that loads and uses your shader for shadertoy-like local shader dev.

Should we support `COLOR.rgba` swizzles?

I decided to limit the API to xyzw - mostly because of the insane number of extension methods being generated - but I think rgba are valid swizzles, perhaps they should be supported?

Output for a simple, standard WebGL 2.0 fragment shader

Should be able to render this following (taken from the webgl2 fundamentals site):

#version 300 es
 
// fragment shaders don't have a default precision so we need
// to pick one. highp is a good default. It means "high precision"
precision highp float;
 
// we need to declare an output for the fragment shader
out vec4 outColor;
 
void main() {
  // Just set the output to a constant reddish-purple
  outColor = vec4(1, 0, 0.5, 1);
}

Return metadata with code print

Currently Ultraviolet is pretty much a straight translation from GLSL-like-Scala to GLSL and this is useful, but we're only scratching the surface.

Rather than returning just a string at the end of the printing process, we could also be returning metadata about the shader and which values it requires to be set.

This would allow us to do things like reading a UBO definition, only available in WebGL 2.0, and rewriting it as a series of uniform statements when exporting to WebGL 1.0. This wouldn't be a super efficient shader, but it would mean you only need to write your code once and stand a fair chance of it working everywhere.

Make examples

WebGL 2 hello triangle in Tyrian
Indigo
Shadertoy

Shader composition

Not a priority, but it would be great to be able to compose Shader types to facilitate testing and code reuse.

For any casual readers: I suspect this isn't as simple as it sounds because of the way inline macros work.

Introduce templates

Most shader programs conform to some sort of structure, sometimes ultraviolet can support that and the user just needs to know to do it. E.g. and Indigo fragment shader needs this entry point:

void fragment() {
 COLOR = vec4(1.0);
}

and that's perfectly encode-able as:

Shader[Env] { env =>
  def fragment: Unit =
    env.COLOR = vec4(1.0f)
}

But ShaderToy requires the following, that we cannot express (this is the default project code) because we don't support in/out function arguments:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));

    // Output to screen
    fragColor = vec4(col,1.0);
}

Going back to the Indigo example, another, more testable way to express that function might be this:

Shader[Env, vec4] { env =>
  vec4(1.0f)
}

where we consider the fragment function definition and COLOR output to just be part of the standard template. This makes the ShaderToy example work too (I think).

All we'd need to do is provide some sort of template information to the toGLSL call so that the output is rendered differently.

Add support for array constructors

Example from the docs:
const float array[3] = float[3](2.5, 7.0, 1.5);

Update, that's a terrible example! array is the variable name! ๐Ÿ˜„
const float foo[3] = float[3](2.5, 7.0, 1.5);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.