5
$\begingroup$

I'm trying to use transparent background in a simple smoke simulation. As soon as I check transparent, in the film settings (cycle), the image loose the color (it is indeed transparent but black).

I've a simple volume shader and just a white background

EDIT: as requested here is the blend with a quick smoke with default settings, nothing specific.

no transparency with transparency enabled volume shader

I've seen this closed bug and this question maybe the bug is still there?

Anyone can confirm this behavior and have a workaround with the compositor?

Because simply mixing the black transparent png with the color doesn't produce the same result

$\endgroup$
4
  • $\begingroup$ Can you upload your .blend file? I'm also puzzled. $\endgroup$
    – oneofmetwo
    Apr 12, 2016 at 19:40
  • $\begingroup$ I'd help but the smoke domain is a complete black box. :/ $\endgroup$
    – Luka ash
    Apr 15, 2016 at 1:35
  • 4
    $\begingroup$ As far as I'm aware this bug is not/never has been fixed. Note that the report was closed as "archived", rather than "fixed". $\endgroup$
    – gandalf3
    Apr 15, 2016 at 6:58
  • $\begingroup$ Thanks gandalf I've missed that important detail! Maybe the issue has changed since then, because in the other thread the proposed solution shows a colored render instead of black. I'm looking for a way to uniformly color the current black transparent output restoring the color it has when rendered with a white environment color. The current tones of grays seems correct it just seems to be missing the color and I can't find a way to add it in the compositor! $\endgroup$ Apr 15, 2016 at 11:34

4 Answers 4

6
+50
$\begingroup$

Short answer: You want to use the volume scatter shader for this, not absorption. (or use the post-pro workaround in the other answer).

Ok, let's back up a bit and I'll try to explain why Cycles produces the values it does with the absorption shader: First of all, the volume absorption shader does not add energy to the ray or add contributions for a light in any way, it can only remove them. This is because absorption does not alter a ray's path, it merely removes energy from it. With transparent film, it's subtracting from the already black background, thus leaving you with a black smoke plume. "But wait!" you're probably saying, "my background isn't black, it's white!"

Oh boy. What a fun can of worms we got into here. So when you're rendering with a transparent background, you need to make the RGBA color of the background black. The reason for this is how the alpha over operation (or "normal" blend mode in Photoshop parlance) works. You can read the formula here: https://en.wikipedia.org/wiki/Alpha_compositing If you look closely, you can see what it does is multiply one layer by the alpha (blacking out the transparent portions) and multiply the other by the inverse of the alpha (blacking out opaque portions) then sums the results. So the function of the alpha channel in this case is to tell the software what part of the existing background to remove to allow the new background to be added.

This works just fine for 100% transparent sections no matter what else you mess up along the way (like writing the RGB channels as non-zero). It's partially transparent areas where the problems start. The non-zero RGB values in the background represent incoming energy from the background, which you do not actually want. You're providing different energy values later by way of comping in your final backplate. When you have a partially transparent region though, you want to preserve some energy (the energy reflected by the occluding object), so rays returning the value of the occluding object have non-zero RGB and an alpha value of 1. (ok, they might have RGB=0 if the occluder is black, but let's just assume it's not). Rays that continue to the background have an alpha of 0, thus the average alpha provides the proper scaling factor so the right amount of composited backplate energy is left on the pixels.

But what if those backplate rays came back with a non-zero RGB? The alpha channel does not distinguish between colors from the occluded object and colors from the backplate, it just represents how much energy is supposed to pass through the occluder. Thus, you get an unnatural glow as you are stacking the energy of the render background and final composited backplate, where this wasn't supposed to happen. Oh yeah, and because of antialiasing all objects get a partially transparent region around their edges, so even opaque objects get a halo if you don't black out this background.

And all this glowy mess isn't fixable in post either, at least using just the main beauty pass. If you have an occluded environment AOV (like cycles' environment pass) you can subtract that from the beauty pass and straighten things out, but no messing with a "convert premultiplied" switch will do the job.

This is all fairly arcane, so to make it easier on the user when you enable transparent film Cycles just stops all camera-ray contributions of the world background, forcing it to return RGB=0 in all cases. Your volume absorption shader tries to remove energy (especially red and blue energy) from a ray that has no energy to begin with, thus your smoke is black. Using the scatter shader instead causes it to REFLECT green light, thus remaining visible on its own. If you'd rather have the glowy green look, you can also specify that directly using the emission shader instead of, or in addition to, the absorption shader.

$\endgroup$
2
  • $\begingroup$ Thanks for your explanation of why this problem shows up! Unfortunately I understand better the problem and I see there is no easy solution, however I can't replicate your proposed solutions. Subtracting AOV (as shown by @cegaton below) leaves trace of the white environment light as you can see here. I know Volume scatter works but the results looks very different! Plugging directly the emission (with density>strength) in the volume socket I got nothing. Using it with an add socket works but the results are different. Any better setup? $\endgroup$ Apr 18, 2016 at 15:02
  • $\begingroup$ It's kind of a tricky problem, because a single RGBA image does not store enough information to get the result you want (filtering the background image) with an arbitrary background. Alpha becomes the average attenuation, but the color comes from the green attenuation being weaker than the red and blue. I think emission+absorption (add shader) or putting the color back in post are your best bets. $\endgroup$
    – JtheNinja
    Apr 19, 2016 at 17:55
2
$\begingroup$

Riding on @JtheNinja 's answer.

Since you only have absorption, which just subtracts light form whatever is behind the somke, try adding some scattering, that will make the smoke visible regardless of its surroundings as it will reflect and scatter light (remember make your light brighter too...).

enter image description here

$\endgroup$
1
  • $\begingroup$ Sincerely thanks for taking the time to look into this matter. Volume scatter it's not homogeneous and gives a different look. The other now removed solution to remove AOV I don't see how is a viewer only issue but thanks anyway. $\endgroup$ Apr 18, 2016 at 15:50
2
$\begingroup$

As an workaround I would use compositor as @Rick Riggs suggest, but in a very different way:

  • Render the smoke over some color that is not included in the smoke and then key it out in external app compositor that keys transparent gradients/transitions well.

  • If the smoke is lit or emission based render the smoke over black background and using this trick turn that black background into transparent.

$\endgroup$
8
  • $\begingroup$ This is a very neat trick but how can I apply here? If I put any background it'll alter the light of the volume absorption, this is not an emission shader. $\endgroup$ Apr 18, 2016 at 13:32
  • $\begingroup$ @diramazioni Yes this is true. If you have a thin smoke that get's effected by the background emission and it's an issue then the only option is that black background. $\endgroup$ Apr 18, 2016 at 14:00
  • $\begingroup$ The black background will make the smoke vanish completely being 0 the light the volume absorption shader is able to absorb! Do you imply some other trick with ray visibility cycle property? I've tried but wasn't able to make it work in any way. Maybe using an emission shader with add in the volume socket is the way to go? Do you have a working example of your idea? $\endgroup$ Apr 18, 2016 at 14:40
  • $\begingroup$ @diramazioni If you have black smoke render it on white like you have the image with green smoke, then invert, make the black transparent, then invert back. Yes I have a working example, our entire studio smoke pipeline is based in this transparent channels pipeline. I'll apply it to the file you provided. $\endgroup$ Apr 18, 2016 at 14:57
  • $\begingroup$ @diramazioni I see what the problem is now, I will use a bit different setup to solve it and will edit my answer. $\endgroup$ Apr 18, 2016 at 15:08
0
$\begingroup$

I think your best bet for now, is to use your Black and White version, and run it through the compositor like so to get your color back.

enter image description here

$\endgroup$
7
  • 2
    $\begingroup$ What if the smoke is multi-colored from lighting for example? This setup is just coloring it with single color and in a weird manner. The correct thing is to render the smoke over some color that is not included in the smoke and then key it. $\endgroup$ Apr 17, 2016 at 11:45
  • $\begingroup$ Rick I've tried your setup and I wonder how you got this result, and the rationale behind it because I can't replicate. From the screenshot I can't see the value of multiply, but beside the numbers why a multiply operation of a black image over black would produce any result? Can you provide an example file because frankly I'm a bit puzzled, The result looks good, but I hope you haven't started by using the png posted here with the non transparent white background, I can't figure out otherwise why of this node setup $\endgroup$ Apr 18, 2016 at 16:57
  • $\begingroup$ I did start with your png greyscale over white. $\endgroup$
    – Rick Riggs
    Apr 19, 2016 at 2:24
  • $\begingroup$ As far as the multiply object goes, notice how the first multiplier is acting as an intensity control on the mix factor by value. The next item is an invert not a black image, so in other words if i am to take the source image's greyscale and invert it then I get its b&w opposites (hope that clarifies that). Now because I am also making the invert of the source image as the alpha channel, all that is left is the multiply of the source left overs and your color of choice. $\endgroup$
    – Rick Riggs
    Apr 19, 2016 at 2:35
  • $\begingroup$ As for the multiply number specifically, I would say start at 160, and slide up or down until you like it. $\endgroup$
    – Rick Riggs
    Apr 19, 2016 at 5:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .