SharpDX4.2 - Instanced Object shader Vertex Manipulation HLSL - C# I am using the same vertex shader and pixel shader for my instances. I am sending ONE FLAT array that contains all the instanced chunk bytes that make the cube of the Minecraft terrain. My goal is to make ONE DRAW CALL... Nothing is working. I am able to use an input element that has the specific index of the vertex logged in memory so all of the instances vertexes share the same index. It should be super easy after that to fetch the byte 0 or 1 inside of the flat chunk array that contains all of the data. cbuffer MatrixBuffer :register(b0) { float4x4 world; float4x4 view; float4x4 proj; }; struct VertexInputType { float4 position : POSITION; float4 indexPos : POSITION1; float4 color : COLOR; float3 normal : NORMAL; float2 tex : TEXCOORD; float3 dummyPad : NORMAL1; float4 indexPosMain : INSTANCEPOSITION; float4 instancePosition1 : INSTANCEPOSITION1; }; struct PixelInputType { float4 position : SV_POSITION; float4 color : COLOR; float3 normal : NORMAL; float2 tex : TEXCOORD; }; float planeSize = 0.1f; static int mapWidth = 4; static int mapHeight = 4; static int mapDepth = 4; static int tinyChunkWidth = 4; static int tinyChunkHeight = 4; static int tinyChunkDepth = 4; //[maxvertexcount(96)] PixelInputType TextureVertexShader(VertexInputType input) { PixelInputType output; input.position.w = 1.0f; //int mainX = input.indexPosMain.x; //int mainY = input.indexPosMain.y; //int mainZ = input.indexPosMain.z; int x = (input.indexPos.x); int y = (input.indexPos.y); int z = (input.indexPos.z); // if frac is NOT good then I use something else. // 0.234f * 10 = 2.34f // floored = index1 // 0.234f * 10 = 2.34f // frac = 0.34f * 10 and then floored = index2 // 0.234f * 100 = 23.4f // frac = 0.4f * 10 and then floored = index3 // 0.2345f * 1000 = 234.5 //fra = 0.5f * 10 and then floored = index4 float currentMapData; float currentByte; int currentIndex = x + tinyChunkWidth * (y + tinyChunkHeight * z); if(currentIndex >= 0 && currentIndex <= 15) { currentMapData = input.indexPosMain.x; currentIndex = currentIndex; currentIndex = 15-currentIndex; } else if(currentIndex >= 16 && currentIndex <= 31) { currentMapData = input.indexPosMain.y; currentIndex = 31 - currentIndex; currentIndex = 15-currentIndex; } else if(currentIndex >= 32 && currentIndex <= 47) { currentMapData = input.indexPosMain.z; currentIndex = 47 - currentIndex; currentIndex = 15-currentIndex; } else if(currentIndex >= 48 && currentIndex <= 63) { currentMapData = input.indexPosMain.w; currentIndex = 63 - currentIndex; currentIndex = 15 - currentIndex; } if(currentIndex == 0) { float before = currentMapData * 0.1f; float newIndex1 = round(before); float lastIndex = before - newIndex1; currentByte = round(lastIndex * 10); } else { int tempData = currentMapData; for(int i = 0;i < 15-currentIndex; i++) { tempData = currentMapData * 0.1f; currentMapData = round(tempData); } float before = currentMapData * 0.1f; float newIndex1 = round(before); float lastIndex = before - newIndex1; float otherByte = lastIndex * 10; currentByte = round(otherByte); } int current = currentByte; if(current == 1) //current >= 5 || wtf { input.position.x += input.instancePosition1.x; input.position.y += input.instancePosition1.y; input.position.z += input.instancePosition1.z; output.position = mul(input.position, world); output.position = mul(output.position, view); output.position = mul(output.position, proj); } else { input.position.x = input.instancePosition1.x; input.position.y = input.instancePosition1.y; input.position.z = input.instancePosition1.z; output.position = mul(input.position, world); output.position = mul(output.position, view); output.position = mul(output.position, proj); } output.color = float4(1,1,1,1);//input.color; output.tex = input.tex; output.normal = mul(input.normal, world); output.normal = normalize(output.normal); return output; } WHAT IT SHOULD LOOK LIKE (down below) - pic of chunk data that are drawn individually - more draw calls as each instance has its own draw calls...But this tiny picture shows instanced chunks with 4096 total instances. Each object created has 64 instances and there is 64 objects. There is 4096 draw calls in here at which point you can argue those aren't really instanced at all but they are! Each instance has its own draw call in order to modify the vertexes and indexes of each instances. It's a very bad programing test and no one should ever attempt this as it's completely useless... I mean, I could probably have better results even without instancing the chunks. WHAT IT LOOKS RIGHT NOW (down below) - I am almost there but again it's not working yet. I am able to send chunk data another way instead of a constant buffer and it seems to do "half" of the job. I'm gonna keep at it. 1 draw call and i could make the terrain as big as I want it. Same thing with the chunks, 64 objects and 64 instances per object. BUT there is only 64 draw calls here hehe. Of course, I benchmarking at the same time and the final version won't be tiny chunksBytes of 4*4*4 by instances 4*4*4 by objects 4*4*4, they will be bigger. As you can see, I got some good results finally where the chunks are correctly aligned and it seems that they are in the right position, but the chunks are missing bytes... I am wondering if it is a padding/packing issue because again, I went over the c# script many times to check the index position and it seems fine. Thanks for the response DMGregory. By the way, I am NOW using floats as the inputElements. Each float contains 16 digits that are made up of bytes 1 and 0. Each bytes represent if the chunkBytes faces should be drawn or not. The inputElement is instanced and 4 floats of 16 digits gives me 64 .... wow wait a minute. is this where I am doing it wrong? brb on this I am building the VertexBufferBinding with an array of floats dismantled into a single float containing 16 digits for each slot. In the shader, i am accessing the vertexBinding and it really is giving me the correct float bytes, i think, for each instance. So everything should be ok. but its not ok. I originally had posted in the beginner section but decided to change it to another thread. I accidentally "hid" the original post and I don't know how to retrieve it again. Thank you for reading and helping. nine https://ift.tt/eA8V8J
I am using the same vertex shader and pixel shader for my instances. I am sending ONE FLAT array that contains all the instanced chunk bytes that make the cube of the Minecraft terrain. My goal is to make ONE DRAW CALL... Nothing is working. I am able to use an input element that has the specific index of the vertex logged in memory so all of the instances vertexes share the same index. It should be super easy after that to fetch the byte 0 or 1 inside of the flat chunk array that contains all of the data. cbuffer MatrixBuffer :register(b0) { float4x4 world; float4x4 view; float4x4 proj; }; struct VertexInputType { float4 position : POSITION; float4 indexPos : POSITION1; float4 color : COLOR; float3 normal : NORMAL; float2 tex : TEXCOORD; float3 dummyPad : NORMAL1; float4 indexPosMain : INSTANCEPOSITION; float4 instancePosition1 : INSTANCEPOSITION1; }; struct PixelInputType { float4 position : SV_POSITION; float4 color : COLOR; float3 normal : NORMAL; float2 tex : TEXCOORD; }; float planeSize = 0.1f; static int mapWidth = 4; static int mapHeight = 4; static int mapDepth = 4; static int tinyChunkWidth = 4; static int tinyChunkHeight = 4; static int tinyChunkDepth = 4; //[maxvertexcount(96)] PixelInputType TextureVertexShader(VertexInputType input) { PixelInputType output; input.position.w = 1.0f; //int mainX = input.indexPosMain.x; //int mainY = input.indexPosMain.y; //int mainZ = input.indexPosMain.z; int x = (input.indexPos.x); int y = (input.indexPos.y); int z = (input.indexPos.z); // if frac is NOT good then I use something else. // 0.234f * 10 = 2.34f // floored = index1 // 0.234f * 10 = 2.34f // frac = 0.34f * 10 and then floored = index2 // 0.234f * 100 = 23.4f // frac = 0.4f * 10 and then floored = index3 // 0.2345f * 1000 = 234.5 //fra = 0.5f * 10 and then floored = index4 float currentMapData; float currentByte; int currentIndex = x + tinyChunkWidth * (y + tinyChunkHeight * z); if(currentIndex >= 0 && currentIndex <= 15) { currentMapData = input.indexPosMain.x; currentIndex = currentIndex; currentIndex = 15-currentIndex; } else if(currentIndex >= 16 && currentIndex <= 31) { currentMapData = input.indexPosMain.y; currentIndex = 31 - currentIndex; currentIndex = 15-currentIndex; } else if(currentIndex >= 32 && currentIndex <= 47) { currentMapData = input.indexPosMain.z; currentIndex = 47 - currentIndex; currentIndex = 15-currentIndex; } else if(currentIndex >= 48 && currentIndex <= 63) { currentMapData = input.indexPosMain.w; currentIndex = 63 - currentIndex; currentIndex = 15 - currentIndex; } if(currentIndex == 0) { float before = currentMapData * 0.1f; float newIndex1 = round(before); float lastIndex = before - newIndex1; currentByte = round(lastIndex * 10); } else { int tempData = currentMapData; for(int i = 0;i < 15-currentIndex; i++) { tempData = currentMapData * 0.1f; currentMapData = round(tempData); } float before = currentMapData * 0.1f; float newIndex1 = round(before); float lastIndex = before - newIndex1; float otherByte = lastIndex * 10; currentByte = round(otherByte); } int current = currentByte; if(current == 1) //current >= 5 || wtf { input.position.x += input.instancePosition1.x; input.position.y += input.instancePosition1.y; input.position.z += input.instancePosition1.z; output.position = mul(input.position, world); output.position = mul(output.position, view); output.position = mul(output.position, proj); } else { input.position.x = input.instancePosition1.x; input.position.y = input.instancePosition1.y; input.position.z = input.instancePosition1.z; output.position = mul(input.position, world); output.position = mul(output.position, view); output.position = mul(output.position, proj); } output.color = float4(1,1,1,1);//input.color; output.tex = input.tex; output.normal = mul(input.normal, world); output.normal = normalize(output.normal); return output; } WHAT IT SHOULD LOOK LIKE (down below) - pic of chunk data that are drawn individually - more draw calls as each instance has its own draw calls...But this tiny picture shows instanced chunks with 4096 total instances. Each object created has 64 instances and there is 64 objects. There is 4096 draw calls in here at which point you can argue those aren't really instanced at all but they are! Each instance has its own draw call in order to modify the vertexes and indexes of each instances. It's a very bad programing test and no one should ever attempt this as it's completely useless... I mean, I could probably have better results even without instancing the chunks. WHAT IT LOOKS RIGHT NOW (down below) - I am almost there but again it's not working yet. I am able to send chunk data another way instead of a constant buffer and it seems to do "half" of the job. I'm gonna keep at it. 1 draw call and i could make the terrain as big as I want it. Same thing with the chunks, 64 objects and 64 instances per object. BUT there is only 64 draw calls here hehe. Of course, I benchmarking at the same time and the final version won't be tiny chunksBytes of 4*4*4 by instances 4*4*4 by objects 4*4*4, they will be bigger. As you can see, I got some good results finally where the chunks are correctly aligned and it seems that they are in the right position, but the chunks are missing bytes... I am wondering if it is a padding/packing issue because again, I went over the c# script many times to check the index position and it seems fine. Thanks for the response DMGregory. By the way, I am NOW using floats as the inputElements. Each float contains 16 digits that are made up of bytes 1 and 0. Each bytes represent if the chunkBytes faces should be drawn or not. The inputElement is instanced and 4 floats of 16 digits gives me 64 .... wow wait a minute. is this where I am doing it wrong? brb on this I am building the VertexBufferBinding with an array of floats dismantled into a single float containing 16 digits for each slot. In the shader, i am accessing the vertexBinding and it really is giving me the correct float bytes, i think, for each instance. So everything should be ok. but its not ok. I originally had posted in the beginner section but decided to change it to another thread. I accidentally "hid" the original post and I don't know how to retrieve it again. Thank you for reading and helping. nine
from GameDev.net https://ift.tt/2OCvB9Z
from GameDev.net https://ift.tt/2OCvB9Z
ليست هناك تعليقات