(Shader question) Check if the light is direct or indirect [Solved]

Is there a way to tell when the surface is lit directly and when it is not? Like, if the ray performs its 1st or 2nd bounce? To create a material which displays a specific texture only in places not touched by direct lighting, for example

You could use the lightpath node “is shadow” then use it as inverted selection.For rays you have possibilitys with Lightpath like ray depth ect you could try.

Here a overview of light path node

1 Like

@pixelgrip Pretty sure that’s not how it works.

You get a 1 from “is shadow ray” port on the light path node in exactly one situation. It’s when the ray crosses your material just before hitting the light source, and your material uses transparent BSDF.
And, in that situation, your material can’t do anything except change the color of all rays going through (it can’t even add a texture). So, literally the only thing you can do with shadow rays is use them to make colored shadows.

You can still make surface effects that distinguish between direct light and indirect light, but it’s not as simple as dropping a light path node into the shader:

@DeckardX08 Problem is, ray tracing runs in the opposite direction. You can tell if it’s the first bounce from the camera, but you can’t tell if it’s the first bounce from the light.

1 Like

Sure,but lightpath is the only node that you can use for these tricks.Maybe you have a better idea how to do it?

1 Like

It’s possible to draw something that’s only visible in direct light, using shadow rays and OSL.

shader TransparentTexture(
point Vector = P,
string Texture = “”,
output closure color BSDF = 0.0)
{
if(raytype(“shadow”))
{
color c = texture(Texture, Vector[0], Vector[1]);
BSDF = c*transparent();
}
else
{
BSDF = transparent();
}
}

Stick this into a “script” shader node, put the path to any texture into the edit box, connect the UV texture coordinate to the input, connect the output to the material. Then, create the object you want, paint it the usual way, create another copy, make it 1% larger, and assign the OSL shader material to it. Make sure to check the “Open Shading Language” checkbox in scene settings. It’ll overlay the texture only in places hit by direct light.

If you want the opposite - draw something only in places not hit by direct light - that’s going to be tricky. If you just reverse the logic, the texture will be visible to all indirect rays, but that’s not the same thing, because all sides of the object are hit with indirect rays, not just those facing away from the light.

1 Like

Okay, thanks everyone, looks like it is going to be annoying. To clarify the task, I wanted an effect when the ambient occlusion texture only affects the intensity of indirect lighting (Occlusion input in some game engines). But if it will be as complex as duplicating the mesh itself every time, I’m not sure it is worth the trouble