garth.denley Posted January 7, 2015 Posted January 7, 2015 I am looking to implement a curved (non-flat) reflective surface in a scene (specifially: a vehicle side mirror) with a different field of view than the active Player.I am currently exploring using render-to-texture, which will likely be useful for other problems we are working on. From some exploration it seems to me that using Unigine::TextureRender is probably the way to go.I believe the rough setup on the C++-side should look a bit like this: Unigine::TextureRenderPtr texturerender; Unigine::TexturePtr ttexture; ... ttexture = Unigine::Texture::create(); ttexture->create2D(size, size, Texture::FORMAT_RGBA8, Texture::WRAP_CLAMP | Texture::FILTER_LINEAR | Texture::USAGE_RENDER); texturerender = Unigine::TextureRender::create(); texturerender->create2D(size, size); ... texturerender->setColorTexture(0, ttexture); texturerender->enable(); render->renderViewport(projection, modelview, materials, viewport_mask, reflection_mask, 1); texturerender->flush(); texturerender->disable();I've been using the Panorama Plugin as a rough guide. This leaves we with (I assume) the end result in a Unigine::TexturePtr ("ttexture") on the C++-side. What I am a bit lost on is an efficient way to get this texture, which will likely be updated every frame, onto an ObjectMesh (or a suitable replacement) in the loaded world.Any suggestions?
unclebob Posted January 11, 2015 Posted January 11, 2015 Hi there, Garth! After you have a TexturePtr instance you can add some function which will be called from the script and will prepare an ObjectMesh for you. All you need to do is to get pointer to its material and call material->setImageTexture and pass your pointer to texture. So from the script side it'll look like this: ObjectMesh mesh = new ObjectMesh("test.mesh"); mesh.setMaterial("super_curvy_reflection","*"); reflection.addMesh(mesh); // this will be our plugin function, you name it And from C++ side it'll look like this: // I assume you've rendered reflection into TexturePtr // TexturePtr dynamic_reflection; void ReflectionPlugin::addMesh(ObjectMeshPtr mesh) { for(int i = 0; i < mesh->getNumSurfaces(); ++i) { MaterialPtr material = mesh->getMaterial(i); int texture = material->findTexture("reflection"); if(texture != -1) material->setImageTexture(texture,dynamic_reflection); } } And that ReflectionPlugin::addMesh function is exposed to UnigineScript as reflection.addMesh.
garth.denley Posted January 12, 2015 Author Posted January 12, 2015 Many thanks for the feedback and the potential solution.I may have hit a problem with this as a solution though: I don't believe our SDK (Oct/Nov 2013 I believe?) has either Material/MaterialPtr on the C++-side, or the setImageTexture call on the Unigine or C++-side. I have not found a way to get a C++ TexturePtr back in to UnigineScript- I'm not sure it is possible with our version of the SDK? Are the missing classes and calls possibly new functionality added since October 2013? A quick look at your online documentation suggests this might be the case.I've found a workaround, namely using getImage() on the resultant texture, and passing that in instead, and using setImageTextureImage on the UnigineScript side. Basically, I call out from UnigineScript to C++ for the TextureRender functionality, and call back in to UnigineScript to get the setImageTextureImage functionality. Whilst a bit messy, this appears to work. I'm concerned that the use of Image as a proxy means there'll be a gratuitous GPU to CPU to GPU copy each time though (is this right?). This might be a bit rough on us performance-wise.At least until we next upgrade (hopefully very soon), is there a potential solution that you can recommend that improves on the one I'm using that uses Images as a proxy, within the constraints of what is possible in the Oct/Nov 2013 SDK?
unclebob Posted January 12, 2015 Posted January 12, 2015 First, lets clarify some things. You can't pass neither TextureRendererPtr nor TexturePtr because they're not bound to UnigineScript. By grabbing ImagePtr from TexturePtr you'll do memory copy from GPU to CPU. So in your case I think all you can go now is low performance way (GPU to CPU copy and vice versa) by using ImagePtr and passing it to the script as it's bound to UnigineScript just to make sure your shaders and rendering things are working correctly. It's better to update your SDK version to the latest one and try what I suggested above.
garth.denley Posted January 13, 2015 Author Posted January 13, 2015 Many thanks. Thanks for the clarification on Texture/RenderTexture, as well as confirmation on the performance implications of the workaround I'm using. Confirmation that upgrading to the latest SDK will solve these performance limitations is also extremely useful to have.It does sound much like the workaround I'm currently using might be enough as a temporary measure, but the real solution will involve using a more recent SDK and a solution in line with the one you gave above.Thanks again!
unclebob Posted January 13, 2015 Posted January 13, 2015 You're welcome, Garth! Please write back about your results when you'll have the latest SDK.
Recommended Posts