Jump to content

Writing to texture from a fragment shader


Recommended Posts

Hello !

 

I'm currently working on a "fog of war" material : the standard material + a texture to keep track of once-lit areas, and display them later event if they are not illuminated (because of the standard lighting model or shadowgenerator). It would produce the ~same effect as classical real-time strategy games FoW,(with a moving light revealing the model) but based on actual lighting and on arbitrary UV-unwrapped models.

 

However, I can't figure out how to write to a texture : when the shader gl_FragColor rgb component would be different from (0,0,0), it must modify the corresponding point on texture. From what I found, Babylon.js' DynamicTexture can be altered from the js part (as an HTML canvas), and I should rather use a Framebuffer Object, but I don't understand how to create and manage it from Babylon.

 

Sorry if this is a really noob question, any clue or thought is welcome. Thanks for reading this :-)

Link to comment
Share on other sites

Hi!

 

I'm not very familiar with using render target textures (RTT) and frame buffer objects in BJS, but I'll try to help you nonetheless.

 

First of all, here is the documentation for the RTT class:

http://doc.babylonjs.com/page.php?p=24711

 

In order to achieve the FOW effet, I think your best bet would be to save the "hidden/shown" state of each part of the scene in a texture. Similarly to a shadow map that will tell you if the pixels rendered must be dark or clear, your "fog map" will tell if each pixel must be rendered or not. As such, I guess the two methods will be similar.

 

This is what comes to my mind after thinking about it :

0: initialize the fog of war map as a texture filled with black (hidden)

1. compute the shadow map by placing the camera in place of the light source and rendering to a RTT

2. compute the "fog of war map" by rendering to a RTT using an orthographic camera facing down : every pixel seen by this camera and lit by the light source should be switched to white (visible), the others left as they are

3. render the scene, checking for each pixel if a/ it is marked as visible in the fog of war map (if no: skip) and if b/ it is lit by the light source (if no: darkens)

 

The "fog of war map" could then be saved and reloaded as an image with lossless compression.

 

That's very unrefined but I think this could work. Hope that helps to give you some ideas :)

Link to comment
Share on other sites

Hi jahow !

 

In order to achieve the FOW effet, I think your best bet would be to save the "hidden/shown" state of each part of the scene in a texture. Similarly to a shadow map that will tell you if the pixels rendered must be dark or clear, your "fog map" will tell if each pixel must be rendered or not.

This is it. Although the "fog map" must be permanent, whereas the shadow map is regularly recreated (from what I understood, may be wrong).

 

 

 


2. compute the "fog of war map" by rendering to a RTT using an orthographic camera facing down : every pixel seen by this camera and lit by the light source should be switched to white (visible), the others left as they are

This would be perfect for a surface (or plane model), but not for any 3D model (e.g. a sphere, with a light revolving around - half the sphere would not be mapped by the orthographic camera). In my opinion, the simplest (if possible) way would be to use a texture with uv coordinates (just like the diffuse texture) and write on it directly from the fragment shader. I forgot to say it doesn't matter if non-visible illuminated areas are not updated on the "fog map" (so the shader seems the place to do it).

 

Thank you for your ideas :)

 

(I keep scratching my head & post whatever I may  find)

Link to comment
Share on other sites

RTT are here for this specific task :)

var texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);

Example:

http://www.babylonjs-playground.com/#EEOWP

! I never thought of RTT that way, for me they were just "additional displays" for another camera. As they can be used "on" an UV-unwrapped model, this is the way to go.

 

Thank you very much to both of you.

Link to comment
Share on other sites

Ok, now I understand better what you want to achieve. It's more complicated than what I first thought, and I think it's a bit out of my league...

 

If I understand correctly, what you're actually looking to do is: for every object, make a copy of the texture and replace the color (diffuse) information in it with the hidden/shown state of the texel. This would mean that you'd need to save, for every texture used in your scene, a copy of the texture with the hidden/shown data, and you'll be keeping and updating this new texture regularly during play.

 

I can't think of a proper way to write the FOW data on an existing texture. Fragment shaders allow you to control & modify each pixel of a rendered polygon, so it will allow you to modify an existing texture's color (by rendering it as a whole on a flat poly). But I don't see how to fetch the "lit/unlit" state of each of the texture's pixels...

 

Also, you need to take into account the fact that one pixel of the texture may be visible multiple times on a mesh.

 

This may not be very helpful to you... :/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...