/// <summary> /// Read image as float array from texture evaluator. /// </summary> /// <param name="pwidth"></param> /// <param name="pheight"></param> /// <param name="textureEvaluator"></param> /// <param name="isEnvironment"></param> /// <param name="planarProjection"></param> /// <returns></returns> private static float[] ReadFloatBitmapFromEvaluator(int pwidth, int pheight, TextureEvaluator textureEvaluator, bool isEnvironment, bool planarProjection) { var fpixel = new float[pwidth * pheight * 4]; var halfpixelU = 0.5 / pwidth; var halfpixelV = 0.5 / pheight; var duvw = new Vector3d(halfpixelU, halfpixelV, 0.0); for (var x = 0; x < pwidth; x++) { for (var y = 0; y < pheight; y++) { var fx = x / (float)pwidth + halfpixelU; if (isEnvironment && !planarProjection) { fx += 0.5f; } var fy = y / (float)pheight + halfpixelV; if (planarProjection) { fy = 1.0f - fy; } // remember z can be !0.0 for volumetrics var col4F = textureEvaluator.GetColor(new Point3d(fx, fy, 0.0), duvw, duvw); var offset = x * 4 + pwidth * y * 4; fpixel[offset] = col4F.R; fpixel[offset + 1] = col4F.G; fpixel[offset + 2] = col4F.B; fpixel[offset + 3] = col4F.A; } } return(fpixel); }
public override Rhino.Display.Color4f GetColor(Rhino.Geometry.Point3d _uvw, Rhino.Geometry.Vector3d duvwdx, Rhino.Geometry.Vector3d duvwdy) { //Apply the mapping transform to get tiling and offset to work Rhino.Geometry.Point3d uvw = new Rhino.Geometry.Point3d(m_mapping * _uvw); double d = uvw.X * 20; int i = (int)d; bool useColorOne = false; if (i % 2 == 0) { useColorOne = true; } else { d = uvw.Y * 20; i = (int)d; if (i % 2 == 0) { useColorOne = true; } } if (m_bSwapColors) { useColorOne = !useColorOne; } bool textureOn = useColorOne ? m_bTexture1On : m_bTexture2On; double textureAmount = useColorOne ? m_dTexture1Amount : m_dTexture2Amount; TextureEvaluator texEval = useColorOne ? textureEvaluatorOne : textureEvaluatorTwo; Rhino.Display.Color4f color = useColorOne ? m_color1 : m_color2; if (textureOn && texEval != null) { //Ensure that the original UVW is passed into the child texture evaluator color = color.BlendTo((float)textureAmount, texEval.GetColor(_uvw, duvwdx, duvwdy)); } return(new Rhino.Display.Color4f(color)); }
private static T[] ReadBitmapFromEvaluator <T>(int pwidth, int pheight, TextureEvaluator textureEvaluator, bool planarProjection, bool isImageBased) { if (typeof(T) != typeof(float) && typeof(T) != typeof(byte)) { throw new ArgumentException($"ReadBitmapFromEvaluator doesn't supporte type {typeof(T)}"); } var upixel = new T[pwidth * pheight * 4]; var halfpixelU = 0.5 / pwidth; var halfpixelV = 0.5 / pheight; var duvw = new Vector3d(halfpixelU, halfpixelV, 0.0); if (isImageBased) { duvw.X = duvw.Y = duvw.Z = 0.0; } for (var x = 0; x < pwidth; x++) { for (var y = 0; y < pheight; y++) { var fx = x / (float)pwidth + halfpixelU; var fy = y / (float)pheight + halfpixelV; //if (planarProjection) fy = 1.0f - fy; // remember z can be !0.0 for volumetrics var col4F = textureEvaluator.GetColor(new Point3d(fx, fy, 0.0), duvw, duvw); var conv = col4F.ToArray <T>(); var offset = x * 4 + pwidth * y * 4; upixel[offset] = conv[0]; upixel[offset + 1] = conv[1]; upixel[offset + 2] = conv[2]; upixel[offset + 3] = conv[3]; } } return(upixel); }
public glTFLoader.Schema.TextureInfo AddMetallicRoughnessTexture(Rhino.DocObjects.Material rhinoMaterial) { Rhino.DocObjects.Texture metalTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Metallic); Rhino.DocObjects.Texture roughnessTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Roughness); bool hasMetalTexture = metalTexture == null ? false : metalTexture.Enabled; bool hasRoughnessTexture = roughnessTexture == null ? false : roughnessTexture.Enabled; RenderTexture renderTextureMetal = null; RenderTexture renderTextureRoughness = null; int mWidth = 0; int mHeight = 0; int rWidth = 0; int rHeight = 0; // Get the textures if (hasMetalTexture) { renderTextureMetal = rhinoMaterial.RenderMaterial.GetTextureFromUsage(Rhino.Render.RenderMaterial.StandardChildSlots.PbrMetallic); renderTextureMetal.PixelSize(out mWidth, out mHeight, out int _w0); } if (hasRoughnessTexture) { renderTextureRoughness = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrRoughness); renderTextureRoughness.PixelSize(out rWidth, out rHeight, out int _w1); } int width = Math.Max(mWidth, rWidth); int height = Math.Max(mHeight, rHeight); TextureEvaluator evalMetal = null; TextureEvaluator evalRoughness = null; // Metal if (hasMetalTexture) { evalMetal = renderTextureMetal.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal); } // Roughness if (hasRoughnessTexture) { evalRoughness = renderTextureRoughness.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal); } // Copy Metal to the blue channel, roughness to the green var bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); float metallic = (float)rhinoMaterial.PhysicallyBased.Metallic; float roughness = (float)rhinoMaterial.PhysicallyBased.Roughness; for (var j = 0; j < height - 1; j += 1) { for (var i = 0; i < width - 1; i += 1) { double x = (double)i / (double)(width - 1); double y = (double)j / (double)(height - 1); Point3d uvw = new Point3d(x, y, 0.0); float g = 0; float b = 0; if (hasMetalTexture) { Color4f metal = evalMetal.GetColor(uvw, Vector3d.Zero, Vector3d.Zero); b = metal.L; //grayscale maps, so we want lumonosity } else { b = metallic; } if (hasRoughnessTexture) { Color4f roughnessColor = evalRoughness.GetColor(uvw, Vector3d.ZAxis, Vector3d.Zero); g = roughnessColor.L; //grayscale maps, so we want lumonosity } else { g = roughness; } Color4f color = new Color4f(0.0f, g, b, 1.0f); bitmap.SetPixel(i, height - j - 1, color.AsSystemColor()); } } return(GetTextureInfoFromBitmap(bitmap)); }
private Bitmap ConvertBumpToNormal(RenderTexture bumpMapTexture) { bumpMapTexture.PixelSize(out int width, out int height, out int depth); if (width <= 0) { width = 1024; } if (height <= 0) { height = 1024; } TextureEvaluator evaluator = bumpMapTexture.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal); Bitmap bmp = new Bitmap(width, height); //Sobel filter for bump to normal conversion https://en.wikipedia.org/wiki/Sobel_operator double widthScaler = 1.0 / (width - 1); double heightScaler = 1.0 / (height - 1); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Point3d aLocation = new Point3d(Mod(x - 1, width) * widthScaler, 1.0 - Mod(y - 1, height) * heightScaler, 0.0); Point3d bLocation = new Point3d(Mod(x, width) * widthScaler, 1.0 - Mod(y - 1, height) * heightScaler, 0.0); Point3d cLocation = new Point3d(Mod(x + 1, width) * widthScaler, 1.0 - Mod(y - 1, height) * heightScaler, 0.0); Point3d dLocation = new Point3d(Mod(x - 1, width) * widthScaler, 1.0 - Mod(y, height) * heightScaler, 0.0); Point3d fLocation = new Point3d(Mod(x + 1, width) * widthScaler, 1.0 - Mod(y, height) * heightScaler, 0.0); Point3d gLocation = new Point3d(Mod(x - 1, width) * widthScaler, 1.0 - Mod(y + 1, height) * heightScaler, 0.0); Point3d hLocation = new Point3d(Mod(x, width) * widthScaler, 1.0 - Mod(y + 1, height) * heightScaler, 0.0); Point3d iLocation = new Point3d(Mod(x + 1, width) * widthScaler, 1.0 - Mod(y + 1, height) * heightScaler, 0.0); float a = evaluator.GetColor(aLocation, Vector3d.Zero, Vector3d.Zero).L; float b = evaluator.GetColor(bLocation, Vector3d.Zero, Vector3d.Zero).L; float c = evaluator.GetColor(cLocation, Vector3d.Zero, Vector3d.Zero).L; float d = evaluator.GetColor(dLocation, Vector3d.Zero, Vector3d.Zero).L; float f = evaluator.GetColor(fLocation, Vector3d.Zero, Vector3d.Zero).L; float g = evaluator.GetColor(gLocation, Vector3d.Zero, Vector3d.Zero).L; float h = evaluator.GetColor(hLocation, Vector3d.Zero, Vector3d.Zero).L; float i = evaluator.GetColor(iLocation, Vector3d.Zero, Vector3d.Zero).L; float dX = a - c + 2.0f * d + -2.0f * f + g - f; float dY = a + 2.0f * b + c - g - 2.0f * h - i; Vector3f normal = new Vector3f(dX, dY, 1.0f); normal.Unitize(); normal = normal * 0.5f + new Vector3f(0.5f, 0.5f, 0.5f); Color4f color = new Color4f(normal.X, normal.Y, normal.Z, 1.0f); bmp.SetPixel(x, y, color.AsSystemColor()); } } return(bmp); }
TextureInfo CombineBaseColorAndAlphaTexture(Rhino.Render.RenderTexture baseColorTexture, Rhino.Render.RenderTexture alphaTexture, bool baseColorDiffuseAlphaForTransparency, Color4f baseColor, bool baseColorLinear) { bool hasBaseColorTexture = baseColorTexture != null; int baseColorWidth, baseColorHeight, baseColorDepth; baseColorWidth = baseColorHeight = baseColorDepth = 0; if (hasBaseColorTexture) { baseColorTexture.PixelSize(out baseColorWidth, out baseColorHeight, out baseColorDepth); } alphaTexture.PixelSize(out int alphaWidth, out int alphaHeight, out int alphaDepth); int width = Math.Max(baseColorWidth, alphaWidth); int height = Math.Max(baseColorHeight, alphaHeight); if (width <= 0) { width = 1024; } if (height <= 0) { height = 1024; } TextureEvaluator baseColorTextureEvaluator = baseColorTexture.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal); TextureEvaluator alphaTextureEvaluator = alphaTexture.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal); Bitmap bitmap = new Bitmap(width, height); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { double x = (double)i / ((double)(width - 1)); double y = (double)j / ((double)(height - 1)); y = 1.0 - y; Point3d uvw = new Point3d(x, y, 0.0); Color4f baseColorOut = baseColor; if (hasBaseColorTexture) { baseColorOut = baseColorTextureEvaluator.GetColor(uvw, Vector3d.Zero, Vector3d.Zero); if (baseColorLinear) { baseColorOut = Color4f.ApplyGamma(baseColorOut, workflow.PreProcessGamma); } } if (!baseColorDiffuseAlphaForTransparency) { baseColorOut = new Color4f(baseColorOut.R, baseColorOut.G, baseColorOut.B, 1.0f); } Color4f alphaColor = alphaTextureEvaluator.GetColor(uvw, Vector3d.Zero, Vector3d.Zero); float alpha = baseColor.A * alphaColor.L; Color4f colorFinal = new Color4f(baseColorOut.R, baseColorOut.G, baseColorOut.B, alpha); bitmap.SetPixel(i, j, colorFinal.AsSystemColor()); } } bitmap.Save(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "out.png")); return(GetTextureInfoFromBitmap(bitmap)); }
private static void InternalMaterialBitmapFromEvaluator(ShaderBody shader, RenderTexture renderTexture, RenderMaterial.StandardChildSlots textureType, Rhino.Geometry.Transform rhinotfm, uint rId, TextureEvaluator actualEvaluator, TextureProjectionMode projectionMode, TextureEnvironmentMappingMode envProjectionMode, bool repeat) { int pheight; int pwidth; try { int u, v, w; renderTexture.PixelSize(out u, out v, out w); pheight = u; pwidth = v; } catch (Exception) { pheight = 1024; pwidth = 1024; } if (pheight == 0 || pwidth == 0) { pheight = 1024; pwidth = 1024; } Transform t = new Transform( rhinotfm.ToFloatArray(true) ); var isFloat = renderTexture.IsHdrCapable(); var isLinear = renderTexture.IsLinear(); if (isFloat) { var img = RetrieveFloatsImg(rId, pwidth, pheight, actualEvaluator, false, false, isLinear); img.ApplyGamma(shader.Gamma); switch (textureType) { case RenderMaterial.StandardChildSlots.Diffuse: shader.DiffuseTexture.IsLinear = isLinear; shader.DiffuseTexture.TexFloat = img.Data; shader.DiffuseTexture.TexByte = null; break; case RenderMaterial.StandardChildSlots.Bump: shader.BumpTexture.IsLinear = isLinear; shader.BumpTexture.TexFloat = img.Data; shader.BumpTexture.TexByte = null; break; case RenderMaterial.StandardChildSlots.Transparency: shader.TransparencyTexture.IsLinear = isLinear; shader.TransparencyTexture.TexFloat = img.Data; shader.TransparencyTexture.TexByte = null; break; case RenderMaterial.StandardChildSlots.Environment: shader.EnvironmentTexture.IsLinear = isLinear; shader.EnvironmentTexture.TexFloat = img.Data; shader.EnvironmentTexture.TexByte = null; break; } } else { var img = RetrieveBytesImg(rId, pwidth, pheight, actualEvaluator, false, false, isLinear); img.ApplyGamma(shader.Gamma); switch (textureType) { case RenderMaterial.StandardChildSlots.Diffuse: shader.DiffuseTexture.IsLinear = isLinear; shader.DiffuseTexture.TexFloat = null; shader.DiffuseTexture.TexByte = img.Data; break; case RenderMaterial.StandardChildSlots.Bump: shader.BumpTexture.IsLinear = isLinear; shader.BumpTexture.TexFloat = null; shader.BumpTexture.TexByte = img.Data; break; case RenderMaterial.StandardChildSlots.Transparency: shader.TransparencyTexture.IsLinear = isLinear; shader.TransparencyTexture.TexFloat = null; shader.TransparencyTexture.TexByte = img.Data; break; case RenderMaterial.StandardChildSlots.Environment: shader.EnvironmentTexture.IsLinear = isLinear; shader.EnvironmentTexture.TexFloat = null; shader.EnvironmentTexture.TexByte = img.Data; break; } } switch (textureType) { case RenderMaterial.StandardChildSlots.Diffuse: shader.DiffuseTexture.TexWidth = pwidth; shader.DiffuseTexture.TexHeight = pheight; shader.DiffuseTexture.ProjectionMode = projectionMode; shader.DiffuseTexture.EnvProjectionMode = envProjectionMode; shader.DiffuseTexture.Transform = t; shader.DiffuseTexture.Repeat = repeat; shader.DiffuseTexture.Name = rId.ToString(CultureInfo.InvariantCulture); break; case RenderMaterial.StandardChildSlots.Bump: shader.BumpTexture.TexWidth = pwidth; shader.BumpTexture.TexHeight = pheight; shader.BumpTexture.ProjectionMode = projectionMode; shader.BumpTexture.EnvProjectionMode = envProjectionMode; shader.BumpTexture.Transform = t; shader.BumpTexture.Repeat = repeat; shader.BumpTexture.Name = rId.ToString(CultureInfo.InvariantCulture); break; case RenderMaterial.StandardChildSlots.Transparency: shader.TransparencyTexture.TexWidth = pwidth; shader.TransparencyTexture.TexHeight = pheight; shader.TransparencyTexture.ProjectionMode = projectionMode; shader.TransparencyTexture.EnvProjectionMode = envProjectionMode; shader.TransparencyTexture.Transform = t; shader.TransparencyTexture.Repeat = repeat; shader.TransparencyTexture.Name = rId.ToString(CultureInfo.InvariantCulture); break; case RenderMaterial.StandardChildSlots.Environment: shader.EnvironmentTexture.TexWidth = pwidth; shader.EnvironmentTexture.TexHeight = pheight; // special texture, always set to Environment/Emap shader.EnvironmentTexture.ProjectionMode = TextureProjectionMode.EnvironmentMap; shader.EnvironmentTexture.EnvProjectionMode = TextureEnvironmentMappingMode.EnvironmentMap; shader.EnvironmentTexture.Transform = t; shader.EnvironmentTexture.Repeat = repeat; shader.EnvironmentTexture.Name = rId.ToString(CultureInfo.InvariantCulture); break; } }
private static FloatBitmap RetrieveFloatsImg(uint rId, int pwidth, int pheight, TextureEvaluator textureEvaluator, bool isEnv, bool planarProjection, bool isLinear) { var read = FloatImagesNew.ContainsKey(rId); var img = read ? FloatImagesNew[rId] : new FloatBitmap(rId, ReadFloatBitmapFromEvaluator(pwidth, pheight, textureEvaluator, isEnv, planarProjection), pwidth, pheight, isLinear); if (!read) { if (RcCore.It.EngineSettings.SaveDebugImages) { img.SaveBitmaps(); } lock (floatlocker) { FloatImagesNew[rId] = img; } } return(img); }
private static ByteBitmap RetrieveBytesImg(uint rId, int pwidth, int pheight, TextureEvaluator textureEvaluator, bool planarProjection, bool isLinear, bool isImageBased) { var read = ByteImagesNew.ContainsKey(rId); var img = read ? ByteImagesNew[rId] : new ByteBitmap(rId, ReadBitmapFromEvaluator <byte>(pwidth, pheight, textureEvaluator, planarProjection, isImageBased), pwidth, pheight, isLinear); if (!read) { if (RcCore.It.EngineSettings.SaveDebugImages) { img.SaveBitmaps(); } lock (bytelocker) { ByteImagesNew[rId] = img; } } return(img); }