DirectX HLSL PointList size

DirectX HLSL PointList size
2016-01-07T12:39:41+01:00
2016-01-12T08:56:11+01:00
2022-10-15T21:46:20+02:00
Peti_22
Üdv,

A múltkor már feltettem ezt a kérdést, de nem sikerült megoldani a problémát. Most meg próbálom másképp.

DirectX HLSL-ben kéne megoldanom azt, hogy amikor én vector3 coordinátákat rajzolok ki a képernyőre és PointList-re állítom a topológiáját akkor ne csak 1x1 pixeles négyszögeket rajzoljon ki hanem mondjuk 4x4 pixel vagy nagyobb, ahogy éppen be állítom. Ezek a négyszögek mindig a kamera vetületére merőlegesen néznek és azonos méretűek. Szóval amelyik háttrébb van az is pl.: 4x4 pixel és az is amelyik előrébb van.

Az lenne a legjobb ha ez PixelShader lenne, mert a GeometryShader-el gondok vannak.
Mutasd a teljes hozzászólást!
Nincs ki kommentelve.
Mutasd a teljes hozzászólást!

  • bazz, az ember megszokja az unreal editorát és totál elhülyül :) :)

    esetleg postprocessként? bár a 4x4 pont nem a legszerencsésebb. esetleg 5x5?

    lerendeled 1pixelként (mondjuk mindegyik fehér)

    pixelshader úgyis végigmegy az egészen
    tudnod kell mekkora a képed
    ebből ki tudod számolni, hogy 1 pixel az UV-n mit jelent (x és y irányba is)

    ha valahol fehér pixel van, az lenne a közepe
    szóval ennek függvényében kellene az összes pontot belőni, azaz 24 pontra


    pixelshader(float2 texCoord):Color0
    tex2d(texcoord + 2*kiszámolt eltolás) -- bal felső lesz majd, de te a középső pontra vagy kíváncsi
    ha ez fehér akkor a visszatérő érték is fehér
    és ezt minden pontra eljátszani, tehát a pixelshadered egy 24 tex2d-ből álló feltétleszerkezet lenne
    Mutasd a teljes hozzászólást!
  • PixelShader egy kicsit elkésik, hiszen a PS egy hívása (leegyszerűsítve) egy darab pixelt fest meg, abból meg nem nagyon lesz 4x4.
    Olyat tudsz csinálni, hogy megnégyszerezed a listádat, és a mindenféle transzformációk után, a képernyő síkjában széthúzod a pontokat (tipikusan mindhen vertexhez teszel egy egységvektort - hogy merre kell mozdulnia -, és a VertexShader-t paraméterezed fel, hogy x és y irányban mennyivel szorozza ezt a vektort).
    Kicsit takarékoskodhatsz úgy, hogy csak háromszorozod a listát, hiszen megfelelő textúrával egy háromszögből is tetszőleges síkidom kivágható.
    Ez amúgy egyfajta instancing, és hát a GeometryShader-t pont arra találták fel, hogy ne ilyen szenvedősen kelljen csinálni.
    Mutasd a teljes hozzászólást!
  • Erre találták ki: Point SpritesDX9be van csak. Utána már asszem nincs.
    Mutasd a teljes hozzászólást!
  • DX-ben van erre beallitas, marmint mi legyen a meret, de elegge GPU fuggo a tamogatasa.
    Mutasd a teljes hozzászólást!
  • Én nem találtam róla semmi infót, de nem baj ha gépigény függő jó lesz az is.
    Mutasd a teljes hozzászólást!
  • látom lusta vagy kb 50 sort megírni :)
    Mutasd a teljes hozzászólást!
  • Nem lustaság csak nem ismerem a HLSL és a videó grafikának ezen részét. Fontos része lenne egy projectemnek, de így nem tudom megoldani már régóta dolgozom rajta. Egy kis segítségnek nagyon örülnék. :)
    Mutasd a teljes hozzászólást!
  • akkor hogy akartál pixelshadert írni, ha nem ismered?

    google: shazzam wpf
    elég sok postprocess shader van benne + abban meg tudod írni

    ebből kiindulhatsz
    ez 3x3 pixel négyzetet rak ki neked

    sampler2D inputSampler : register(S0); float4 main(float2 uv : TEXCOORD) : COLOR { // 100x100 image float x = 1.0 / 100.0; float y = 1.0 / 100.0; float4 origin = tex2D(inputSampler, uv); float4 color; // midline color = tex2D(inputSampler, uv + float2(x,0)); if(color.r > 0.5 ) return float4(1,1,1,1); color = tex2D(inputSampler, uv + float2(-x,0)); if(color.r > 0.5 ) return float4(1,1,1,1); // up color = tex2D(inputSampler, uv + float2(x,y)); if(color.r > 0.5 ) return float4(1,1,1,1); color = tex2D(inputSampler, uv + float2(0,y)); if(color.r > 0.5 ) return float4(1,1,1,1); color = tex2D(inputSampler, uv + float2(-x,y)); if(color.r > 0.5 ) return float4(1,1,1,1); // down color = tex2D(inputSampler, uv + float2(x,-y)); if(color.r > 0.5 ) return float4(1,1,1,1); color = tex2D(inputSampler, uv + float2(0,-y)); if(color.r > 0.5 ) return float4(1,1,1,1); color = tex2D(inputSampler, uv + float2(-x,-y)); if(color.r > 0.5 ) return float4(1,1,1,1); return origin; }
    Mutasd a teljes hozzászólást!
  • És akkor ezt C# részről átadom egy PixelShader-nek valahogy így?:

    using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\SimplePS.hlsl", "PSMain", "ps_5_0")) pixelShader = ToDispose(new PixelShader(device, bytecode));

    SharpDX-ről van szó...
    Mutasd a teljes hozzászólást!
  • RenderStateManager.PointSize

    De sajnos csak DX9-ig van, mint a kollega irta korabban.
    Mutasd a teljes hozzászólást!
  • passz
    ezer éve nem csináltam

    de, ez nem olyan pixelshader, mint amire Te gondolsz (azaz nem egy modelhez társul)

    amikor a teljes jeleneted kész van, azt egy rendertarget-be tedd (ez egy kép)
    ezt a képet kell átadnod ennek a shader-nek

    erre keress rá: postprocess
    Mutasd a teljes hozzászólást!
  • Nem igazán alakul a dolog...

    Ezt kéne működésre bírni. Ez SlimDX de lényegében ugyan az mint a SharpDX: Geometry shader receives extra point on origin
    Mutasd a teljes hozzászólást!
  • és most hogy néz ki a shader-ed?
    Mutasd a teljes hozzászólást!
  • struct GS_OUTPUT { float4 pos : SV_POSITION; }; struct VS_INPUT { float3 pos : SV_POSITION; }; VS_INPUT VShader(VS_INPUT input) { return input; } float4 PSMain(PixelShaderInput pixel) : SV_Target { return float4(0.0, 1.0, 0.0, 0.0); //float4 output = float4(pixel.Position.z, 0, 0, 1); } [maxvertexcount(4)] void Triangulat0r(VS_INPUT input, TriangleStream<GS_OUTPUT> OutputStream) { GS_OUTPUT output; float3 _input; _input = input; output.pos = float4(_input.x + 0.1, _input.y - 0.1, _input.z, 1.0); OutputStream.Append(output); output.pos = float4(_input.x - 0.1, _input.y - 0.1, _input.z, 1.0); OutputStream.Append(output); output.pos = float4(_input.x - 0.1, _input.y + 0.1, _input.z, 1.0); OutputStream.Append(output); output.pos = float4(_input.x + 1, _input.y + 0.1, _input.z, 1.0); OutputStream.Append(output); }
    C#:

    using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\SimplePS.hlsl", "PSMain", "ps_5_0")) pixelShader = ToDispose(new PixelShader(device, bytecode));
    Itt a C# kód most nem a fenti HLSL-t kapja meg hanem ezt:

    // Globals for texture sampling Texture2D Texture0 : register(t0); SamplerState Sampler : register(s0); #include "Common.hlsl" // A simple Pixel Shader that simply passes through the interpolated color float4 PSMain(PixelShaderInput pixel) : SV_Target { if (HasTexture) return Texture0.Sample(Sampler, pixel.TextureUV); return pixel.Diffuse; }
    Mutasd a teljes hozzászólást!
  • az a probléma, hogy annyira messze vagy még a "próbáljuk ki ezt az irányt" lehetőségtől is, hogy nem is tudom mit írjak.

    amit te készítettél, az egy pixelshader
    amit belinkeltél, abban van minden

    van egy ilyen sorod
    new PixelShader(device, bytecode)
    ebből kellene még pluszba
    new VertexShader(device, vertexShaderByteCode);
    new GeometryShader(device, geometryShaderByteCode);

    ezeket mind használnod kellene, és az egyes függvényeket ide kellene beírnod

    de még ekkor se leszel beljebb, mert ha megnézed a geometry shadert
    az _input.z-t használja, azaz minden kirakott háromszög mérete függ a z pozitól (persze ezt lenullázhatod, ha a kamerád fix helyen van)


    namost
    mivel lekaptad a sharpdx-et, abban találsz egy minitri.fx-et, ami így néz ki

    struct VS_IN { float4 pos : POSITION; float4 col : COLOR; }; struct PS_IN { float4 pos : SV_POSITION; float4 col : COLOR; }; PS_IN VS( VS_IN input ) { PS_IN output = (PS_IN)0; output.pos = input.pos; output.col = input.col; return output; } float4 PS( PS_IN input ) : SV_Target { return input.col; } technique10 Render { pass P0 { SetGeometryShader( 0 ); SetVertexShader( CompileShader( vs_4_0, VS() ) ); SetPixelShader( CompileShader( ps_4_0, PS() ) ); } }
    valami ilyesmi kell neked is, ahol SetGeometryShader nem 0-ra mutat, hanem arra a függvényre ami neked kell
    Mutasd a teljes hozzászólást!
  • Oké most agy néz ki a HLSL:

    struct GS_OUTPUT { float4 pos : SV_POSITION; float4 col : COLOR; }; struct VS_IN { float4 pos : POSITION; float4 col : COLOR; }; struct PS_IN { float4 pos : SV_POSITION; float4 col : COLOR; }; PS_IN VS( VS_IN input ) { PS_IN output = (PS_IN)0; output.pos = input.pos; output.col = input.col; return output; } float4 PS( PS_IN input ) : SV_Target { return input.col; } //VS_IN VS(VS_IN input) //{ // return input; //} float4 PShader(float4 position: SV_POSITION) : SV_Target { return float4(0.0, 1.0, 0.5, 0.0); } [maxvertexcount(4)] void Triangulat0r(VS_IN input[1], TriangleStream<GS_OUTPUT> OutputStream) //void Triangulat0r(point VS_IN input[1], inout TriangleStream<GS_OUTPUT> OutputStream) { GS_OUTPUT output; float3 _input; _input = input; output.pos = float4(_input.x + 0.1, _input.y - 0.1, _input.z, 1.0); OutputStream.Append(output); output.pos = float4(_input.x - 0.1, _input.y - 0.1, _input.z, 1.0); OutputStream.Append(output); output.pos = float4(_input.x - 0.1, _input.y + 0.1, _input.z, 1.0); OutputStream.Append(output); output.pos = float4(_input.x + 1, _input.y + 0.1, _input.z, 1.0); OutputStream.Append(output); } technique10 Render { pass P0 { SetGeometryShader(CompileShader(vs_4_0, Triangulat0r())); SetVertexShader( CompileShader( vs_4_0, VS() ) ); SetPixelShader( CompileShader( ps_4_0, PS() ) ); } }
    És így a C# kód:

    using System; using SharpDX; using SharpDX.D3DCompiler; using SharpDX.Direct3D; using SharpDX.Direct3D11; using SharpDX.DXGI; using SharpDX.Windows; using Buffer = SharpDX.Direct3D11.Buffer; using Device = SharpDX.Direct3D11.Device; namespace MiniTri { /// <summary> /// SharpDX port of SharpDX-MiniTri Direct3D 11 Sample /// </summary> internal static class Program { [STAThread] private static void Main() { var form = new RenderForm("SharpDX - MiniTri Direct3D 11 Sample"); // SwapChain description var desc = new SwapChainDescription() { BufferCount = 1, ModeDescription= new ModeDescription(form.ClientSize.Width, form.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm), IsWindowed = true, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; // Create Device and SwapChain Device device; SwapChain swapChain; Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out device, out swapChain); var context = device.ImmediateContext; // Ignore all windows events var factory = swapChain.GetParent<Factory>(); factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll); // New RenderTargetView from the backbuffer var backBuffer = Texture2D.FromSwapChain<Texture2D>(swapChain, 0); var renderView = new RenderTargetView(device, backBuffer); // Compile Vertex and Pixel shaders var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "VS", "vs_4_0", ShaderFlags.None, EffectFlags.None); var vertexShader = new VertexShader(device, vertexShaderByteCode); var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "PS", "ps_4_0", ShaderFlags.None, EffectFlags.None); var pixelShader = new PixelShader(device, pixelShaderByteCode); var geometryShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "Triangulat0r", "gs_4_0", ShaderFlags.None, EffectFlags.None); var geometryShader = new GeometryShader(device, geometryShaderByteCode); // Layout from VertexShader input signature var layout = new InputLayout( device, ShaderSignature.GetInputSignature(vertexShaderByteCode), new[] { new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0) }); // Instantiate Vertex buiffer from vertex data var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[] { new Vector4(0.0f, 0.5f, 0.5f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new Vector4(0.5f, -0.5f, 0.5f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), new Vector4(-0.5f, -0.5f, 0.5f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f) }); // Prepare All the stages context.InputAssembler.InputLayout = layout; context.InputAssembler.PrimitiveTopology = PrimitiveTopology.PointList; context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, 32, 0)); context.VertexShader.Set(vertexShader); context.Rasterizer.SetViewport(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f)); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(geometryShader); context.OutputMerger.SetTargets(renderView); // Main loop RenderLoop.Run(form, () => { context.ClearRenderTargetView(renderView, Color.Black); context.Draw(3, 0); swapChain.Present(0, PresentFlags.None); }); // Release all resources vertexShaderByteCode.Dispose(); vertexShader.Dispose(); pixelShaderByteCode.Dispose(); pixelShader.Dispose(); geometryShaderByteCode.Dispose(); geometryShader.Dispose(); vertices.Dispose(); layout.Dispose(); renderView.Dispose(); backBuffer.Dispose(); context.ClearState(); context.Flush(); device.Dispose(); context.Dispose(); swapChain.Dispose(); factory.Dispose(); } } }
    Mutasd a teljes hozzászólást!
  • oké. és???

    a shaderben a geometry shadernek szerintem gs prefix kell nem pedig vs
    Mutasd a teljes hozzászólást!
  • Tudom azt át írttam viszont amig ez a kettő:

    VS_IN VS_Input(VS_IN input) { return input; } [maxvertexcount(4)] void Triangulat0r(VS_IN input[1], TriangleStream<GS_OUTPUT> OutputStream) //void Triangulat0r(point VS_IN input[1], inout TriangleStream<GS_OUTPUT> OutputStream) { GS_OUTPUT output; float3 _input; _input = input; output.pos = float4(_input.x + 0.1, _input.y - 0.1, _input.z, 1.0); OutputStream.Append(output); output.pos = float4(_input.x - 0.1, _input.y - 0.1, _input.z, 1.0); OutputStream.Append(output); output.pos = float4(_input.x - 0.1, _input.y + 0.1, _input.z, 1.0); OutputStream.Append(output); output.pos = float4(_input.x + 1, _input.y + 0.1, _input.z, 1.0); OutputStream.Append(output); }
    Bent vannak addig azt írja a vertexshaderre, hogy az objektumhivatkozás nincs beállítva semmilyen... Szóval nem fút le jól a shader.
    Mutasd a teljes hozzászólást!
  • azért azt észrevetted, hogy a vertexahdered ki van kommentezve?
    Mutasd a teljes hozzászólást!
  • Nincs ki kommentelve.
    Mutasd a teljes hozzászólást!
  • //VS_IN VS(VS_IN input)
    //{
    //   return input;
    //}
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd