Skip to content

virtual program / shader program , unexpected result in osgearth compare to plain osg #2923

@adithyahk46

Description

@adithyahk46

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

Image

osgearth

Image
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();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    supportSupport questions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions