|
С# Средство разработки на платформе .Net |
15.03.2011, 00:47
|
#16
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
Сообщение от pax
ps3.0 либо оптимизация расчетов. У тебя превышен лимит инструкций для пиксельного шейдера 2.0 (у тебя 70 из 64 возможных).
|
Врят ли ето поможет..
А если я напишу сам функцию построения 3Д текстуры без использования tex3D???
Не знаю зделаю ли я ето так же легко как на Блице но принцып 3Д текстуры я понял.
Например: - Создам 3 массивы полигонов (NX, NY и NZ).
- К каждому полигону массива NX привяжу текстуру с файла соотвецтвенного слоя (с двух сторон).
- Текстуру для полигонов масива NY и NZ сгенерирую как CLAMP UV и CLAMP VU тексур слоев массива NX.
Наверно тогда компилятор не будет возмущатса по поводу превишения лимита инструкций.
Как вам моя идея???
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
Последний раз редактировалось ІГРОГРАЙКО, 16.03.2011 в 05:02.
|
(Offline)
|
|
17.03.2011, 12:19
|
#17
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
Сделал я то что думал.
И вот как оно виглядит:
У клас Volume.cs дописал:
VertexBuffer vertexBufferNX; VertexBuffer vertexBufferNY; VertexBuffer vertexBufferNZ; VertexPositionColor[] pointListNX; VertexPositionColor[] pointListNY; VertexPositionColor[] pointListNZ; int pointsNX; int pointsNY; int pointsNZ; short[] triangleStripIndicesNX, triangleStripIndicesNY, triangleStripIndicesNZ; ... protected override void LoadContent() { base.LoadContent(); pointsNX = 4 * mHeight; pointsNY = 4 * mWidth; pointsNZ = 4 * mDepth; pointListNX = new VertexPositionColor[pointsNX]; pointListNY = new VertexPositionColor[pointsNY]; pointListNZ = new VertexPositionColor[pointsNZ]; for (int ny = 0; ny < mHeight; ny++) { for (int nx = 0; nx < 2; nx++) { for (int nz = 0; nz < 2; nz++) { pointListNX[(ny * 4) + (nx * 2) + nz] = new VertexPositionColor(new Vector3((float)nx, (float)(1.0f / mHeight) * ny, (float)nz),Color.White); } } } for (int nx = 0; nx < mWidth; nx++) { for (int ny = 0; ny < 2; ny++) { for (int nz = 0; nz < 2; nz++) { pointListNY[(nx * 4) + (ny * 2) + nz] = new VertexPositionColor(new Vector3((float)(1.0f / mWidth) * nx, (float)ny, (float)nz),Color.White); } } } for (int nz = 0; nz < mDepth; nz++) { for (int nx = 0; nx < 2; nx++) { for (int ny = 0; ny < 2; ny++) { pointListNZ[(nz * 4) + (nx * 2) + ny] = new VertexPositionColor(new Vector3((float)nx, (float)ny, (float)(1.0f / mDepth) * nz),Color.White); } } } vertexBufferNX = new VertexBuffer(Game.GraphicsDevice, VertexPositionTexture.SizeInBytes * pointListNX.Length, BufferUsage.None); vertexBufferNX.SetData<VertexPositionColor>(pointListNX); vertexBufferNY = new VertexBuffer(Game.GraphicsDevice, VertexPositionTexture.SizeInBytes * pointListNY.Length, BufferUsage.None); vertexBufferNY.SetData<VertexPositionColor>(pointListNY); vertexBufferNZ = new VertexBuffer(Game.GraphicsDevice, VertexPositionTexture.SizeInBytes * pointListNZ.Length, BufferUsage.None); vertexBufferNZ.SetData<VertexPositionColor>(pointListNZ); triangleStripIndicesNX = new short[pointsNX]; triangleStripIndicesNY = new short[pointsNY]; triangleStripIndicesNZ = new short[pointsNZ]; for (int y = 0; y < mHeight; y++) { for (int i = 0; i < 4; i++) { triangleStripIndicesNX[(y * 4) + i] = (short)((y * 4) + i); } } for (int x = 0; x < mWidth; x++) { for (int i = 0; i < 4; i++) { triangleStripIndicesNY[(x * 4) + i] = (short)((x * 4) + i); } } for (int z = 0; z < mDepth; z++) { for (int i = 0; i < 4; i++) { triangleStripIndicesNZ[(z * 4) + i] = (short)((z * 4) + i); } } }
И метод отрисовки полигонов:
private void DrawTriangleStrip() { for (int i = 0; i < pointListNX.Length; i++)pointListNX[i].Color = new Color(1f,1f,1f,0.01f); for (int nx = 0; nx < mHeight; nx++) { GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>( PrimitiveType.TriangleStrip, pointListNX, nx*4, // vertex buffer offset to add to each element of the index buffer 4, // number of vertices to draw triangleStripIndicesNX, nx*4, // first index element to read 2 // number of primitives to draw ); } for (int i = 0; i < pointListNY.Length; i++)pointListNY[i].Color = new Color(1f, 1f, 1f, 0.01f); for (int ny = 0; ny < mWidth; ny++) { GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>( PrimitiveType.TriangleStrip, pointListNY, ny*4, // vertex buffer offset to add to each element of the index buffer 4, // number of vertices to draw triangleStripIndicesNY, ny*4, // first index element to read 2 // number of primitives to draw ); } for (int i = 0; i < pointListNZ.Length; i++)pointListNZ[i].Color = new Color(1f, 1f, 1f, 0.01f); for (int nz = 0; nz < mDepth; nz++) { GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>( PrimitiveType.TriangleStrip, pointListNZ, nz*4, // vertex buffer offset to add to each element of the index buffer 4, // number of vertices to draw triangleStripIndicesNZ, nz*4, // first index element to read 2 // number of primitives to draw ); } }
Подскажите только как убрать ети светла (R,G,B )???
VolumeRayCasting_101.rar
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
17.03.2011, 12:53
|
#18
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
Сообщение от ІГРОГРАЙКО
Подскажите только как убрать ети светла (R,G,B )???
|
Эмм...
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
17.03.2011, 15:42
|
#19
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
Ета цветовая фигня была в шейдере:
float4 PositionPS(VertexShaderOutput input) : COLOR0
{
return float4(input.texC, 1.0f);
}
Теперь все ровно:
float4 PositionPS(VertexShaderOutput input) : COLOR0
{
return float4(1.0f, 1.0f, 1.0f, 0.1f);
}
Ну теперь самое сложное. Надо написать новую технику в шейдере, чтоб она привязывала каждий слой текстуры с файла к соотвецтвующему полигону...
Есть неплохой пример: How To: Create Custom Texture Effects
Етот кусок кода привязывает текстуру к всем граням куба:
// This code would go between a device BeginScene-EndScene block.
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
GraphicsDevice.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
0,
0,
cubeVertices.Length,
0,
12
);
pass.End();
}
effect.End();
Но мне нужно привязывать каждому полигону соответствующую текстуру с RAW файла.
Вопрос:
1. Как добыть тексуры с файла для каждого полигона?
2. Как привязать каждому полигону отдельную текстуру?
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
17.03.2011, 23:51
|
#20
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
Помогите мне пожалуйста!
Я не знаю как мне добыть масив Texture2D с RAW файла
Етот метод:
private void loadRAWFile16(FileStream file)
{
BinaryReader reader = new BinaryReader(file);
ushort[] buffer = new ushort[mWidth * mHeight * mDepth];
for (int i = 0; i < buffer.Length; i++)
buffer[i] = reader.ReadUInt16();
reader.Close();
//scale the scalar values to [0, 1]
mScalars = new float[buffer.Length];
for (int i = 0; i < buffer.Length; i++)
{
mScalars[i] = (float)buffer[i] / byte.MaxValue;
}
mVolume.SetData(mScalars);
mEffect.Parameters["Volume"].SetValue(mVolume);
}
Считывает с RAW файла даные и заполняет екземпляр mVolume класа Texture3D:
mVolume = new Texture3D(Game.GraphicsDevice, mWidth, mHeight, mDepth, 0, TextureUsage.None, SurfaceFormat.Single);
А потом отсилает в шейдер к параметру Volume с типом Texture3D:
float4x4 World;
float4x4 WorldViewProj;
float4x4 WorldInvTrans;
float3 StepSize;
int Iterations;
int Side = 2;
float4 ScaleFactor;
texture2D Front;
texture2D Back;
texture3D Volume;
sampler2D FrontS = sampler_state
{
Texture = <Front>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = LINEAR;
AddressU = CLAMP; // border sampling in U
AddressV = CLAMP; // border sampling in V
BorderColor = float4(0,0,0,0); // outside of border should be black
};
sampler2D BackS = sampler_state
{
Texture = <Back>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = LINEAR;
AddressU = CLAMP; // border sampling in U
AddressV = CLAMP; // border sampling in V
BorderColor = float4(0,0,0,0); // outside of border should be black
};
sampler3D VolumeS = sampler_state
{
Texture = <Volume>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = CLAMP; // border sampling in U
AddressV = CLAMP; // border sampling in V
AddressW = CLAMP;
BorderColor = float4(0,0,0,0); // outside of border should be black
};
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 texC : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float3 texC : TEXCOORD0;
float4 pos : TEXCOORD1;
};
VertexShaderOutput PositionVS(VertexShaderInput input)
{
VertexShaderOutput output;
output.Position = mul(input.Position * ScaleFactor, WorldViewProj);
output.texC = input.Position;
output.pos = output.Position;
return output;
}
float4 PositionPS(VertexShaderOutput input) : COLOR0
{
return float4(1.0f, 1.0f, 1.0f, 0.1f);
}
float4 WireFramePS(VertexShaderOutput input) : COLOR0
{
return float4(1.0f, .5f, 0.0f, .85f);
}
//draws the front or back positions, or the ray direction through the volume
float4 DirectionPS(VertexShaderOutput input) : COLOR0
{
float2 texC = input.pos.xy /= input.pos.w;
texC.x = 0.5f*texC.x + 0.5f;
texC.y = -0.5f*texC.y + 0.5f;
float3 front = tex2D(FrontS, texC);
float3 back = tex2D(BackS, texC);
if(Side == 0)
{
return float4(front, .9f);
}
if(Side == 1)
{
return float4(back, .9f);
}
return float4(back - front, .9f);
}
float4 RayCastSimplePS(VertexShaderOutput input) : COLOR0
{
//calculate projective texture coordinates
//used to project the front and back position textures onto the cube
float2 texC = input.pos.xy /= input.pos.w;
texC.x = 0.5f*texC.x + 0.5f;
texC.y = -0.5f*texC.y + 0.5f;
float3 front = tex2D(FrontS, texC).xyz;
float3 back = tex2D(BackS, texC).xyz;
float3 dir = normalize(back - front);
float4 pos = float4(input.texC, 0);
float4 dst = float4(0, 0, 0, 0);
float4 src = 0;
float value = 0;
float3 Step = dir * StepSize;
for(int i = 0; i < 1; i++)
{
pos.w = 0;
value = tex3D(VolumeS, pos).r;
src = (float4)value;
src.a *= .1f; //reduce the alpha to have a more transparent result
//this needs to be adjusted based on the step size
//i.e. the more steps we take, the faster the alpha will grow
//Front to back blending
// dst.rgb = dst.rgb + (1 - dst.a) * src.a * src.rgb
// dst.a = dst.a + (1 - dst.a) * src.a
//src.rgb *= src.a;
dst = (1.0f - dst.a)*src + dst;
//break from the loop when alpha gets high enough
if(dst.a >= .9f)
break;
//advance the current position
pos.xyz += Step;
//break if the position is greater than <1, 1, 1>
if(pos.x > 1.0f || pos.y > 1.0f || pos.z > 1.0f)
break;
}
return dst;
}
technique RenderPosition
{
pass Pass1
{
VertexShader = compile vs_1_0 PositionVS();
PixelShader = compile ps_2_0 PositionPS();
}
}
technique RayCastDirection
{
pass Pass1
{
VertexShader = compile vs_1_0 PositionVS();
PixelShader = compile ps_2_0 DirectionPS();
}
}
technique RayCastSimple
{
pass Pass1
{
VertexShader = compile vs_1_0 PositionVS();
PixelShader = compile ps_2_0 RayCastSimplePS();
}
}
technique WireFrame
{
pass Pass1
{
VertexShader = compile vs_1_0 PositionVS();
PixelShader = compile ps_2_0 WireFramePS();
}
}
Вопрос:
Как зделать так чтобы даные с файла RAW наполнили массив Texture2D???
Жду ваших предложений!!!
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
18.03.2011, 05:51
|
#21
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
Ну вот я и релизовал часть свого хитрого плана .
Метод загрузки RAW файла я переделал, чтоб он создавал масив Texture2D. Но есть проблема с параметром шейдера в которий я хочу сливать масив текстур. А точнее говоря я не знаю как переслать массив текстур в шейдер...
Код метода:
. private void loadRAWFile16(FileStream file) { BinaryReader reader = new BinaryReader(file); ushort[] buffer = new ushort[fWidth * fHeight * fDepth]; for (int i = 0; i < buffer.Length; i++) buffer[i] = reader.ReadUInt16(); reader.Close(); //scale the scalar values to [0, 1] mScalars = new Color[buffer.Length]; for (int i = 0; i < buffer.Length; i++) { mScalars[i] = new Color(1f, 0f, 0f, ((float)buffer[i] / byte.MaxValue) * 0.1f); } int wd = mVolume[0].Width; int hg = mVolume[0].Height; for (int i = 0; i < mHeight; i++) { int start = i * (wd * hg); mVolume[i].SetData<Color>(mScalars, start, wd * hg, SetDataOptions.None); mVolume[i].Save("IMG_" + i + ".tga", ImageFileFormat.Tga); mEffect.Parameters["Volume"].SetValue(mVolume[i]); } mScalars = null; }
Код шейдера:
float4x4 World;
float4x4 WorldViewProj;
float4x4 WorldInvTrans;
float3 StepSize;
int Iterations;
int Side = 2;
float4 ScaleFactor;
texture2D Front;
texture2D Back;
texture2D[] Volume;
sampler2D FrontS = sampler_state
{
Texture = <Front>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = LINEAR;
AddressU = CLAMP; // border sampling in U
AddressV = CLAMP; // border sampling in V
BorderColor = float4(0,0,0,0); // outside of border should be black
};
sampler2D BackS = sampler_state
{
Texture = <Back>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = LINEAR;
AddressU = CLAMP; // border sampling in U
AddressV = CLAMP; // border sampling in V
BorderColor = float4(0,0,0,0); // outside of border should be black
};
sampler3D VolumeS = sampler_state
{
Texture = <Volume>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = CLAMP; // border sampling in U
AddressV = CLAMP; // border sampling in V
AddressW = CLAMP;
BorderColor = float4(0,0,0,0); // outside of border should be black
};
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 texC : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float3 texC : TEXCOORD0;
float4 pos : TEXCOORD1;
};
VertexShaderOutput PositionVS(VertexShaderInput input)
{
VertexShaderOutput output;
output.Position = mul(input.Position * ScaleFactor, WorldViewProj);
output.texC = input.Position;
output.pos = output.Position;
return output;
}
float4 PositionPS(VertexShaderOutput input) : COLOR0
{
return float4(1.0f, 1.0f, 1.0f, 0.1f);
}
float4 WireFramePS(VertexShaderOutput input) : COLOR0
{
return float4(1.0f, .5f, 0.0f, .85f);
}
//draws the front or back positions, or the ray direction through the volume
float4 DirectionPS(VertexShaderOutput input) : COLOR0
{
float2 texC = input.pos.xy /= input.pos.w;
texC.x = 0.5f*texC.x + 0.5f;
texC.y = -0.5f*texC.y + 0.5f;
float3 front = tex2D(FrontS, texC);
float3 back = tex2D(BackS, texC);
if(Side == 0)
{
return float4(front, .9f);
}
if(Side == 1)
{
return float4(back, .9f);
}
return float4(back - front, .9f);
}
float4 RayCastSimplePS(VertexShaderOutput input) : COLOR0
{
//calculate projective texture coordinates
//used to project the front and back position textures onto the cube
float2 texC = input.pos.xy /= input.pos.w;
texC.x = 0.5f*texC.x + 0.5f;
texC.y = -0.5f*texC.y + 0.5f;
float3 front = tex2D(FrontS, texC).xyz;
float3 back = tex2D(BackS, texC).xyz;
float3 dir = normalize(back - front);
float4 pos = float4(input.texC, 0);
float4 dst = float4(0, 0, 0, 0);
float4 src = 0;
float value = 0;
float3 Step = dir * StepSize;
for(int i = 0; i < 1; i++)
{
pos.w = 0;
value = tex3D(VolumeS, pos).r;
src = (float4)value;
src.a *= .1f; //reduce the alpha to have a more transparent result
//this needs to be adjusted based on the step size
//i.e. the more steps we take, the faster the alpha will grow
//Front to back blending
// dst.rgb = dst.rgb + (1 - dst.a) * src.a * src.rgb
// dst.a = dst.a + (1 - dst.a) * src.a
//src.rgb *= src.a;
dst = (1.0f - dst.a)*src + dst;
//break from the loop when alpha gets high enough
if(dst.a >= .9f)
break;
//advance the current position
pos.xyz += Step;
//break if the position is greater than <1, 1, 1>
if(pos.x > 1.0f || pos.y > 1.0f || pos.z > 1.0f)
break;
}
return dst;
}
technique RenderPosition
{
pass Pass1
{
VertexShader = compile vs_1_0 PositionVS();
PixelShader = compile ps_2_0 PositionPS();
}
}
technique RayCastDirection
{
pass Pass1
{
VertexShader = compile vs_1_0 PositionVS();
PixelShader = compile ps_2_0 DirectionPS();
}
}
technique RayCastSimple
{
pass Pass1
{
VertexShader = compile vs_1_0 PositionVS();
PixelShader = compile ps_2_0 RayCastSimplePS();
}
}
technique WireFrame
{
pass Pass1
{
VertexShader = compile vs_1_0 PositionVS();
PixelShader = compile ps_2_0 WireFramePS();
}
}
Вылетает ошибка:
Ошибка 2 E:\My Work\XNA to Silverlight\VolumeRayCasting_101\VolumeRayCasting\Content\Shaders\RayCasting.fx(15,10): error X3000: syntax error: unexpected token '['
E:\My Work\XNA to Silverlight\VolumeRayCasting_101\VolumeRayCasting\Content\Shaders\RayCasting.fx VolumeRayCasting
Я понял что так делать нелзя. Но а как нужно я не знаю.
Подскажыте мне как поступить?
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
18.03.2011, 11:16
|
#22
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
нельзя в шейдере использовать массив текстур, ты же создавал 3d текстуру, почему отказался то?
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
18.03.2011, 17:37
|
#23
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
Сообщение от pax
нельзя в шейдере использовать массив текстур, ты же создавал 3d текстуру, почему отказался то?
|
Отказался из за етого:
Ошибка 2 E:\My Work\XNA to Silverlight\VolumeRayCasting_101\VolumeRayCasting\Content\Shaders\RayCasting.fx(112,8): error X5608: Compiled shader code uses too many arithmetic instruction slots (70). Max. allowed by the target (ps_2_0) is 64.
E:\My Work\XNA to Silverlight\VolumeRayCasting_101\VolumeRayCasting\Content\Shaders\RayCasting.fx(187,23): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression
ID3DXEffectCompiler: Compilation failed
E:\My Work\XNA to Silverlight\VolumeRayCasting_101\VolumeRayCasting\Content\Shaders\RayCasting.fx VolumeRayCasting
Ты говорил про оптимизацыю рашчетов, но ето поможет отрисовать только второй слой, а что делать с остальными 126??? Если вы мне предложите какой нибудь иной способ (полегче моего) создать и отрисовать 3Д текстуру я буду оч благодарен!
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
19.03.2011, 06:47
|
#24
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
Я опять обращаюсь к вам за помощю!
У меня есть 3 масива цветных даных с RAW файла:
private Color[] mTextDataNX;
private Color[] mTextDataNY;
private Color[] mTextDataNZ;
Массив текстур:
private Texture2D[] mTexture;
mTexture = new Texture2D[fDepth];
for (int i = 0; i < fDepth; i++)
{
mTexture[i] = new Texture2D(Game.GraphicsDevice, fWidth, fHeight, 0, TextureUsage.None, SurfaceFormat.Color);
}
После заполнения масива текстур масивом цветных данных и сохранения их в файлы:
int wd = mTexture[0].Width;
int hg = mTexture[0].Height;
for (int i = 0; i < fHeight; i++)
{
int start = i * (wd * hg);
mTexture[i].SetData<Color>(mTextDataN*, start, wd * hg, SetDataOptions.None);
mTexture[i].Save("IMG_" + i + ".tga", ImageFileFormat.Tga);
}
Я получаю текстуры соотвецтвенных слоев:
mTextDataNX
mTextDataNY
mTextDataNZ
Как мне ети масивы цветных даных переобразовать в 3 большых текстуры? (атласы или как их там...)
Я пробовал:
private Texture2D nTexture;
int source = fWidth * fHeight * fDepth;
int maxHeight = GraphicsDevice.GraphicsDeviceCapabilities.MaxTextureHeight;
int maxWidth = GraphicsDevice.GraphicsDeviceCapabilities.MaxTextureWidth;
for (mHeight = 2; mHeight < maxHeight; mHeight *= 2)
{
mWidth = source / mHeight;
if (mWidth <= maxWidth)
break;
}
nTexture = new Texture2D(Game.GraphicsDevice, mWidth, mHeight, 0, TextureUsage.None, SurfaceFormat.Color);
int wd = nTexture.Width;
int hg = nTexture.Height;
nTexture.SetData<Color>(mTextDataNX, 0, hg * wd, SetDataOptions.None);
nTexture.Save("MAP.tga", ImageFileFormat.Tga);
Но уменя получаетса вот такая фигня:
(оригинал 4096 х 512)
Как ето сделать коректно?
Помогите пожалуйста!
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
09.04.2011, 00:37
|
#25
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
Добрый вечер!
У меня возник вопрос связаный с шейдером.
Код:
float4x4 WorldViewProj;
texture3D Volume;
sampler3D SVolume = sampler_state
{
Texture = <Volume>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
};
struct VS_INPUT
{
float4 Position : POSITION0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float4 pos : TEXCOORD0;
};
VS_OUTPUT PositionVS(VS_INPUT input)
{
VS_OUTPUT output;
output.Position = mul(input.Position, WorldViewProj);
output.pos = input.Position;
return output;
}
float4 PixelShaderFunction(VS_OUTPUT input) : COLOR0
{
float4 texColor = tex3D(SVolume,input.pos);
return texColor;
}
technique BasicView
{
pass Pass1
{
VertexShader = compile vs_1_1 PositionVS();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}
Мне нужно отрезать половину 3Д текстуры. Я подумал, что лучше всего ето можно осуществить умножением Альфа канала 3Д текстури на "0" в заданом промежутке:
float4x4 WorldViewProj;
texture3D Volume;
sampler3D SVolume = sampler_state
{
Texture = <Volume>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
};
struct VS_INPUT
{
float4 Position : POSITION0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float4 pos : TEXCOORD0;
};
VS_OUTPUT PositionVS(VS_INPUT input)
{
VS_OUTPUT output;
output.Position = mul(input.Position, WorldViewProj);
output.pos = input.Position;
return output;
}
float4 PixelShaderFunction(VS_OUTPUT input) : COLOR0
{
float4 outColor;
if(input.Position.x > 0.5f)
outColor = float4(1,1,1,0);
else
outColor = float4(1,1,1,1);
float4 texColor = tex3D(SVolume,input.pos);
return texColor * outColor;
}
technique BasicView
{
pass Pass1
{
VertexShader = compile vs_1_1 PositionVS();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}
Но при построении оно вилетает:
Ошибка 1 Errors compiling C:\Documents and Settings\Володя\Мои документы\Visual Studio 2008\Projects\Vol_Render\Vol_Render\Content\Shaders\VolumeRendering.fx:
C:\Documents and Settings\Володя\Мои документы\Visual Studio 2008\Projects\Vol_Render\Vol_Render\Content\Shaders\VolumeRendering.fx(20): error X4502: invalid reference to input semantic 'POSITION0'
C:\Documents and Settings\Володя\Мои документы\Visual Studio 2008\Projects\Vol_Render\Vol_Render\Content\Shaders\VolumeRendering.fx(52): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression
ID3DXEffectCompiler: Compilation failed C:\Documents and Settings\Володя\Мои документы\Visual Studio 2008\Projects\Vol_Render\Vol_Render\Content\Shaders\VolumeRendering.fx 20 1 Vol_Render
Не понимаю почему???
Помогите исправить ошибку, пожалуйста!
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
09.04.2011, 00:58
|
#26
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Volume Rendering на XNA (Texture3D)
ну так if(input.pos.x > 0.5f)
Ты же специально для этого скопировал значение output.pos = input.Position; в вершинном шейдере. POSITION0 не передать в пиксельный шейдер, только через текстурные слоты.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 13:26.
|