26-12-2019, 04:47 PM (This post was last modified: 26-12-2019, 05:51 PM by sc00b.)
(26-12-2019, 10:40 AM)josemendez Wrote: As I said before, the SimpleFluidRenderer is intended for mobile devices, and works in iOS devices as far back as iPhone 4S with iOS 9.0.
The standard FluidRenderer is intended for desktop platforms, and not guaranteed to work in mobile. Also, it requires the device to support floating point textures. If it doesn't, there's nothing we can do, short of writing a custom renderer for your specific device.
ScreenSpaceCurvatureFlow - this shader does not work on a mobile device. How much does it cost you to write us a working shader that will work with ObiFluidRenderer ???
SimpleFluidRenderer - does not work with mixing two colors)
If we comment on this shader, then we do not like the visual display of the render ...
I just can’t understand one thing, we spent two weeks trying to figure it out! Why does it work for you, but not for us. As a result, it does not support mobile platforms.
ScreenSpaceCurvatureFlow - this shader does not work on a mobile device. How much does it cost you to write us a working shader that will work with ObiFluidRenderer ???
SimpleFluidRenderer - does not work with mixing two colors)
If we comment on this shader, then we do not like the visual display of the render ...
I just can’t understand one thing, we spent two weeks trying to figure it out! Why does it work for you, but not for us. As a result, it does not support mobile platforms.
I didn't say it "works for me", all I know is that you're trying to get the FluidRenderer (that is not intended for mobile) to work on a mobile device that does not support floating point textures. That just won't work. Let me know what your requirements are (what do you need to get working and in what device) and if it's feasible I'll get you a working solution.
26-12-2019, 07:26 PM (This post was last modified: 26-12-2019, 07:41 PM by sc00b.)
(26-12-2019, 06:25 PM)josemendez Wrote: I didn't say it "works for me", all I know is that you're trying to get the FluidRenderer (that is not intended for mobile) to work on a mobile device that does not support floating point textures. That just won't work. Let me know what your requirements are (what do you need to get working and in what device) and if it's feasible I'll get you a working solution.
We need to mix two liquids so that the render displays them with liquid, not balls) Write me on Skype - t3200ml, I will show the project, it may be easier to write an individual shader for us. We will pay for the work.
ScreenSpaceCurvatureFlow - can you make this shader for us to work on the mobile version?
(26-12-2019, 07:26 PM)sc00b Wrote: We need to mix two liquids so that the render displays them with liquid, not balls) Write me on Skype - t3200ml, I will show the project, it may be easier to write an individual shader for us. We will pay for the work.
ScreenSpaceCurvatureFlow - can you make this shader for us to work on the mobile version?
Hi,
I’ll write the shader/renderer combination for free, should be pretty straightforward. Also, when using 2D fluid there isnt any need to use the screen space curvature shader.
Give me a few days (we are in christmas holidays) and I’ll have it done.
I’ll write the shader/renderer combination for free, should be pretty straightforward. Also, when using 2D fluid there isnt any need to use the screen space curvature shader.
Give me a few days (we are in christmas holidays) and I’ll have it done.
27-12-2019, 10:22 AM (This post was last modified: 27-12-2019, 11:15 AM by josemendez.)
Ok, I think it's done. It all boils down to modifying the SimpleRenderer so that it shows per-particle colors, instead of using a flat color for the entire surface of the fluid. You can find the required files attached:
ObiSimpleFluidRendererColored.cs (the renderer you need to use)
FluidColorsBlendSimple.shader (shader for the color material)
SimpleFluidColored.shader (shader for the fluid material)
Here's the FluidMixing scene using these files, running at roughly 50 fps in an iPhone 7. Note we set the ParticleRenderer's radius scale to 1.8 to ensure good particle coverage.:
A short explanation of what needed to be done and why:
We start from the ObiSimpleFluidRenderer as it has better mobile compatibility, so we make a copy and call it ObiSimpleFluidRendererColored. We need to bring in the standard renderer's capability of rendering individual particle colors, so let's look into it and figure out how it's done. The comment on line 138 of ObiFluidRenderer.cs says:
Code:
// draw fluid thickness and color:
Predictably enough, the following lines set a render target, clear it to a color (1,1,1,0), and then we iterate over all particle renderers drawing their meshes into this render target 2 times: one using the thicknessMaterial, and a second time using the colorMaterial:
If you take a look at the equivalent code in ObiSimpleFluidRenderer, you will see 2 differences:
It clears the render target to pitch black (0,0,0,0). In the standard fluid renderer, (1,1,1,0) is used instead because particle color blending is multiplicative, and thickness blending is additive. For multiplication "1" is the neutral value, and for addition, "0" is.
It does not render the particles a second time using the colorMaterial.
So it seems like a good idea to copy these lines over to our simple renderer. Also, we'll need to copy the declaration of the colorMaterial used to render the particle colors. That's all we need to do in ObiSimpleFluidRendererColored.cs.
Now for the shaders. The shader used by thicknessMaterial is Hidden/FluidThickness. If we take a look into it, we'll see it only writes to the alpha channel of the render target, as specified in line 16:
Code:
ColorMask A
Similarly, the shader used by colorMaterial only writes to the RGB channels:
Code:
ColorMask RGB
So with the modifications we did in our simple renderer, thickness is being stored in the alpha channel of the _Thickness render target, and particle color in the red, green and blue channels. All that's left to do is read the rgb channels in our fluid shader. So we make a copy of SimpleFluid.shader, call it SimpleFluidColored.shader, and slightly modify its last line so that it modulates the final color using the particle color we read from the rgb channels of _Thickness:
Code:
return output * _Color * half4(fluid.rgb,1);
If we tried now, things *should* run. However if we take a look at the shader used to draw the colors into the _Thickness render target, we'd see it reads/writes from the depth buffer, which we aren't using at all because we're in 2D. So we can get rid of most of the zbuffer-related code in FluidColorsBlend and get a nice speedup.
That's it! all it took was modifying 3 lines of the simple fluid renderer, 1 line of the fluid shader, and optionally a few lines of the color blending shader.
If you want to further hide the particle-based structure of the fluid, you could also perform a blurring pass of the _Thickness render target before using it to render the final image. This would be a very simplified version of what the screen space curvature shader used in the standard renderer does (the curvature shader has to deal with depth discontinuities and depth-dependent blurring kernel size, both of which aren't needed in 2D).
(27-12-2019, 10:22 AM)josemendez Wrote: Ok, I think it's done. It all boils down to modifying the SimpleRenderer so that it shows per-particle colors, instead of using a flat color for the entire surface of the fluid. You can find the required files attached:
ObiSimpleFluidRendererColored.cs (the renderer you need to use)
FluidColorsBlendSimple.shader (shader for the color material)
SimpleFluidColored.shader (shader for the fluid material)
Here's the FluidMixing scene using these files, running at roughly 50 fps in an iPhone 7. Note we set the ParticleRenderer's radius scale to 1.8 to ensure good particle coverage.:
A short explanation of what needed to be done and why:
We start from the ObiSimpleFluidRenderer as it has better mobile compatibility, so we make a copy and call it ObiSimpleFluidRendererColored. We need to bring in the standard renderer's capability of rendering individual particle colors, so let's look into it and figure out how it's done. The comment on line 138 of ObiFluidRenderer.cs says:
Code:
// draw fluid thickness and color:
Predictably enough, the following lines set a render target, clear it to a color (1,1,1,0), and then we iterate over all particle renderers drawing their meshes into this render target 2 times: one using the thicknessMaterial, and a second time using the colorMaterial:
If you take a look at the equivalent code in ObiSimpleFluidRenderer, you will see 2 differences:
It clears the render target to pitch black (0,0,0,0). In the standard fluid renderer, (1,1,1,0) is used instead because particle color blending is multiplicative, and thickness blending is additive. For multiplication "1" is the neutral value, and for addition, "0" is.
It does not render the particles a second time using the colorMaterial.
So it seems like a good idea to copy these lines over to our simple renderer. Also, we'll need to copy the declaration of the colorMaterial used to render the particle colors. That's all we need to do in ObiSimpleFluidRendererColored.cs.
Now for the shaders. The shader used by thicknessMaterial is Hidden/FluidThickness. If we take a look into it, we'll see it only writes to the alpha channel of the render target, as specified in line 16:
Code:
ColorMask A
Similarly, the shader used by colorMaterial only writes to the RGB channels:
Code:
ColorMask RGB
So with the modifications we did in our simple renderer, thickness is being stored in the alpha channel of the _Thickness render target, and particle color in the red, green and blue channels. All that's left to do is read the rgb channels in our fluid shader. So we make a copy of SimpleFluid.shader, call it SimpleFluidColored.shader, and slightly modify its last line so that it modulates the final color using the particle color we read from the rgb channels of _Thickness:
Code:
return output * _Color * half4(fluid.rgb,1);
If we tried now, things *should* run. However if we take a look at the shader used to draw the colors into the _Thickness render target, we'd see it reads/writes from the depth buffer, which we aren't using at all because we're in 2D. So we can get rid of most of the zbuffer-related code in FluidColorsBlend and get a nice speedup.
That's it! all it took was modifying 3 lines of the simple fluid renderer, 1 line of the fluid shader, and optionally a few lines of the color blending shader.
If you want to further hide the particle-based structure of the fluid, you could also perform a blurring pass of the _Thickness render target before using it to render the final image. This would be a very simplified version of what the screen space curvature shader used in the standard renderer does (the curvature shader has to deal with depth discontinuities and depth-dependent blurring kernel size, both of which aren't needed in 2D).
It depends on how you’re performing color blending. Red multiplied by green is black (1,0,0) * (0,1,0) = (0,0,0), so this is the expected result when using multiplicative blending. I’d suggest using additive blending instead, so (1,0,0)+(0,1,0) = (1,1,0). That would yield yellow.
This is however basic color math, not specific to Obi.
(27-12-2019, 01:12 PM)josemendez Wrote: It depends on how you’re performing color blending. Red multiplied by green is black (1,0,0) * (0,1,0) = (0,0,0), so this is the expected result when using multiplicative blending. I’d suggest using additive blending instead, so (1,0,0)+(0,1,0) = (1,1,0). That would yield yellow.
This is however basic color math, not specific to Obi.
Same reason as the previous question: pink * pink=purple (which is just darker pink, in zones with more particle density). Cyan * cyan = Cyan. Using numbers: