GLSLES. Shader artefact

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
ENGine
Goblin
Posts: 266
Joined: Fri Jan 27, 2006 9:13 pm
Location: Belarus
x 2
Contact:

GLSLES. Shader artefact

Post by ENGine »

Hi, all.

Can't solve the bug connected with Shadow Map under Ogre3D v1.9, iOS Platform.
As the camera movement the shadow is being changed:

OK: http://joxi.ru/v29XpWOuGq6ZYm

Bugs:
http://joxi.ru/n2YZxkdujpxbOA
http://joxi.ru/5mdvq7zhvnX3lA
http://joxi.ru/vAWLn3lhkEWg9r

DepthShadowmap:

Code: Select all

vertex_program Ogre/DepthShadowmap/CasterVP glsles
{
    source DepthShadowmapCasterVp.glsles
	profiles glsles
	preprocessor_defines LINEAR_RANGE=0

    default_params
    {
        param_named_auto worldViewProj worldviewproj_matrix
		param_named_auto texelOffsets texel_offsets
		//param_named_auto depthRange scene_depth_range
    }
}


fragment_program Ogre/DepthShadowmap/CasterFP glsles
{
    source DepthShadowmapCasterFp.glsles
    profiles glsles

	preprocessor_defines LINEAR_RANGE=0

    default_params
    {
    }
}

// Generic Shadow caster material (floating point shadowmap)
material Ogre/DepthShadowmap/Caster/Float
{
	technique
    {
        pass 
        {
            vertex_program_ref Ogre/DepthShadowmap/CasterVP
            {
            }
            fragment_program_ref Ogre/DepthShadowmap/CasterFP
            {
            }
        }
    }
}

Code: Select all

#version 100

precision highp int;
precision highp float;

uniform mat4 worldViewProj;
uniform vec4 texelOffsets;
uniform vec4 depthRange;

attribute vec4 position;
varying vec2 depth;

void main()
{
	gl_Position = worldViewProj * position;

	// fix pixel / texel alignment
	gl_Position.xy += texelOffsets.zw * gl_Position.w;
	// linear depth storage
	// offset / scale range output
#if LINEAR_RANGE
	depth.x = (gl_Position.z - depthRange.x) * depthRange.w;
#else
	depth.x = gl_Position.z;
#endif
	depth.y = gl_Position.w;


}

Code: Select all

#version 100

precision highp int;
precision highp float;

varying vec2 depth;

void main()
{
    #if LINEAR_RANGE
        float finalDepth = depth.x;
    #else
        float finalDepth = depth.x / depth.y;
    #endif
    // just smear across all components
    // therefore this one needs high individual channel precision
    gl_FragColor.r = finalDepth;// = vec4(finalDepth, finalDepth, finalDepth, 1.0);
}
It was standard shader from Ogre3d v1.9

Now I'm trying to show the shadow on my floor:
Material:

Code: Select all

vertex_program Led_ProjectionVS glsles
{
	source Led_ProjectionVS.glsles
	profiles glsles
     
	default_params
    {
		param_named_auto modelViewProjectionMatrix worldviewproj_matrix
        param_named_auto modelWorldMatrix world_matrix
		param_named_auto texWorldViewProj texture_viewproj_matrix
    }
}

fragment_program Led_ProjectionFS glsles
 {
     source Led_ProjectionFS.glsles
     profiles glsles
          
	default_params
    {
		param_named shadowMap int 0
    }
 }
material Led
{
	technique
	{
		pass
		{
		       vertex_program_ref Led_ProjectionVS
			{
			}
			
			fragment_program_ref Led_ProjectionFS
			{
			}

			texture_unit
			{
				content_type shadow
				tex_address_mode clamp
				filtering none
			}
		}
		
	}
}

Code: Select all

#version 100

precision highp int;
precision highp float;

uniform mat4 modelViewProjectionMatrix;
uniform mat4 modelWorldMatrix;
uniform mat4 texWorldViewProj;

attribute vec4 position;
attribute vec4 uv0;

varying vec4 oUv;
varying vec4 texCoord;

void main()
{
    gl_Position = modelViewProjectionMatrix * position;
	vec4 shadowPosition = modelWorldMatrix * position;
	texCoord = texWorldViewProj * shadowPosition;
	oUv = uv0;
}

Code: Select all

#version 100

precision highp int;
precision highp float;

uniform sampler2D shadowMap;

varying vec4 oUv;
varying vec4 texCoord;

