I was trying to google and understand my problem in two weeks but i am defeated, so i am asking for help.
The main problem is that my custom unlit frag shader after certain amount of time on devices with mali gpu starts to drop fps - i see it via fps counter in the cpu section. I dont know why in that section and not in render section, but with out this fps counter i can still feel the drop of fps.
So on Samsung S4, Samsung sm-t 380, xiaomi redmi note 5, samsung tab s2 is all ok, the drop was only on samsung s6 - to solve the problem i just half the resolution by Screen.SetResolution function.
I was thinking that drawing the full screen sprite on such a high res device is the point.
Then i can test app on samsung sm-t580 - and the drop was there - this device has low resolution than S6.
I assume that the problem in arm mali gpu - or i am sure in my hands.
So again, i am rendering full-screen with draw-mode = tile(countinuous) sprite with 3 textures, just changing theirs uvs in vert func and apply in fragment.
This makes distorting effect.
The shader show that i have 10 maths and 4 textures, yes 3 textures but i am making 4 sampling.
The textures are 256x256 with repeat mode.
I was trying diferrent textures compressions, dxt5, etc1-2, alpha8, R5 - no effect.
I was trying to different precisions half and float in different parts in shader - no effect.
I was thinking in alpha, so i took textures without alpha and not getting it from tex2D.
Even the size of textures is doesnt matter, even if they 64x64.
The dance with ZTest, ZWrite, Blend, Queue RenderType, other params - no effect.
My guess was that maybe on mali uv : TEXCOORD0 must be only float2, not float3 or float4 - no effect.
I am applying _Time.y and replace it with float from script - no effect.
Only reducing amount of tex2d in shader - is working.
Why?
What i`m doing wrong?
Related
I wrote a simple OpenTK program based on the OpenTK official tutorial (here) that basically draws a cube on the screen, applies a mixed texture, and rotates it based on elapsed time.
What I found is that when I set GameWindowSettings RenderFrequency and UpdateFrequency, weird stuff happens (all time/frequencies are measured with System.Diagnostics.Stopwatch):
If I don't set any frequency, the program runs at max speed and I see a smooth textured cube rotating in the widows. The measured screen FPS is about 1000 and updates are about 1000 per second. The cube rotates smoothly and the CPU / GPU runs at 100%.
if I set RenderFrequency say to 60.0 Hz and UpdateFrequency say to 1.0 Hz, the magic happens: the actual UpdateFrequency is about 1 Hz but the actual RenderFrequecy is about half the set, says around 30 Hz. The most stunning thing is that the cube still rotates but instead of rotating smoothly, it stays still for around 1 second and then suddenly moves, and all the rotation amount is done in a short time, but in a smooth way (I don't see any twitchy movement of the image, simply rotate very fast and smooth). CPU and GPU run at about 10-15%.
If I let RenderFrequency to its default value and I set UpdateFrequency, then the actual update matches the set and the RenderFrequency goes to 1500-2000 Hz and the cube rotates smoothly. The CPU is about 50% and the GPU goes up to 90-100%.
If I let the UpdateFrequency to its default and I set RenderFrequency to 60.0 Hz, then the actual UpdateFrequency goes to more than 100 kHz, the RenderFrequency matched 60 Hz, and the cube rotates as in case 2. CPU runs about 30% (why not the max?) and GPU around 10%.
OpenTK behavior, CPU/GPU usage, and the rotating cube I see don't make any sense to me.
I run the software on a Lifebook U Series Laptop with Win10.
Any clue?
I'm losing the night on this, many thanks in advance.
To start, I have a bird eye view 2d tilemap that I generate procedural. I color each tile using TileMap.SetColor( new Color(r,g,b,a));. This works very well with the default shader that does not process light on the scene. I want light in my game, so I swapped the shader, 1 by 1, to every other shader with none supporting the custom color and lighting at the same time in Legacy vertex Lit Mode. I tried swapping my rendering mode to Forward and Deffered and this did work as I had my custom colors on top of the lighting, but problems occurred. The reason I swapped to Vertex Lit in the first place was because I was getting artifacts at the boundaries of every tile with lines that showed the cross sections of tiles that overlapped and I get a way lower frame rate in forward/deffered, so I prefer legacy. I know why the shader does this and I tried writing my own, but I am very new to Unity, so I am not experience enough to dive into graphics that far.
What Is Needed: All that is needed is my custom tile colors and lighting in Legacy Vertex Lit mode or A fix to the overlapping tiles lighting up in forward and deffered modes.
Thanks again for the help! I am losing my mind trying to solve this.
EDIT: I noticed that when I changed the layer or z position of a tile in that map, the effect disappeared completely in forward and deffered of just that tile only. I don't know if this the solution I am looking for, but its a start.
EDIT #2: I set the chunk rendering mode to individual and it fixes the problem as in the first edit, but performance takes a very big hit. Any way to tell the render/shader that each tile is separated?
Ok, I eventually got it to work. What I did to get rid of the lines and get custom coloring in the game was to swap rendering modes to forward mode. Then, you can go into the shader you are using for the tilemap and add #pragma noforwardadd.
I pretty much put the question in the title. Would it help performance-wise if I stopped drawing targets are aren't on the screen anymore? What I mean by this is:
if (textureLocation is on the screen)
{
draw code here
}
Or it is so insignificant(if at all) that it doesn't matter?
Thanks,
Shyy
Depends. Ultimately spent time comes down to 3 things: sending data to the GPU, vertex shading, and pixel shading.
If the texture is located on a spritesheet that has other textures that are being drawn on screen and the offscreen draw call is within the same .Begin() .End() block as those others, it won't hurt performance since it takes just as long to send data and set the GPU up for the spritesheet. The 4 off-screen vertices will run through the vertex shader but that is not a bottle neck. The graphic pipeline culls offscreen objects between the vertex shader and pixel shader so it won't spend any time in the pixel shader
But if is a stand alone texture or in it's own .Begin() .End() block, it will cost time sending it's data to the GPU even though the GPU will cull it.
Whether it is significant or not only profiling can tell you.
I am creating realtime scene in XNA, it is 2D using sprites only (rendered on quads, standard spritebatch with alpha map on sprites). I would like to create create simply lens flare, actually only occlusion around light source (I donĀ“t need direction to center of camera to offset multiple sprites for lens flare, etc.) Only thing I basically need is to calculate how many pixels from light source sprite (small star) are rendered and according to it set scale of lens flare sprite (so scale 0 if sprite there are not visible pixels from relevant sprite).
I know how to do it in 3D, I read through this and tested few things:
http://my.safaribooksonline.com/book/programming/game-programming/9781849691987/1dot-applying-special-effects/id286698039
I would like to ask what is best and cheapest way to do it in 2D scene (counting how many pixels of sprite were rendered / occluded with per pixel precision or something comparable).
I know also stencil buffer could help but I am not sure how to applicate in this case.
Okay, two ways how to solve it, either kinda old school approach, using stencil to calculate count of occluded pixels and scale sprites of lens flare according to it.
Other way: modern approach, use screen space lens flare, isolate bright pixels (I recommend HDR rendering pipeline and use values of brightness above 1.0 to generate lens flares, but it depends on scene average and maximum) and generate ghosts, like so:
https://www.youtube.com/watch?v=_A0nKfzbs80&list=UUywPlxpmCZtuqOs6_bZEG9A
I'm currently learning HLSL with XNA, I figured the best place to start after tutorials would be some simple 2D shaders. I'm attempting to implement a simple lighting shader in 2D.
I draw the scene without shadows to a rendertarget, swap my rendertarget to a shadowmap, draw my light(each individually) onto the shadowmap via alpha channel, swap my rendertarget back to default and render the scene then the shadows on top.
The alpha of the light changes depending on the distance of the current pixel and the point of the light, this is all working fine for me except when I render the scene, if two lights overlap it causes a nasty blending issue.
I'm using alphablend when I draw on the shadowmap, and when I draw the shadowmap to the scene.
Am I just using the wrong blending settings here? I don't know much about blendstates.
Sorry if the question was vague.
I've had this happen before when doing software lighting, where your values exceed 255 (or 1.0) and you end up back in the realms of blackness. I believe the values are clamped using a modulo operation causing 1.1 to be 0.1 or 256 to be 1. I notice how the black ellipse is actually two spheres edges combined, this is what is giving me this conclusion.
Hope this gets you closer to understanding and finding out your problem. I have no idea what code you are using already but in your HLSL technique pass you could try adding:
AlphaBlendEnable = true;
SrcBlend = One;
DestBlend = One;