Advertisement Jump to content
  • Advertisement

Ivo Leitao

  • Content Count

  • Joined

  • Last visited

Community Reputation

172 Neutral

About Ivo Leitao

  • Rank
  1. I've post an issue concerning this in the slimdx issues area. It's located here I've managed to correct the issue and I have attached some code in there to handle this case. Tnks
  2. Hi, I'm working in a language that outputs to hlsl namely hlsl 2.0, 3.0, and 4.0. This language supports basic scalar types (bool, int and float), vector types (float2, float3 and float4) and matrix types (float2x2, float3x3 and float4x4). The vector and matrix types are custom defined. I support global variables in this language and thus it allows get/set operations in them. In my D3D9 ouput I'm using the [font="consolas"]SetValue<T> and GetValue<T> [/font]without any kind of problems, namely I'm able to get and set Matrix variables correctly. In my D3D10/11 output I'm having problems setting and obtaining the values from matrix variables (float2x2, float3x3 and float4x4). The problem is, I'm not getting the expected output. Everything works just fine with the scalar variables and the vector variables. The problem is the matrix variables. With D3D10 and D3D11 I'm using the GetRawValue method (I've compiled the latest version of SlimDX since the Get/SetRawValue method was not in the last official release) To illustrate the problem I'm providing the following code snippet which builds a Quad and obtains a matrix variable through the pixel shader. The program bellow also allows setting and getting global variables from the shader. It needs a custom compiled version of slimdx because it uses the Get/SetRawValue functions. The problem is on the following lines: bool test = prg.GetOutput<Float2x2>().Equals(new Float2x2(1.0f, 2.0f, 3.0f, 4.0f)); //OK test &= prg.GetVariable<Float2x2>("a").Equals(new Float2x2(1.0f, 2.0f, 3.0f, 4.0f)); //Error, I'm getting Float2x2(1.0f, 3.0f, 0.0f, 0.0f) The code is here: namespace Test { using global::SlimDX; using global::SlimDX.D3DCompiler; using global::SlimDX.DXGI; using D3D10 = global::SlimDX.Direct3D10; using System; using System.Runtime.InteropServices; using SlimDX.Windows; public class Program2 : IDisposable { #region Types [Serializable, StructLayout(LayoutKind.Sequential, Pack = 4)] public struct Float4 : IEquatable<Float4> { #region Fields public float X; public float Y; public float Z; public float W; #endregion #region Constructors public Float4(float x, float y, float z, float w) { this.X = x; this.Y = y; this.Z = z; this.W = w; } #endregion #region Operators public static bool operator ==(Float4 value1, Float4 value2) { return value1.X == value2.X && value1.Y == value2.Y && value1.Z == value2.Z && value1.W == value2.W; } public static bool operator !=(Float4 value1, Float4 value2) { return value1.X != value2.X || value1.Y != value2.Y || value1.Z != value2.Z || value1.W != value2.W; } #endregion #region Methods public override int GetHashCode() { return (int)(this.X + this.Y + this.Z + this.W); } public override bool Equals(object obj) { if (!(obj is Float4)) { return false; } return (Float4)obj == this; } public bool Equals(Float4 other) { return this == other; } #endregion } [Serializable, StructLayout(LayoutKind.Sequential, Pack = 4)] public struct Float2x2 : IEquatable<Float2x2> { #region Fields public float M00; public float M01; public float M10; public float M11; #endregion #region Constructors public Float2x2(float value) { this.M00 = this.M01 = this.M10 = this.M11 = value; } public Float2x2(float m00, float m01, float m10, float m11) { this.M00 = m00; this.M01 = m01; this.M10 = m10; this.M11 = m11; } #endregion #region Operators public static bool operator ==(Float2x2 value1, Float2x2 value2) { return value1.M00 == value2.M00 && value1.M01 == value2.M01 && value1.M10 == value2.M10 && value1.M11 == value2.M11; } public static bool operator !=(Float2x2 value1, Float2x2 value2) { return value1.M00 != value2.M00 || value1.M01 != value2.M01 || value1.M10 != value2.M10 || value1.M11 != value2.M11; } #endregion #region Methods public override int GetHashCode() { return (int)(this.M00 + this.M01 + this.M10 + this.M11); } public override bool Equals(object obj) { if (!(obj is Float2x2)) { return false; } return (Float2x2)obj == this; } public bool Equals(Float2x2 other) { return this == other; } #endregion } private struct VertexPosition10 { #region Constants public static readonly D3D10.InputElement[] Elements = new D3D10.InputElement[] { new D3D10.InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0) }; #endregion #region Fields public Vector3 Position; #endregion #region Constructors public VertexPosition10(Vector3 position) { this.Position = position; } #endregion #region Properties public static int SizeInBytes { get { return Marshal.SizeOf(typeof(VertexPosition10)); } } #endregion } #endregion #region Constants private string EffectCode = @"struct VertexShaderInput { float3 pos : POSITION; }; struct VertexShaderOutput { float4 pos : SV_POSITION; float2 coord : TEXCOORD0; }; struct PixelShaderOutput { float4 Output0 : SV_Target0; }; VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output = (VertexShaderOutput)0; output.pos = float4(input.pos, 1); output.coord = 0.5 * input.pos.xy + 0.5; return output; } float2x2 a = float2x2(1.0, 2.0, 3.0, 4.0); PixelShaderOutput PixelShaderFunction() { PixelShaderOutput output = (PixelShaderOutput)0; output.Output0 = a._11_12_21_22; return output; } technique10 Default { pass P0 { SetVertexShader(CompileShader(vs_4_0, VertexShaderFunction())); SetGeometryShader(0); SetPixelShader( CompileShader(ps_4_0, PixelShaderFunction())); } }"; private static VertexPosition10[] Vertices = new VertexPosition10[] { new VertexPosition10(new Vector3(-1.0f, -1.0f, 0.5f)), new VertexPosition10(new Vector3(-1.0f, 1.0f, 0.5f)), new VertexPosition10(new Vector3(1.0f, -1.0f, 0.5f)), new VertexPosition10(new Vector3(1.0f, 1.0f, 0.5f)) }; private static short[] Indices = new short[] { 0, 1, 2, 3 }; #endregion #region Fields private int width = 1; private int height = 1; private RenderForm renderForm; private Factory factory; private Adapter adapter; private SwapChainDescription swapChainDescription; private SwapChain swapChain; private D3D10.Device device; private D3D10.Effect effect; private D3D10.EffectPass pass; private D3D10.InputLayout inputLayout; private D3D10.Buffer vertexBuffer; private D3D10.Buffer indexBuffer; private D3D10.RenderTargetView backbuffer; private D3D10.Texture2D gpuTexture; private D3D10.Texture2D cpuTexture; private Surface cpuSurface; private D3D10.RenderTargetView renderTarget; #endregion #region Constructors public Program2() { } ~Program2() { Dispose(false); } #endregion #region Methods public T GetVariable<T>(string name) where T: struct { return this.effect.GetVariableByName(name).GetRawValue(Marshal.SizeOf(typeof(T))).Read<T>(); } public void SetVariable<T>(string name, T value) where T: struct { int sizeInBytes = Marshal.SizeOf(typeof(T)); using (DataStream ds = new DataStream(sizeInBytes, true, true)) { ds.Write<T>(value); ds.Position = 0; this.effect.GetVariableByName(name).SetRawValue(ds, sizeInBytes); } } private void CreateForm() { this.renderForm = new RenderForm(); } private void CreateDevice() { this.factory = new Factory(); this.adapter = this.factory.GetAdapter(0); this.device = new D3D10.Device( this.adapter, D3D10.DriverType.Hardware, D3D10.DeviceCreationFlags.Debug); this.swapChainDescription = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription( this.width, this.height, new Rational(60, 1), Format.R8G8B8A8_UNorm), OutputHandle = this.renderForm.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; this.swapChain = new SwapChain(this.factory, this.device, this.swapChainDescription); this.factory.SetWindowAssociation(this.renderForm.Handle, WindowAssociationFlags.IgnoreAll | WindowAssociationFlags.IgnoreAltEnter); } private void CreateEffect() { string compilationErrors; this.effect = D3D10.Effect.FromString( this.device, EffectCode, "fx_4_0", ShaderFlags.None, EffectFlags.None, null, null, null, out compilationErrors); this.pass = this.effect.GetTechniqueByName("Default").GetPassByName("P0"); } private void LoadVariables() { } private void CreateInput() { int sizeInBytes = Vertices.Length * VertexPosition10.SizeInBytes; using (DataStream ds = new DataStream(sizeInBytes, true, true)) { ds.WriteRange(Vertices); ds.Position = 0; this.vertexBuffer = new D3D10.Buffer( this.device, ds, new D3D10.BufferDescription() { SizeInBytes = sizeInBytes, Usage = D3D10.ResourceUsage.Default, BindFlags = D3D10.BindFlags.VertexBuffer, CpuAccessFlags = D3D10.CpuAccessFlags.None, OptionFlags = D3D10.ResourceOptionFlags.None } ); } sizeInBytes = Indices.Length * Marshal.SizeOf(typeof(short)); using (DataStream ds = new DataStream(sizeInBytes, true, true)) { ds.WriteRange(Indices); ds.Position = 0; this.indexBuffer = new D3D10.Buffer( this.device, ds, new D3D10.BufferDescription() { SizeInBytes = sizeInBytes, Usage = D3D10.ResourceUsage.Default, BindFlags = D3D10.BindFlags.IndexBuffer, CpuAccessFlags = D3D10.CpuAccessFlags.None, OptionFlags = D3D10.ResourceOptionFlags.None } ); } this.inputLayout = new D3D10.InputLayout(this.device, pass.Description.Signature, VertexPosition10.Elements); } private void CreateOutput() { using (D3D10.Texture2D texture = D3D10.Texture2D.FromSwapChain<D3D10.Texture2D>(this.swapChain, 0)) { this.backbuffer = new D3D10.RenderTargetView(this.device, texture); } this.gpuTexture = new D3D10.Texture2D( this.device, new D3D10.Texture2DDescription() { Width = this.width, Height = this.height, Format = Format.R32G32B32A32_Float, Usage = D3D10.ResourceUsage.Default, ArraySize = 1, MipLevels = 1, BindFlags = D3D10.BindFlags.RenderTarget, SampleDescription = new SampleDescription(1, 0), CpuAccessFlags = D3D10.CpuAccessFlags.None, OptionFlags = D3D10.ResourceOptionFlags.None }); this.cpuTexture = new D3D10.Texture2D( this.device, new D3D10.Texture2DDescription() { Width = this.width, Height = this.height, Format = Format.R32G32B32A32_Float, Usage = D3D10.ResourceUsage.Staging, ArraySize = 1, MipLevels = 1, BindFlags = D3D10.BindFlags.None, SampleDescription = new SampleDescription(1, 0), CpuAccessFlags = D3D10.CpuAccessFlags.Read, OptionFlags = D3D10.ResourceOptionFlags.None }); this.cpuSurface = this.cpuTexture.AsSurface(); this.renderTarget = new D3D10.RenderTargetView(this.device, this.gpuTexture); } public void Initialize() { CreateForm(); CreateDevice(); } public void LoadContent() { CreateEffect(); LoadVariables(); CreateInput(); CreateOutput(); } public virtual void UnloadContent() { Dispose(true); } public void DrawQuad() { this.device.InputAssembler.SetInputLayout(this.inputLayout); this.device.InputAssembler.SetPrimitiveTopology(D3D10.PrimitiveTopology.TriangleStrip); this.device.InputAssembler.SetIndexBuffer(this.indexBuffer, Format.R16_UInt, 0); this.device.InputAssembler.SetVertexBuffers(0, new D3D10.VertexBufferBinding(this.vertexBuffer, VertexPosition10.SizeInBytes, 0)); this.pass.Apply(); this.device.DrawIndexed(Indices.Length, 0, 0); } public T GetOutput<T>() where T: struct { this.device.OutputMerger.SetTargets(this.renderTarget); this.device.Rasterizer.SetViewports(new D3D10.Viewport(0, 0, this.width, this.height, 0.0f, 1.0f)); DrawQuad(); this.device.CopyResource(this.gpuTexture, this.cpuTexture); DataRectangle dr = this.cpuSurface.Map(MapFlags.Read); this.cpuSurface.Unmap(); return dr.Data.Read<T>(); } private static void Dispose<T>(T target) where T : class, IDisposable { ComObject co = target as ComObject; if (target != null && (co == null || !co.Disposed)) { target.Dispose(); } } private static void Dispose<T>(ref T target) where T : class, IDisposable { if (target != null) { Dispose<T>(target); target = null; } } private static void Dispose<T>(ref T[] target) where T : class, IDisposable { if (target != null) { for (int i = 0; i < target.Length; i++) { Dispose(ref target); } target = null; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposeManagedResources) { if (disposeManagedResources) { Dispose(ref this.cpuSurface); Dispose(ref this.cpuTexture); Dispose(ref this.gpuTexture); Dispose(ref this.renderTarget); Dispose(ref this.effect); Dispose(ref this.inputLayout); Dispose(ref this.vertexBuffer); Dispose(ref this.indexBuffer); Dispose(ref this.backbuffer); Dispose(ref this.device); Dispose(ref this.swapChain); Dispose(ref this.adapter); Dispose(ref this.factory); } } #endregion static void Main(string[] args) { using (Program2 prg = new Program2()) { prg.Initialize(); prg.LoadContent(); bool test = prg.GetOutput<Float2x2>().Equals(new Float2x2(1.0f, 2.0f, 3.0f, 4.0f)); //OK test &= prg.GetVariable<Float2x2>("a").Equals(new Float2x2(1.0f, 2.0f, 3.0f, 4.0f)); //Error, I'm getting Float2x2(1.0f, 3.0f, 0.0f, 0.0f) } Console.ReadKey(); } } } Any help on this ? Tnks in advance
  3. Ivo Leitao

    Length in hlsl (confused)

    Quote:Original post by galop1n It looks like you found weird bug! I took the latest fxc.exe from the june 2010 directx sdk and here the result *** Source Snippet Removed *** And here the assembly generate *** Source Snippet Removed *** We clearly see that on cst it compute (x*x+y*y)^0.5 (the square root done by a invert square root followed by the reciprocal) On the constant, it pick up the first component, x, and updating y did nothing! I found a sick workaround for you, wrote this like that and the compiler do the math correctly. *** Source Snippet Removed *** with the good result: *** Source Snippet Removed *** galop1n Tnks a lot for your answer. I have changed my unit tests. I was almost thinking that I was not seeing it clearly :-S The same happens with other hlsl functions like distance and smoothstep for example. This is unbelievable :-(. I'm doing a small pixel shader focused language and I have a lot of unit tests, this was one of the first type of tests that I have done. In a professional tool like the Microsoft Hlsl compiler I cannot understand how things simpel as that escape.... [Edited by - Ivo Leitao on December 1, 2010 7:11:01 PM]
  4. I'm very confused with the length function in hlsl. From what i can understand it gives me the length of a vector so for example for: length(float2(4.0, 3.0)) It should calculate the square root of 4^2 + 3^2 = 16 + 9 = 25 i.e. 5 I'm obtaining 4... what the helll ???? Here is the shader that I have used in Fx Composer 2.5. I have debugged it and confirmed that for one of the pixels the value is indeed 4.0 float4x4 WorldViewProj : WorldViewProjection; float4 mainVS(float3 pos : POSITION) : POSITION{ return mul(float4(, 1.0), WorldViewProj); } float4 mainPS() : COLOR { float a = length(float2(4.0, 3.0)); return float4(1.0, 0.0, 0.0, 1.0); } technique technique0 { pass p0 { CullMode = None; VertexShader = compile vs_3_0 mainVS(); PixelShader = compile ps_3_0 mainPS(); } } [Edited by - Ivo Leitao on December 1, 2010 12:35:37 PM]
  5. Hi, I need to obtain/set the value of a shader variable in d3d9, d3d10 and in d3d11 (I'm targeting the three). I have custom vector and matrix types (in my case Float2, Float3, Float4, Matrix2x2, Matrix3x3 and Matrix4x4) and in D3D9 i do not have any problems obtaining/setting the values of these type of variables in the shader since I could do something like this (from my code): protected T GetVariable<T>(string name) where T : struct { return this.effect.GetValue<T>(this.variableHandles[name]); } protected void SetVariable<T>(string name, ref T oldValue, T newValue, bool compare) where T : struct, IEquatable<T> { if (!compare || !oldValue.Equals(newValue)) { oldValue = newValue; this.effect.SetValue<T>(this.variableHandles[name], newValue); } } The important part here is the this.effect.GetValue<T> and this.effect.SetValue<T>. This generic methods are very handy in D3D9 allowing me to use custom types not only here but in other parts of the api. Till now my other interactions with d3d10 and d3d11 api where through a DataStream from where I was able to extract my custom types too but in this case, setting and getting shader variables, I'm not finding similar options. I've searched and I've found getRawValue and setrawvalue methods in Effect variable (unfortunately in d3d10 only in the source of slimdx not on the latest official release) How can I accomplish something similar ? Tnks in advance
  6. Quote:Original post by Matias Goldberg Yes. Suppose you know the minimum negative value is -50, and the maximum positive value is 112. Then you do: x = (x + 50) / (50 + 112) That's it! Simple math to get the value in the range [0; 1] Cheers Dark Sylinc Tnks a lot! I've not made many tests yet (too sleepy :-)) but it seems to work. I've incorporated Ysaneya code from�. Bellow in HLSL : float4 PackToFloat4(float value) { const float4 bitSh = float4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0); const float4 bitMsk = float4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); float4 res = frac(value * bitSh); res -= res.xxyz * bitMsk; return res; } float4 PackToFloat4(float value, float min, float max) { return PackToFloat4((value - min) / (max - min)); } float UnpackToFloat(float4 value) { const float4 bitSh = float4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0); return dot(value, bitSh); } float UnpackToFloat(float4 value, float min, float max) { return UnpackToFloat(value) * (max - min) + min; }
  7. Quote:Original post by Matias Goldberg Quote:Original post by Ivo Leitao Those links (specially the last two) store numbers in the [0..1) range I would like to store arbitrary floats. I don't know even if that is possible. Just divide the float by the largest possible number you know that can appear. This is often a good practice even for FP formats, since best precision is in the [0; 1] range. For example if you're doing shadow mapping, divide all values by the far clipping plane of your shadow camera. When packing to an integer texture you will always lose some precision, so the division won't actually hurt. Cheers Dark Sylinc Hum, I'm going to test it tonight Tkns. One question, what you have mentioned can be applied also to negative values for example -2.3 ? Tnks for your answer
  8. Quote:Original post by JorenJoestar Hi Ivo, there are a bunch of links around that can be useful: Hope those helps! Tnks for your answer but I've already reviewed all those links (two of them are on my list) but I was hoping for a way to do that with 32 bit ARGB textures where we have 8 bits per channel. I would like to split a float into 4 parts of 8 bits each and unpack it from those channels into a float. Those links (specially the last two) store numbers in the [0..1) range I would like to store arbitrary floats. I don't know even if that is possible.
  9. Quote:Original post by smasherprog What do you mean an rgba texture? What format? You can create several types of float rgba formats pick which one you want and create it. I'm sorry I forgot to mention I was referring to A8R8G8B8 32 bit format. tnks for your answer
  10. Hi, I've searched the forums and the web for an answer to the topic above but I was able to find only code to do it for numbers between 0 and 1. I wonder if it's possible to encode a generic float (for example 2.3, 12.33454 or -0.4) in a rgba texture (A8R8G8B8 32 bits). I know that I can use float textures and I'm using them, however for old graphic cards like the integrated intel cards that are still in a lot of notebooks using the float format is not possible. I've compiled a couple of links bellow concerning this topic, but none of them answer my problem I wanto to pack in HLSL or GLSL and unpack in C# [Edited by - Ivo Leitao on October 19, 2010 12:41:24 PM]
  11. Ivo Leitao

    Tech Demo Video 2010

    Amazing !!
  12. Quote:Original post by ndhb I also think Chunked LOD is a fairly good solution but only if A) The terrain dataset is static (CLOD uses a non-trivial algorithm for preprocessing the dataset, it isn't something you want to run on-the-fly), B) You're satisfied with using skirts to cover the artefacts from t-junctions. The skirt technique adds a little to the fillrate requirement and increases the # draw calls. CLOD might also slightly complicate accurate collision detection and terrain following because the mesh isn't regular. On the other hand the algorithm scales well and streaming in new data from disk or network is straightforward. If you need to handle a really large dataset, then you should work with algorithms that use clipmaps or similar techniques. But they're also a bit more complicated to implement. Remember the algorithm Hoppes first published does not require the latest hardware (! However, what I would do in your situation, is to implement either "Geomipmap (W. de Boer)" (either with VBO or VTF depending on what hardware generation you want to support), OR " GPU Terrain Rendering from Game Programming Gems 6" (H. Vistnes). Then extend it with some geomorphing in the VS. You probably also want to texture the terrain. This can obviously take a lot of time as well if you're hard to please :) I think the fastest algorithm is the chunked lod or at least the principle behind it. Concerning Geomorphing it is easy if you use the simplification method of the geomipmapping algorithm. Therefore a hybrid approach between Geomipmapping and Chunked Lod is IMHO the best strategy. Also using skirts does not increase draw calls if you connect the skirts with the main block with degenerate triangles. The fillrate problem can be handled if you use the geometric error as the size of the skirts. If you want dynamic changes you can use the strategy mentioned in the "GPU Terrain Rendering from Game Programming Gems 6" as was mentioned. It blend nicely with the rest. I have to recommend one of the best articles out there about this: Rendering Very Large, Very Detailed Terrains. Unfortunately its not online anymore (it was on the, but you can find the source code here: They use an approach very similar to this in the Torque engine. the only difference is that they use clipmapping for the textures, which by the way is a good solution and handles the only problem of the Rendering Very Large Very Detailed Terrains solution, the seams between textures. Also the approach used in the Infinity project by Ysaneya ( is somewhat similar with a quadtree like simplification. I have implemented all of this minus the clipmapping of the textures and I have to say that I'm very happy with it.
  13. Ivo Leitao

    2008 Retrospective and progress

    Have you seen this paper ( Precomputed atmospheric Scattering) : The results they are getting look amazing
  14. Quote:Original post by theZapper To add to you skeptisism, CrystalSitral, your game also has to pass peer review. So depending on how hard that is and how long it takes to review, you could make a game and never see it on Live! anyway. If your game is good enough i don't think that is an actual problem. A lot of games pass the peer review process in the beta version of the site in just a couple of hours. It seems a lot of people likes to peer review games. I have a subscription and the last games i have only managed to see them in the final state (approved), besides you get useful opinions on your game if you don't reach an approved state. There's another important thing here: recognition. This is a great way to start a career as a game developer. People with good ideas attract attention. This is a good way to make yourself known (if that is one of your objectives) Check to see the latest games approved in the beta. There are some fine looking games there like Colosseum, skip lancer, jelly factory, Gymnast, Jelly car (my personal favorite) just to mention a few...
  15. Just sharing some great news ;-) We can know make games publish them and get paid :-) Nice
  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!