forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   С# (http://forum.boolean.name/forumdisplay.php?f=128)
-   -   Volume Rendering на XNA (Texture3D) (http://forum.boolean.name/showthread.php?t=14398)

ІГРОГРАЙКО 10.03.2011 23:15

Volume Rendering на XNA (Texture3D)
 
Вложений: 1
Привет всем!
У меня сильно наболел вопрос.:wild: Могу ли я конец концов пользоватса класом Texture3D для создания объемной текстуры с моей ничтожной Nvidia 5200 FX? (макс. шейдеры - 2.0)

Потому что при создании екземпляра:
Код:

public Texture3D (
        GraphicsDevice graphicsDevice,
        int width,
        int height,
        int depth,
        int numberLevels,
        TextureUsage usage,
        SurfaceFormat format
)

ошибка:

Вложение 12925

Кто небудь делал Volume Rendering на XNA?
Есть хороший пример тут. Но он у меня не работает и оч сложный...

Есть примеры создания 3Д Текстур на DirectX, OpenGL где не требуютса шейдеры 3.0. Но мне нужно сделать ето на XNA.

Посоветуйте мне как справитса с етой задачей. Пожалуйста!

Mr_F_ 10.03.2011 23:22

Ответ: Volume Rendering на XNA (Texture3D)
 
Цитата:

Но он у меня не работает и оч сложный...
пример оч просто реализован, я его имплементировал, только не на ХНА. там же код шейдера есть. тебе остаётся только организовать несколько пассов в разные таргеты.

Цитата:

ошибка:
можно в принципе попробовать хранить 3д текстуру не в виде 3д текстуры, а в виде атласа, где все слои поочерёдно. но придётся немного изменить шейдер.

а ваще накопил бы 100 баксов и купил повменяемее видюху.

ABTOMAT 10.03.2011 23:31

Ответ: Volume Rendering на XNA (Texture3D)
 
Цитата:

Сообщение от Mr_F_ (Сообщение 182270)
а ваще накопил бы 100 баксов и купил повменяемее видюху.

По-моему придётся весь комп менять лол. Видях на AGP уже не делают. Или искать по барахолкам что-нибудь типа GF7600















ІГРОГРАЙКО 11.03.2011 00:17

Ответ: Volume Rendering на XNA (Texture3D)
 
Спасибо за незамедлительный ответ!
Цитата:

Сообщение от Mr_F_ (Сообщение 182270)
пример оч просто реализован, я его имплементировал, только не на ХНА. там же код шейдера есть. тебе остаётся только организовать несколько пассов в разные таргеты.

Я пробовал изменять шейдер но ошибка та же.
Цитата:

Сообщение от Mr_F_ (Сообщение 182270)
можно в принципе попробовать хранить 3д текстуру не в виде 3д текстуры, а в виде атласа, где все слои поочерёдно. но придётся немного изменить шейдер.

Что ти имеешь в виду (атлас)? хранить как масив Texture2D?
Цитата:

Сообщение от Mr_F_ (Сообщение 182270)
а ваще накопил бы 100 баксов и купил повменяемее видюху.

А вот ето здесь не к чему. В первых Volume Rendering доступен и на видяхах похуже моей, во вторих АВТОМАТ прав, и ето не сильно изменит результат, так как мне и нужно добитса Volume Rendering на видео с шейдерами 2.0.

Есть еще какие ни-ть предложения. Или мне придетса писать собственный клас 3Д Текстур?:4to:

pax 11.03.2011 00:27

Ответ: Volume Rendering на XNA (Texture3D)
 
Почему SurfaceFormat.Vector4? твоя видеокарта конечно не будет поддерживать
Цитата:

(IEEE format) 128-bit float format using 32 bits for each channel (alpha, blue, green, red).
Попробуй другой, типа HalfVector4 или на худой конец Color

Mr_F_ 11.03.2011 00:32

Ответ: Volume Rendering на XNA (Texture3D)
 
Цитата:

Что ти имеешь в виду (атлас)? хранить как масив Texture2D?
нет, в смысле у тебя одна большая 2д текстура, в которой лежат слои 3д текстуры по очереди. в шейдере смещаешь текскоорды - получаешь нужный кусок.

ІГРОГРАЙКО 11.03.2011 00:49

Ответ: Volume Rendering на XNA (Texture3D)
 
Вложений: 1
Спасибо!

SurfaceFormat.Color - пошло!
Только теперь надо как нибудь переделать метод загрузки .RAW:

Код:

        private void loadRAWFile8(FileStream file)
        {
            BinaryReader reader = new BinaryReader(file);

            byte[] buffer = new byte[mWidth * mHeight * mDepth];
            int size = sizeof(byte);

            reader.Read(buffer, 0, size * buffer.Length);

            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(0, 0, 0, (float)buffer[i] / byte.MaxValue);
            }

            mVolume.SetData(mScalars);
            mEffect.Parameters["Volume"].SetValue(mVolume);
        }

И наверно надо написать свой шейдер...<O>

К стате! Кто небудь пробовал загружать RAW с параметрами у файле DAT?
Вот как здесь:
Вложение 12926

ІГРОГРАЙКО 13.03.2011 13:59

Ответ: Volume Rendering на XNA (Texture3D)
 
Вложений: 2
Всем Привет!

У меня возник еще один вопрос:

Код:

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 = LINEAR;
        MagFilter = LINEAR;
        MipFilter = LINEAR;
       
        AddressU = Border;                                // border sampling in U
    AddressV = Border;                                // border sampling in V
    BorderColor = float4(0,0,0,0);        // outside of border should be black
};

sampler2D BackS = sampler_state
{
        Texture = <Back>;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
        MipFilter = LINEAR;
       
        AddressU = Border;                                // border sampling in U
    AddressV = Border;                                // 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 = Border;                                // border sampling in U
    AddressV = Border;                                // border sampling in V
    AddressW = Border;
    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(input.texC, 1.0f);
}

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).rgb;
    float3 back = tex2D(BackS, texC).rgb;
       
        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(front, 0);
   
    float4 dst = float4(0, 0, 0, 0);
    float4 src = 0;
   
    float value = 0;
       
        float3 Step = dir * StepSize;
   
    for(int i = 0; i < Iterations; i++)
    {
                pos.w = 0;
                value = tex3Dlod(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 >= .95f)
                        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_2_0 PositionVS();
        PixelShader = compile ps_2_0 PositionPS();
    }
}

technique RayCastDirection
{
    pass Pass1
    {               
        VertexShader = compile vs_2_0 PositionVS();
        PixelShader = compile ps_2_0 DirectionPS();
    }
}

technique RayCastSimple
{
    pass Pass1
    {               
        VertexShader = compile vs_2_0 PositionVS();
        PixelShader = compile ps_3_0 RayCastSimplePS();
    }
}

technique WireFrame
{
    pass Pass1
    {               
        VertexShader = compile vs_2_0 PositionVS();
        PixelShader = compile ps_2_0 WireFramePS();
    }
}

В коде шейдера есть функция tex3Dlod которая строит 3Д Текстуру.
Но она не работает на моем компютере, так как нет доступных ей апаратных возможностей (шейдеров 3.0). Но програмка работеат и ее результат:

Вложение 12959

внутри пусто:

Вложение 12961

Что посоветуэте делать???

P.S. На основе примера VolumeRayCasting_101

Помогите пожалуйста!:dontknow:

pax 13.03.2011 14:21

Ответ: Volume Rendering на XNA (Texture3D)
 
Так просто tex3D используй.

ІГРОГРАЙКО 13.03.2011 19:06

Ответ: Volume Rendering на XNA (Texture3D)
 
Заменил:
Код:

value = tex3Dlod(VolumeS, pos).r;
на
Код:

value = tex3D(VolumeS, pos).r;
результат:

Код:

