Here's a teapot and a bunch of boxes. I wish I could be bothered to make a more structured scene

Joe
Code: Select all
param_named_auto depthRange shadow_scene_depth_range 0
Code: Select all
param_named_auto light_viewprojection texture_viewproj_matrixCode: Select all
pass your_lighting_pass
{
iteration once_per_light
scene_blend add
// shaders to calculate light and shadow here for 1 light
}
Check "config.ini" (or whatever the config file was named, I think it was in /data/). There should be a numShadowTextures variable. With default Ogre shadow textures, you have a 1:1 ratio between lights and shadow textures. Meaning, if you want 15 shadowing lights, you need 15 shadow textures. If you have only, say, 4 shadow textures, then Ogre will try to "nudge" the closest lights into shadowing.xadhoom wrote:Hi Nullsquared!
I tested your demo and it seems, that after a certain number of lights created/recreated with space. The visible lights seem to switch between there
current state (position direction and lightcolor) maybe to there previous state, depending on my camera position. So if I fly threw your demo dungeon the lights switch between certain positions.
Is this a "feature" of your code or could this be a driver problem?
I´m happy about any hint!
Code: Select all
diffuse vertexcolourThe best solution is to integrate only the shadowing code into your own shaders. Meaning, diffuse_vs/ps is really only there as an example, you're not meant to actually use it (unless you specifically want to, of course).vitefalcon wrote:Hi nullsquared, I've tried out the soft-shadows in my project but I'm having one problem. One of my materials doesn't have a texture unit. Instead it gets coloured by the diffuse colourHow do I change the diffuse.cg to work like, if there's a texture use the colour value of the corresponding UV coordinates otherwise use the diffuse colour? Thanks in advance.Code: Select all
diffuse vertexcolour
Code: Select all
struct VIn {
float4 p : POSITION;
float3 n : NORMAL;
float4 d : COLOR0; // Taken off texture coordinates and put diffuse colour instead
};
struct VOut {
float4 p : POSITION;
float4 d : TEXCOORD0;
float4 wp : TEXCOORD1;
float3 n : TEXCOORD2;
float4 lp : TEXCOORD3;
float3 sdir : TEXCOORD4;
};
struct PIn {
float4 d : TEXCOORD0;
float4 wp : TEXCOORD1;
float3 n : TEXCOORD2;
float4 lp : TEXCOORD3;
float3 sdir : TEXCOORD4;
};
struct POut {
float4 c : COLOR;
};
VOut diffuse_no_tex_vs(VIn IN,
uniform float4x4 wMat,
uniform float4x4 wvpMat,
uniform float4x4 tvpMat,
uniform float4 spotlightDir
) {
VOut OUT;
OUT.wp = mul(wMat, IN.p);
OUT.p = mul(wvpMat, IN.p);
OUT.d = IN.d;
OUT.n = mul(wMat, float4(IN.n, 0)).xyz; // world-space normal
OUT.sdir = mul(wMat, spotlightDir).xyz; // spotlight dir in world space
OUT.lp = mul(tvpMat, OUT.wp);
return OUT;
}
float2 btex2D_rg(sampler2D map, float2 uv, float radius, float2 offset) {
// this is sometimes too slow and long
// (3 * 2 + 1) ^ 2 = 7 ^ 2 = 49 samples
// float2 sample = float2(0, 0);
// for (float x = -radius; x <= radius; x += 1) {
// for (float y = -radius; y <= radius; y += 1) {
// sample += tex2D(map, float2(uv.x + x * offset.x, uv.y + y * offset.y)).rg;
// }
// }
// return sample / ((radius * 2 + 1) * (radius * 2 + 1));
// simple 3x3 filter
float2 o = offset;
float2 c = tex2D(map, uv.xy).rg; // center
c += tex2D(map, uv.xy - o.xy).rg; // top left
c += tex2D(map, uv.xy + o.xy).rg; // bottom right
c += tex2D(map, float2(uv.x - o.x, uv.y)).rg; // left
c += tex2D(map, float2(uv.x + o.x, uv.y)).rg; // right
c += tex2D(map, float2(uv.x, uv.y + o.y)).rg; // bottom
c += tex2D(map, float2(uv.x, uv.y - o.y)).rg; // top
c += tex2D(map, float2(uv.x - o.x, uv.y + o.y)).rg; // bottom left
c += tex2D(map, float2(uv.x + o.x, uv.y - o.y)).rg; // top right
return c / 9;
}
float shadow(
sampler2D shadowMap, float4 shadowMapPos, float ourDepth, float radius, float2 offset) {
float2 suv = shadowMapPos.xy / shadowMapPos.w;
float2 moments = //tex2D(shadowMap, suv).rg;
// blurred texture read
btex2D_rg(shadowMap, suv, radius, offset);
float litFactor = (ourDepth <= moments.x ? 1 : 0);
// standard variance shadow mapping code
float E_x2 = moments.y;
float Ex_2 = moments.x * moments.x;
float vsmEpsilon = 0.0001;
float variance = min(max(E_x2 - Ex_2, 0.0) + vsmEpsilon, 1.0);
float m_d = moments.x - ourDepth;
float p = variance / (variance + m_d * m_d);
return smoothstep(0.4, 1, max(litFactor, p));
//return litFactor;
}
// to put it simply, this does 100% per pixel diffuse lighting
POut diffuse_no_tex_ps(PIn IN,
uniform float3 lightDif0,
uniform float4 lightPos0,
uniform float4 lightAtt0,
uniform float4 depthRange,
uniform float4 invSMSize,
uniform float4 spotlightParams,
uniform sampler2D dMap : TEXUNIT0,
uniform sampler2D shadowMap : TEXUNIT1
) {
POut OUT;
// direction
float3 ld0 = normalize(lightPos0.xyz - (lightPos0.w * IN.wp.xyz));
// attenuation
half ila = length(lightPos0.xyz - IN.wp.xyz) / lightAtt0.r;
ila *= ila; // quadratic falloff
half la = 1.0 - ila;
float3 normal = normalize(IN.n);
float3 LdotN0 = max(dot(ld0, normal), 0);
// calculate the spotlight effect
float spot = dot(ld0, normalize(-IN.sdir)); // angle between spotlight dir and actual dir
spot = saturate((spot - spotlightParams.y) / (spotlightParams.x - spotlightParams.y));
float3 light0C =
// N . L LIGHT DIF TEX DIF ATT
(LdotN0 * lightDif0 * IN.d.xyz) * la * spot
* shadow(
// pass in the shadow map
shadowMap,
// the calculated shadow position in the shadow map
IN.lp,
// distance to light, done just as in the caster shader
(length(lightPos0.xyz - IN.wp.xyz) - depthRange.x) * depthRange.w,
// radius to blur (we discussed)
3,
// inverse shadow map size so we know how much to move when blurring
invSMSize.xy);
OUT.c = float4(light0C, 1);
return OUT;
}Code: Select all
vertex_program diffuse_no_tex_vs cg
{
source diffuse_no_tex.cg
profiles vs_1_1 arbvp1
entry_point diffuse_no_tex_vs
default_params
{
param_named_auto wMat world_matrix
param_named_auto wvpMat worldviewproj_matrix
param_named_auto tvpMat texture_viewproj_matrix 0
param_named_auto spotlightDir light_direction_object_space 0
}
}
fragment_program diffuse_no_tex_ps cg
{
source diffuse_no_tex.cg
profiles ps_2_x arbfp1
entry_point diffuse_no_tex_ps
default_params
{
param_named_auto lightDif0 light_diffuse_colour 0
param_named_auto lightPos0 light_position 0
param_named_auto lightAtt0 light_attenuation 0
param_named_auto invSMSize inverse_texture_size 1
param_named_auto depthRange shadow_scene_depth_range 0
param_named_auto spotlightParams spotlight_params 0
}
}
material diffuse_no_tex_template
{
technique
{
pass
{
ambient 1 1 1
diffuse 0 0 0
specular 0 0 0 0
emissive 0 0 0
vertex_program_ref ambient_vs
{
}
fragment_program_ref ambient_ps
{
}
}
pass
{
max_lights 8
scene_blend add
iteration once_per_light
ambient 0 0 0
diffuse 1 1 1
specular 1 1 1 128
vertex_program_ref diffuse_no_tex_vs
{
}
fragment_program_ref diffuse_no_tex_ps
{
}
texture_unit shadow_tex
{
content_type shadow
filtering anisotropic
max_anisotropy 16
tex_address_mode border
tex_border_colour 1 1 1
}
}
}
}Code: Select all
uniform sampler2D dMap : TEXUNIT0,
uniform sampler2D shadowMap : TEXUNIT1
Code: Select all
uniform sampler2D shadowMap : TEXUNIT0
Code: Select all
diffuse 1 1 1
Code: Select all
diffuse vertexcolour
Code: Select all
uniform sampler2D shadowMap : TEXUNIT0Code: Select all
vertex_program diffuse_no_tex_vs cg
{
source diffuse_no_tex.cg
profiles vs_1_1 arbvp1
entry_point diffuse_no_tex_vs
default_params
{
param_named_auto wMat world_matrix
param_named_auto wvpMat worldviewproj_matrix
param_named_auto tvpMat texture_viewproj_matrix 0
param_named_auto spotlightDir light_direction_object_space 0
}
}
fragment_program diffuse_no_tex_ps cg
{
source diffuse_no_tex.cg
profiles ps_2_x arbfp1
entry_point diffuse_no_tex_ps
default_params
{
param_named_auto lightDif0 light_diffuse_colour 0
param_named_auto lightPos0 light_position 0
param_named_auto lightAtt0 light_attenuation 0
param_named_auto invSMSize inverse_texture_size 1
param_named_auto depthRange shadow_scene_depth_range 0
param_named_auto spotlightParams spotlight_params 0
}
}
material diffuse_no_tex_template
{
technique
{
pass
{
ambient 1 1 1
diffuse vertexcolour
specular 0 0 0 0
emissive 0 0 0
vertex_program_ref ambient_vs
{
}
fragment_program_ref ambient_ps
{
}
}
pass
{
max_lights 8
scene_blend add
iteration once_per_light
ambient 0 0 0
diffuse 1 1 1
specular 1 1 1 128
vertex_program_ref diffuse_no_tex_vs
{
}
fragment_program_ref diffuse_no_tex_ps
{
}
texture_unit shadow_tex
{
content_type shadow
filtering anisotropic
max_anisotropy 16
tex_address_mode border
tex_border_colour 1 1 1
}
}
}
}
Code: Select all
struct VIn {
float4 p : POSITION;
float3 n : NORMAL;
float4 d : COLOR0;
};
struct VOut {
float4 p : POSITION;
float4 d : TEXCOORD0;
float4 wp : TEXCOORD1;
float3 n : TEXCOORD2;
float4 lp : TEXCOORD3;
float3 sdir : TEXCOORD4;
};
struct PIn {
float4 d : TEXCOORD0;
float4 wp : TEXCOORD1;
float3 n : TEXCOORD2;
float4 lp : TEXCOORD3;
float3 sdir : TEXCOORD4;
};
struct POut {
float4 c : COLOR;
};
VOut diffuse_no_tex_vs(VIn IN,
uniform float4x4 wMat,
uniform float4x4 wvpMat,
uniform float4x4 tvpMat,
uniform float4 spotlightDir
) {
VOut OUT;
OUT.wp = mul(wMat, IN.p);
OUT.p = mul(wvpMat, IN.p);
OUT.d = IN.d;
OUT.n = mul(wMat, float4(IN.n, 0)).xyz; // world-space normal
OUT.sdir = mul(wMat, spotlightDir).xyz; // spotlight dir in world space
OUT.lp = mul(tvpMat, OUT.wp);
return OUT;
}
float2 btex2D_rg(sampler2D map, float2 uv, float radius, float2 offset) {
// this is sometimes too slow and long
// (3 * 2 + 1) ^ 2 = 7 ^ 2 = 49 samples
// float2 sample = float2(0, 0);
// for (float x = -radius; x <= radius; x += 1) {
// for (float y = -radius; y <= radius; y += 1) {
// sample += tex2D(map, float2(uv.x + x * offset.x, uv.y + y * offset.y)).rg;
// }
// }
// return sample / ((radius * 2 + 1) * (radius * 2 + 1));
// simple 3x3 filter
float2 o = offset;
float2 c = tex2D(map, uv.xy).rg; // center
c += tex2D(map, uv.xy - o.xy).rg; // top left
c += tex2D(map, uv.xy + o.xy).rg; // bottom right
c += tex2D(map, float2(uv.x - o.x, uv.y)).rg; // left
c += tex2D(map, float2(uv.x + o.x, uv.y)).rg; // right
c += tex2D(map, float2(uv.x, uv.y + o.y)).rg; // bottom
c += tex2D(map, float2(uv.x, uv.y - o.y)).rg; // top
c += tex2D(map, float2(uv.x - o.x, uv.y + o.y)).rg; // bottom left
c += tex2D(map, float2(uv.x + o.x, uv.y - o.y)).rg; // top right
return c / 9;
}
float shadow(
sampler2D shadowMap, float4 shadowMapPos, float ourDepth, float radius, float2 offset) {
float2 suv = shadowMapPos.xy / shadowMapPos.w;
float2 moments = //tex2D(shadowMap, suv).rg;
// blurred texture read
btex2D_rg(shadowMap, suv, radius, offset);
float litFactor = (ourDepth <= moments.x ? 1 : 0);
// standard variance shadow mapping code
float E_x2 = moments.y;
float Ex_2 = moments.x * moments.x;
float vsmEpsilon = 0.0001;
float variance = min(max(E_x2 - Ex_2, 0.0) + vsmEpsilon, 1.0);
float m_d = moments.x - ourDepth;
float p = variance / (variance + m_d * m_d);
return smoothstep(0.4, 1, max(litFactor, p));
//return litFactor;
}
// to put it simply, this does 100% per pixel diffuse lighting
POut diffuse_no_tex_ps(PIn IN,
uniform float3 lightDif0,
uniform float4 lightPos0,
uniform float4 lightAtt0,
uniform float4 depthRange,
uniform float4 invSMSize,
uniform float4 spotlightParams,
uniform sampler2D shadowMap : TEXUNIT0
) {
POut OUT;
// direction
float3 ld0 = normalize(lightPos0.xyz - (lightPos0.w * IN.wp.xyz));
// attenuation
half ila = length(lightPos0.xyz - IN.wp.xyz) / lightAtt0.r;
ila *= ila; // quadratic falloff
half la = 1.0 - ila;
float3 normal = normalize(IN.n);
float3 LdotN0 = max(dot(ld0, normal), 0);
// calculate the spotlight effect
float spot = dot(ld0, normalize(-IN.sdir)); // angle between spotlight dir and actual dir
spot = saturate((spot - spotlightParams.y) / (spotlightParams.x - spotlightParams.y));
float3 light0C =
// N . L LIGHT DIF TEX DIF ATT
(LdotN0 * lightDif0 * IN.d.xyz) * la * spot
* shadow(
// pass in the shadow map
shadowMap,
// the calculated shadow position in the shadow map
IN.lp,
// distance to light, done just as in the caster shader
(length(lightPos0.xyz - IN.wp.xyz) - depthRange.x) * depthRange.w,
// radius to blur (we discussed)
3,
// inverse shadow map size so we know how much to move when blurring
invSMSize.xy);
OUT.c = float4(light0C, 1);
return OUT;
}
Code: Select all
11:01:13: OGRE EXCEPTION(7:InternalErrorException): Unable to compile Cg program blur_ps: CG ERROR : The compile returned an error.
(0) : error C6001: Temporary register limit of 12 exceeded; 49 registers needed to compile program
in CgProgram::loadFromSource at e:\projects\ogrecvs\branches\eihort\ogre\plugins\cgprogrammanager\src\ogrecgprogrammanagerdll.cpp (line 66)
11:01:13: High-level program blur_ps encountered an error during loading and is thus not supported.
OGRE EXCEPTION(7:InternalErrorException): Unable to compile Cg program blur_ps: CG ERROR : The compile returned an error.
(0) : error C6001: Temporary register limit of 12 exceeded; 49 registers needed to compile program
in CgProgram::loadFromSource at e:\projects\ogrecvs\branches\eihort\ogre\plugins\cgprogrammanager\src\ogrecgprogrammanagerdll.cpp (line 66)
Code: Select all
SceneManager *mgr = mRoot->createSceneManager(ST_GENERIC, "Default SceneManager");
mgr->setShadowTextureSelfShadow(true);
mgr->setShadowTextureCasterMaterial("shadow_caster");
mgr->setShadowTextureCount( 1 );
mgr->setShadowTextureSize( 512 );
mgr->setShadowTexturePixelFormat(PF_FLOAT16_RGB);
mgr->setShadowCasterRenderBackFaces(false);
const unsigned numShadowRTTs = mgr->getShadowTextureCount();
for (unsigned i = 0; i < numShadowRTTs; ++i) {
Ogre::TexturePtr tex = mgr->getShadowTexture(i);
Ogre::Viewport *vp = tex->getBuffer()->getRenderTarget()->getViewport(0);
vp->setBackgroundColour(Ogre::ColourValue(1, 1, 1, 1));
vp->setClearEveryFrame(true);
}
mgr->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED);
}

