Доброго всем времени суток. Как организовать попиксельную отрисовку модели загруженную откуда-то(из DirectX-файла). Конкретно, мне нужно получить координату пиксела и на основании этого покрасить его в соответствующий цвет. Есть ли какое решение кроме пиксельных шейдеров?
Booster Мне нужно получить карту глубин, чтотто вроде этого: Мне нужен способ, как ее получить(проще всего). Через шейдеры или еще как. Dmitry_Milk Модель задана полигонами. Загружается из x-файла. Используется DirectX9
DeepD А разве поверхности должны быть обязательно "видимыми" ? С поверности копируйте и усё (lpSurface ... Pitch * Height).
Booster О координатах позиции отрисовываемой точки. Т.е. подобное, например, не прокатывает(программа падает) Код (Text): struct VS_OUTPUT { float4 Position : POSITION; // vertex position float4 Diffuse : COLOR0; float2 TextureUV : TEXCOORD0; } PS_OUTPUT RenderScenePS( VS_OUTPUT In, uniform bool bTexture ) { PS_OUTPUT Output; Output.RGBColor = float4(In.Position.x,0,0,0); return Output; }
DeepD Пиксельный шейдер не может принимать семантику POSITION. Если нужно передать позицию, то её нужно копировать в TEXCOORD[n] и тогда её можно использовать. Что касается значения буфера глубины для пикселя, то это легко посчитать. Так как вершинный шейдер переводит мировые координаты в экранные, то глубину в пиксельном можно считать так - lerp(Viewport.MinZ, Viewport.MaxZ, input.pos.z / input.pos.w);
Сделал так: Код (Text): struct VS_OUTPUT { float4 Position : POSITION; // vertex position float4 Diffuse : COLOR0; // vertex diffuse color (note that COLOR0 is clamped from 0..1) float2 TextureUV : TEXCOORD0; // vertex texture coords float Depth : TEXCOORD2; <---Добавленное поле }; В конце вершинного шейдера прописал: Код (Text): Output.Depth = lerp(0, 1.0, Output.Position.z / Output.Position.w); И сам пиксельный шейдер: Код (Text): PS_OUTPUT RenderScenePS( VS_OUTPUT In, uniform bool bTexture ) { PS_OUTPUT Output; Output.RGBColor = float4(In.Depth,0,0,0); return Output; } По идее моя модель должна выводиться в градациях красного (0<In.Depth<1). Но вместо этого она выводится одним цветом(красным)... У меня ошибка?
Это надо считать в пиксельном, где координата интерполируется для конкретного пикселя, а не для всего полигона.
Хорошо. Делаю так: Код (Text): struct VS_OUTPUT { float4 Position : POSITION; // vertex position float4 Diffuse : COLOR0; // vertex diffuse color (note that COLOR0 is clamped from 0..1) float2 TextureUV : TEXCOORD0; // vertex texture coords float4 Position4PS : TEXCOORD1; <-- Копирую сюда позицию вершины в вершинном шейдере }; Код (Text): PS_OUTPUT RenderScenePS( VS_OUTPUT In, uniform bool bTexture ) { PS_OUTPUT Output; float f; f = lerp(0, 1.0, In.Position4PS.z / In.Position4PS.w); Output.RGBColor = float4(f,0,0,0); return Output; } Но когда я запускаю приложоние падает с ошибкой E_FAIL 0x80004005. Вероятно из-за строки Output.RGBColor = float4(f,0,0,0)
Падает потому-что шейдер неправильный. POSITION во входе пиксельного шейдера вообще быть не должно. А так надо смотреть более детально, может не только в этом ошибка. Приведите полностью шедеры. Кстати, зачем? Код (Text): float f; f =
Код из примеров к Directx SDK HLSL Sample Код (Text): float4 g_MaterialAmbientColor; // Material's ambient color float4 g_MaterialDiffuseColor; // Material's diffuse color int g_nNumLights; float3 g_LightDir[3]; // Light's direction in world space float4 g_LightDiffuse[3]; // Light's diffuse color float4 g_LightAmbient; // Light's ambient color texture g_MeshTexture; // Color texture for mesh float g_fTime; // App's time in seconds float4x4 g_mWorld; // World matrix for object float4x4 g_mWorldViewProjection; // World * View * Projection matrix //-------------------------------------------------------------------------------------- // Texture samplers //-------------------------------------------------------------------------------------- sampler MeshTextureSampler = sampler_state { Texture = <g_MeshTexture>; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; }; //-------------------------------------------------------------------------------------- // Vertex shader output structure //-------------------------------------------------------------------------------------- struct VS_OUTPUT { float4 Position : POSITION; // vertex position float4 Diffuse : COLOR0; // vertex diffuse color (note that COLOR0 is clamped from 0..1) float2 TextureUV : TEXCOORD0; // vertex texture coords float4 Position4PS : TEXCOORD1; }; //-------------------------------------------------------------------------------------- // This shader computes standard transform and lighting //-------------------------------------------------------------------------------------- VS_OUTPUT RenderSceneVS( float4 vPos : POSITION, float3 vNormal : NORMAL, float2 vTexCoord0 : TEXCOORD0, uniform int nNumLights, uniform bool bTexture, uniform bool bAnimate ) { VS_OUTPUT Output; float3 vNormalWorldSpace; float4 vAnimatedPos = vPos; // Animation the vertex based on time and the vertex's object space position if( bAnimate ) vAnimatedPos += float4(vNormal, 0) * (sin(g_fTime+5.5)+0.5)*5; // Transform the position from object space to homogeneous projection space Output.Position = mul(vAnimatedPos, g_mWorldViewProjection); Output.Position4PS = Output.Position; // Transform the normal from object space to world space vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space) // Compute simple directional lighting equation float3 vTotalLightDiffuse = float3(0,0,0); for(int i=0; i<nNumLights; i++ ) vTotalLightDiffuse += g_LightDiffuse[i] * max(0,dot(vNormalWorldSpace, g_LightDir[i])); Output.Diffuse.rgb = g_MaterialDiffuseColor * vTotalLightDiffuse + g_MaterialAmbientColor * g_LightAmbient; Output.Diffuse.a = 1.0f; // Just copy the texture coordinate through if( bTexture ) Output.TextureUV = vTexCoord0; else Output.TextureUV = 0; return Output; } //-------------------------------------------------------------------------------------- // Pixel shader output structure //-------------------------------------------------------------------------------------- struct PS_OUTPUT { float4 RGBColor : COLOR0; // Pixel color }; //-------------------------------------------------------------------------------------- // This shader outputs the pixel's color by modulating the texture's // color with diffuse material color //-------------------------------------------------------------------------------------- PS_OUTPUT RenderScenePS( VS_OUTPUT In, uniform bool bTexture ) { PS_OUTPUT Output; float f; f = lerp(0, 1.0, In.Position4PS.z / In.Position4PS.w); Output.RGBColor = float4(f,0,0,0); return Output; } //-------------------------------------------------------------------------------------- // Renders scene to render target //-------------------------------------------------------------------------------------- technique RenderSceneWithTexture1Light { pass P0 { VertexShader = compile vs_1_1 RenderSceneVS( 1, true, true ); PixelShader = compile ps_1_1 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired) } } technique RenderSceneWithTexture2Light { pass P0 { VertexShader = compile vs_1_1 RenderSceneVS( 2, true, true ); PixelShader = compile ps_1_1 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired) } } technique RenderSceneWithTexture3Light { pass P0 { VertexShader = compile vs_1_1 RenderSceneVS( 3, true, true ); PixelShader = compile ps_1_1 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired) } } technique RenderSceneNoTexture { pass P0 { VertexShader = compile vs_1_1 RenderSceneVS( 1, false, false ); PixelShader = compile ps_1_1 RenderScenePS( false ); // trivial pixel shader (could use FF instead if desired) } }
Затем что 0<f<1 показывает глубину. А команда Код (Text): Output.RGBColor = float4(f,0,0,0) ; должна окрасить пиксел в оттенок красного в зависимости от удаления от камеры. Это как раз то, что мне нужно. Почему-то когда я заменяю f на 0 шейдер запускается нормально. P S Position4PS передается в пиксельный шейдер не как POSITION а как TEXCOORD.
А есть разница? Не так не так не работает. Может можно как-то бес шейдеров обойтись? Мне нужно получить монохромное изображение глубины...