Ошибка        1        Building content threw TimeoutException: FXC took more than 20 seconds to compile!
  в WindowsEffectCompiler.WindowsEffectCompiler.Process(EffectContent input, ContentProcessorContext context) в E:\My Work\XNA to Silverlight\VolumeRayCasting_101\WindowsEffectCompiler\WindowsEffectCompiler.cs:строка 60
  в Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor`2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context)
  в Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAssetWorker(BuildItem item)
  в Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAsset(BuildItem item)
  в Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.RunTheBuild()
  в Microsoft.Xna.Framework.Content.Pipeline.Tasks.BuildContent.RemoteProxy.RunTheBuild(BuildCoordinatorSettings settings, TimestampCache timestampCache, ITaskItem[] sourceAssets, String[]& outputContent, String[]& rebuiltContent, String[]& intermediates, Dictionary`2& dependencyTimestamps, KeyValuePair`2[]& warnings)        E:\My Work\XNA to Silverlight\VolumeRayCasting_101\VolumeRayCasting\Content\Shaders\RayCasting.fx        VolumeRayCasting

Зменяю
Код:

technique RayCastSimple
{
    pass Pass1
    {               
        VertexShader = compile vs_1_0 PositionVS();
        PixelShader = compile ps_3_0 RayCastSimplePS();
    }
}

на
Код:

technique RayCastSimple
{
    pass Pass1
    {               
        VertexShader = compile vs_1_0 PositionVS();
        PixelShader = compile ps_2_0 RayCastSimplePS();
    }
}

Результат:
Код:

Ошибка        2        E:\My Work\XNA to Silverlight\VolumeRayCasting_101\VolumeRayCasting\Content\Shaders\RayCasting.fx(133,9): error X3511: unable to unroll loop, loop does not appear to terminate in a timely manner (33 iterations), use the [unroll(n)] attribute to force an exact higher number
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

Есть еще какие небудь идеи?
Или в XNA нету возможности построить 3Д текстуры без шейдеров 3.0???

С нетерпением жду ваших ответов!

pax 13.03.2011 20:14

Ответ: Volume Rendering на XNA (Texture3D)
 
у тебя проблемы с циклом, а не с этой командой, читай внимательнее ошибки. Попробуй явно задать количество итераций.

ІГРОГРАЙКО 13.03.2011 21:07

Ответ: Volume Rendering на XNA (Texture3D)
 
Вложений: 1
Да... Спасибо! Но!

Код:

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(front, 0);
   
    float4 dst = float4(0, 0, 0, 0);
    float4 src = 0;
   
    float value = 0;
       
        float3 Step = dir * StepSize;
   
    for(int i = 0; i < 10; 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 >= .95f)
                        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 RayCastSimple
{
    pass Pass1
    {               
        VertexShader = compile vs_1_0 PositionVS();
        PixelShader = compile ps_2_0 RayCastSimplePS();
    }
}
}

Все одно вылетает из за:

Код:

Ошибка        2        E:\My Work\XNA to Silverlight\VolumeRayCasting_101\VolumeRayCasting\Content\Shaders\RayCasting.fx(136,9): error X5426: Shader uses texture addressing operations in a dependency chain that is too complex for the target shader model (ps_2_0) to handle. 
ID3DXEffectCompiler: Compilation failed

        E:\My Work\XNA to Silverlight\VolumeRayCasting_101\VolumeRayCasting\Content\Shaders\RayCasting.fx        VolumeRayCasting

И если изменяю ps_2_0 на ps_3_0 Опять:

Вложение 12965

Что с етим делать???:dontknow:

pax 13.03.2011 21:49

Ответ: Volume Rendering на XNA (Texture3D)
 
Попробуй начать не с 10, а еще меньше посмотри на сколько можно для SM2.0,
Получается, что у тебя много операций выборки текстур.

И еще, шейдер не генерирует 3d текстуру, а делает из нее выборку. Позаботься, чтобы текстура была задана и не черная.

ІГРОГРАЙКО 14.03.2011 11:24

Ответ: Volume Rendering на XNA (Texture3D)
 
Вложений: 1
Да рах ты прав!
Запустилось у меня, но отрисовует только один шар:

Вложение 12972

Если:

Код:

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 < 2; 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;
}

то вилетает:

Код:

Ошибка        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

Что с етим делать?
Как быть? :dontknow:

pax 14.03.2011 12:23

Ответ: Volume Rendering на XNA (Texture3D)
 
ps3.0 либо оптимизация расчетов. У тебя превышен лимит инструкций для пиксельного шейдера 2.0 (у тебя 70 из 64 возможных).


Часовой пояс GMT +4, время: 18:12.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot