Jump to content

klepto2

Developers
  • Posts

    854
  • Joined

  • Last visited

Posts posted by klepto2

  1. Hi, i wanted to use them to build a small control ui. Unfortunatly the Widget system seems to have changed. the Widget::gui is protected and a weak ptr. So the provided Widgets are not working anymore.

  2. On a side note, which i will later post in a block in more depth: 

    While the limit of parameters is now 64, this is still not enough for the precomputed scattering. I needed at least 88 unique identifiers (maybe 2 or 3 less, as i haven't fully optimized each vec4) + 4 texture slots. so i currently need a  total of around 92 floats/values passed to the posteffect. Well to overcome this i used a common practice used in shadertoy and maybe this can be made more practical later. 

    As a background: I need to precalculate a lot of these shadervalues, but once they are calculated, most of them don't change anymore. So i created a tiny texture, lets say 13 * 3 PX in RGBA32 format and the corresponding pixmap.  Then I store each set of Vec4 in the pixmap and upload it to the texture. 

    In the shader i can now simply get the values with a texelFetch.

     

    void WritePixel(shared_ptr<Pixmap> pixmap, int x, int y, iVec4 data)
    	{
    		pixmap->WritePixel(x, y, Vec4(data.x, data.y, data.z, data.w));
    	}
    
    	void WritePixel(shared_ptr<Pixmap> pixmap, int x, int y, Vec4 data)
    	{
    		pixmap->WritePixel(x, y, data);
    	}
    
    	void WritePixel(shared_ptr<Pixmap> pixmap, int x, int y, Mat4 data)
    	{
    		pixmap->WritePixel(x, y, data[0]);
    		pixmap->WritePixel(x + 1, y, data[1]);
    		pixmap->WritePixel(x + 2, y, data[2]);
    		pixmap->WritePixel(x + 3, y, data[3]);
    	}
    
    	
    
    	void AtmosphereCalculator::updateUniforms_forpfx(double* lambdas, double* luminance_from_radiance)
    	{
    		auto pixmap = CreatePixmap(iVec2(m_settings_texture->GetSize().x, m_settings_texture->GetSize().y), TEXTURE_RGBA32);
    		// constants
    		WritePixel(pixmap, 0, 0, _atmosphereData.c.data0);
    		WritePixel(pixmap, 1, 0, _atmosphereData.c.data1);
    		WritePixel(pixmap, 2, 0, _atmosphereData.c.data2);
    		WritePixel(pixmap, 3, 0, _atmosphereData.c.SKY_SPECTRAL_RADIANCE_TO_LUMINANCE);
    		WritePixel(pixmap, 4, 0, _atmosphereData.c.SUN_SPECTRAL_RADIANCE_TO_LUMINANCE);
      
      		... much more data goes in here
      
      		m_settings_texture->SetPixels(pixmap);
      }
      
      // and in the shader it looks like this:
      void SetupUniformDataForPFX(sampler2D settings)
    {
    	AtmosphereParameters atmParams;
    	AtmosphereConstants constants;
    	
    	constants.data0 = ivec4(texelFetch(settings, ivec2(0,0),0));
    	constants.data1 = ivec4(texelFetch(settings, ivec2(1,0),0));
    	constants.data2 = ivec4(texelFetch(settings, ivec2(2,0),0));
    	
    	constants.SKY_SPECTRAL_RADIANCE_TO_LUMINANCE = texelFetch(settings, ivec2(1,0),0);
    	constants.SUN_SPECTRAL_RADIANCE_TO_LUMINANCE = texelFetch(settings, ivec2(2,0),0);
       
      	...
    }

     

    • Like 2
    • Upvote 1
  3. 21 hours ago, Josh said:

    I might have found the cause just by looking at the code:

    	void RenderCamera::SetPostEffectObject(const int index, const int offset, shared_ptr<RenderTexture> value)
    	{
    		posteffectsobjects[index][offset] = value;
    		if (value)
    		{
    			posteffectsparameters[index][offset] = value->core->id;
    		}
    		else
    		{
    			posteffectsparameters[index][offset] = -1;
    		}
    		UpdateData();
    	}

    value->core->id should be wrapped in a call to IntBitstoFloat().

    Works now with the latest version :)

    • Like 1
  4. Ok, i will temporarily use the "make public approach" and i get some very nice results :)

    precomputed atmospheric scattering as a posteffect in Ultraengine:

    image.thumb.png.697f2e3099f16bcb6ccb053527c6f270.png

    image.thumb.png.d6e0fb389aee61e4f90fcb5049a70349.png

    And this is the actual code in main.cpp to integrate it:

     auto settings = EnvironmentSettings::GetEarthSettings();
        auto env = CreateEnvironment(world, settings);
        env->AssignToCamera(camera);
        env->Start();

     

     

    • Like 3
    • Upvote 2
  5. ah ok, so it should even work without using hooks as the id is resolved already when needed. 

    but why does it work seamingless with this:

     

    c->SetPostEffectParameter(_camera_posteffects[c], 3, _textureStorage->m_transmittance_array[READ]->rendertexture->core->id);

    Edit: Nevermind, found it. It is an override for int and i assume this already use the inttofloatbits.

    • Upvote 1
  6. Ok, for an experiment, I made everything public in texture.h and corrected my code to add a RENDER_HOOK to assign the textures. (Before rendering the id system is not initialized) 

    With these changes the following works and the correct ids are stored in the parameters:

    void BeginEnvironmentHook(const UltraEngine::Render::VkRenderer& renderer, shared_ptr<Object> extra)
    	{
    		auto env = extra->As<Environment>();
    		if (env != nullptr)
    		{
    			env->StartInternal();
    		}
    	}
      
      void Environment::StartInternal()
    	{
    		for (auto c : _cameras)
    		{
    			// First 3 Values are to check if the new parameter system works for simple values and they work;
    			c->SetPostEffectParameter(_camera_posteffects[c], 0, 1.0f); 
    			c->SetPostEffectParameter(_camera_posteffects[c], 1, 0.0f);
    			c->SetPostEffectParameter(_camera_posteffects[c], 2, 0.0f);
    			// Made everything public in Texture.h to access the internals and it works as expected
    			c->SetPostEffectParameter(_camera_posteffects[c], 3, _textureStorage->m_transmittance_array[READ]->rendertexture->core->id);
    			c->SetPostEffectParameter(_camera_posteffects[c], 4, _textureStorage->m_scattering_array[READ]->rendertexture->core->id);
    			c->SetPostEffectParameter(_camera_posteffects[c], 5, _textureStorage->m_irradiance_array[READ]->rendertexture->core->id);
    		}
    	}

    but this is not working even with a hook:

    	void Environment::StartInternal()
    	{
    		for (auto c : _cameras)
    		{
    			// First 3 Values are to check if the new parameter system works for simple values and they work;
    			c->SetPostEffectParameter(_camera_posteffects[c], 0, 1.0f); 
    			c->SetPostEffectParameter(_camera_posteffects[c], 1, 0.0f);
    			c->SetPostEffectParameter(_camera_posteffects[c], 2, 0.0f);
    			// Default behaviour with protected access modifiers and it doesn't work
    			c->SetPostEffectParameter(_camera_posteffects[c], 3, _textureStorage->m_transmittance_array[READ]);
    			c->SetPostEffectParameter(_camera_posteffects[c], 4, _textureStorage->m_scattering_array[READ]);
    			c->SetPostEffectParameter(_camera_posteffects[c], 5, _textureStorage->m_irradiance_array[READ]);
    		}
    	}

    parameters for values 3,4,5 are zero.

  7. I have tried it this way but none way is working. Any idea why? : 

    first i create the textures: i verfied that they are created by applying a material with the texture to a box.

    now i tried to pass them to the posteffect like this:

    	void Environment::SetupCamera(shared_ptr<Camera> camera)
    	{
    		_cameras.push_back(camera);
    		auto pfx_id = camera->AddPostEffect(_posteffect);
    		_camera_posteffects[camera] = pfx_id;	
        }
    
    ...
    
    for (auto c : _cameras)
    		{
    			c->SetPostEffectParameter(_camera_posteffects[c], 3, _textureStorage->m_transmittance_array[READ]);
    			c->SetPostEffectParameter(_camera_posteffects[c], 4, _textureStorage->m_scattering_array[READ]);
    			c->SetPostEffectParameter(_camera_posteffects[c], 5, _textureStorage->m_irradiance_array[READ]);
    		}

    in the post effect itself i tried different different ways to get the correct texture, but both failed:

    mat4 params = ExtractPostEffectParameters(0);
    
    int transmittance_id = floatBitsToInt(params[0][3]);
    
    col = texture(texture2DSampler[transmittance_id], uv).xyz;

    Direct using the PostEffectTextureID which also fails:

    col = texture(texture2DSampler[PostEffectTextureID3], uv).xyz;
  8. yes, this might work. But wouldn't that mean, that we need a way to assign the textures via code? 

    From my understanding the current system (based on the json) would still rerender the textures every time. And we don't have a way to get the correct texture index, so we can not pass it with the parameters.  

  9. well, not in every case :

    image.thumb.png.2bfe692372a8dc3cfcb15e8db5863342.png

    Source of the heightmap: https://johnflower.org/heightmap/mt-ruapehu-mt-ngauruhoe

    and the code how i apply the height:

    terrain->SetScale(tscale, scale, tscale);
        auto pixmap = LoadPixmap("Heightmaps/hm_nz.png");
        pixmap = pixmap->Resize(terrain->resolution.x, terrain->resolution.y);
        float low_p = 1.0;
    
        for (int x = 0; x < terrain->resolution.x; x++)
            for (int y = 0; y < terrain->resolution.y; y++)
            {
               auto h = pixmap->Sample(iVec2(x, y)).r;
               terrain->SetHeight(x, y,h);
               //auto h = terrain->GetHeight(x, y);
               if (h < low_p)
                   low_p = h;
            }
       
        terrain->SetPosition(0.0, -1.0 * (low_p * scale), 0.0);

     

  10. Or to make it work as before, you can set  the default back to 1.0 instead of 1000.0.

    With 1.0 it works as expected: 

     terrain->LoadHeightmap("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Terrain/1024.r16",1);
        terrain->SetScale(1, 100, 1);

     

  11. While experimenting with the posteffect system i found some smaller things which would be nice to have:

    1. More possible paramters: Currently it is only possible to pass (at least if i look into the shader files) 8 different float parameters to the shader. this might be enough for most simple cases, but for more complex scenarios this might be a show-stopping limitation. eg: 8 floats means just 2 vec4 , which means just 2 colors may be passed or 2 rgb colors with 2 additional parameters.

    [Disclaimer] I know that you already use the maximum supported sizes (damn you AMD ;)* ) but maybe there is another way for this (Registering uniform buffers for the rescue?).

    2. currently it is only possible to create additional textures with a multiplier of the current framebuffer size, i would suggest to add the possibility to add an absolute size as well. Some effects might need some smaller textures like 256*256 or 32*32 to calculate additional data.

    3. Make some passes one time only, with the possibility to mark them as dirty from the api.

    Explanation:  Lets say we want to have simple noise distortion pfx which needs a noise texture generated (with a size of 256*256 see pt. 2) now in pass 1 you would generate the noise and use it in pass 2. Currently the first pass is executed everytime, even it is only needed once, but it should be only regenerated, when eg: the seed has changed.

     

    * AMD allows just 128 bytes for push-constants while NVIDIA has changed to 256 on more recent cards.

    • Upvote 2
  12. Since the Collision/Hole Update terrain throws a validation error:

    Validation Error: [ UNASSIGNED-CoreValidation-Shader-InputNotProduced ] Object 0: handle = 0x8168780000000092, type = VK_OBJECT_TYPE_SHADER_MODULE; | MessageID = 0x23e43bb7 | fragment shader consumes input location 0.0 which is not written by vertex shader

  13. I am currently working on a post processing effect and when i try to read the normal map i get this:

    image.thumb.png.6524b3f7b5612e4d1cf6e907ef4f584b.png

    It seems that the normalbuffer isn't defined in the areas where the terrain is rendered, sometimes it looks like this, sometimes when moving the camera the terrain is rendered just black.

     

     vec3 n = textureLod(texture2DSampler[PostEffectTextureID1], uv, 0).rgb;
    outColor = vec4(n,1.0);

     

  14. From what i remember the only limitations which are set within the shaders are the different textures types:

    Limits.glsl:

    #define MAX_TEXTURES_2D 512
            #define MAX_TEXTURES_CUBE 128
            #define MAX_TEXTURES_SHADOW 64
            #define MAX_TEXTURES_2D_INTEGER 32
            #define MAX_TEXTURES_2D_UINTEGER 32
            #define MAX_TEXTURES_CUBE_SHADOW 128
            #define MAX_VOLUME_TEXTURES 128
            #define MAX_TEXTURES_STORAGE_2D 32
            #define MAX_TEXTURES_STORAGE_3D 128
            #define MAX_TEXTURES_STORAGE_CUBE 128
            #define MAX_TEXTURES_2DMS 32
    
            #define MAX_IMAGES_2D MAX_TEXTURES_2D
            #define MAX_IMAGES_3D 128
            #define MAX_IMAGES_CUBE 128

    Everything else should just be limited by the available memory. You can also alter this file to your needs, but you need to recompile the shaders when you do so.  Which will be complicated if you rely on the terrain shaders as they are currently not available via source.

    • Like 1
    • Thanks 1
  15. 3 hours ago, SpiderPig said:

    Unless there's already a way to do this?

    This is the hacky way without direct header access, but which needs to be updated when the class structure changes:

    struct PublicMaterial : public Asset
    {
        // copy everything from Material.h Material class here
    	// remove the access modifier
    	// remove all methods/constructors and friend functions
    };
    
    // Call this in your loop
    auto refmat = (*sample_material);
    auto mat = reinterpret_cast<PublicMaterial*>(&refmat);
    auto materialId = mat->rendermaterial->id;

     

    • Like 1
    • Thanks 1
    • Sad 1
×
×
  • Create New...