Ogre WIP and random screenshot thread (for everyone!)

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!
chaos creator
Gnoblar
Posts: 22
Joined: Tue May 08, 2012 5:56 pm

Re: Ogre WIP and random screenshot thread (for everyone!)

Post by chaos creator » Sun Sep 10, 2017 3:31 pm

I made a postprocess contour / outline shader :)
It works by comparing depths and drawing lines when there are discontinuities - which is normally at edges.
The line colour, thickness and detection thresholds are freely adjustable.

Image

Unfortunately, right now it doesn't work with FSAA + OpenGL.

If anyone is interested, here is the code:

Sketch_ps.hlsl

Code: Select all

Texture2D<float> depthTexture	: register(t0);
Texture2D RT					: register(t1);
SamplerState samplerState		: register(s0);



struct PS_INPUT
{
	float2 uv0			: TEXCOORD0;
	float3 cameraDir	: TEXCOORD1;
};

uniform float2 projectionParams;

float linearDepth(float2 uv)
{
	float fDepth = depthTexture.Sample(samplerState, uv).x;
    return projectionParams.y / (fDepth - projectionParams.x);
}

float gain(float x, float k) 
{
    // copied from http://www.iquilezles.org/www/articles/functions/functions.htm
    float a = 0.5*pow(2.0*((x<0.5)?x:1.0-x), k);
    return (x<0.5)?a:1.0-a;
}

float4 main(PS_INPUT inPs) : SV_Target
{
    //size of the lines
    float size = 0.0015;
    //colour of the lines
    float3 LineColour = float3(1.0, 0.2, 0.0);
    //steepness of the gain
    float k = 4;
    //higher values mean more lines / less depth deviation necessary for lines to be drawn
    float sensitivity = 50000;


    float3 Colour = RT.Sample(samplerState, inPs.uv0 ).rgb;
    float centerDepth = linearDepth(inPs.uv0);
	

    float topDepth    = linearDepth( inPs.uv0 + float2( 0, -1) * size );
    float bottomDepth = linearDepth( inPs.uv0 + float2( 0,  1) * size );
    float leftDepth   = linearDepth( inPs.uv0 + float2(-1,  0) * size );
    float rightDepth  = linearDepth( inPs.uv0 + float2(+1,  0) * size );

    //difference between interpolated and measured depth
    //- represents how "flat" the surface is
    float yDeviation = centerDepth - (topDepth + bottomDepth) / 2.0;
    float xDeviation = centerDepth - (leftDepth + rightDepth) / 2.0;

    float Deviation = abs(xDeviation) + abs(yDeviation);
    
    float Sketch = clamp(Deviation * sensitivity, 0.0, 1.0);
    Sketch = gain(Sketch, k);

    return float4(lerp(Colour, LineColour, Sketch), 1.0);
}
Sketch_ps.glsl

Code: Select all

#version 330

uniform sampler2D depthTexture;
uniform sampler2D RT;

out vec4 fragColour;

in block
{
	vec2 uv0;
} inPs;

uniform vec2 projectionParams;

float linearDepth(vec2 uv)
{
    float fDepth = texture(depthTexture, uv).x;
    return projectionParams.y / (fDepth - projectionParams.x);
}

float gain(float x, float k) 
{
    // copied from http://www.iquilezles.org/www/articles/functions/functions.htm
    float a = 0.5*pow(2.0*((x<0.5)?x:1.0-x), k);
    return (x<0.5)?a:1.0-a;
}

void main()
{
    //size of the lines
    float size = 0.0015;
    //colour of the lines
    vec3 LineColour = vec3(1.0, 0.2, 0.0);
    //steepness of the gain
    float k = 4;
    //higher values mean more lines / less depth deviation necessary for lines to be drawn
    float sensitivity = 50000;

    
    vec3 Colour = texture(RT, inPs.uv0).rgb;
    float centerDepth = linearDepth(inPs.uv0);


    float topDepth    = linearDepth( inPs.uv0 + vec2( 0, -1) * size );
    float bottomDepth = linearDepth( inPs.uv0 + vec2( 0,  1) * size );
    float leftDepth   = linearDepth( inPs.uv0 + vec2(-1,  0) * size );
    float rightDepth  = linearDepth( inPs.uv0 + vec2(+1,  0) * size );

    //difference between interpolated and measured depth
    //- represents how "flat" the surface is
    float yDeviation = centerDepth - (topDepth + bottomDepth) / 2.0;
    float xDeviation = centerDepth - (leftDepth + rightDepth) / 2.0;

    float Deviation = abs(xDeviation) + abs(yDeviation);
    
    float Sketch = clamp(Deviation * sensitivity, 0.0, 1.0);
    Sketch = gain(Sketch, k);

    fragColour = vec4(mix(Colour, LineColour, Sketch), 1.0);
}
Sketch.material

Code: Select all

fragment_program Sketch_ps_HLSL hlsl
{
	source Sketch_ps.hlsl
	target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3
	entry_point main
}

fragment_program Sketch_ps_GLSL glsl
{
	source Sketch_ps.glsl
	default_params
	{
		param_named depthTexture int 0
		param_named RT int 1
	}
}

fragment_program Sketch_ps unified
{
	delegate Sketch_ps_GLSL
	delegate Sketch_ps_HLSL
}

