I've been trying to work out shaders for a couple of months now, in an attempt to render 3d scenes as 'pixel art'. Recently, I've tried my hand at incorporating ATTENUATION.

Its giving me a good bit of grief.

In editor, things seem okay-- in game its a different story. The shadows definitely appear, but not as I would be expecting them to.

Editor shadows:

In game:

I've tried to adjust the main light shadow settings, but nothing I try seems to get things to show up properly. These screenshots are taken with a default Directional Light, and default Project Settings (Rendering > Lights & Shadows).

Would anybody be able to help me determine what I'm doing wrong?

I'm also not 100% clear on how ATTENUATION works... Currently, I have the following light() function in my toon ramp shader:

The way I currently understand ATTENUATION is that it should be > 0.0 when an object is 'in the light'; Should it be < 0.0 when in shadow? Am I understanding this correctly? Ideally I'll be bumping the ramp down a step, clamped to the lowest step, when an object is shadowed-- That's certainly not what I'm doing now, though... Feel like I'd have an easier time working things out if I knew the range of values ATTENUATION was returning.

An effect that changes the colors of the scene should be in a postprocess shader, not a material.
Don't touch the light shader, use standard material. You have toon and lambert to choose from.

Thank you for your reply!

Why do I need to do things in a postprocess shader?
Most of the things I've seen apply color ramping in a material shader; Wouldn't a postprocess shader affect the entire scene?

I feel like applying my edge outlines/highlights that broadly wouldn't allow me to have as much control as I currently do for determining what gets outlined/highlighted, what colors are used, etc. Lighting, on the other hand, would be consistently applied... I may not want all shadows ramping colors down a step, though. I figured characters/objects could just be dimmed in their entirety in shadow, and the ramp shifting could be left for ground/foliage.

I've heard there's a built in toon shader, but frankly-- using that doesn't teach me anything. Ultimately, I'd like to be proficient enough in shader programming to think up and program effects myself.

In editor if you toggle the active camera preview, does it give same results as runtime? Your shader effect is likely dependent on view transform.

My understanding is that in Godot Attenuation is in the range of 0 to 1, with 0 being in darkness and 1 being in light. So you are not far off the mark

The code I've used before to do this would be like DIFFUSE_LIGHT += mix(shadowColor.rgb, ALBEDO.rgb, ATTENUATION);
I am spitballing, but if I remember correctly a lot of those unity shaders that do custom toon ramping sample from either a texture or a stepped gradient depending on the attenuation is and then change that shadowColor.rgb to whatever was sampled.

I think its a little disingenuous to say this has to be done in post process. The light section of the shaders is for.... writing custom light functions like custom toon shaders. While godot does provide a fantastic premade toon-shader, learning things is good actually.

Edge outlines are a little bit of a different conversation because they are not usually related to the light function, and there are several different approaches to doing them, usually in post processing but there are some per material approaches floating around. I like to add highlights separately from shadows but I don't know if that is 'correct'

Bit late to the replies, but thank you for your thoughts-- I really appreciate you both taking the time to help me out.

@Megalomaniak Not entirely sure where to toggle the active camera preview-- unless you're referring to 'Cinematic Preview', as per:

This is a demo scene I created with a fresh Godot build that I compiled myself the other night-- I figured trying to sort things out in a clean environment would help me pinpoint the issues.

@CakeCadaver Thank you for explaining ATTENUIATION! I have a rough time understanding a lot of shader concepts, both because I don't know the values and because its confusing as a new learner. For instance, the Godot documentation notes VIEW_MATRIX as one of the Fragment built-ins:

I understand that mat4 is a 4x4 matrix, which I interpret as, more or less, an array... But an array of what? I usually just end up trying the value at each index and seeing what happens (nothing good, more often than not), but I'd always wished there was a lil bit more information... What does "World space to view space transform" even mean? Is that common knowledge? I don't know, maybe I'm just not looking hard enough.

Mid-reply note: I did stumble upon this again: https://docs.godotengine.org/en/stable/tutorials/math/matrices_and_transforms.html

I've seen it before, and don't remember it relating to gdshaders, but maybe conceptually it will help.

Anyways, thank you so much for the information-- I want to be able to use my own shadow colors as opposed to having a basic darker/lighter ramp on things, so I'll look into doing some kind of mix when I've gotten things down.

I think I'm just starting to realize that shadows are more fickle than I'd have anticipated... Especially so for orthographic cameras, as there is a clear difference in how things draw out in perspective vs orthographic. I want the shadows to be hard, as I get this weird speckly effect that affects grass blades in the final image:

Could be one of them floating point precision errors I've heard about... But I can just use hard shadows in the project Rendering & Light settings!:

...Except I end up with a weird 'blockiness' when doing that:

The 'blockiness' is also extra pronounced in motion, with the sides kind of waving around... Almost as if its following some sort of grid. I could record some video, but I don't think I was able to upload one directly when I OP'd.

Sorry for the big posts... lol.

    Tomcat Thank you! Unfortunately, I don't seem to have the same options:

    Cinematic preview does seem to do it for me though, at least as far as I can tell:

      The matrix's are all pre-made collections of values that are used in multiplication to convert one type of positions into another. So for example, the data stored in VIEW_MATRIX is the math you would need to convert a world space position to a view space position. This is typically because the maths are big and complicated and its easier to just hand you the already computed matrix and allow the user to go ValueA = ValueB * VIEW_MATRIX or whatever.

      a good video series would be these lectures

      For the speckly shadows, I would guess that is a shadow bias/acne problem. I would try going into your light node and increase the shadow bias setting to see if that helps. You have to click on your camera node in the scene tab for Tomcat's camera preview to pop up

        LordChopps Unfortunately, I don't seem to have the same options:

        This option appears in the preview window when you select a camera in the scene tree.

        But the cinematic preview is probably close to it.

        CakeCadaver Maaasive resource. Thank you so much for providing it.

        I ended up decreasing the Far value in my camera, and the shadows bumped up in resolution significantly-- everything looks pretty smooth now, and I'm able to use the hard shadows in project settings:

        It also seems to have solved the speckling with soft shadows-- although I'm not sure I'll use them. Need to do a little more trial and error. If the softness can be ramped as well, we may end up rolling with that.

        Now I just need to work out a better way of distributing foliage than whatever default behavior populate uses on multimesh instances... Poisson disc sampling seems like the move. Not sure how that will pan out in 3D, but I'll need to use the same or some similar approach for trees/bushes.

        Anyways-- huge help from the lot of you. Thank you both for also pointing this camera preview stuff out for me, even if it seems trivial. I really appreciate it.