I need to generate a texture based on a heightmap,I use Texture2D->PlatformData->Mips[0].BulkData.Lock and UnLock to read and write,then Texture2D->UpDateResource,and I put the codes in
BeginPlay(),but the engine keeps crashing or results in starnge output,so i want to ask:
1.Is too much codes cause the crash,its about a billion loops;
2.Will lock and unlock every times read and write boost perfomance?
3.Will UpDateResource every times write boost perfomance?
4.What causes the problem on the picture i upload
5.Easiest tool to generate texture?
You should post as much of your code as possible, and the crash output.
Not sure why you need to Lock / Unlock a gazillion times. Typically you only need to do this once per texture data generation.
thanks for replying!
no crash uotput,engine just qiuts or freezes,it seems to be “UpDateResource” that causes the crash,
AProbeMapGenerater::AProbeMapGenerater()//LevelScriptActor
{
TextureAsset= LoadObject<UTexture2D>(nullptr, TEXT("/Game/tex.tex"));
TextureAsset->MipGenSettings = TMGS_NoMipmaps;
TextureAsset->CompressionSettings = TC_VectorDisplacementmap;
TextureAsset->SRGB = false;
TextureSize = TextureAsset->GetSizeX();
TexturePrecision=TextureSize*TexturePrecisionInUV;
Channels = TextureAsset->HasAlphaChannel() ? 4 : 3;
}
int AProbeMapGenerater::LookUp(int x, int y, int offsetx, int offsety, int channel)
{
uint8* raw = (uint8*)(TextureAsset->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE));
int value = (int)*(raw+ ((x + offsetx)*(y + offsety) + x + offsetx)*Channels + channel);
TextureAsset->PlatformData->Mips[0].BulkData.Unlock();
return value;
}
void AProbeMapGenerater::ReWrite(int x, int y, int offsetx, int offsety, int channel, int value)
{
uint8* raw = (uint8*)(TextureAsset->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE));
if (value < 256) { *(raw + ((x + offsetx)*(y + offsety) + x + offsetx)*Channels + channel) = (uint8)value; }
TextureAsset->PlatformData->Mips[0].BulkData.Unlock();
}
void AProbeMapGenerater::BeginPlay()
{
for (int y = 0; y < TextureSize; y++)
{
for (int x = 0; x < TextureSize; x++)
{
ReWrite(x,y,0,0,HeightMapChannel,LookUp(x,y,0,0,HeightMapChannel)*TextureHeightRatio);
}
}
if(Simulate())
{
TextureAsset->UpdateResource();
TextureAsset->MarkPackageDirty();
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green,TEXT("complete"));
}
}
bool AProbeMapGenerater::Simulate()
{
//a lot of loops calling LookUp and ReWrite,too much lines so i skip this part
}
Does it lock up if you just do one ReWrite or 100?
One trick is to go to the Debug menu and select “BreakAll”. Then open up the threads view and find your code - you can f10 from there. On Mac it would be MacKey+Y+C I think (its whatever continue is, I rely on muscle memory).
In terms of code structure what you have is a bit horrible to my understanding (don’t worry - I saw early iteration DirectX code doing something identical many years ago). The Lock command could be highly complex - stopping the GPU, copying data over to you, preventing further use of that data until you Unlock it. The Unlock command would do the opposite.
Not sure what Unreal’s implementation does, but if you want high performance graphics you have to play nice with the hardware, so it’s likely the case.
I’d suggest doing my initial quick and easy test (limit your thrashing of the buffers). Then I’d be looking to restructure your code into this:
Lock()
Do lots and lots of things with my buffer()
Unlock()
1.I tried lock-unlock eveytime and lock-unlock one time at begin-end,it both worked after i commented out half of my loops(freeze again if uncommented),second way was actually quicker.
2.While I trying to reduce my codes,the problem remains.same result even trying to fill it with single color.
3.I dont have much expirence of c++ and VS,Im doing out of my scope,but i do need this texture,let go of me if Im beyond help, thank you kindly!

