Open-source project
AcademySoftwareFoundation/OpenShadingLanguage avatar
AcademySoftwareFoundation/OpenShadingLanguage

OSL shaders compute closures, and the integrator does the sampling

Advanced shading language for production GI renderers

2,335 stars414 forksC++BSD-3-Clause

At a glance

What is it?
The Open Shading Language is a C-like language for programmable shading in production renderers, and its central design decision is that a shader does not return a colour. It returns a radiance closure, a symbolic description of how a surface scatters light, which the renderer's integrator evaluates, samples and re-evaluates. That is why there are no light loops in an OSL shader, and why the same material works under path tracing, bidirectional path tracing or a re-light without being rewritten.
Who is it for?
Adopt OSL if you are writing materials for a physically based renderer, because the closure model is what lets your shader be re-lit, re-sampled and reused by integrators you did not write, and the licence lets you embed it in a commercial renderer without a copyleft obligation. Do not adopt it for a real-time or GPU path, where a shader that returns a colour for a direction is the right shape and an integrator is not involved.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A shader returns a description, not a number

The difference the project leads with is the one that matters. In OSL, surface and volume shaders compute radiance closures rather than final colours, and a closure is an explicit symbolic description of the way a surface or volume scatters light, expressed in units of radiance. The contrast the README draws is with the older convention, where a shading language computes a surface colour visible from a particular direction. Those older shaders are described as black boxes that a renderer can do little with but execute to find one number, and the argument is specific: there is no effective way to discover from such a shader which directions are important to sample, and the physical units of lights and surfaces are often underspecified, which makes a physically correct shader hard to guarantee. A closure fixes both. It can be evaluated in particular directions, sampled to find the important ones, or saved and re-evaluated later, which is what a physically based renderer with ray tracing and global illumination needs. Everything else in the design follows from taking that seriously.

No light loops, and four things you get back

Because a shader describes rather than samples, OSL surface shaders contain no light loops and shoot no illumination rays. Reflection and refraction are not special cases in the shader; they are part of the radiance closure and look like any other BSDF to the renderer. A component called the integrator evaluates the closures for a particular set of light sources and decides in which directions rays should be traced. The README then lists what you get for giving up control of the sampling, and the list is the reason to care. Integration and sampling may be batched or re-ordered to increase ray coherence. A ray budget can be allocated to sample the BSDF optimally. The closures can be used for bidirectional ray tracing or Metropolis light transport. And a closure can be rapidly re-evaluated with new lighting without re-running the shaders, which is the feature that turns a re-light from a full re-render into a cheap pass. The cost is equally concrete: your shader no longer decides where light comes from, so a shader that would have compensated for bad sampling by brute force no longer can, and the quality you get depends on the integrator and its budget.

Lights are surfaces, and transparency is just illumination

Two smaller consequences of the closure model are stated as headline characteristics, and both come from the same place. First, there is no separate kind of shader for light sources: a light is simply an emissive surface, and all lights are area lights. There is no point light shader to write and no distinction to maintain in your code, which removes a category of shader that other languages make you write twice. Second, you do not set transparency or opacity variables in a shader, because transparency is another way light can interact with a surface and is carried inside the main radiance closure a surface shader computes. If you have written shaders for a renderer with an opacity output, the migration is a change of thinking rather than a change of syntax: the material describes how light leaves it in every direction including the transmissive one, and the integrator decides what to do with that. The language keeps C-like syntax, so a shader author will find the surface syntax familiar, while the semantics underneath are the part that takes reading twice.

AOVs are light path expressions, not output variables

The output mechanism is the fourth distinctive feature and the most immediately practical. Sometimes you want images of individual lighting components, a specular pass, a diffuse pass, a reflection pass, a per-light pass, and in most languages that means adding a pile of output variables to every shader and having the renderer collect them. OSL replaces that with a regular-expression-based notation for describing which light paths should contribute to which outputs, called light path expressions. The important detail is where the work happens: the README states that this is done on the renderer side, though supported by the OSL implementation. So the shader stays clean, and the studio decides what it wants to render in one place. For a library of two hundred shaders that is the difference between editing two hundred files and editing one configuration, and for anyone porting an existing shading library it is the part of the migration that touches the fewest lines. The tradeoff is that you no longer have a shader-local definition of your outputs, so the outputs become a property of the render rather than of the material.

make is a wrapper around cmake, and the knobs are LLVM ones

Installation is documented in INSTALL.md, and the top-level Makefile exists because the project would rather you not remember the CMake incantation. Its own comment says it is a fancy wrapper around cmake and that for many people it is a lot simpler to just type make and have everything happen automatically, and it offers make help to list the targets, with all, debug, profile, clean, realclean and nuke among them:

bash
make

The interesting part is which variables the wrapper forwards. A VERBOSE setting turns on verbose CMake and Ninja output and raises the test verbosity, and the forwarding is a plain translation of a make variable into a CMake define, for example:

bash
MY_CMAKE_FLAGS += -DLLVM_DIRECTORY:STRING=${LLVM_DIRECTORY}

There are matching switches for LLVM_VERSION, LLVM_NAMESPACE, LLVM_STATIC and USE_LLVM_BITCODE, plus an OSL_NAMESPACE define of its own and overridable paths for CMake and Ninja. That list tells you what the build is sensitive to. This is a project that compiles shading language source through LLVM, and the wrapper exists so that choosing an LLVM installation, a namespace or a static link is a make variable rather than a hand-edited cache.

