[v1.9.0] [GL] Shadow problem! SHADOWTYPE_TEXTURE_ADDITIVE eats my Lightmaps. SHADOWTYPE_TEXTURE_MODULATIVE has artifacts

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
nuke
Halfling
Posts: 42
Joined: Wed Oct 01, 2014 1:16 am
Location: Eastern Europe

[v1.9.0] [GL] Shadow problem! SHADOWTYPE_TEXTURE_ADDITIVE eats my Lightmaps. SHADOWTYPE_TEXTURE_MODULATIVE has artifacts

Post by nuke »

Ogre Version: v1.9.0
Operating System: Windows 10 x64
Render System: OpenGL

I've tried both SHADOWTYPE_TEXTURE_MODULATIVE and SHADOWTYPE_TEXTURE_ADDITIVE

I like SHADOWTYPE_TEXTURE_ADDITIVE but it completely "eats" my lightmapps :(((((


Here is screenshots:
1) SHADOWTYPE_TEXTURE_MODULATIVE
Strange artifact on the right wall, it follows me when I move the car.
Note, Lightmaps are OK!
Image
Image

2) SHADOWTYPE_TEXTURE_ADDITIVE
Lightmaps are disappeared :( scene become much darker :(
But no annoying artifacts on walls and perfect shadows!
Image

How to fix artifacts (in SHADOWTYPE_TEXTURE_MODULATIVE mode) or preserve Lightmaps (in SHADOWTYPE_TEXTURE_ADDITIVE mode)
Please help! :roll:



My material with baked Lightmaps (generated by Easy Ogre Exporter):

Code: Select all

material "baked_Default_1"
{
	receive_shadows on
	technique baked_Default_1_technique
	{
		pass baked_Default_1_standard
		{
			ambient 0.7 0.7 0.7 0.7
			diffuse 0.6 0.6 0.6 0.6
			specular 0 0 0 0 25.5
			emissive 0 0 0 1

			texture_unit baked_Default_1_Ambient#0
			{
				texture RoadFade_1LightingMap.tga
				tex_coord_set 2
				colour_op add
				alpha_op_ex source2 src_manual src_current 1
			}

			texture_unit baked_Default_1_Diffuse#1
			{
				texture mock-chess.jpg
				tex_coord_set 0
				colour_op modulate
			}
		}
	}
}
and my shadow settings (I use Lua , but there is absolute no differeces between Lua-call and C++-call )

Code: Select all

       .....
	-- shadows
	do
		sm:setShadowTechnique(OgreGlobal.SHADOWTYPE_TEXTURE_MODULATIVE)
		sm:setShadowColour(Ogre.ColourValue(0.6, 0.6, 0.6))

		sm:setShadowTextureSize(2048)
		sm:setShadowTextureCount(1)
		
		sm:setShadowCasterRenderBackFaces(true) 
		sm:setShadowTextureFadeStart(0.5)
		sm:setShadowTextureFadeEnd(1.0)
		sm:setShadowFarDistance(300.0)

		-- shadowcam	
		self.oShadowCameraSetup = Help.Ogre_.create_LiSPSMShadowCameraSetup() 
		self.oShadowCameraSetup:setUseSimpleOptimalAdjust(true) 
		sm:setShadowCameraSetup(Help.Ogre.ShadowCameraSetupPtr(self.oShadowCameraSetup))
	end
	.....

User avatar
nuke
Halfling
Posts: 42
Joined: Wed Oct 01, 2014 1:16 am
Location: Eastern Europe

Re: [v1.9.0] [GL] Shadow problem! SHADOWTYPE_TEXTURE_ADDITIVE eats my Lightmaps. SHADOWTYPE_TEXTURE_MODULATIVE has artif

Post by nuke »

I tried fix MODULATIVE mode and use my custom shadow materials/shaders forked from Ogre Sampled

But I get big parasite shadow :(

Image
Image

Shadow settings:

Code: Select all

	-- shadows
	do
		sm:setShadowTechnique(OgreGlobal.SHADOWTYPE_TEXTURE_MODULATIVE)  -- Yes I use MODULATIVE
		sm:setShadowColour(Ogre.ColourValue(0.6, 0.6, 0.6))
		
		sm:setShadowTextureCasterMaterial('Ogre/DepthShadowmap/Caster/Float')
		sm:setShadowTextureReceiverMaterial('Ogre/DepthShadowmap/Receiver/Float')
		sm:setShadowTextureSelfShadow(false)
		
		sm:setShadowTextureSize(1024*4)
		sm:setShadowTextureCount(10)
	
		self.oShadowCameraSetup = Ogre.LiSPSMShadowCameraSetup() 
		self.oShadowCameraSetup:setUseSimpleOptimalAdjust(true)  	
		sm:setShadowCameraSetup(Help.Ogre.ShadowCameraSetupPtr(self.oShadowCameraSetup))
	end

DepthShadowmap.material

Code: Select all

vertex_program Ogre/DepthShadowmap/CasterVP unified
{
	delegate Ogre/DepthShadowmap/CasterVP_GLSL
}
fragment_program Ogre/DepthShadowmap/CasterFP unified
{
	delegate Ogre/DepthShadowmap/CasterFP_GLSL
}
vertex_program Ogre/DepthShadowmap/ReceiverVP unified
{
	delegate Ogre/DepthShadowmap/ReceiverVP_GLSL
}
fragment_program Ogre/DepthShadowmap/ReceiverFP unified
{
	delegate Ogre/DepthShadowmap/ReceiverFP_GLSL
}




vertex_program Ogre/DepthShadowmap/CasterVP_GLSL glsl
{
    source DepthShadowmapCasterVp.glsl
	
    default_params
    {
        param_named_auto worldViewProj worldviewproj_matrix
		param_named_auto texelOffsets texel_offsets
    }
}


fragment_program Ogre/DepthShadowmap/CasterFP_GLSL glsl
{
    source DepthShadowmapCasterFp.glsl
	
    default_params
    {
    }
}
vertex_program Ogre/DepthShadowmap/ReceiverVP_GLSL glsl
{
    source DepthShadowmapReceiverVp.glsl

    default_params
    {
                param_named_auto M_World 			world_matrix
                param_named_auto M_World_it 		inverse_transpose_world_matrix
		param_named_auto M_WorldVP 		worldviewproj_matrix
		param_named_auto M_TexVP 			texture_viewproj_matrix
		param_named_auto Light_Pos 			light_position 0
		param_named_auto Light_Diffuse 		light_diffuse_colour 0
    }
}


fragment_program Ogre/DepthShadowmap/ReceiverFP_GLSL glsl
{
    source DepthShadowmapReceiverFp.glsl

	preprocessor_defines PCF=1

	default_params
    {

		param_named uShadowMap 		        int 0
                param_named inverseShadowmapSize 	float 0.000244140625
		param_named fixedDepthBias 			float 0.0005
		param_named gradientClamp 			float 0.0098
		param_named gradientScaleBias 		float 0
		
		param_named uShadowFadeMaxDistance	float 	10000.0 // NOT USED
    }
}


// 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
            {
            }
        }
    }
}

// Generic Shadow receiver material (floating point shadowmap)
material Ogre/DepthShadowmap/Receiver/Float
{
	technique
    {
        pass 
        {

            vertex_program_ref Ogre/DepthShadowmap/ReceiverVP
            {
            }
            fragment_program_ref Ogre/DepthShadowmap/ReceiverFP
            {
            }
            texture_unit ShadowMap
            {
                tex_address_mode clamp
                filtering anisotropic
            }
        }
    }
}
DepthShadowMapReceiverVP.glsl

Code: Select all

#version 120

uniform mat4 	M_World;
uniform mat4 	M_World_it;
uniform mat4 	M_WorldVP;
uniform mat4 	M_TexVP;

uniform vec4 	Light_Pos;
uniform vec4 	Light_Diffuse;

attribute vec4 vertex;
attribute vec3 normal;

varying	vec4 oUv;
varying	vec4 outColor;


varying	float 	oDist; // NOTE: need for shadow-by-dist optimization

void main()
{
	gl_Position 	= M_WorldVP * vertex;

	vec4 p = M_World * vertex; // world pos
	vec3 n = (M_World_it * vec4(normal, 1.0)).xyz;

	// calculate lighting (simple vertex lighting)
	vec3 ldir 		= normalize(vec3(Light_Pos-p)); 	// light dir
	float sDotN 	= max(dot(ldir,n),0.0);

	outColor = Light_Diffuse;// * 0.5;// * sDotN;

	oDist 				= abs(gl_Position.z)*0.01;

	// calculate shadow map coords
	oUv = M_TexVP * p;
}
DepthShadowMapReceiverFP.glsl

Code: Select all

#version 120

uniform float inverseShadowmapSize;
uniform float fixedDepthBias;
uniform float gradientClamp;
uniform float gradientScaleBias;

uniform float uShadowFadeMaxDistance;


uniform sampler2D uShadowMap;

varying	vec4 oUv;
varying	vec4 outColor;
varying	float oDist;

void main()
{
	float cShadowFadeMaxDistanceInv = 1.0/uShadowFadeMaxDistance;
	
	vec4 shadowUV = oUv;
	// point on shadowmap
	shadowUV = shadowUV / shadowUV.w;
	float centerdepth = texture2D(uShadowMap, shadowUV.xy).x;
    
    // gradient calculation
  	float pixeloffset = inverseShadowmapSize;
    vec4 depths = vec4(
    	texture2D(uShadowMap, shadowUV.xy + vec2(-pixeloffset, 0)).x,
    	texture2D(uShadowMap, shadowUV.xy + vec2(+pixeloffset, 0)).x,
    	texture2D(uShadowMap, shadowUV.xy + vec2(0, -pixeloffset)).x,
    	texture2D(uShadowMap, shadowUV.xy + vec2(0, +pixeloffset)).x);

	vec2 differences = abs( depths.yw - depths.xz );
	float gradient = min(gradientClamp, max(differences.x, differences.y));
	float gradientFactor = gradient * gradientScaleBias;

	// visibility function
	float depthAdjust = gradientFactor + (fixedDepthBias * centerdepth);
	float finalCenterDepth = centerdepth + depthAdjust;

	// shadowUV.z contains lightspace position of current object

	// use depths from prev, calculate diff
	depths += depthAdjust;
	float k = (finalCenterDepth > shadowUV.z) ? 1.0 : 0.0;
	k += (depths.x > shadowUV.z) ? 1.0 : 0.0;
	k += (depths.y > shadowUV.z) ? 1.0 : 0.0;
	k += (depths.z > shadowUV.z) ? 1.0 : 0.0;
	k += (depths.w > shadowUV.z) ? 1.0 : 0.0;
	
	k *= 0.2;

	gl_FragColor = vec4(vec3(1,1,1) * k , 1);
	
Please HELP!!! :roll:

paroj
OGRE Team Member
OGRE Team Member
Posts: 1191
Joined: Sun Mar 30, 2014 2:51 pm
x 463
Contact:

Re: [v1.9.0] [GL] Shadow problem! SHADOWTYPE_TEXTURE_ADDITIVE eats my Lightmaps. SHADOWTYPE_TEXTURE_MODULATIVE has artif

Post by paroj »

try using the normal camera setup (i.e. non LiSPSMShadowCameraSetup)

User avatar
nuke
Halfling
Posts: 42
Joined: Wed Oct 01, 2014 1:16 am
Location: Eastern Europe

Re: [v1.9.0] [GL] Shadow problem! SHADOWTYPE_TEXTURE_ADDITIVE eats my Lightmaps. SHADOWTYPE_TEXTURE_MODULATIVE has artif

Post by nuke »

Thank you so much for reply, Pavel!
I tried using normal camera setup - no effect. Shadow size was 1 blurred texel under car :) but shadow texture resolution 4096x4096
Because ,probably, my light source is too far (like a sun). The distance to it is about 15000...20000 ogre untis.
I did a workaround for this issue:
1) I decided to turn off shadow casting for this far light source
2) I added near dynamic/movable near light direct above car with 1024x1024 shadow texture resolution and default/normal camera setup
The result is in screenshot:

Image

But the annoying artifact on the wall is still there:
Image

I plan to migrate from v1.9.0 to latest OGRE version v1.12.x+ but without SDL input system dependency, I want use newer version of OIS input system. Is it possible ?

OIS
https://github.com/wgois/OIS

paroj
OGRE Team Member
OGRE Team Member
Posts: 1191
Joined: Sun Mar 30, 2014 2:51 pm
x 463
Contact:

Re: [v1.9.0] [GL] Shadow problem! SHADOWTYPE_TEXTURE_ADDITIVE eats my Lightmaps. SHADOWTYPE_TEXTURE_MODULATIVE has artif

Post by paroj »

nuke wrote:
Wed Sep 09, 2020 11:42 am
I tried using normal camera setup - no effect. Shadow size was 1 blurred texel under car :) but shadow texture resolution 4096x4096
Because ,probably, my light source is too far (like a sun). The distance to it is about 15000...20000 ogre untis.
just use a directional light for the sun - then the distance does not matter.
nuke wrote:
Wed Sep 09, 2020 11:42 am
But the annoying artifact on the wall is still there:
Image
the underlying issue you are facing is that the wall is just a shadow receiver, while blocking the light path. As ogre is not aware of its depth, it applies the shadow as if the light source was below the ground. (similarly how you see it on the ground, assuming the light source is below it)