Code: Select all
08:44:42: OGRE EXCEPTION(7:InternalErrorException): Unable to compile Cg program shadow_caster_ps: CG ERROR : The compile returned an error.
(38) : error C3004: function "length" not supported in this profile
in CgProgram::loadFromSource at ..\src\OgreCgProgramManagerDll.cpp (line 66)
08:44:42: High-level program shadow_caster_ps encountered an error during loading and is thus not supported.
OGRE EXCEPTION(7:InternalErrorException): Unable to compile Cg program shadow_caster_ps: CG ERROR : The compile returned an error.
(38) : error C3004: function "length" not supported in this profile
in CgProgram::loadFromSource at ..\src\OgreCgProgramManagerDll.cpp (line 66)
Yup, this was my code example. No mesh is loaded before that.xadhoom wrote: Do you init your shadows before loading any mesh? You know initShadow() method in the demo.
Nope, how exactly do I have to implement that?xadhoom wrote: Do you add a ShadowListener (Eihort) to manage the shadow camera distance
per light?
Yup. Yup.xadhoom wrote:Do your models cast/receive shadows (flag in osm file)? Do your lights cast shadows etc.?
No, will try to do so after figuring out how to implement a Shadow Listener, some help would always be appreciatedxadhoom wrote: Did you test some simple meshes which you loaded manually? If they have shadows or not you are a big step further...
Code: Select all
sceneMgr->addShadowListener(theShadowListener);

