protected override Number4 GetLinear( SamplerState samplerState, ITextureMipMap mipMap, ref Number4 texCoords) { int intTexelX = (int) texCoords.Float0; int intTexelY = (int) texCoords.Float1; float fracX = texCoords.Float0 - intTexelX; float fracY = texCoords.Float1 - intTexelY; texCoords.Int0 = intTexelX; texCoords.Int1 = intTexelY; var c00 = GetColor(samplerState, mipMap, ref texCoords); texCoords.Int0 = intTexelX + 1; texCoords.Int1 = intTexelY; var c10 = GetColor(samplerState, mipMap, ref texCoords); texCoords.Int0 = intTexelX; texCoords.Int1 = intTexelY + 1; var c01 = GetColor(samplerState, mipMap, ref texCoords); texCoords.Int0 = intTexelX + 1; texCoords.Int1 = intTexelY + 1; var c11 = GetColor(samplerState, mipMap, ref texCoords); var cMinV = Number4.Lerp(ref c00, ref c10, fracX); var cMaxV = Number4.Lerp(ref c01, ref c11, fracX); return Number4.Lerp(ref cMinV, ref cMaxV, fracY); }
/// <summary> /// /// </summary> /// <param name="texture"></param> /// <param name="samplerState"></param> /// <param name="location"></param> /// <param name="lod">A number that specifies the mipmap level. If the value is <=0, the zero'th (biggest map) /// is used. The fractional value (if supplied) is used to interpolate between two mipmap levels.</param> /// <returns></returns> public Number4 SampleLevel( ITexture texture, SamplerState samplerState, ref Number4 location, float lod) { // TODO: Don't always pass minifying=true to GetFilteredColor. switch (samplerState.Filter) { case Filter.MinPointMagLinearMipPoint: case Filter.MinLinearMagMipPoint: case Filter.MinMagLinearMipPoint: case Filter.MinMagMipPoint: { // Calculate nearest mipmap level. var nearestLevel = MathUtility.Round(lod); return GetFilteredColor(texture, samplerState, true, nearestLevel, ref location); } case Filter.MinLinearMagPointMipLinear: case Filter.MinMagMipLinear: case Filter.MinMagPointMipLinear: case Filter.MinPointMagMipLinear: { // Calculate nearest two levels and linearly filter between them. var nearestLevelInt = (int) lod; var d = lod - nearestLevelInt; var c1 = GetFilteredColor(texture, samplerState, true, nearestLevelInt, ref location); var c2 = GetFilteredColor(texture, samplerState, true, nearestLevelInt + 1, ref location); return Number4.Lerp(ref c1, ref c2, d); } default: throw new NotSupportedException(); } }
public VirtualMachine(BytecodeContainer bytecode, int numContexts) { if (bytecode.Shader.Version.ProgramType == ProgramType.PixelShader && numContexts % 4 != 0) throw new ArgumentOutOfRangeException("numContexts", "numContexts must be a multiple of 4 for pixel shaders."); _bytecode = bytecode; var instructionTokens = bytecode.Shader.Tokens.OfType<InstructionToken>().ToArray(); var branchingInstructions = ExplicitBranchingRewriter.Rewrite(instructionTokens); var controlFlowGraph = ControlFlowGraph.FromInstructions(branchingInstructions); _executableInstructions = ExecutableInstructionRewriter.Rewrite(controlFlowGraph).ToArray(); _requiredRegisters = RequiredRegisters.FromShader(bytecode.Shader); _executionContexts = new ExecutionContext[numContexts]; for (int i = 0; i < _executionContexts.Length; i++) _executionContexts[i] = new ExecutionContext(this, i, _requiredRegisters); ConstantBuffers = new Number4[_requiredRegisters.ConstantBuffers.Count][]; for (int i = 0; i < _requiredRegisters.ConstantBuffers.Count; i++) ConstantBuffers[i] = new Number4[_requiredRegisters.ConstantBuffers[i]]; TextureSamplers = new TextureSampler[_requiredRegisters.Resources.Count]; for (int i = 0; i < _requiredRegisters.Resources.Count; i++) TextureSamplers[i] = TextureSamplerFactory.Create(_requiredRegisters.Resources[i]); Textures = new ITexture[_requiredRegisters.Resources.Count]; Samplers = new SamplerState[_requiredRegisters.Samplers]; }
protected override Number4 GetNearestNeighbor( SamplerState samplerState, ITextureMipMap mipMap, ref Number4 texCoords) { texCoords.Int0 = MathUtility.Floor(texCoords.Float0); texCoords.Int1 = MathUtility.Floor(texCoords.Float1); return GetColor(samplerState, mipMap, ref texCoords); }
public Number4 SampleGrad( ITexture texture, SamplerState samplerState, ref Number4 location, ref Number4 ddx, ref Number4 ddy) { var lod = CalculateLevelOfDetail(texture, samplerState, ref ddx, ref ddy); return SampleLevel(texture, samplerState, ref location, lod); }
private static Number4 GetColor(SamplerState samplerState, ITextureMipMap mipMap, ref Number4 texCoords) { if (!GetTextureAddress(texCoords.Int0, mipMap.Width, samplerState.AddressU, out texCoords.Int0)) return samplerState.BorderColor; if (!GetTextureAddress(texCoords.Int1, mipMap.Height, samplerState.AddressV, out texCoords.Int1)) return samplerState.BorderColor; return mipMap.GetData(ref texCoords); }
private Number4 GetFilteredColor( ITexture texture, SamplerState samplerState, bool minifying, int level, ref Number4 location) { var clampedLevel = MathUtility.Clamp(level, 0, texture.MipMapCount - 1); ITextureMipMap mipMap; Number4 texCoords; GetMipMapAndTransformedCoordinates( texture, ref location, clampedLevel, out mipMap, out texCoords); // Minifying if (minifying) switch (samplerState.Filter) { case Filter.MinMagMipPoint: case Filter.MinMagPointMipLinear: case Filter.MinPointMagLinearMipPoint: case Filter.MinPointMagMipLinear: return GetNearestNeighbor(samplerState, mipMap, ref texCoords); case Filter.MinLinearMagMipPoint: case Filter.MinLinearMagPointMipLinear: case Filter.MinMagLinearMipPoint: case Filter.MinMagMipLinear: return GetLinear(samplerState, mipMap, ref texCoords); default: throw new NotSupportedException(); } // Magnifying switch (samplerState.Filter) { case Filter.MinLinearMagMipPoint: case Filter.MinLinearMagPointMipLinear: case Filter.MinMagMipPoint: case Filter.MinMagPointMipLinear: return GetNearestNeighbor(samplerState, mipMap, ref texCoords); case Filter.MinMagLinearMipPoint: case Filter.MinMagMipLinear: case Filter.MinPointMagLinearMipPoint: case Filter.MinPointMagMipLinear: return GetLinear(samplerState, mipMap, ref texCoords); default: throw new NotSupportedException(); } }
public override float CalculateLevelOfDetail( ITexture texture, SamplerState samplerState, ref Number4 ddx, ref Number4 ddy) { var mostDetailedMipMap = texture.GetMipMap(0, 0); int width = mostDetailedMipMap.Width; int height = mostDetailedMipMap.Height; float xBound2 = width * width; float yBound2 = height * height; float dudx2 = ddx.Float0 * ddx.Float0 * xBound2; float dvdx2 = ddx.Float1 * ddx.Float1 * yBound2; float dudy2 = ddy.Float0 * ddy.Float0 * xBound2; float dvdy2 = ddy.Float1 * ddy.Float1 * yBound2; // Proportional to the amount of a texel on display in a single pixel float pixelSizeTexelRatio2 = Math.Max(dudx2 + dvdx2, dudy2 + dvdy2); // Uses formula for p410 of Essential Mathematics for Games and Interactive Applications float result = 0.5f * MathUtility.Log2(pixelSizeTexelRatio2); // Clamp to >= 0. return Math.Max(result, 0.0f); }
public abstract float CalculateLevelOfDetail( ITexture texture, SamplerState samplerState, ref Number4 ddx, ref Number4 ddy);
protected abstract Number4 GetLinear( SamplerState samplerState, ITextureMipMap mipMap, ref Number4 texCoords);
protected abstract Number4 GetNearestNeighbor( SamplerState samplerState, ITextureMipMap mipMap, ref Number4 texCoords);
public void SetSampler(RegisterIndex registerIndex, SamplerState sampler) { Samplers[registerIndex.Index1D] = sampler; }