Video here. Any idea why this happens? Is this something wrong with my compostor setup in editor or a bug in planar reflections?
It looks like the PlanarReflection camera is using the wrong parameters (could be aspect ratio, near/far plane, viewport size).
This is handled by PlanarReflections::update
and PlanarReflections::cameraMatches
:
Code: Select all
void PlanarReflections::update( Camera *camera, Real aspectRatio )
{
...
actorData->workspace->setEnabled( true );
actorData->reflectionCamera->setPosition( camPos );
actorData->reflectionCamera->setOrientation( camRot );
actorData->reflectionCamera->setNearClipDistance( nearPlane );
actorData->reflectionCamera->setFarClipDistance( farPlane );
actorData->reflectionCamera->setAspectRatio( aspectRatio );
actorData->reflectionCamera->setFocalLength( focalLength );
actorData->reflectionCamera->setFOVy( fov );
actorData->reflectionCamera->enableReflection( actor->mPlane );
}
bool PlanarReflections::cameraMatches( const Camera *camera )
{
return !camera->isReflected() && mLastAspectRatio == camera->getAspectRatio() &&
mLastCameraPos == camera->getDerivedPosition() &&
mLastCameraRot == camera->getDerivedOrientation();
}
I just noticed viewport size is not part of the data that is being copied (so far OgreNext's PlanarReflections implementation always assumed you're rendering to the whole screen) and thus that may explain the problem.
I'm not sure if the viewport size is available at that stage.
Another simple reason is that the parameters are correctly copied in PlanarReflections::update
; but later on the Camera you passed to it gets its aspect ratio changed (e.g. because of Camera::setAutoAspectRatio which is true by default).
I'm moving to material.json now and editing it in my Material Editor window on Gui. It's better.
But, if I save some I have this then present in json:And if I start editor again with this it will crash early on parsing, because DynamicCubemap is created from code much later.
How to deal with this? Instead of removing this manually and adding that in code, based on a parameter stored somewhere.
Mmmm... I see multiple possible solutions:
- Create the texture "DynamicCubemap" early on as a cubemap; but don't even schedule it to Resident. I'm not sure if that will work because at some point HlmsPbsDatablock::loadAllTextures() will be called and it will try to load your cubemap.
- Upon saving implement use HlmsJsonListener::savingChangeTextureName to change the texture name to something else (i.e. a dummy name to a 1x1 cubemap)
That's off the top of my head.
it is really nice and very easy to have those:
ALBEDO, NORMAL, METALLIC, ROUGHNESS, SPECULAR, ALPHA etc output variables for PBS to set up with your own stuff.
Can you list all variables from our 800.PixelShader_piece_ps.any that would do the same thing?
Most of them should be in PixelData pixelData.
Naturally by piece @insertpiece( custom_ps_posExecution )
you can be certain all of these variables have been fully populated. If you use earlier pieces, you may find yourself that some of these variables haven't been populated yet.
Can you tell how much work or in how many places do I need to change TerraShadowMapper for my terrain with unlimited floats (any values, in meters). I can't handle this 10bit and other assumptions. Generally it works now, but only for terrain above 0, below it's all shadowed.
Look for PFG_R10G10B10A2_UNORM
in TerraShadowMapper.cpp.
Note that you may need to modify TerraShadowGenerator.glsl which performs:
Code: Select all
float currHeight = float( texelFetch( heightMap, xyPos << int( resolutionShift ), 0 ).x );
...
imageStore( shadowMap, xyPos, vec4( shadowValue, roundedHeight.y, invHeightLength, 1.0 ) );
If I recall, currHeight is already in range [0; 1] in out of the box Terra (because we use R16_UNORM to store the height).
I suspect what's really troubling you is none of that, but rather this in PbsTerraShadows_piece_vs_piece_ps.glsl:
Code: Select all
vec3 terraShadowData = textureLod( vkSampler2D( terrainShadows, terrainShadowSampler ),
terraWorldPos.xz * passBuf.invTerraBounds.xz +
passBuf.terraOrigin.xz, 0 ).xyz;
float terraHeightWeight = terraWorldPos.y * passBuf.invTerraBounds.y + passBuf.terraOrigin.y;
terraHeightWeight = (terraHeightWeight - terraShadowData.y) * terraShadowData.z * 1023.0;
outVs.terrainShadow = mix( midf_c( terraShadowData.x ), _h( 1.0 ), midf_c( saturate( terraHeightWeight ) ) );
Of extreme particular importance is passBuf.invTerraBounds.y + passBuf.terraOrigin.y
which takes care of squashing the Y position to the range [0; 1]
You could add:
Code: Select all
if( terraHeightWeight < 0.0 )
outVs.terrainShadow = mix( midf_c( terraShadowData.x ), _h( 1.0 ), midf_c( saturate( terraHeightWeight ) ) );
else
outVs.terrainShadow = _h( 1.0 );
Or maybe passBuf.terraOrigin.y
is not the correct value.
I'm not sure how you can be "below the terrain" and be something you want to render.
What freaks me out still, is those white flashes when a new texture appears (on Gui mostly now).
Gee, you sound like another client of mine.
Every frame you can call TextureGpuManager::waitForStreamingCompletion() to avoid that (but you gain stall or stutter because the engine must wait for textures to be loaded).
Lastly why is Ogre-Next still not using auto keyword, this shortens code so much. Do you still need old C++ standard supported?
We adopted C++11 for OgreNext 3.0 but I'll be deep in the cold cold ground before I allow auto in the codebase
With a few exceptions where it's reasonable (e.g. deep templates, example documentation), auto brings more problems than benefits.