Отрисовка пикселов в DirectX

Тема в разделе "WASM.DirectX", создана пользователем DeepD, 4 окт 2011.

  1. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Доброго всем времени суток.
    Как организовать попиксельную отрисовку модели загруженную откуда-то(из DirectX-файла).
    Конкретно, мне нужно получить координату пиксела и на основании этого покрасить его в соответствующий цвет.
    Есть ли какое решение кроме пиксельных шейдеров?
     
  2. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Точнее мне нужно создать изображение глубины для 3d модели.
     
  3. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Координаты пиксела в мировом пространстве? В чём проблема с шейдерами?
     
  4. Dmitry_Milk

    Dmitry_Milk Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2007
    Сообщения:
    535
    А чем задана 3D модель? полигонами с заданными 3D-координатами, или непрерывной двумерной функцией?
     
  5. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Booster
    Мне нужно получить карту глубин, чтотто вроде этого:
    [​IMG]
    Мне нужен способ, как ее получить(проще всего). Через шейдеры или еще как.
    Dmitry_Milk
    Модель задана полигонами. Загружается из x-файла.
    Используется DirectX9
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    В пиксельном шейдере есть доступ к буферу глубины.
     
  7. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Booster
    Да. Пиксельному шейдеру передаются координаты (x,y,z). Но работать напрямую с ними нельзя.
     
  8. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Можно ли сделать вывод из пиксельного шейдера куда-нибудь кроме экрана?
     
  9. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    DeepD
    А разве поверхности должны быть обязательно "видимыми" ?
    С поверности копируйте и усё (lpSurface ... Pitch * Height).
     
  10. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Это о чём?
     
  11. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Booster

    О координатах позиции отрисовываемой точки.

    Т.е. подобное, например, не прокатывает(программа падает)
    Код (Text):
    1. struct VS_OUTPUT
    2.  {
    3.  float4 Position : POSITION; // vertex position
    4.  float4 Diffuse : COLOR0;
    5.  float2 TextureUV : TEXCOORD0;
    6.  }
    7.  
    8.  
    9.  PS_OUTPUT RenderScenePS( VS_OUTPUT In, uniform bool bTexture )
    10.  {
    11.  PS_OUTPUT Output;
    12.  
    13.  Output.RGBColor = float4(In.Position.x,0,0,0);
    14.  
    15.  return Output;
    16.  }
     
  12. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    DeepD
    Пиксельный шейдер не может принимать семантику POSITION. Если нужно передать позицию, то её нужно копировать в TEXCOORD[n] и тогда её можно использовать. Что касается значения буфера глубины для пикселя, то это легко посчитать. Так как вершинный шейдер переводит мировые координаты в экранные, то глубину в пиксельном можно считать так - lerp(Viewport.MinZ, Viewport.MaxZ, input.pos.z / input.pos.w);
     
  13. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Сделал так:
    Код (Text):
    1. struct VS_OUTPUT
    2. {
    3.     float4 Position   : POSITION;   // vertex position
    4.     float4 Diffuse    : COLOR0;     // vertex diffuse color (note that COLOR0 is clamped from 0..1)
    5.     float2 TextureUV  : TEXCOORD0;  // vertex texture coords
    6.  
    7.     float Depth : TEXCOORD2;  <---Добавленное поле
    8. };
    В конце вершинного шейдера прописал:
    Код (Text):
    1. Output.Depth = lerp(0, 1.0, Output.Position.z / Output.Position.w);
    И сам пиксельный шейдер:
    Код (Text):
    1. PS_OUTPUT RenderScenePS( VS_OUTPUT In,
    2.                          uniform bool bTexture )
    3. {
    4.     PS_OUTPUT Output;  
    5.     Output.RGBColor = float4(In.Depth,0,0,0);  
    6.     return Output;
    7. }
    По идее моя модель должна выводиться в градациях красного (0<In.Depth<1). Но вместо этого она выводится одним цветом(красным)... У меня ошибка?
     
  14. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Это надо считать в пиксельном, где координата интерполируется для конкретного пикселя, а не для всего полигона.
     
  15. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Хорошо. Делаю так:

    Код (Text):
    1. struct VS_OUTPUT
    2. {
    3.     float4 Position   : POSITION;   // vertex position
    4.     float4 Diffuse    : COLOR0;     // vertex diffuse color (note that COLOR0 is clamped from 0..1)
    5.     float2 TextureUV  : TEXCOORD0;  // vertex texture coords
    6.     float4 Position4PS : TEXCOORD1;  <-- Копирую сюда позицию вершины в вершинном шейдере
    7. };
    Код (Text):
    1. PS_OUTPUT RenderScenePS( VS_OUTPUT In,
    2.                          uniform bool bTexture )
    3. {
    4.     PS_OUTPUT Output;
    5.     float f;
    6.     f = lerp(0, 1.0, In.Position4PS.z / In.Position4PS.w);
    7.     Output.RGBColor = float4(f,0,0,0);  
    8.     return Output;
    9. }
    Но когда я запускаю приложоние падает с ошибкой E_FAIL 0x80004005.
    Вероятно из-за строки Output.RGBColor = float4(f,0,0,0)
     
  16. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Падает потому-что шейдер неправильный. POSITION во входе пиксельного шейдера вообще быть не должно. А так надо смотреть более детально, может не только в этом ошибка. Приведите полностью шедеры.

    Кстати, зачем?
    Код (Text):
    1. float f;
    2. f =
     
  17. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Код из примеров к Directx SDK HLSL Sample
    Код (Text):
    1. float4 g_MaterialAmbientColor;      // Material's ambient color
    2. float4 g_MaterialDiffuseColor;      // Material's diffuse color
    3. int g_nNumLights;
    4.  
    5. float3 g_LightDir[3];               // Light's direction in world space
    6. float4 g_LightDiffuse[3];           // Light's diffuse color
    7. float4 g_LightAmbient;              // Light's ambient color
    8.  
    9. texture g_MeshTexture;              // Color texture for mesh
    10.  
    11. float    g_fTime;                   // App's time in seconds
    12. float4x4 g_mWorld;                  // World matrix for object
    13. float4x4 g_mWorldViewProjection;    // World * View * Projection matrix
    14.  
    15.  
    16.  
    17. //--------------------------------------------------------------------------------------
    18. // Texture samplers
    19. //--------------------------------------------------------------------------------------
    20. sampler MeshTextureSampler =
    21. sampler_state
    22. {
    23.     Texture = <g_MeshTexture>;
    24.     MipFilter = LINEAR;
    25.     MinFilter = LINEAR;
    26.     MagFilter = LINEAR;
    27. };
    28.  
    29.  
    30. //--------------------------------------------------------------------------------------
    31. // Vertex shader output structure
    32. //--------------------------------------------------------------------------------------
    33. struct VS_OUTPUT
    34. {
    35.     float4 Position   : POSITION;   // vertex position
    36.     float4 Diffuse    : COLOR0;     // vertex diffuse color (note that COLOR0 is clamped from 0..1)
    37.     float2 TextureUV  : TEXCOORD0;  // vertex texture coords
    38.     float4 Position4PS : TEXCOORD1;
    39.    
    40. };
    41.  
    42.  
    43. //--------------------------------------------------------------------------------------
    44. // This shader computes standard transform and lighting
    45. //--------------------------------------------------------------------------------------
    46. VS_OUTPUT RenderSceneVS( float4 vPos : POSITION,
    47.                          float3 vNormal : NORMAL,
    48.                          float2 vTexCoord0 : TEXCOORD0,
    49.                          uniform int nNumLights,
    50.                          uniform bool bTexture,
    51.                          uniform bool bAnimate )
    52. {
    53.     VS_OUTPUT Output;
    54.     float3 vNormalWorldSpace;
    55.  
    56.     float4 vAnimatedPos = vPos;
    57.    
    58.     // Animation the vertex based on time and the vertex's object space position
    59.     if( bAnimate )
    60.         vAnimatedPos += float4(vNormal, 0) * (sin(g_fTime+5.5)+0.5)*5;
    61.    
    62.     // Transform the position from object space to homogeneous projection space
    63.     Output.Position = mul(vAnimatedPos, g_mWorldViewProjection);
    64.     Output.Position4PS = Output.Position;
    65.    
    66.     // Transform the normal from object space to world space    
    67.     vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space)
    68.    
    69.     // Compute simple directional lighting equation
    70.     float3 vTotalLightDiffuse = float3(0,0,0);
    71.     for(int i=0; i<nNumLights; i++ )
    72.         vTotalLightDiffuse += g_LightDiffuse[i] * max(0,dot(vNormalWorldSpace, g_LightDir[i]));
    73.        
    74.     Output.Diffuse.rgb = g_MaterialDiffuseColor * vTotalLightDiffuse +
    75.                          g_MaterialAmbientColor * g_LightAmbient;  
    76.     Output.Diffuse.a = 1.0f;
    77.    
    78.     // Just copy the texture coordinate through
    79.     if( bTexture )
    80.         Output.TextureUV = vTexCoord0;
    81.     else
    82.         Output.TextureUV = 0;
    83.    
    84.    
    85.    
    86.    
    87.     return Output;    
    88. }
    89.  
    90.  
    91. //--------------------------------------------------------------------------------------
    92. // Pixel shader output structure
    93. //--------------------------------------------------------------------------------------
    94. struct PS_OUTPUT
    95. {
    96.  
    97.     float4 RGBColor : COLOR0;  // Pixel color    
    98. };
    99.  
    100.  
    101. //--------------------------------------------------------------------------------------
    102. // This shader outputs the pixel's color by modulating the texture's
    103. //       color with diffuse material color
    104. //--------------------------------------------------------------------------------------
    105. PS_OUTPUT RenderScenePS( VS_OUTPUT In,
    106.                          uniform bool bTexture )
    107. {
    108.     PS_OUTPUT Output;
    109.     float f;
    110.     f = lerp(0, 1.0, In.Position4PS.z / In.Position4PS.w);
    111.     Output.RGBColor = float4(f,0,0,0);  
    112.     return Output;
    113. }
    114.  
    115.  
    116. //--------------------------------------------------------------------------------------
    117. // Renders scene to render target
    118. //--------------------------------------------------------------------------------------
    119. technique RenderSceneWithTexture1Light
    120. {
    121.     pass P0
    122.     {          
    123.         VertexShader = compile vs_1_1 RenderSceneVS( 1, true, true );
    124.         PixelShader  = compile ps_1_1 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired)
    125.     }
    126. }
    127.  
    128. technique RenderSceneWithTexture2Light
    129. {
    130.     pass P0
    131.     {          
    132.         VertexShader = compile vs_1_1 RenderSceneVS( 2, true, true );
    133.         PixelShader  = compile ps_1_1 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired)
    134.     }
    135. }
    136.  
    137. technique RenderSceneWithTexture3Light
    138. {
    139.     pass P0
    140.     {          
    141.         VertexShader = compile vs_1_1 RenderSceneVS( 3, true, true );
    142.         PixelShader  = compile ps_1_1 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired)
    143.     }
    144. }
    145.  
    146. technique RenderSceneNoTexture
    147. {
    148.     pass P0
    149.     {          
    150.         VertexShader = compile vs_1_1 RenderSceneVS( 1, false, false );
    151.         PixelShader  = compile ps_1_1 RenderScenePS( false ); // trivial pixel shader (could use FF instead if desired)
    152.     }
    153. }
     
  18. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    Затем что 0<f<1 показывает глубину.
    А команда
    Код (Text):
    1. Output.RGBColor = float4(f,0,0,0)
    ; должна окрасить пиксел в оттенок красного в зависимости от удаления от камеры. Это как раз то, что мне нужно.
    Почему-то когда я заменяю f на 0 шейдер запускается нормально.

    P S Position4PS передается в пиксельный шейдер не как POSITION а как TEXCOORD.
     
  19. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    DeepD
    Я спрашивал о другом. Почему не float f =?
    А вообще сомневаюсь что 1.1 это осилит.
     
  20. DeepD

    DeepD New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2011
    Сообщения:
    20
    А есть разница? Не так не так не работает. Может можно как-то бес шейдеров обойтись? Мне нужно получить монохромное изображение глубины...