Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Eye Dome Lighting post-processing effect #6633

Closed
goatchurchprime opened this issue Apr 4, 2023 · 4 comments
Closed

Implement Eye Dome Lighting post-processing effect #6633

goatchurchprime opened this issue Apr 4, 2023 · 4 comments

Comments

@goatchurchprime
Copy link

Describe the project you are working on

tunnelvr, a VR cave map drawing application, which can work from point clouds

Describe the problem or limitation you are having in your project

I spotted a really nice feature in the potree point cloud system that makes depth changes stand out in spite of the fact that points are usually flat shaded.

Here is a demo from potree

With EDL:
image
Without EDL:
image

Describe the feature / enhancement and how it helps to overcome the problem or limitation

This is now a pretty standard post-processing feature that is applied to point cloud data to make it the depth changes in the points visible.

It's important enough to be a tickbox feature in Unreal Engine and Unity, as well as any point cloud visualizers such as CloudCompare and Potree.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

There are a set of post-processing features controlled by the World Environment node, such as Glow and Fog, that involve running a pixel shader across the whole of the image with access to the depth buffer. This feature should exist as one of those on/off options, with the various settings (radius, strength, opacity) opened up when it is enabled.

If this enhancement will not be used often, can it be worked around with a few lines of script?

Unfortunately there is no way to edit the image post processing GPU shader defined by the World Environment, in the same way that we can edit the Material Shaders (by converting them from Spatial Material to Shader Material is which it is possible to hand edit the shader code), or there would be a potential work around by adding code to that.

The code that can be used in Unity to implement it is here:
https://github.com/SFraissTU/BA_PointCloud/blob/master/PointCloudRenderer/Assets/Resources/Shaders/EDL.shader

Is there a reason why this should be core and not an add-on in the asset library?

As stated above, unless the post-processing World Environment shader is editable, it can't be done other than as a feature that is directly included in this core node.

@Calinou
Copy link
Member

Calinou commented Apr 4, 2023

Unfortunately there is no way to edit the image post processing GPU shader defined by the World Environment, in the same way that we can edit the Material Shaders (by converting them from Spatial Material to Shader Material is which it is possible to hand edit the shader code), or there would be a potential work around by adding code to that.

It is possible to create custom post-processing effects, including effects that use the depth buffer.

@Calinou Calinou changed the title Implement Eye Dome Lighting Implement Eye Dome Lighting post-processing effect Apr 4, 2023
@goatchurchprime
Copy link
Author

Turns out I was completely wrong. You can do Eye Dome Shading in Godot. However it needs to be done in GLES3 (on Godot3), because accessing DEPTH_TEXTURE in GLES2 destroys the SCREEN_TEXTURE. It doesn't require you to set a shader_mode.

Without EDL
Screenshot from 2023-04-11 17-44-16
With EDL.
Screenshot from 2023-04-11 17-44-06

As the documentation to the screen reading shader says, this feature is invoked whenever a ShaderMaterial that references either SCREEN_TEXTURE or DEPTH_TEXTURE is in view.

The easiest way to cover the whole screen is to use a PlaneMesh with size (1.0, 1.0) and define the vertex() function so that the corners of the mesh convert to a rectangle covering the screen.

Depth buffer decoding is lifted from the EDL shader in CloudCompare.

shader_type spatial;
render_mode unshaded, cull_disabled;

uniform float Znear = 0.05; // set these from the camera settings 
uniform float Zfar = 321.0; 

void vertex() {
	// this flattens the corners of the incoming mesh to the 
	// screen, ignoring the projection
	POSITION = vec4(VERTEX, 0.7);
}

float sdepth(sampler2D dtex, vec2 suv, float offsx, float offsy) {
	float db = textureLod(dtex, suv + vec2(offsx, offsy), 0).r; 
	//float depth = Zm/(1.0 - dr11*(1.0 - Zm/ZM));
	return Znear/(Zfar - db*Zfar + db*Znear);
}

const float diagF = 1.0/sqrt(2.0); 
const float diagFsum = 1.0/(4.0 + 4.0*diagF); 
uniform float Exp_scale = 350.0; 

void fragment() {
	vec2 SCREEN_PIXEL_SIZE = vec2(1.0)/VIEWPORT_SIZE; 
	float sd0 = sdepth(DEPTH_TEXTURE, SCREEN_UV, 0.0, 0.0); 
	float sdSum = sdepth(DEPTH_TEXTURE, SCREEN_UV, -SCREEN_PIXEL_SIZE.x, 0.0); 
	sdSum += sdepth(DEPTH_TEXTURE, SCREEN_UV, SCREEN_PIXEL_SIZE.x, 0.0); 
	sdSum += sdepth(DEPTH_TEXTURE, SCREEN_UV, 0.0, -SCREEN_PIXEL_SIZE.y); 
	sdSum += sdepth(DEPTH_TEXTURE, SCREEN_UV, 0.0, SCREEN_PIXEL_SIZE.y); 
	sdSum += sdepth(DEPTH_TEXTURE, SCREEN_UV, -SCREEN_PIXEL_SIZE.x, -SCREEN_PIXEL_SIZE.y)*diagF; 
	sdSum += sdepth(DEPTH_TEXTURE, SCREEN_UV, -SCREEN_PIXEL_SIZE.x, SCREEN_PIXEL_SIZE.y)*diagF; 
	sdSum += sdepth(DEPTH_TEXTURE, SCREEN_UV, SCREEN_PIXEL_SIZE.x, SCREEN_PIXEL_SIZE.y)*diagF; 
	sdSum += sdepth(DEPTH_TEXTURE, SCREEN_UV, SCREEN_PIXEL_SIZE.x, -SCREEN_PIXEL_SIZE.y)*diagF; 
	float sddiff = sd0 - sdSum*diagFsum; 
	float dk = exp(-Exp_scale*max(0.0, sddiff));
	ALBEDO = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0).xyz*dk;
	//ALBEDO.r = clamp(sd0*Zfar - 3.0, 0.0, 1.0);   // for debugging if depth buffer is working
}

I still feel it would make more sense if this sort of post-processing step could be done by attaching a shader to the WorldEnvironment or the Camera in order to apply the effect across the whole picture, instead of to some random mesh that you have to keep in view of the camera. It seems like a hack to do it that way.

@Zireael07
Copy link

@goatchurchprime please put the shader on GodotShaders or some other easily accessible place? Plz plz <3

@Calinou Calinou closed this as not planned Won't fix, can't repro, duplicate, stale Apr 11, 2023
@Calinou
Copy link
Member

Calinou commented Apr 12, 2023

I still feel it would make more sense if this sort of post-processing step could be done by attaching a shader to the WorldEnvironment or the Camera in order to apply the effect across the whole picture, instead of to some random mesh that you have to keep in view of the camera. It seems like a hack to do it that way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants