Hi, all!
Is there some implementation of origin shifting in Ogre, i.e. the ability to move world objects closer to 0 maintaining virtual offset to avoid floating point precision side effects?
Origin shifting
-
slapin
- Bronze Sponsor

- Posts: 250
- Joined: Fri May 23, 2025 5:04 pm
- x 16
Origin shifting
-
eventhorizon
- Kobold
- Posts: 38
- Joined: Wed Oct 20, 2010 4:56 am
- x 12
Re: Origin shifting
slapin wrote: Mon Jul 07, 2025 6:13 pmHi, all!
Is there some implementation of origin shifting in Ogre, i.e. the ability to move world objects closer to 0 maintaining virtual offset to avoid floating point precision side effects?
I remembered there being a feature like that in Ogre, or it was the other graphics engine I worked with (it's been a long time since I worked directly with features like that). It might've been an addon or something. I think at one point I tried doing origin shifting, but in the end went with double-precision builds of Ogre instead, so that the world scene can stay consistent and not move around, where the camera/character moves instead. To fix the issues further, I have a unit scale resizer that rescales coordinates back and forth, it's mainly there to prevent floating point issues with small objects very close to the camera if I remember correctly. The same functions also convert the simulator engine's left-hand coordinate system to Ogre's right-hand one.
-
paroj
- OGRE Team Member

- Posts: 2238
- Joined: Sun Mar 30, 2014 2:51 pm
- x 1217
-
slapin
- Bronze Sponsor

- Posts: 250
- Joined: Fri May 23, 2025 5:04 pm
- x 16
Re: Origin shifting
Won't this break shaders which depend on world position, i.e. water when multiple water planes used which need to have matching seamless simulation?
Also, in case of moving camera, what about look of such simulations?
But that might work as alternative to LODs to avoid z-fighting...
-
rpgplayerrobin
- Orc Shaman
- Posts: 788
- Joined: Wed Mar 18, 2009 3:03 am
- x 447
Re: Origin shifting
It does affect shaders in some ways of course, but not as much as you might think.
When I switched from normal to that relative rendering, it was not that much that needed to change.
The only thing you might need to do is to use the true camera position in the shader and add it to the calculations that really need a world position (which are far less situations than you might think, since a relative position is many times the same result).
Some things are actually easier because of this as well in the shaders, for example, fog.
Since you know that its pixel position is already relative to the camera position, which makes fog and such effects extremely easy to calculate.
The only thing needed is to add it to the shader material:
Code: Select all
param_named_auto fogColour fog_colour
param_named_auto fogParams fog_params
...
param_named_auto trueCameraPosition camera_relative_position <-- This line is the important one!
//param_named_auto trueCameraPosition camera_position <-- Note that this will never work, since it will always be 0,0,0 with relative rendering!Then, to get the world position in the shader:
Code: Select all
float3 trueCameraPosition;
...
float4 main_ps( float3 position : TEXCOORD0 )
{
float3 worldPosition = position + trueCameraPosition;
...
}
You will also need to do this in the vertex shader:
Code: Select all
float4x4 worldMatrix; //param_named_auto worldMatrix world_matrix
float4x4 modelViewProj; // param_named_auto modelViewProj worldviewproj_matrix
struct VS_OUTPUT
{
float3 oVertexPos : TEXCOORD0;
float3 oNormal : TEXCOORD1;
float3 oTangent : TEXCOORD2;
float3 oBitangent : TEXCOORD3;
...
};
VS_OUTPUT main_vs(float4 position : POSITION,
out float4 oPosition : POSITION,
float3 normal : NORMAL,
float3 iTangent : TANGENT,
float2 iUV : TEXCOORD0)
{
VS_OUTPUT Out;
float3 worldPos = mul(worldMatrix, position).xyz;
float3 worldNorm = normalize(mul((float3x3)worldMatrix, normal));
float3 worldTangent = normalize(mul((float3x3)worldMatrix, iTangent.xyz));
oPosition = mul(modelViewProj, position);
Out.oVertexPos = worldPos;
Out.oNormal = worldNorm;
Out.oTangent = worldTangent;
Out.oBitangent = cross( Out.oTangent, Out.oNormal );
...
return Out;
}
But, for some reason that I don't remember, in my application I am not using that automatic camera_relative_position variable in the shader material.
I am instead using my own variable for it, which might be very unnecessary, but if the above code does not work for you for some reason, you can use my way of doing it (and my code might also be good to learn how to create any shared shader variable anyway!):
Here is how I do it in a shader material:
Code: Select all
param_named_auto fogColour fog_colour
param_named_auto fogParams fog_params
...
shared_params_ref TrueCameraPosition <-- This line is the important one!Then in the shader itself:
Code: Select all
float3 trueCameraPosition;
...
float4 main_ps( float3 position : TEXCOORD0 )
{
float3 worldPosition = position + trueCameraPosition;
...
}
And in C++ (which makes you be able to add it to any shader easily):
Creation (only once on startup):
Code: Select all
GpuSharedParametersPtr tmpGpuSharedParameters = GpuProgramManager::getSingleton().createSharedParameters("TrueCameraPosition");
tmpGpuSharedParameters->addConstantDefinition("trueCameraPosition", GCT_FLOAT3);
SetSharedParameters_TrueCameraPosition(Vector3::ZERO);
Function to set it:
Code: Select all
void CApplication::SetSharedParameters_TrueCameraPosition(Vector3 trueCameraPosition)
{
GpuSharedParametersPtr tmpGpuSharedParameters = GpuProgramManager::getSingleton().getSharedParameters("TrueCameraPosition");
tmpGpuSharedParameters->setNamedConstant("trueCameraPosition", trueCameraPosition);
}And finally the automatic update of it:
Code: Select all
bool CApplication::frameStarted(const FrameEvent& evt)
{
...
// Set the true camera position for shaders
SetSharedParameters_TrueCameraPosition(m_Camera->getDerivedPosition());
// Continue
return true;
}My project: https://imagindar.com/
-
slapin
- Bronze Sponsor

- Posts: 250
- Joined: Fri May 23, 2025 5:04 pm
- x 16
Re: Origin shifting
Thanks a lot for the data, will look into this