The real solution would be switching to depth-based shadows. Maybe you can alternatively disable shadow receiving on the walls, while keeping it for the ground.
nuke wrote:
Wed Sep 09, 2020 11:42 am
I plan to migrate from v1.9.0 to latest OGRE version v1.12.x+ but without SDL input system dependency, I want use newer version of OIS input system. Is it possible ?

OIS
https://github.com/wgois/OIS
yes things should just work as they do now, but you will not get any OgreBites integration, like input handling for ImGui.

User avatar
nuke
Halfling
Posts: 42
Joined: Wed Oct 01, 2014 1:16 am
Location: Eastern Europe

Re: [v1.9.0] [GL] Shadow problem! SHADOWTYPE_TEXTURE_ADDITIVE eats my Lightmaps. SHADOWTYPE_TEXTURE_MODULATIVE has artif

Post by nuke »

Hallo, Pavel!
Thank you very much for your answer and advice!
I need you help again! :)

I decided to keep 2 lights in my scene.
One source is real, this is the "sun", it does not generate shadows.
The second light is fake, it is only needed to generate shadows, its diffusion and reflection settings are all 0.

Code: Select all

...
fakeLight:setDiffuseColour (ColourValue(0,0,0,0))	
fakeLight:setSpecularColour(0.0, 0.0, 0.0)		
...
But that's not what I wanted to ask you :)