No output? Also - are you running from inside visual studio? If not I suggest you do it gives you a huge insight into what’s going on.
Looking at your code it looks close to something that should run.
Minor thought - you’ll want to unlock the buffer whatever simulate returns (obviously right now it only returns true, but the unlocking should just be tied to the locking).
bool AProbeMapGenerater::Simulate()
{
for (int y = 0; y < TextureSize; y++)
{
for (int x = 0; x < TextureSize; x++)
{
int depth =LookUp(x, y, 0, 0, HeightMapChannel);
int pr = 0;
for (int d = TextureHeight; d >depth; d--)
{
for (int r = 1; r <=TextureSize / 2; r++)
{
bool f=false;
for(float a=0;a<2*PI;a+=1/r)
{
int xo = FMath::FloorToInt(r*FMath::Cos(a));
int yo = FMath::FloorToInt(r*FMath::Sin(a));
if(depth <=LookUp(x,y, xo, yo,HeightMapChannel)){f=true;break;}
In this code above its not immediately clear to me why you’re not going to access the texture memory out of bounds. x,y will take you to the last pixel in the source data and then LookUp is going to offset by xo,yo which will be in a range -TextureSize/2 → +TextureSize/2.
Lookup probably needs to cope with this, either clamping or wrapping it’s lookup point.
Not sure why this would freeze your code, but it would cause crap.
I solve the tiling issue,but problems just kept coming,suddenly codes worked before now throw crashes,I am exhausted.then I moved all codes to a counsol program and surprisingly successed!even slow as hell.link text
Anyway thanks again for your patient,i really appreciate it.
I ll post the codes here,if anyone is searching this question,you may have something for reference.
Well - glad you got somewhere - probably faster running in a standalone program without all the fancy graphics. You can actually invoke the standalone from within unreal - I do that in one of my tools.
What are you trying to do? I read the code but couldn’t really tell what the end effect was going to be.
Im studing parallax mapping,been very intersted about it,I use the codes to test a idea I came up,failed though.I post some results at the forum,come take a look.Been trying to optimize parallax occlusion mapping,here are some progress,come discuss!(need help!) - Rendering - Epic Developer Community Forums
Interesting, no wonder I couldn’t work out what you were doing!
If you keep pushing at it and have performance concerns I’d be looking to put the compute onto a GPU, they’re great at number crunching. However you have an interesting problem to optimize there - I bet you could learn a lot trying.
For instance:
- Branching - can you use math or bitwise logic instead? Can you move inner branches inside loops to outer branches (more loops written, less CPU consumed)
- Type conversions - int and float conversions.
- Memory access management - access memory as linearly as possible so the cache use is optimal.
- Try inlining your inner functions
- Do you need the accuracy that sin and cos provide? We used to use lookup tables and lerps.
- img(x, y, 0, channel) - what sort of performance does this have? You might want to manage your own memory buffers. CImg sounds cool (thanks - now I know it exists) but given it provides a fairly generic solution to image handling there is likely overhead over the simple memory read/write operations you need.
- Are there inner loops you can precalculate? Do any of the perpixel computations get repeated?
- Find a way to not nest 5 loops
- Vectorize!! Why do one operation when a modern CPU can do four at once!
- Time to learn assembly
Looks like a fun project anyway - good luck if you keep going, good luck if you don’t!
This is where my high school vc6.0 skill comes short,the reason I chosed ue4 at first is I wanted a high level api because I know nothing about debug or gpu or memory optimizatino,best I can understand is inline the functin.I hope to improve in the future.
anyway my learning stoped as the problem is too cmplex,but with this experience I feel confident to nail it in the future.
By the way I find that substance dsigner has a “pixel processor” which has read write ability,maybe give that a try.
You’re doing great fwiw - optimization is a skill that takes years to learn properly and while important comes a long way after making things work ™.