[2.3] Using Depth texture in Terra based Ocean shader

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
Ridder Geel
Gnoblar
Posts: 5
Joined: Sat Aug 19, 2023 2:39 pm
x 2

[2.3] Using Depth texture in Terra based Ocean shader

Post by Ridder Geel »

I am having difficulty passing the depth texture of the rendered scene into the rendering of an ocean (in a separate pass).
How exactly would one go about this?

This is what the compositor looks like:

Code: Select all

compositor_node OsirisRenderingNode
{
	in 0 rt_renderwindow

	texture depthTexture	target_width target_height PFG_D32_FLOAT
	texture rtt01		target_width target_height target_format

	rtv rtt01
	{
		depth_stencil	depthTexture
	}

	target rtt01
	{
		pass render_scene //Normal scene
		{
			load
			{
				all				clear
				clear_colour	0.2 0.4 0.6 1
			}
			store
			{
				colour	store_or_resolve
				depth	store
				stencil	dont_care
			}
			rq_first	0
			rq_last		239
			
			shadows		Tutorial_TerrainShadowNode
		}
	}

	texture rtt_final	target_width target_height target_format msaa_auto

	rtv rtt_final
	{
		depth_stencil	depthTexture
	}

	target rtt_final
	{
		pass texture_copy
		{
			in	rtt01
			out rtt_final

			profiling_id "Copy / Clone rtt01"
		}

		pass render_scene //Ocean
		{
			load
			{
				all		load
			}
			store
			{
				colour	store_or_resolve
				depth	dont_care
				stencil	dont_care
			}
			rq_first	240
			rq_last		249

			input 0 depthTexture
		}
	}
		
	target rt_renderwindow
	{
		//Output to window
		pass render_quad
		{
			load { all dont_care }
			material Ogre/Copy/4xFP32
			input 0 rtt_final

			profiling_id "Copy to Window"
		}

		pass render_scene
		{
			camera ui_camera
			rq_first	250
			rq_last		255
		}
	}
}

And this is how the pixel shader part looks:

Code: Select all

// START UNIFORM DECLARATION
vulkan_layout( ogre_t0 ) uniform texture2D depthTexture; //<<<this one
vulkan( layout( ogre_s0 ) uniform sampler depthTextureSampler ); //<<<that one
vulkan_layout( ogre_t@value(heightMap) ) uniform texture2D heightMap;
vulkan_layout( ogre_t@value(terrainData) ) uniform texture3D terrainData;
vulkan_layout( ogre_t@value(blendMap) ) uniform texture2D blendMap;
@insertpiece( custom_ps_uniformDeclaration )
// END UNIFORM DECLARATION

(and further down)

Code: Select all

	rshort2 iFragCoord = rshort2( gl_FragCoord.x, gl_FragCoord.y );
//	float tTexDepth = texture( vkSampler2D( depthTexture, depthTextureSampler ), gl_FragCoord.xy/400 ).x;
	float tTexDepth = 1 - OGRE_Load2DMS( depthTexture, iFragCoord.xy, 0 ).x;
	outPs_colour0.xyz = vec3(tTexDepth,tTexDepth,tTexDepth);

I'm obviously doing something wrong, or I'm unable to pass the depth texture like one would do in the render_quad pass.
So how would one go about this, or what part am I missing?

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5277
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1268
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by dark_sylinc »

Hi!

You're close, but you got a few details wrong.

I'm not sure why you need rtt_final, but I don't know if you have something specific in mind. Am I gonna assume you don't need that.

When you do:

Code: Select all

	target rtt_final
	{
		pass texture_copy
		{
			in	rtt01
			out rtt_final

			profiling_id "Copy / Clone rtt01"
		}

You're copying the colour RTT (rtt01 into rt_final), however you're not copying the depth buffer.
And because you can't sample from a depth buffer at the same time as you write to the depth buffer, you need to copy the depth buffer.

Code: Select all

compositor_node OsirisRenderingNode
{
	in 0 rt_renderwindow

	texture rtt01			target_width target_height target_format msaa_auto
	texture depthTexture01	target_width target_height PFG_D32_FLOAT
	texture depthTexture02	target_width target_height PFG_D32_FLOAT

	rtv rtt01
	{
		depth_stencil	depthTexture01
	}

	target rtt01
	{
		pass render_scene //Normal scene
		{
			load
			{
				all				clear
				clear_colour	0.2 0.4 0.6 1
			}
			store
			{
				colour	store_or_resolve
				depth	store
				stencil	dont_care
			}
			rq_first	0
			rq_last		239

			shadows		Tutorial_TerrainShadowNode
		}
	}


	rtv rtt01_otherDepth
	{
		// Use the same colour rtt01 but a different depthTexture
		colour			rtt01
		depth_stencil	depthTexture02
	}

	target rtt01_otherDepth
	{
		pass texture_copy
		{
			in	depthTexture01
			out depthTexture02

			profiling_id "Copy depth buffer"
		}

		pass render_scene //Ocean
		{
			load
			{
				all		load
			}
			store
			{
				colour	store_or_resolve
				depth	dont_care
				stencil	dont_care
			}
			rq_first	240
			rq_last		249

			expose depthTexture01
		}
	}

	target rt_renderwindow
	{
		//Output to window
		pass render_quad
		{
			load { all dont_care }
			material Ogre/Copy/4xFP32
			input 0 rtt01

			profiling_id "Copy to Window"
		}

		pass render_scene
		{
			camera ui_camera
			rq_first	250
			rq_last		255
		}
	}
}

In this new script we have two depth buffers and reuse the same colour RTT.

When I do "expose depthTexture01" you can now from C++ access the DepthBuffer:

Code: Select all

const Ogre::CompositorTextureVec &textures = sceneManager->getCompositorTextures()
for( ... )
{
    if( textures[i].name = "depthTexture01" )
    {
        TextureGpu *depthTexture = textures[i].texture; // This is the texture you need to bind
        break;
    }
}
Ridder Geel
Gnoblar
Posts: 5
Joined: Sat Aug 19, 2023 2:39 pm
x 2

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Ridder Geel »

Awesome, thanks, it works now!
My biggest issue was not knowing how to bind the textures in c++, thanks for the quick response!

Are the depth values in the texture linear/actual meter depth, or do i need to adjust those values in order to compare it to the current pixel's Z position? (so the question is, how do I reconstruct the Z position of the 'object' in the depth buffer in the shader)

Last edited by Ridder Geel on Sun Aug 20, 2023 10:26 am, edited 2 times in total.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5277
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1268
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by dark_sylinc »

Ridder Geel wrote: Sun Aug 20, 2023 10:01 am

Are the depth values in the texture linear/actual meter depth, or do i need to adjust those values in order to compare it to the current pixel's Z position? (so the question is, how do I reconstruct the Z position of the 'object' in the depth buffer in the shader)

Hi.

The depth values are in "screen space" which are not very useful if you think of liner/meter values.

To convert them to linear/meters I usually recommend Tutorial_ReconstructPosFromDepth sample (which is based on this article, this one, and this one); but that shows how to do it via a fullscreen pass; and it may be hard to do if you're rendering arbitrary objects.

A (slightly expensive) way of unprojecting depth is to send the inverse of the view-projection matrix:

Code: Select all

float4 worldDepthPos = mul( invViewProj, float4( gl_FragCoord.xy, depthValue, 1.0f ) );
worldDepthPos.xyz /= worldDepthPos.w;
Ridder Geel
Gnoblar
Posts: 5
Joined: Sat Aug 19, 2023 2:39 pm
x 2

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Ridder Geel »

Is this the way to get the inverse view projection matrix into the shader?

In c++:

Code: Select all

			psParams->setNamedAutoConstant("invViewProj", Ogre::GpuProgramParameters::ACT_INVERSE_VIEWPROJ_MATRIX);

In the Pixel Shader:

Code: Select all

vulkan( layout( ogre_P0 ) uniform Params { )
	uniform mat4 invViewProj;
vulkan( }; )

Code: Select all

	rshort2 iFragCoord = rshort2( gl_FragCoord.x, gl_FragCoord.y );
	float tTexDepth = OGRE_Load2DMS( depthTexture, iFragCoord.xy, 0 ).x;
	
float4 worldDepthPos = mul( invViewProj, float4( gl_FragCoord.xy, tTexDepth, 1.0f ) );
worldDepthPos.xyz /= worldDepthPos.w;
float t_dpth = worldDepthPos.z - inPs.pos.z;
outPs_colour0.xyz = vec3(t_dpth,t_dpth,t_dpth);

Also am i right to assume that the resulting position is with Z going 'away' from the camera, positive Z?
To verify that things are being done correctly I expect to see things that are more than a meter away to be white, and closer black, but this isn't the case right now.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5277
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1268
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by dark_sylinc »

Ridder Geel wrote: Sun Aug 20, 2023 7:19 pm

Is this the way to get the inverse view projection matrix into the shader?

Hi. Since you seem to be using the Hlms, that interface won't work.

You can use an HlmsListener to add this. I just happened to reply the same question.

You can find the documentation in the manual and the FAQ has a collection of resources.

Ridder Geel
Gnoblar
Posts: 5
Joined: Sat Aug 19, 2023 2:39 pm
x 2

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Ridder Geel »

Thanks for all the help, turns out I didn't have to do all of the things I asked, however the result is amazing and I learned a bunch!
Image

Ridder Geel
Gnoblar
Posts: 5
Joined: Sat Aug 19, 2023 2:39 pm
x 2

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Ridder Geel »

I thought all was ready and finished, but now it turns out when I try to compile the shaders for Direct X I get several errors like this one (I managed to fix a bunch of the normal 'wrong constructor' and 'unknown types' errors):

Code: Select all

600000000VertexShader_vs.hlsl(421,19-29): error X4500: overlapping register semantics not yet implemented 't0'

The error line is rather incorrect with any significant information, it mentions line numbers (or one would assume) but they don't correspond to anything remotely in that area. This was the case for all of the errors that were generated and written in the logs, so it was quite a pain to debug without using an online HLSL verifier, am I missing something to get clearer information in the logs?
However the main problem I'm running into is due to the generated code becoming:

Code: Select all

// START UNIFORM DECLARATION
Texture2D<float> heightMap: register(t0);
Texture3D<float4> terrainData: register(t0);
SamplerState terrainDataSampler : register(s0);
Texture2D<float4> blendMap: register(t0);
// END UNIFORM DECLARATION

The code used to generate it is fairly much the same as textures in the Terra or other shaders code:

Code: Select all

// START UNIFORM DECLARATION
Texture2D<float> heightMap: register(t@value(heightMap));
Texture3D<float4> terrainData: register(t@value(terrainData));
SamplerState terrainDataSampler : register(s@value(terrainData));
Texture2D<float4> blendMap: register(t@value(blendMap));
// END UNIFORM DECLARATION

It also cries about the "error X3004: undeclared identifier 'gl_FragCoord'", even though this one is also used in other shaders, so again I'm probably missing a small detail.

Code: Select all


@insertpiece( output_type ) main
(
	PS_INPUT inPs
	@property( hlms_vpos ), float4 gl_FragCoord : SV_Position@end
	@property( two_sided_lighting ), bool gl_FrontFacing : SV_IsFrontFace@end
	@property( hlms_use_prepass_msaa && hlms_use_prepass ), uint gl_SampleMask : SV_Coverage@end
)
{
	PS_OUTPUT outPs;
	@insertpiece( custom_ps_preExecution )
	@insertpiece( DefaultOceanBodyPS )
	@insertpiece( custom_ps_posExecution )

@property( !hlms_render_depth_only )
	return outPs;
@end
}

Any help would be appreciated! (Also let me know if you need more of the shader's code, as far as I know this is the only relevant part)

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5277
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1268
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by dark_sylinc »

Hi!

Ridder Geel wrote: Wed Oct 18, 2023 7:35 pm

it mentions line numbers (or one would assume) but they don't correspond to anything remotely in that area.

Strip the dumped properties. Shaders will look like this:

Code: Select all

#if 0
	***	threads_per_group_x	8
	***	num_uav_slots	1
	***	uav0_data_type	425488324
	***	texture0_orig_pf_srgb	1
	***	precision_mode	-2126167738
	***	glsl	635204550
	***	threads_per_group_y	8
	***	threads_per_group_z	1
	***	uav0_orig_pf_srgb	1
	***	texture0	1
	***	typed_uav_load	1
	***	texture0_msaa_samples	1
	***	num_thread_groups_y	2
	***	glsles	1070293233
	***	TextureTypes_TypeCube	1084001037
	***	texture0_slot	0
	***	uav0_mipmaps	5
	***	texture0_texture_type	1084001037
	***	uav0_width	256
	***	TextureTypes_Type1DArray	1462074231
	***	typed_uav_loads	1
	***	GL_ARB_shading_language_420pack	1
	***	texture0_mipmaps	9
	***	relaxed	1726237731
	***	uav0_texture_type	1084001037
	***	hlslvk	1841745752
	***	texture0_pf_type	1476917420
	***	texture0_msaa	0
	***	TextureTypes_Type1D	2144086064
	***	full32	-2126167738
	***	TextureTypes_Unknown	-2095941475
	***	midf16	-1978079318
	***	uav0_pf_type	1476917420
	***	num_texture_slots	1
	***	syntax	-338983575
	***	metal	-1698855755
	***	TextureTypes_Type2D	-1647413313
	***	GL_ARB_base_instance	1
	***	texture0_depth	6
	***	uav0_width_with_lod	16
	***	uav0_height_with_lod	16
	***	uav0_msaa	0
	***	GL3+	450
	***	uav0	1
	***	TextureTypes_Type2DArray	-1281955822
	***	TextureTypes_Type3D	-1245584791
	***	texture0_height	256
	***	uav0_height	256
	***	TextureTypes_TypeCubeArray	-960317670
	***	texture0_data_type	425488324
	***	num_thread_groups_z	6
	***	uav0_depth	6
	***	glslvk	-338983575
	***	hlsl	-334286542
	***	uav0_msaa_samples	1
	***	texture0_width	256
	***	num_thread_groups_x	2
	***	GL_ARB_texture_buffer_range	1
	DONE DUMPING PROPERTIES
#endif

// LINE 0 ACTUALLY STARTS HERE

You can control this automatically with Hlms::setDebugOutputPath. Set the parameter outputProperties to false.

Otherwise just strip it yourself, since LINE 0 starts at the end of the #endif.

Ridder Geel wrote: Wed Oct 18, 2023 7:35 pm

However the main problem I'm running into is due to the generated code becoming:

Code: Select all

// START UNIFORM DECLARATION
Texture2D<float> heightMap: register(t0);
Texture3D<float4> terrainData: register(t0);
SamplerState terrainDataSampler : register(s0);
Texture2D<float4> blendMap: register(t0);
// END UNIFORM DECLARATION

Yeah that's definitely invalid HLSL, both blendMap, heightMap & terrainData are assigned to t0.
What's worst, terrainData is Texture3D while heightMap & blendMap are Texture2D.

terrainData & blendMap seem to be your customization, but as for the rest, in the original HlmsTerra the values are set in HlmsTerra::notifyPropertiesMergedPreGenerationStep:

Code: Select all

setTextureReg( tid, VertexShader, "heightMap", texUnit++ );

Make sure to set them to valid values and the same slots you bind the textures to in C++ (in HlmsTerra::fillBuffersFor)

Code: Select all

It also cries about the "error X3004: undeclared identifier 'gl_FragCoord'", even though this one is also used in other shaders, so again I'm probably missing a small detail.

gl_FragCoord is always defined in OpenGL, but in HLSL it needs to be defined explicitly.

As you've figured out we have:

Code: Select all

@insertpiece( output_type ) main
(
	PS_INPUT inPs
	@property( hlms_vpos ), float4 gl_FragCoord : SV_Position@end
)

So that by setting the hlms_vpos property when it's needed: either in preparePassHash, calculateHashForPreCreate/calculateHashForPreCaster, or notifyPropertiesMergedPreGenerationStep. Which one you'll need depends on when do you think you'll need gl_FragCoord (i.e. if all your terrain shader permutations need it, then it could be in preparePassHash; since it's pass-wide).

Cheers.

Ridder Geel
Gnoblar
Posts: 5
Joined: Sat Aug 19, 2023 2:39 pm
x 2

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Ridder Geel »

Odd, I did the setTextureReg thing before, but for some reason it didn't catch it when I tried it. It works now though!
And great, now the gl_FragCoord part works as well!
Stripping the dumped properties makes the error messages much clearer, it all compiles now. :D

Thanks again, you've been a great help!

Nickak2003
Goblin
Posts: 272
Joined: Thu Jun 10, 2004 4:19 am
x 26

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Nickak2003 »

Hello, I have been using ogre for some time and have some experience with it. However, I have not worked on writing custom shaders before and am curious about how one goes about to do something like this terra-ocean. Could you describe your process or resources on how you managed to accomplish this?

Did you use any existing tutorials or samples to aid you?

User avatar
Crystal Hammer
Gnome
Posts: 307
Joined: Sat Jun 23, 2007 5:16 pm
x 67
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Crystal Hammer »

I'm also very interested in this.
Only close sample I've seen is ReconstructPosFromDepth. But not sure how useful for water.

It would be really great to have a sample with just a transparent plane that does water coloring from depth buffer.
Also another highly requested sample from me would be similar but for soft particles.

Lax
Hobgoblin
Posts: 583
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 50

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Lax »

Hi,

I also asked in some topics about ocean! It would really be great, to have an ocean example in the Ogre showcase like terra.

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5277
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1268
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by dark_sylinc »

Hi!

Regarding the use of depth textures in shaders, there are the following examples:

  1. Sample_ReconstructPosFromDepth -> Mostly aimed for postprocessing with low level materials, but the theory can apply to anything.

  2. Sample_Refractions -> Ideal to what you're looking for. HlmsPbs and Compositor have to work together in order to get access to the depth buffer. While HlmsPbs reads the depth buffer, this one must be bound by the Compositor as read-only (you can't write to it, it's an HW limitation unless you're willing to copy/clone the depth buffer and works with two copies). I recommend that you first see it in RenderDoc, then see both Refractions.compositor and Refractions.compositor.example (the latter is a simplified version for learning), then see the HlmsPbs code handling it by looking at whatever has "HlmsPbsDatablock::Refractive", "HlmsBaseProp::ScreenSpaceRefractions", and "hlms_screen_space_refractions".

  3. Sample_ScreenSpaceReflections -> I do not recommend this sample. It's too complex, SSR did not live up to its promise and was too expensive to maintain, didn't play nice with MSAA, it's not working on some APIs (I think Metal and Vulkan).

User avatar
Crystal Hammer
Gnome
Posts: 307
Joined: Sat Jun 23, 2007 5:16 pm
x 67
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Crystal Hammer »

So I'm trying to use depth texture not in Terra based shader but just in Pbs now in my Terrain Demo.
I added from Sample_Refractions, the Refractions.compositor.example (not that other with MSAA from Refractions.compositor),
also added createRefractiveWall(), modified a bit.
This works and I got a plane that has refractions.
I also can modify refraction shader in /Media/Hlms/Pbs/Any/Refractions_piece_ps.any

But how to get depth there?
I saw this:
midf refractionDepth = OGRE_SampleLevelF16( depthTextureNoMsaa, refractionMapSampler, refractUv, 0 ).x;
but it seems to be always 0 or so.
I'd like best, a variable here in this piece (applyRefractions), giving water depth. Something like that from Sample_Tutorial_ReconstructPosFromDepth, which is too different, not using Pbs or .any etc.

Secondly, now (with depth in compositor and refractions) my Terrain Demo crashes when creating Planar Reflections plane.
Did I miss something? Or wasn't it tested (with refractions at once) so it naturally doesn't work. Could you fix it or tell how?
This is from log, missing refractionMap

Code: Select all

19:18:50: GLSL compile log: 100000086PixelShader_ps
0:928(41): error: `refractionMap' undeclared
0:928(29): error: no matching function for call to `textureLod(error, vec2, int)'; candidates are:
0:928(29): error:    vec4 textureLod(sampler1D, float, float)
....
0:939(6): warning: `refractionDepth' used uninitialized
0:945(23): warning: `refractionCol' used uninitialized
0:945(38): warning: `fallbackRefractionCol' used uninitialized
19:18:50: OGRE EXCEPTION(3:RenderingAPIException): Fragment Program 100000086PixelShader_ps failed to compile. See compile log above for details. in GLSLShader::compile at /home/ch/_sr/Ogre/ogre-next/RenderSystems/GL3Plus/src/GLSL/OgreGLSLShader.cpp (line 313)

If you wanted to test then this is the main part (and it's all pushed in ogre3ter-demo):

Code: Select all

            //  plane reflect works, refract not
            // "Tutorial_TerrainWorkspace_NoRefract", true );  // in Tutorial_Terrain.compositor
            //  plane reflect crashes, refract works
            "Tutorial_TerrainWorkspace", true );  // in Tutorial_Terrain.compositor

Code: Select all

	void TerrainGame::CreateWater()
	{
        createRefractiveWall();  // test refract
    return;  // crash below!

And just doing that flips vertically planar reflection camera! If I didn't crash shader, setting refractions.

Code: Select all

// bad: inverses reflect cam
        waterItem->setRenderQueueGroup( 200u );

and that:
// bad: crashes shader 'refractionMap' undeclared

BTW, poll will end soon (or was it only for Ogre 14?) when can we expect some news about OgreNext future and release? I feel not much changed since November.
Also you didn't comment about Terrain Demo. I'm guessing you don't want it inside OgreNext or to mainain it right?

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5277
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1268
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by dark_sylinc »

Crystal Hammer wrote: Sat Feb 24, 2024 7:33 pm

But how to get depth there?
I saw this:
midf refractionDepth = OGRE_SampleLevelF16( depthTextureNoMsaa, refractionMapSampler, refractUv, 0 ).x;
but it seems to be always 0 or so.
I'd like best, a variable here in this piece (applyRefractions), giving water depth. Something like that from Sample_Tutorial_ReconstructPosFromDepth, which is too different, not using Pbs or .any etc.

You can get the linear space depth with the following math (untested code):

Code: Select all

float3 ndcPos = float3( gl_FragCoord.xy * passBuf.invWindowRes * 2.0f - 1.0f, refractionDepth );
float4 linearSpacePos = mul( inverse( passBuf.viewProj ), float4( ndcPos, 1.0f  ) );
linearSpacePos /= linearSpacePos.w;
// Now linearSpacePos contains the original position (in camera space) at the given xyz pixel

Note that calculating the inverse() of a 4x4 matrix in the pixel shader is expensive. You should do that from C++ and send it to PassBuffer via an HlmsListener.

Crystal Hammer wrote: Sat Feb 24, 2024 7:33 pm

Secondly, now (with depth in compositor and refractions) my Terrain Demo crashes when creating Planar Reflections plane.
Did I miss something? Or wasn't it tested (with refractions at once) so it naturally doesn't work. Could you fix it or tell how?
This is from log, missing refractionMap

Code: Select all

19:18:50: GLSL compile log: 100000086PixelShader_ps
0:928(41): error: `refractionMap' undeclared
0:928(29): error: no matching function for call to `textureLod(error, vec2, int)'; candidates are:
0:928(29): error:    vec4 textureLod(sampler1D, float, float)
....
0:939(6): warning: `refractionDepth' used uninitialized
0:945(23): warning: `refractionCol' used uninitialized
0:945(38): warning: `fallbackRefractionCol' used uninitialized
19:18:50: OGRE EXCEPTION(3:RenderingAPIException): Fragment Program 100000086PixelShader_ps failed to compile. See compile log above for details. in GLSLShader::compile at /home/ch/_sr/Ogre/ogre-next/RenderSystems/GL3Plus/src/GLSL/OgreGLSLShader.cpp (line 313)

In debug builds you should be getting the following assert:

"A material that uses refractions is used in a pass where refractions are unavailable! See "
"Samples/2.0/ApiUsage/Refractions for which pass refractions must be rendered in"

Basically make sure the refractive object with the refractive material is ONLY rendered in the specific passes meant for refractions. Such properly setup pass will call SceneManager::_setRefractions (see OgreCompositorPassScene.cpp) with a non-nullptr.

That includes shadow mapping (i.e. disable shadow casting for that object).

Crystal Hammer wrote: Sat Feb 24, 2024 7:33 pm

BTW, poll will end soon (or was it only for Ogre 14?) when can we expect some news about OgreNext future and release? I feel not much changed since November.
Also you didn't comment about Terrain Demo. I'm guessing you don't want it inside OgreNext or to mainain it right?

Thanks for the reminder. I am incredibly busy lately with Alliance: Air War Open Beta (it uses OgreNext btw!) and end up tired and forget dealing with it.

User avatar
Crystal Hammer
Gnome
Posts: 307
Joined: Sat Jun 23, 2007 5:16 pm
x 67
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Crystal Hammer »

Ok thanks. Good to know.

Code: Select all

GLSL compile log: 100000071PixelShader_ps
0:1389(18): error: `gl_Position' undeclared
0:1389(18): error: type mismatch

I am inside .any, seems gl_Position appears in glsl only. Is this same as inPs.pos?
Apart from this error, seems okay.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5277
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1268
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by dark_sylinc »

Ah! Where it says gl_Position it should read gl_FragCoord.

I'll edit the original post.

Is this same as inPs.pos?

No. inPs.pos contains position in view space, while gl_FragCoord is in range [0; width) and [0; height)

Edit: To elaborate further a pixel is calculated from vertex shader like this (some parts of the math is done by the GPU in the rasterizer chip; I'm writing the equations to explain it):

Code: Select all

gl_Position.xyzw = mul( worldViewProjection, float4( inVs_vertex, 1.0f ) );
// The following is done by the rasterizer
gl_FragCoord.xyz = gl_Position.xyz / gl_Position.w; // Now xy is in range [-1; 1] and depth in [0; 1] aka Normalized Device Coordinates aka NDC.
gl_FragCoord.xy = ( gl_FragCoord.xy * 0.5 + 1.0 ) * resolution.xy;

Thus to make the inverse operation, we already know gl_FragCoord.xy, and the depth is known from what is stored in the depth buffer:

Code: Select all

// gl_FragCoord.xy is already known (it's the pixel we're working on)
// However we don't know gl_Position.w. We don't need it, because fortunately the operation is symmetrical
depthValue = texelFetch( depthBuffer, gl_FragCoord.xy );
float3 ndc = float3( gl_FragCoord.xy * 2.0 - 1.0, depthValue );
float4 tmp = mul( inverse( worldViewProjection ), float4( ndc, 1.0f  ) );
float3 restored_inVs_vertex = tmp.xyz / tmp.w;

That is, we follow the inverse operation, but because we don't know gl_Position.w, we can still apply it later (when we do / tmp.w).

This operation is explained in Reconstructing Position from Depth which is linked in our Tutorial_ReconstructPosFromDepth sample; because it is the original way of reconstructing position from depth. It's also the most expensive way.

The ReconstructPosFromDepth uses a trick to get a much cheaper way to calculate it for postprocessing effects by sending the far plane value to the pixel shader.
But when this is difficult to achieve in a complex geometry, the original way is fine.

User avatar
Crystal Hammer
Gnome
Posts: 307
Joined: Sat Jun 23, 2007 5:16 pm
x 67
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Crystal Hammer »

Right. I understand. And I'm pretty sure it would work, given right data and in glsl (only).
New code has worldViewProjection which is for glsl.

But I am inside this .any here (demo/Media/Hlms/Pbs/Any/Refractions_piece_ps.any)
And I think the main problem is that this (called above):
midf refractionDepth = OGRE_SampleLevelF16( depthTextureNoMsaa, refractionMapSampler, refractUv, 0 ).x;
gives 0 always for me.
IDK if some Ogre code sets depthTextureNoMsaa and how, or maybe it just doesn't and I need to?

Do I need this earlier logic from this topic, for "copying the depth buffer" and new depthBufferCopy?

Or maybe I need that more complex MSAA setup of depthTexture from Refractions.compositor?
I have only basic setup (Sample_Refractions, the Refractions.compositor.example)
in my Tutorial_Terrain.compositor#L140

Anyways for testing this, such places in my code are of interest to change and with comments.
TerrainGame_Compositor.cpp#L151
TerrainGame_Create.cpp#L142
TerrainScene_Water.cpp#L209

And now I got the same issue with planar reflect camera flipped Y in refractions too.
Behaves the same as in my other preview RTT from SR3 editor, in earlier video and you already commented on solution here, but I didn't yet get to fixing it. I surely need to now, as it causes 2 problems (in editor preview camera and for water plane reflect with refractions).

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5277
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1268
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by dark_sylinc »

Hi!

Regarding this particular problem:

Crystal Hammer wrote: Sun Feb 25, 2024 2:40 pm

But I am inside this .any here (demo/Media/Hlms/Pbs/Any/Refractions_piece_ps.any)
And I think the main problem is that this (called above):

gives 0 always for me.
IDK if some Ogre code sets depthTextureNoMsaa and how, or maybe it just doesn't and I need to?

If I recall, your demo worked fine on Vulkan (if you have to, disable the GUI that was causing trouble).

RenderDoc has source-level shader debugging for Vulkan, which can be very helpful. There's a ton of reasons why sampling the texture returns 0:

  1. The actual value is 0
  2. The value is not 0, but so close to 0 it rounds to 0 when printed as text. Open the raw buffer contents in RenderDoc.
  3. Wrong texture bound at that slot
  4. The UVs are out of bounds. refractUv is not guaranteed to be in bounds (specially if strength is too big).
User avatar
Crystal Hammer
Gnome
Posts: 307
Joined: Sat Jun 23, 2007 5:16 pm
x 67
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Crystal Hammer »

Thanks. I checked it in RenderDoc, in GL even.
Wow I got depth values there. Just very small, from 0.00005 to 0.0021.
Have to multiply by 1000 to get them to something colorful on screen.

User avatar
Crystal Hammer
Gnome
Posts: 307
Joined: Sat Jun 23, 2007 5:16 pm
x 67
Contact:

Re: [2.3] Using Depth texture in Terra based Ocean shader

Post by Crystal Hammer »

Wow I got it. Details in commit.

Image

Code: Select all

	midf depthValue = OGRE_SampleLevelF16( depthTextureNoMsaa, refractionMapSampler, screenPosUv.xy, 0 ).x;
	midf4 ndc = midf4( screenPosUv.xy * 2.0 - 1.0, depthValue, 1.0 );
	midf4 tmp = mul( ndc, inverse( passBuf.viewProj ) );  // worldViewProj-
	midf3 pos = tmp.xyz / tmp.w;
	midf depth = inPs.worldH - pos.y;

and that last was added in vertex shader to have word y pos in PS too (same like I had for height fog)

Code: Select all

	outVs.worldH = worldPos.y;

It still has some bugs from refraction, but already very cool.

Post Reply