material Postprocess/Sketch
{
	technique
	{
		pass
		{
			depth_check off
			depth_write off

			cull_hardware none

			vertex_program_ref Ogre/Compositor/Quad_vs
			{
			}

			fragment_program_ref Sketch_ps
			{
			}

			texture_unit depthTexture
			{
				tex_address_mode clamp
				filtering none
			}

			texture_unit RT
			{
				tex_address_mode clamp
				filtering none
			}
		}
	}
}
Compostior script

Code: Select all

compositor_node Sketch
{
	in 0 rt_input
	in 1 rt_output

	custom_id Ogre/Postprocess

	//The depthTexture will be a "view" to rt0's depth because it has the exact same parameters
	//(PF_D32_FLOAT, pool ID = 2; rt0 was asked to use a depth_texture)
	//
	//Note that other RTTs may share the same depth buffer if they have the same parameters as well due
	//to depth buffer sharing (depth_pool 65534 is a special pool where sharing is disabled so each RTT gets
	//its own depth buffer/texture; depth textures are by default placed there so we need to explicitly set
	//it to 2).
	texture depthTexture target_width target_height PF_D32_FLOAT depth_pool 2
	
	//This depthTexture will be a copy of the original. We can read from 'depthTexture' directly, however
	//on a lot of HW reading from the depth texture means it needs to be decompressed. If you later
	//need to keep rendering using the same depth buffer (something very common in most use cases
	//for this technique) you will pay the performance price for using a decompressed buffer.
	//See section '4.1.4.2 Depth Textures' of the manual for an explanation.
	texture depthTextureCopy target_width target_height PF_D32_FLOAT

	target rt_output
	{
		pass depth_copy
		{
			//When alias_on_copy_failure is on, if the copy fails (i.e. hardware doesn't support it)
			//then 'depthTextureCopy' will internally point to the same buffer as depthTexture.
			//For a lot of cases this is harmless and a nice fallback.
			alias_on_copy_failure	on
			in		depthTexture
			out		depthTextureCopy
		}

		// Draw a fullscreen quad with the black and white image
		pass render_quad
		{
			// Renders a fullscreen quad with a material
			material Postprocess/Sketch
			input 0 depthTextureCopy
			input 1 rt_input
		}
	}

	out 0 rt_output
	out 1 rt_input
}

//The texture that the scene gets rendered to has to have the same depth format
texture renderTarget target_width target_height PF_R8G8B8 depth_texture depth_format PF_D32_FLOAT depth_pool 2
The script needs following data to linearise the depth:

Code: Select all

        Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().load(
                    "ReconstructPosFromDepth",
                    Ogre::ResourceGroupManager::
                    AUTODETECT_RESOURCE_GROUP_NAME ).staticCast<Ogre::Material>();

        Ogre::Pass *pass = material->getTechnique(0)->getPass(0);
        Ogre::GpuProgramParametersSharedPtr psParams = pass->getFragmentProgramParameters();

        Ogre::Camera *camera = mGraphicsSystem->getCamera();
        Ogre::Real projectionA = camera->getFarClipDistance() /
                                    (camera->getFarClipDistance() - camera->getNearClipDistance());
        Ogre::Real projectionB = (-camera->getFarClipDistance() * camera->getNearClipDistance()) /
                                    (camera->getFarClipDistance() - camera->getNearClipDistance());
        //The division will keep "linearDepth" in the shader in the [0; 1] range.
        projectionB /= camera->getFarClipDistance();
        psParams->setNamedConstant( "projectionParams", Ogre::Vector4( projectionA, projectionB, 0, 0 ) );
0 x

User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7142
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 9

Re: Ogre WIP and random screenshot thread (for everyone!)

Post by Kojack » Fri Sep 21, 2018 9:46 pm

No WIP posts for a year? :(

Just a few hours ago I got this going:

Image

Loading level 1 from System Shock 1 in Ogre 2.2.

The map data is compressed in a confusing way with 14 bit words, 16 bit dictionaries of offsets and lengths and other stuff. The third party SS1Edit tool came with docs and lua source, but the docs are confusing for the compression and I got heap corruption when I tried to port the lua to C++, so I gave up and just ran a tool to decompress the map's data file. Loading a decompressed map is MUCH easier.

Although then we get into the map data, where the docs were wrong again (saying each tile was 20 bytes when they are 16). Argh.
I got that working though.

Each map is a 64x64 grid. Each tile of the grid has a floor height, ceiling height, slope amount and shape. There are 18 shapes (solid, empty, diagonals, valleys, ridges, ramps).
0 x

Slicky
Bronze Sponsor
Bronze Sponsor
Posts: 471
Joined: Mon Apr 14, 2003 11:48 pm
Location: Was LA now France
x 5

Re: Ogre WIP and random screenshot thread (for everyone!)

Post by Slicky » Sat Sep 22, 2018 6:47 am

Interesting. What did you do for material conversion?
0 x

User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7142
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 9

Re: Ogre WIP and random screenshot thread (for everyone!)

Post by Kojack » Sat Sep 22, 2018 11:13 am

Slicky wrote:
Sat Sep 22, 2018 6:47 am
Interesting. What did you do for material conversion?
I just put a pallas cat on every wall. I haven't looked at materials yet. :)
(The top half of the pic is the real game, the bottom half is my one of the same area)
0 x

Post Reply