void main()
{
	vec4 shadowUV1 = texCoord / texCoord.w;
float shadow1 = texture2D( shadowMap, shadowUV1.xy ).x;
	vec4 final = vec4(1.0, 1.0, 1.0, 1.0) * shadow1;
    gl_FragColor = final;
}

Code: Select all

	mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);
	mSceneMg->setShadowTextureSettings(1024, 1);
	mSceneMgr->setShadowColour(0, 0, 0, 0.25);
	mSceneMgr->setShadowTextureSelfShadow(true);
	mSceneMgr->setShadowTexturePixelFormat(PF_A8R8G8B8);
	mSceneMgr->setShadowTextureCasterMaterial("Ogre/DepthShadowmap/Caster/Float");
Please, guys, let me know what I'm doing wrong. Thanks.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: GLSLES. Shader artefact

Post by dark_sylinc »

I remember fighting this bug in 1.x very often, in Desktop.

I never found out the where the bug is exactly happening but it in Ogre 2.0 it didn't matter because I rewrote the damn thing.
I noticed it happened more often if I used instancing (via InstanceMananger). It seemed that Ogre incorrectly calculated the scene's combined shadow casting AABB.
A workaround I used that worked very well was to place four (or up to eight) shadowcasting instanced cubes (hidden away inside other geometry, or using front face culling to make it look like it's invisible) to force this scene's combined shadow casting AABB to enclose these cubes. That's why I used four: One in each corner. Sometimes I needed more to account for height.

A workaround. If it looks stupid but it works...
User avatar
ENGine
Goblin
Posts: 266
Joined: Fri Jan 27, 2006 9:13 pm
Location: Belarus
x 2
Contact:

Re: GLSLES. Shader artefact

Post by ENGine »

Could you tell about workaround more? Frankly speaking, I understood it so-so.
Short example... it will be great :)
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: GLSLES. Shader artefact

Post by dark_sylinc »

It looks like a ice hockey rink, right?
Suppose your hockey rink goes from [-16; -16; -32] to [16; 24; 32] (values in meters. According to wikipedia it should be 30m wide and 61m long. I just rounded them to power of 2: 32 & 64).

Then you would create around 6 cubes, like this:

Code: Select all

//Choosing "InstanceManager::ShaderBased" because I don't know if the others are available in iOS. Typically I would go for InstanceManager::HWInstancingBasic
mCurrentManager = mSceneMgr->createInstanceManager(
            "InstanceMgr", "DebugCube.mesh",
            ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, InstanceManager::ShaderBased,
            6, IM_USEALL);

InstancedEntity *ent = mCurrentManager->createInstancedEntity( "InstancingMaterialName" );
ent->setPosition( -16; -16; -32 );

ent = mCurrentManager->createInstancedEntity( "InstancingMaterialName" );
ent->setPosition( 16; -16; -32 );

ent = mCurrentManager->createInstancedEntity( "InstancingMaterialName" );
ent->setPosition( -16; -16; 32 );

ent = mCurrentManager->createInstancedEntity( "InstancingMaterialName" );
ent->setPosition( 16; 24; 32 );

//Two more in the middle just in case
ent = mCurrentManager->createInstancedEntity( "InstancingMaterialName" );
ent->setPosition( -16; 24; 0 );

ent = mCurrentManager->createInstancedEntity( "InstancingMaterialName" );
ent->setPosition( 16; -16; 0 );
In other words make them be the "markers" of the scene's bounds. If you have artifacts in a particular camera angle, it's probably because all markers got culled, so you need more markers.
These markers don't have to be debug cubes. Props (i.e. lighting reflectors) can work too.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: GLSLES. Shader artefact

Post by dark_sylinc »

I just noticed you call:

Code: Select all

mSceneMgr->setShadowTexturePixelFormat(PF_A8R8G8B8);
Does iOS support something better? Like PF_FLOAT32_R or at least PF_FLOAT16_R.
Do you call setShadowCameraSetup? If not you're using the default one, and it not does only suck, but also its default parameters were extremely bad.
User avatar
ENGine
Goblin
Posts: 266
Joined: Fri Jan 27, 2006 9:13 pm
Location: Belarus
x 2
Contact:

Re: GLSLES. Shader artefact

Post by ENGine »

dark_sylinc,

Could you answer me if it's fixed on 1.10 or I will have to move up to 2.X? Thanks.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: GLSLES. Shader artefact

Post by dark_sylinc »

I doubt it's fixed in 1.10 but I do not know. I also do not know where the problem is.

I know it was fixed in 2.x because I rewrote the whole thing. Simple as that.
Post Reply