-
Notifications
You must be signed in to change notification settings - Fork 829
Open
Labels
supportSupport questionsSupport questions
Description
the virtual program shader giving unexpected result in osg earth compare to osg
raw osg structure: root->SceaneGroup->geod
osgEarth : root->mapnode
the below shader program for viewshed Analysis is working fine in osg , but shader program in osgEarth is giving unexpected result,
can anyone hepl me to resolve this issue. it will be hepfull toimplement many gis features like traditional Radar Dom, radar platter, and traditional Viewshed Analysis
raw osg
osgearth
const char* depthMapVertVP = R"(
#version 330 core
out float lightDistance;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat4 osg_ViewMatrixInverse;
uniform mat4 osg_ModelViewMatrix;
uniform vec3 lightPos;
uniform mat4 inverse_view;
uniform float near_plane;
uniform float far_plane;
void depthMapVertex(inout vec4 vertex) {
vec3 worldPos = (inverse_view * osg_ModelViewMatrix * vertex).xyz;
lightDistance = length(worldPos - lightPos);
lightDistance = ((1 / lightDistance) - (1 / near_plane)) / (1 / far_plane - 1 / near_plane);
gl_Position = osg_ModelViewProjectionMatrix * vertex;
}
)";
const char* depthMapFragVP = R"(
#version 330 core
in float lightDistance;
void depthMapFragment(inout vec4 color) {
gl_FragDepth = lightDistance;
// Optional: if you want to see the depth as a color (for debugging)
// color = vec4(vec3(gl_FragDepth), 1.0);
}
)";
const char* visibilityShaderVertVP = R"(
#version 330 core
in vec3 osg_Normal;
// in vec3 osg_Vertex;
in vec4 osg_MultiTexCoord0;
uniform mat4 osg_ViewMatrixInverse;
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat4 osg_ModelViewMatrix;
uniform vec3 lightPos;
out vec3 worldPos;
out vec3 vNormal;
// out vec2 texCoords;
out float lightDistance;
void visibilityVertex(inout vec4 vertex)
{
// vec4 w = osg_ViewMatrixInverse * vertex;
// worldPos = w.xyz / w.w;
worldPos = (osg_ViewMatrixInverse * osg_ModelViewMatrix * vertex).xyz;
lightDistance = length(worldPos - lightPos);
vNormal = normalize(osg_Normal);
gl_Position = osg_ModelViewProjectionMatrix * vertex;
}
)";
const char* visibilityShaderFragVP = R"(
#version 330 core
in vec3 worldPos;
in vec3 vNormal;
// in vec2 texCoords;
in float lightDistance;
uniform vec3 lightPos;
uniform vec4 visibleColor;
uniform vec4 invisibleColor;
// uniform sampler2D baseTexture;
uniform samplerCube shadowMap;
uniform float near_plane;
uniform float far_plane;
uniform float user_area;
float linearizeDepth(float z)
{
float z_n = 2.0 * z - 1.0;
return 2.0 * near_plane * far_plane / (far_plane + near_plane - z_n * (far_plane - near_plane));
};
// Return 1 for shadowed, 0 visible
bool isShadowed(vec3 lightDir)
{
float bias = max(0.01 * (1.0 - dot(vNormal, lightDir)), 0.001) * far_plane;
float z = linearizeDepth(texture(shadowMap, lightDir).r);
return lightDistance - bias > z;
}
void visibilityFragment(inout vec4 color)
{
float distToLight = length(worldPos - lightPos);
if(distToLight < user_area)
{
vec3 lightDir = normalize(lightPos - worldPos);
float normDif = max(dot(lightDir, vNormal), 0.0);
if (normDif > 0.0 && isShadowed(-lightDir) == false)
{
color.rgb *= visibleColor.rgb;
}
else
{
color.rgb *= invisibleColor.rgb;
}
}
}
)";
shaders and depth Camara creation
osg::Camera * VisibilityTestArea::generateCubeCamera(osg::ref_ptr<osg::TextureCubeMap> cubeMap, unsigned face, osg::Camera::BufferComponent component)
{
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
camera->setViewport(0, 0, SM_TEXTURE_WIDTH, SM_TEXTURE_WIDTH);
camera->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
camera->attach(component, cubeMap, 0, face);
camera->setNodeMask(0xffffffff & (~INTERSECT_IGNORE));
return camera.release();
}
void VisibilityTestArea::updateAttributes()
{
// Light source info
osg::Vec3 lightPos = _lightSource;
std::vector<osg::Matrix> shadowViews;
shadowViews.push_back(
osg::Matrix::lookAt(lightPos, lightPos + osg::Vec3(1.0, 0.0, 0.0), osg::Vec3(0.0, -1.0, 0.0)));
shadowViews.push_back(
osg::Matrix::lookAt(lightPos, lightPos + osg::Vec3(-1.0, 0.0, 0.0), osg::Vec3(0.0, -1.0, 0.0)));
shadowViews.push_back(
osg::Matrix::lookAt(lightPos, lightPos + osg::Vec3(0.0, 1.0, 0.0), osg::Vec3(0.0, 0.0, 1.0)));
shadowViews.push_back(
osg::Matrix::lookAt(lightPos, lightPos + osg::Vec3(0.0, -1.0, 0.0), osg::Vec3(0.0, 0.0, -1.0)));
shadowViews.push_back(
osg::Matrix::lookAt(lightPos, lightPos + osg::Vec3(0.0, 0.0, 1.0), osg::Vec3(0.0, -1.0, 0.0)));
shadowViews.push_back(
osg::Matrix::lookAt(lightPos, lightPos + osg::Vec3(0.0, 0.0, -1.0), osg::Vec3(0.0, -1.0, 0.0)));
// Update light source info for shadow map
for (int i = 0; i < 6; i++)
{
auto depthCamera = _depthCameras[i];
depthCamera->setViewMatrix(shadowViews[i]);
}
if(!_inverseViewUniform[0].valid())
{
for (int i = 0; i < 6; i++){
_inverseViewUniform[i] = new osg::Uniform("inverse_view", osg::Matrixf::inverse(shadowViews[i]));
}
for (int i = 0; i < 6; i++)
{
auto depthCamera = _depthCameras[i];
depthCamera->getOrCreateStateSet()->addUniform(_inverseViewUniform[i]);
}
}
else{
for (int i = 0; i < 6; i++){
_inverseViewUniform[i]->set(osg::Matrixf::inverse(shadowViews[i]));
}
}
}
void VisibilityTestArea::buildModel()
{
// If shadow exist
if (!_shadowedScene.valid())
{
osg::notify(osg::WARN) << "shadow scene is not valid" << std::endl;
return;
}
_mainViewer->getCamera()->getGraphicsContext()->getState()->setUseModelViewAndProjectionUniforms(true);
// Light source in shader
far_plane = _lightSource.z()+ (float)_viewingRadius ;
_lightPosUniform = new osg::Uniform("lightPos", _lightSource);
_viewRadiusUniform = new osg::Uniform("user_area", (float)_viewingRadius);
_farPlaneUniform = new osg::Uniform("far_plane",far_plane);
_nearPlaneUniform = new osg::Uniform("near_plane", near_plane);
_visibleColorUniform = new osg::Uniform("visibleColor", visibleColor);
_invisibleColorUniform = new osg::Uniform("invisibleColor", invisibleColor);
// _baseTextureUniform = new osg::Uniform("baseTexture", 0);
_shadowMapUniform = new osg::Uniform("shadowMap", 1);
// Generate shadow map cameras and corresponding textures
osg::Matrix shadowProj = osg::Matrix::perspective(_verticalFOV, SM_TEXTURE_WIDTH / SM_TEXTURE_WIDTH, near_plane, far_plane);
depthMap = new osg::TextureCubeMap;
depthMap->setTextureSize(SM_TEXTURE_WIDTH, SM_TEXTURE_WIDTH);
depthMap->setInternalFormat(GL_DEPTH_COMPONENT);
depthMap->setSourceFormat(GL_DEPTH_COMPONENT);
depthMap->setSourceType(GL_FLOAT);
depthMap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
depthMap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
depthMap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE);
depthMap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
depthMap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
osgEarth::VirtualProgram* _depthCamerasVP = new osgEarth::VirtualProgram();
_depthCamerasVP->setFunction("depthMapVertex",depthMapVertVP,osgEarth::VirtualProgram::LOCATION_VERTEX_MODEL);
_depthCamerasVP->setFunction("depthMapFragment",depthMapFragVP,osgEarth::VirtualProgram::LOCATION_FRAGMENT_COLORING);
_depthCamerasVP->setShaderLogging(true, "shaders.txt");
// Generate one camera for each side of the shadow cubemap
for (int i = 0; i < 6; i++)
{
_depthCameras[i] = generateCubeCamera(depthMap, i, osg::Camera::DEPTH_BUFFER);
_depthCameras[i]->setProjectionMatrix(shadowProj);
osg::StateSet* ss= _depthCameras[i]->getOrCreateStateSet();
ss->setAttributeAndModes( _depthCamerasVP, osg::StateAttribute::ON );
ss->addUniform(_lightPosUniform);
ss->addUniform(_farPlaneUniform);
ss->addUniform(_nearPlaneUniform);
_depthCameras[i]->addChild(_shadowedScene);
_parentScene->addChild(_depthCameras[i]);
}
// Render the result in shader
_parentScene->getOrCreateStateSet()->setTextureAttributeAndModes(1, depthMap, osg::StateAttribute::ON);
osg::StateSet* ss= _parentScene->getOrCreateStateSet();
_visibilityShader = osgEarth::VirtualProgram::getOrCreate(ss);
_visibilityShader->setFunction("visibilityVertex",visibilityShaderVertVP,osgEarth::VirtualProgram::LOCATION_VERTEX_MODEL);
_visibilityShader->setFunction("visibilityFragment",visibilityShaderFragVP,osgEarth::VirtualProgram::LOCATION_FRAGMENT_COLORING);
// ss->addUniform(_baseTextureUniform);
ss->addUniform(_shadowMapUniform);
ss->addUniform(_visibleColorUniform);
ss->addUniform(_invisibleColorUniform);
// Update light source info for shadowing scene
ss->addUniform(_lightPosUniform);
ss->addUniform(_farPlaneUniform);
ss->addUniform(_nearPlaneUniform);
ss->addUniform(_viewRadiusUniform);
_lightIndicator = makeIndicator(_lightSource);
_parentScene->getParent(0)->addChild(_lightIndicator);
updateAttributes();
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
supportSupport questionsSupport questions