Here's the main question:
I use bump mapping on all objects in the scene.
(material "Examples/BumpMapping/MultiLight" from OGRE examples)
It has a pass - "perlight", it works for every light source.

Code: Select all

// Any number of lights, diffuse
material Examples/BumpMapping/MultiLight
{

	// This is the preferred technique which uses both vertex and
	// fragment programs, supports coloured lights
	technique
	{
		// Base ambient pass
		pass ambient
		{
			// base colours, not needed for rendering, but as information
			// to lighting pass categorisation routine
			ambient 1 1 1
			diffuse 0 0 0 
			specular 0 0 0 0 
			// Really basic vertex program
			// NB we don't use fixed function here because GL does not like
			// mixing fixed function and vertex programs, depth fighting can
			// be an issue
			vertex_program_ref Ogre/BasicVertexPrograms/AmbientOneTextureUnified
			{
				param_named_auto ambient ambient_light_colour
			}
			fragment_program_ref Ogre/BasicFragmentPrograms/PassthroughFP
			{
			}
			
		}
		// Now do the lighting pass
		// NB we don't do decal texture here because this is repeated per light
		pass perlight
		{
			// base colours, not needed for rendering, but as information
			// to lighting pass categorisation routine
			ambient 0 0 0 
			
			// do this for each light
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			iteration once_per_light // <! ==============  here is problem ==== I wan't to exclude my Fake "Shadow" Light from processing to save FPS
			// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!

		
			scene_blend add

			// Vertex program reference
			vertex_program_ref Examples/BumpMapVP
			{
				param_named_auto lightPosition light_position_object_space 0
				param_named_auto worldViewProj worldviewproj_matrix
			}

			// Fragment program
			fragment_program_ref Examples/BumpMapFP
			{
				param_named_auto lightDiffuse light_diffuse_colour 0 
			}

			// texture shadow receiver program
			shadow_receiver_vertex_program_ref Examples/BumpMapVPShadowRcv
			{
				param_named_auto lightPosition light_position_object_space 0
				param_named_auto worldViewProj worldviewproj_matrix
				param_named_auto worldMatrix world_matrix
				param_named_auto texViewProj texture_viewproj_matrix
			}
			// Additive texture shadow receiver program
			shadow_receiver_fragment_program_ref Examples/BumpMapFPShadowRcv
			{
				param_named_auto lightDiffuse light_diffuse_colour 0 
			}
			
			// Base bump map
			texture_unit normalmap
			{
				texture NMBumpsOut.png
				colour_op replace
			}
		}
		
		// Decal pass
		pass decal
		{
			// base colours, not needed for rendering, but as information
			// to lighting pass categorisation routine
			lighting off
			// Really basic vertex program
			// NB we don't use fixed function here because GL does not like
			// mixing fixed function and vertex programs, depth fighting can
			// be an issue
			vertex_program_ref Ogre/BasicVertexPrograms/AmbientOneTextureUnified
			{
				param_named ambient float4 1 1 1 1
			}
			fragment_program_ref Ogre/BasicFragmentPrograms/PassthroughFP
			{
			}
			scene_blend dest_colour zero
			texture_unit decalmap
			{
				texture RustedMetal.jpg 
			}
		}
	}
}
My stuff is much simpler, it is inherited:

Code: Select all

material "Concrete" : Examples/BumpMapping/MultiLight
{
	technique
	{
		pass perlight
		{
			// Base bump map
			texture_unit normalmap
			{
				texture ConcreteNormalMap.png
			}
		}
		
		// Decal pass
		pass decal
		{
			texture_unit decalmap
			{
				texture ConcreteDiffuse.jpg
			}
		}
	}
}
The question is - how can I disable (exclude) my fake shadow light from bumpmap processing in order to save FPS, reduce the load on the GPU.
I want to add a method isFake to the Ogre::Light in my local version of OGRE.
And I want to call this method when the light sources are enumerated.
But I did not find the place where the light source enumerates with each iteration of the "perlight" pass, to exclude fake light.
I searched in OgreTechnique.cpp ,in OgrePass.cpp and in OgreSceneManager.cpp and did not find.


Post Reply