Two release lines, one day apart

The release history shows something a version number alone would not. Three tags are visible: v1.15.7.0 on 2026-09-07, v1.14.12.0 on 2026-09-07 and v1.15.6.0 on 2026-08-02, and the last push to main is 2026-09-26. Two different major lines received a release on the same day, which reads as a maintenance line receiving fixes while the current line moves. The four-component version, 1.15.7.0, is a good reminder that a studio's shading library is versioned like the renderer it targets rather than like a web library. The repository also carries the files that say how the project is run: GOVERNANCE.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, THIRD-PARTY.md and CHANGES.md, alongside an .agents directory and an AGENTS.md, a .clang-format with a matching ignore file, and a .git-blame-ignore-revs file, which is the list of commits excluded from blame. That last file is a small and honest signal: a repository-wide reformat happened, it was recorded, and blame was repaired rather than left unreadable.

BSD for the code, Creative Commons for the documentation

The licensing is split by artefact, which is worth noticing because the two are chosen for different readers. The code is distributed under what the README calls the New/3-clause BSD licence, and the documentation under the Creative Commons Attribution 4.0 International licence. The README then spells out the practical effect, and it is unusually plain: you are free to use OSL in your own applications, whether they are free or commercial, open or proprietary, and to modify the OSL code and documentation as you desire, provided that you retain the original copyright notices as described in the licence. For a renderer vendor that sentence is the whole commercial argument, and for a studio it means the shading language you write is not encumbered by the tool you write it in. The history explains where the technology came from and who sustains it: OSL was originally developed by Sony Pictures Imageworks for its in-house renderer for feature film animation and visual effects, then open sourced so other studios and vendors could use it, and it received an Academy Award for Technical Achievement in 2017.

Against a language that returns a colour, and against GLSL

The comparison that matters is with the shading language your renderer would otherwise give you. A renderer's native language, or GLSL or WGSL, computes a colour for a direction, and that is the right shape when the hardware does the work: a GPU evaluates a program per pixel per ray, and there is no integrator to defer to. OSL inverts the relationship, returning a description to a CPU-side integrator, which is what makes path tracing, bidirectional methods and re-lighting possible at all. The cost is that an OSL shader is not portable to a real-time engine, and it is not useful without a renderer that implements the closure model, so the README's claim that support is in most leading renderers is the precondition rather than a bonus. The filmography the project lists, from The Amazing Spider-Man through Hotel Transylvania, Edge of Tomorrow, Ant-Man and Finding Dory, is evidence of that ecosystem, not a substitute for checking your own renderer's version, since a language with four version components will have features that a given renderer has not implemented.

Editorial conclusion

Adopt OSL if you are writing materials for a physically based renderer, because the closure model is what lets your shader be re-lit, re-sampled and reused by integrators you did not write, and the licence lets you embed it in a commercial renderer without a copyleft obligation. Do not adopt it for a real-time or GPU path, where a shader that returns a colour for a direction is the right shape and an integrator is not involved. Verify four things before you commit a shading library: that your renderer supports OSL at the version you are building against, that you understand what your integrator does with the closures you return, because the sampling decision is no longer yours, that any AOVs you relied on from output variables are re-expressed as light path expressions, and which line you pin, given v1.15.7.0 and v1.14.12.0 both released on 2026-09-07 with the last push on 2026-09-26. The code is BSD-3-Clause and the documentation is CC-BY-4.0.

Frequently asked questions

What is the Open Shading Language used for?

It is a small but rich language for programmable shading in advanced renderers and other applications, aimed at describing materials, lights, displacement and pattern generation. It was developed by Sony Pictures Imageworks for its in-house renderer and is described as the de facto standard shading language for VFX and animated features.

What is a radiance closure in OSL?

It is the explicit symbolic description, in units of radiance, of how a surface or volume scatters light, which surface and volume shaders compute instead of a final colour. A renderer can evaluate it in particular directions, sample it to find important directions, or save and re-evaluate it later.

Why do OSL shaders not loop over lights?

Because the closures they compute are evaluated by an integrator in the renderer, which decides in which directions rays should be traced. The README lists the advantages as batchable and re-orderable integration for ray coherence, ray budget allocation, use with bidirectional ray tracing or Metropolis light transport, and rapid re-evaluation with new lighting without re-running shaders.

How do OSL shaders handle transparency and lights?

There is no separate light shader: a light is an emissive surface and all lights are area lights. Transparency needs no explicit opacity variable, because it is another interaction carried inside the main radiance closure the surface shader computes.

How do I build Open Shading Language?

The top-level Makefile is a wrapper around CMake, so typing make in a configured source tree is the simple path, and make help lists the targets. Variables are forwarded to CMake as defines, including LLVM_DIRECTORY, LLVM_VERSION, LLVM_NAMESPACE, LLVM_STATIC, USE_LLVM_BITCODE and OSL_NAMESPACE. Full details are in INSTALL.md.

What licence is Open Shading Language released under?

The code is under the 3-clause BSD licence and the documentation under Creative Commons Attribution 4.0. The README states you may use OSL in free or commercial, open or proprietary applications and modify the code and documentation, provided you retain the original copyright notices.

Official sources

  1. AcademySoftwareFoundation/OpenShadingLanguage on GitHub
  2. Issues
  3. License: BSD-3-Clause
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/academysoftwarefoundation-openshadinglanguage.svg)](https://hysenlabs.com/projects/academysoftwarefoundation-openshadinglanguage)