But I don't know if it has anything to do with the shader or the problem at all.WARNING: Texture instance 'Ogre/ShadowTexture0' was defined as manually loaded, but no manual loader was provided. This Resource will be lost if it has to be reloaded.
Code: Select all
class ShadowClass : public ShadowListener, public WindowEventListener
{
void shadowTextureCasterPreViewProj(Ogre::Light *light, Ogre::Camera *cam);
void shadowTexturesUpdated(size_t) {}
void shadowTextureReceiverPreViewProj(Ogre::Light*, Ogre::Frustum*) {}
};
//inserting the Shadow Class;
ShadowClass* ShadowL;
ShadowL = new ShadowClass();
mgr->addShadowListener(ShadowL);Code: Select all
void shadowTextureCasterPreViewProj(Ogre::Light *light, Ogre::Camera *cam){
protected:
public:
void shadowTextureCasterPreViewProj(Ogre::Light *light, Ogre::Camera *cam)
{
cam->setFOVy(Degree(30));
cam->setNearClipDistance(0.01);
cam->setFarClipDistance(light->getAttenuationRange());
}
void shadowTexturesUpdated(size_t) {}
void shadowTextureReceiverPreViewProj(Ogre::Light*, Ogre::Frustum*) {}
}Code: Select all
Entity* pEntity = mMan->createEntity("LevelEntity", "LevelEntity.mesh");
pEntity->setCastShadows(true);
pEntity->setMaterialName("karte");
SceneNode* pLNode = mMan->getRootSceneNode()->createChildSceneNode("TestNode");
pLNode->attachObject( pEntity );
pLNode->scale(0.1, 0.1, 0.1);
pLNode->setPosition( Vector3(0,0,0));
pEntity = mMan->createEntity("TestLemming","Lemming_01.mesh");
pEntity->setCastShadows(true);
SceneNode* pONode = mMan->getRootSceneNode()->createChildSceneNode("LemNode");
pONode->attachObject( pEntity );
pONode->setPosition( Vector3(0,30,10));
Light* light = mMan->createLight("Omni");
light->setCastShadows(true);
light->setType(Light::LT_SPOTLIGHT);
light->setDiffuseColour( 1, 1, 1 );
light->setPosition(Vector3(0, 400, 10));
light->setDirection(0, -1, 0);
light->setSpotlightInnerAngle( Radian(Degree(50)));
light->setSpotlightOuterAngle( Radian(Degree(25)));