#New to rendering, need help

1 messages · Page 1 of 1 (latest)

buoyant aurora
#

I've been trying to make a halftone effect that reply to any light sources for an indie game I'm working on but I've very very new to shaders and rendering and have spent around 10 hours of looking at tutorials and trying things it without any success. So I decided to ask for help because my friend is trying to convince me to go on UE5 and I don't want to!

Here is the tutorial I've been following and the result I have (doesn't respond to any light source)
Please ping me so I can reply faster !
https://danielilett.com/2022-07-28-tut6-1-halftone

Daniel Ilett: Games | Shaders | Tutorials

With halftone, we can posterize a smooth shading gradient into a stylistic dot-matrix pattern with differently-sized dots.

buoyant aurora
#

Update : It does respond to the sun, but would it be possible to make it respond to every single light source ?

low elm
#

shader graph by default only exposes information about the main directional light.
(meaning you dont need the code they provided to do this)

You can use this package to add extra nodes to process other lights but the effect would need to be handled differently per light type (e.g. spot, point)
https://github.com/Cyanilux/URP_ShaderGraphCustomLighting

GitHub

💡✨Custom lighting functions/sub-graphs for Shader Graph, Universal Render Pipeline. (See Readme!) - Cyanilux/URP_ShaderGraphCustomLighting

zealous sleet
#

Additional lights also need to be handled in a loop, so may need to replicate the halftone calculations inside a custom function code rather than graph. Depends on the setup, i.e. if you need to support different light colours / how the lights are combined.
Can duplicate the AdditionalLights_float function in my package to your own .hlsl file & edit it

buoyant aurora
# low elm shader graph by default only exposes information about the main directional ligh...

Hi, thanks for the reply, I didn't receive any notifications but I continued trying some stuff!
I have used an hlsl file for the main light (tho it wasn't of use since I only needed direction and there's a node for that already) but I've discovered we can get additional lights (any type if i understood corectly) with GetAdditionalLightsCount() function and then light.direction when cycling through them. But I don't know how to use them because I guess there would be multiple directions at the same time so I don't really know how to handle them yet.

buoyant aurora
# zealous sleet Additional lights also need to be handled in a loop, so may need to replicate th...

Yes I actually used an hlsl file for the main light direction despite having a main light direction node in shader graph. And I did try to use a custom function for AdditionalLights as well but I've seen people use it with colors because you can add the color of multiple additional lights and it'll work fine, but for my halftone shader I only care about the direction and I'm not sure how to add multiple direction onto one output.

#

I wanted to show what I currently have but I'm getting errors from my hlsl file and I can't even figure out why :/, should clean things up before trying new things again

buoyant aurora
#

i've remade it from scratch

#

the color are doing very weird things, for exemple when I put pink it is red, and blue just become fully black somehow

modest lagoon
#

But hard to guess without any information about your nodes or functions

buoyant aurora
buoyant aurora
buoyant aurora
#

The only thing left is getting my shader to react to lights other than the sun..

#

this is what I tried doing (using tutorials and adapting them) but it doesn't work, tho it doesn't break anything either

buoyant aurora
#

Apparently whatever I do GetAdditionalLightsCount() always returns 0 and trying to #include any hlsl file just gives me an error, I don't get it

zealous sleet
#

ShaderGraph needs to support all render pipelines, so it has it's own library separate to URP's one and includes usually cause conflicts. You usually need to use blocks like #ifdef SHADERGRAPH_PREVIEW .. #else .. #endif to generate different code paths for node previews in graph vs the final shader in URP scene.

#

Though files for lighting related stuff should be included automatically. (But again, still only available in the final shader, not previews)

buoyant aurora
#
void AdditionalLight_float(float3 WorldPos, int lightID, out float3 Direction, out float3 Color, out float Attenuation)
{
    Direction = normalize(float3(1.0f, 1.0f, 0.0f));
    Color = float3(0.0f, 0.0f, 0.0f);
    Attenuation = 0.0f;

#ifndef SHADERGRAPH_PREVIEW
    int lightCount = GetAdditionalLightsCount();

    if(lightID <= lightCount)
    {
        Light light = GetAdditionalLight(lightID, WorldPos);
        Direction = light.direction;
        Color = light.color;
        Attenuation = light.distanceAttenuation;
    }

#endif
}

I changed the "<" to "<=" and I managed to obtain the datas of my light

#

this has gotten out of my field of expertise a week ago, i'm just trying out stuff until something works

zealous sleet
#

GetAdditionalLightsCount() might return 0 if you don't have the appropiate keywords.

#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _CLUSTER_LIGHT_LOOP // in 6.1 or _FORWARD_PLUS in 6.0
buoyant aurora
#

well that's what i was trying to look into

#

but i have no idea what any of them do

zealous sleet
buoyant aurora
#

and the only examples i found on the web were fully written shaders

buoyant aurora
#
void GetAllAdditionalLights_float(float3 WorldPos, float3 WorldNormal, float2 CutoffThresholds, out float3 LightColor)
{
    LightColor = float3(0.0f, 0.0f, 0.0f);

#ifndef SHADERGRAPH_PREVIEW
    int lightCount = GetAdditionalLightsCount();

    for(int i = 0; i < lightCount; i++)
    {
        Light light = GetAdditionalLight(i + 1, WorldPos);

        float3 color = dot(light.direction, WorldNormal);
        color = smoothstep(CutoffThresholds.x, CutoffThresholds.y, color);
        color *= light.color;
        color *= light.distanceAttenuation;
        
        LightColor += color;
    }
    
#endif
}
#

that's why i'm trying to use

zealous sleet
# buoyant aurora what does those line do ?

#pragma multi_compiles tell Unity to generate multiple variants of the shader. Behind the scenes Unity will enable keywords if it needs to render additional lights on those objects. Without them, lighting related functions will usually return 0 to avoid "unnecessary" calculations.

#

Specifically the first line enables additional lights, second enables shadows for them, and the last is to support the Forward+ rendering path

#

There are also LIGHT_LOOP_BEGIN/END macros you should use to properly support both Forward and Forward+ paths. They turn into for() or while() loops when the shader is compiled (and declare lightIndex)

The usual setup looks like this :

uint pixelLightCount = GetAdditionalLightsCount();
uint meshRenderingLayers = GetMeshRenderingLayer();

InputData inputData = (InputData)0;
float4 screenPos = ComputeScreenPos(TransformWorldToHClip(WorldPosition));
inputData.normalizedScreenSpaceUV = screenPos.xy / screenPos.w;
inputData.positionWS = WorldPosition;
  // (this sets up some data used by LIGHT_LOOP_BEGIN in Forward+ path)

LIGHT_LOOP_BEGIN(pixelLightCount)
    Light light = GetAdditionalLight(lightIndex, WorldPosition, Shadowmask);
#ifdef _LIGHT_LAYERS
    if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
    {
        // per-light code here
    }
LIGHT_LOOP_END
#endif

(Shadowmask can be half4(1,1,1,1) if you don't need to support the 'Shadowmask' Baked GI mode. Otherwise see Shadowmask_half function in my custom lighting repo)

buoyant aurora
#

sorry had something to do

#

yeah okay that's what I was looking at when you responded

buoyant aurora
zealous sleet
# buoyant aurora 3 questions : - I currently have `#define ADDITIONAL_LIGHT_INCLUDED`, is it usef...

ADDITIONAL_LIGHT_INCLUDED sounds like the "custom" define at the start of files, like MYHLSLINCLUDE_INCLUDED in the docs. The purpose of that is so you can use the file in multiple Custom Function nodes without causing duplicate code (which would error)

For #pragmas, I don't think it really matters where they go. But yes, typically at the start.

Should be fine to use _CLUSTER_LIGHT_LOOP in 6.2 too. It used to be _FORWARD_PLUS but was renamed in 6.1 onwards. Probably should have put "6.1+"

buoyant aurora
#

well the pragmas alone definitively don't work

#

I didn't fully understand the LIGHT_LOOP_BEGIN/END part

#

I tried copying the code from the github and shaving it down to what I need

#

i definitively don't get whatever any of this means

buoyant aurora
zealous sleet
# buoyant aurora wait so pragmas' purpose is basically to say additional light and additional lig...

There's some pages here that explain the multicompile pragma - https://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html (and shaderfeature / dynamicbranch which are similar)

I think most of those examples are for custom keywords, but URP & Unity has specific ones defined for stuff like lights, shadows, etc. e.g. listed in the URP/Lit shader : https://github.com/Unity-Technologies/Graphics/blob/5b723784671c637b2397b395a60474c68ee7af73/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader#L137

You can think of it as defining what features the shader needs/requires.

#

For this one specifically
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
multi_compile = "generate multiple versions of this shader"
_ is the "off/disabled" state (no additional lights)
_ADDITIONAL_LIGHTS_VERTEX is for when you have additional lights set to "Per-Vertex" under the URP Asset. (Probably makes lights look worse but is cheaper)
_ADDITIONAL_LIGHTS for the usual "Per-Fragment/Pixel"

#

Later the shader (or in this case, code defined in the URP ShaderLibrary/includes) will branch on those keywords using #ifdef (I think you can also just use if () nowadays?)
With multi_compile/shader_feature it means the shader will only end up running code it needs. If lights are set to per-vertex, the per-pixel code is excluded from that version of the compiled shader. And vice versa. And if off, both are excluded.

buoyant aurora
#

ok yeah that makes lot of sense

#

thanks a lot for the help

#

I'll try to modify the code to use those and get back to you if it doesn't work