Procedural texture


Hello! I’m trying to create a texture by means of simple post-processing effect on the auxiliary viewport. Here’s the code

SharedPtr<Texture2D> Game::CreateTexture(int width, int height)
    //Get the Resource Cache subsystem
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    SharedPtr<Texture2D> renderTexture(new Texture2D(context_));
    renderTexture->SetSize(width, height, Graphics::GetRGBFormat(), TEXTURE_RENDERTARGET);

    // Create the scene which will be rendered to a texture
    rttScene_ = new Scene(context_);
    // Create a camera for the render-to-texture scene.
    rttCameraNode_ = rttScene_->CreateChild("Camera");
    auto* rttCamera = rttCameraNode_->CreateComponent<Camera>();

    RenderSurface* surface = renderTexture->GetRenderSurface();
    SharedPtr<Viewport> rttViewport(new Viewport(context_, rttScene_, rttCameraNode_->GetComponent<Camera>()));
    surface->SetViewport(0, rttViewport);

    SharedPtr<RenderPath> effectRenderPath = rttViewport->GetRenderPath()->Clone();


    return renderTexture;

I’ve created BasicPP.xml and the corresponding BasicPP.glsl which creates a simple gradient by using gl_FragColor. The effect is working as expected on the main viewport. Also, when I attach a .png texture to my sprite, it gets shown on the screen.

So what am I missing?


What results do you get and how do they not match up with your expectations?


For a 128x128 texture I get a black rectangle. I render the effect on the renderer’s viewport to be sure that it’s working, so I’m expecting to see a mini-version of the background where the black 128x128 rectangle is.

If I don’t set size with sprite->SetSize(IntVector2(128, 128)); I don’t get anything… Just a background with a post processing gradient. So, obviously, the post-processing effect is not rendered on the created texture.


I think you may need to add an octree to the scene, possibly also a zone.


The Renderer has a default Zone (which can be accessed and modified through GetSubsystem<Renderer>()->GetDefaultZone()) so that should not be the problem.
Indeed the Scene does not seems to have an Octree component added. @Lunarovich Your program should output an error about this to the console/terminal/IDE (if it contains Drawables).

ERROR: No Octree component in scene, drawable will not render


Thanx. I’ll try the solution and inform about the results.


Your intent seems to be to use - the currently unused - auto* rttCamera here, btw. This should not be causing any trouble, though.


Is single shader all you want to draw into this texture? Or you also want to draw some 3d geometry there? If first, you don’t really need a scene, viewport, camera and all that stuff. You can draw a quad right into render target.

here is the code for that:

Graphics* graphics = context_->GetSubsystem<Graphics>();

WeakPtr<Texture2D> renderTarget(renderTexture);

graphics->SetRenderTarget(0, renderTarget);
graphics->SetViewport(IntRect(0, 0, TEX_X, TEX_Y));
graphics->Clear(CLEAR_COLOR, Color(9e99, 0.0f, 0.0f, 0.0f));
ShaderVariation* vs = graphics->GetShader(VS, "SdfCalculator" );
ShaderVariation* ps = graphics->GetShader(PS, "SdfCalculator", this->GetDefines());
graphics->SetShaders(vs, ps);

Matrix3x4 modelMatrix = Matrix3x4::IDENTITY;
modelMatrix.m23_ = 0.0f;
graphics->SetShaderParameter(VSP_MODEL, modelMatrix);
graphics->SetShaderParameter(VSP_VIEWPROJ, Matrix4::IDENTITY);

graphics->SetTexture(TU_DIFFUSE, upldTexture);
Renderer* renderer = context_->GetSubsystem<Renderer>();
Geometry* geometry = renderer->GetQuadGeometry();