Archive 17/01/2023.

Implementing custom lens flare shader

htmlboss

Hey all! This is my first time trying to implement a shader (from john chapman graphics) in Urho3D. I’ve read as much documentation as I could find on the subject, but the shader will not work (no blatant visual errors, or other indicators at runtime). I am appending my xml file to the cloned renderpath of the primary viewport, and enabling it (so it’s probably me being noob with this post-processing pipeline and the shader too). Any ideas? Thanks a bunch in advance! :smiley:

LensFlare.xml:

<renderpath>
	<command  type="quad" tag="LensFlare" vs="LensFlare" ps="LensFlare" output="viewport" blend="add" enabled="true">
		<parameter name="Samples" value="8" />
		<parameter name="Dispersal" value="0.25" />
		<parameter name="HaloWidth" value="1.0" />
		<parameter name="Distortion" value="1.0" />
		<texture unit="InputTex" name="viewport" />
		<texture unit="LensColor" name="Textures/lenscolor.png" />
	</command>
</renderpath>

LensFlare.glsl

[code]/*******************************************************************************
Copyright © 2013 John Chapman
Edited for Urho3D by htmlboss (2016)

This software is distributed freely under the terms of the MIT License.
See "license.txt" or "http://copyfree.org/licenses/mit/license.txt".

*******************************************************************************/
//#include “common/def.glsl”

// Urho3D Stuff
#include “Uniforms.glsl”
#include “Samplers.glsl”
#include “Transform.glsl”
#include “ScreenPos.glsl”

layout(binding=0) uniform sampler2D sInputTex;
layout(binding=1) uniform sampler1D sLensColor;

const int MAX_SAMPLES = 64;
uniform int cSamples; // Samples for ghosting generation
uniform float cDispersal; // Ghosting dispersion factor
uniform float cHaloWidth; // Width of Halo
uniform float cDistortion; // Chromatic aberration factor

varying vec2 vScreenPos;

noperspective in vec2 vTexcoord; // 2D screen coords?

layout(location=0) out vec4 fResult; //Final output

/----------------------------------------------------------------------------/
vec4 textureDistorted(
in sampler2D tex,
in vec2 texcoord,
in vec2 direction,
in vec3 distortion
) {
return vec4(
texture(tex, texcoord + direction * distortion.r).r,
texture(tex, texcoord + direction * distortion.g).g,
texture(tex, texcoord + direction * distortion.b).b,
1.0
);
}

/----------------------------------------------------------------------------/
// Not doing anything here…
void VS() {
mat4 modelMatrix = iModelMatrix;
vec3 worldPos = GetWorldPos(modelMatrix);
gl_Position = GetClipPos(worldPos);
vTexcoord = GetQuadTexCoord(gl_Position); // Is this right??
vScreenPos = GetScreenPosPreDiv(gl_Position);
}

void PS() {
vec2 texcoord = -vTexcoord + vec2(1.0); // flip texcoords
vec2 texelSize = 1.0 / vec2(textureSize(sInputTex, 0));

vec2 ghostVec = (vec2(0.5) - texcoord) * cDispersal;
vec2 haloVec = normalize(ghostVec) * cHaloWidth;

vec3 distortion = vec3(-texelSize.x * cDistortion, 0.0, texelSize.x * cDistortion);

// sample ghosts:
vec4 result = vec4(0.0);
for (int i = 0; i < cSamples; ++i) {
vec2 offset = fract(texcoord + ghostVec * float(i));

	float weight = length(vec2(0.5) - offset) / length(vec2(0.5));
	weight = pow(1.0 - weight, 10.0);

	result += textureDistorted(
		sInputTex,
		offset,
		normalize(ghostVec),
		distortion
	) * weight;
}

result *= texture(sLensColor, length(vec2(0.5) - texcoord) / length(vec2(0.5)));

// sample halo:
float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5));
weight = pow(1.0 - weight, 10.0);
result += textureDistorted(
sInputTex,
fract(texcoord + haloVec),
normalize(ghostVec),
distortion
) * weight;

fResult = result; //Output final result

}
[/code]

codingmonkey

Hi!

I am not familar with this technicue yet, but i guess you probably forgot to add a few additional passes in RenderPath

  1. Gettting threshold from actual frame to additional RT (it store within only while-black color only) (see to boom shader how it extract overbrighten-white color)
  2. Bluring previous RT
  3. Use your shader (for mix default scene frame and this new RT)

So i think needed more complex RenderPath, and not just what you added previously

htmlboss

So here’s an update: I basically copy-pasted the bloom shader and just added the lens flare stuff as an additional command, BUT it seems to be sampling the logo from the bottom-left corner of the window (da fuq?) so I just see a massive blurred Urho3D logo across my screen. If I remove all UI code in the sample program, the shader goes back to not doing anything…am I getting the wrong “screen layer” in the xml file?

New xml:

<renderpath>
    <rendertarget name="blurv" tag="Bloom1" sizedivisor="4 4" format="rgb" filter="true" />
    <rendertarget name="blurh" tag="Bloom1" sizedivisor="4 4" format="rgb" filter="true" />
    <rendertarget name="threshold" tag="Bloom1" />
    
    <command type="quad" tag="Bloom1" vs="Bloom1" ps="Bloom1" psdefines="BRIGHT" output="threshold">
        <parameter name="BloomThreshold" value="0.3" />
        <texture unit="diffuse" name="viewport" />
    </command>

    <command type="quad" tag="Bloom1" vs="Bloom1" ps="Bloom1" psdefines="FLARE" output="blurh" >
        <parameter name="Samples" value="8" />
        <parameter name="Dispersal" value="0.25" />
        <parameter name="HaloWidth" value="1.0" />
        <parameter name="Distortion" value="1.0" />
        <parameter name="FlareMix" value="1.0" />

        <texture unit="LensColor" name="Textures/lenscolor.png" />
    </command>
    
    <command type="quad" tag="Bloom1" vs="Bloom1" ps="Bloom1" psdefines="BLURH" output="blurh">
        <texture unit="diffuse" name="blurv" />
    </command>
    
    <command type="quad" tag="Bloom1" vs="Bloom1" ps="Bloom1" psdefines="BLURV" output="blurv">
        <texture unit="diffuse" name="blurh" />
    </command>
    
    <command type="quad" tag="Bloom1" vs="Bloom1" ps="Bloom1" psdefines="COMBINE" output="viewport">
        <parameter name="BloomMix" value="0.9 0.4" />

        <texture unit="diffuse" name="viewport" />
        <texture unit="normal" name="blurv" />
    </command>
</renderpath>
rasteron

Hi there htmlboss,

Welcome to the forums! You should probably focus more and test your GLSL code. It looks like there’s a lot of incompatibilities there and your light source position/direction is not setup properly.

But then again if you’re just new to the engine, I suggest doing some simple shader stuff first until you get some grasp on how it works compared to generic GLSL setup.

htmlboss

[quote=“rasteron”]Hi there htmlboss,

Welcome to the forums! You should probably focus more and test your GLSL code. It looks like there’s a lot of incompatibilities there and your light source position/direction is not setup properly.

But then again if you’re just new to the engine, I suggest doing some simple shader stuff first until you get some grasp on how it works compared to generic GLSL setup.[/quote]

Thanks mate! You know, you’re probably right about doing the simple shader stuff first :stuck_out_tongue: I got a little excited about all the features Urho has (since C++ is second-nature to me) so I jumped into the deep-end with GLSL LOL. Is there some specific documentation for Urho’s shader pipeline?

codingmonkey

IMO documentation in part of about shaders is extreamly tiny
urho3d.github.io/documentation/H … aders.html

Also related
urho3d.github.io/documentation/H … paths.html
urho3d.github.io/documentation/H … rials.html
urho3d.github.io/documentation/H … ering.html

reattiva

I think you can use only the standard units names or the texture unit number. See ParseTextureUnitName and textureUnitNames.

rasteron

Sure thing. You can always check out existing code and some of them are simple enough for you to get started creating or porting shaders.