Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - maru

Pages: [1] 2 3 ... 892
1
Porting and API / Re: Corona Image Editor alternative?
« on: Yesterday at 16:01:36 »
I would non-ironically recommend trying developing a web tool with ChatGPT or another AI model. Here is what it was able to pull off in about 15 minutes. Just take this code and either save it as HTML or copypaste it into an online compiler like https://onecompiler.com/html/
Instructions:
1. Set up your LightMix in Corona
2. Use the "save all" option and pick PNG as the format (24-bit) - this will save all your LightSelect elements. The tool specifically expects the PNG format!
3. Click "choose files" and pick your LightSelect layers
4. What it does is blend all those layers together and display with an option to control the overall exposure. It even does the mumbo jumbo required for proper linear blending.

Feel free to take the code and develop it further with or without some help. :)

Code: [Select]
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Additive Blend Tool – Gamma Correction & Exposure</title>
  <style>
    /* Basic styles for layout and clarity */
    body { font-family: sans-serif; background: #f9f9f9; padding: 1em; }
    h2 { margin-top: 0; }
    #controls { margin-bottom: 1em; }
    label { font-weight: bold; margin-right: 0.5em; }
    input[type="range"] { vertical-align: middle; }
    input[type="number"] { width: 4em; text-align: right; }
    canvas { display: block; border: 1px solid #ccc; }
  </style>
</head>
<body>
  <h2>Additive Image Blending Tool</h2>
  <div id="controls">
    <!-- File input for multiple images -->
    <input type="file" id="fileInput" multiple accept="image/png" />
    <br/><br/>
    <!-- Exposure slider and number input -->
    <label for="exposure">Exposure:</label>
    <input type="range" id="exposure" min="0.1" max="5.0" step="0.1" value="1.0">
    <input type="number" id="exposureNum" min="0.1" max="5.0" step="0.1" value="1.0">
  </div>

  <!-- Canvas for the blended output -->
  <canvas id="canvas"></canvas>

  <script>
  // ==== Global Variables and Setup ====
  const fileInput = document.getElementById('fileInput');
  const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');
  const exposureSlider = document.getElementById('exposure');
  const exposureNum = document.getElementById('exposureNum');

  let imagesData = [];    // Array to hold image pixel data (ImageData objects or pixel arrays)
  let imgWidth = 0, imgHeight = 0;  // Dimensions of the images (assumed all the same)

  // Helper: sRGB -> Linear (gamma 2.2)
  function srgbToLinear(value) {
    // value is in [0,1] range (normalized sRGB)
    return Math.pow(value, 2.2);
  }
  // Helper: Linear -> sRGB (gamma 1/2.2)
  function linearToSrgb(value) {
    // value is in [0,1] range (linear)
    return Math.pow(value, 1/2.2);
  }

  // Main blending function: converts all images to linear, blends, then draws to canvas
  function blendImages() {
    if (imagesData.length === 0) {
      return; // No images loaded yet
    }
    const exposure = parseFloat(exposureSlider.value) || 1.0;  // current exposure multiplier

    // Create an output ImageData to hold the blended result
    let outputImage = ctx.createImageData(imgWidth, imgHeight);
    let outputPixels = outputImage.data;  // Uint8ClampedArray for output pixel bytes

    // We will accumulate linear color in a separate array of floats (to avoid precision loss during addition)
    let linearAccum = new Float32Array(imgWidth * imgHeight * 3);
    // Note: We use 3 components per pixel (R,G,B). Alpha channel, if any, is handled separately below.

    // Loop over each image’s data and accumulate linear values
    imagesData.forEach(imageData => {
      const data = imageData.data;  // Uint8ClampedArray of [r,g,b,a,...] for this image
      const len = data.length;
      for (let i = 0; i < len; i += 4) {  // iterate over every pixel (4 bytes per pixel in ImageData)
        const r_srgb = data[i]   / 255;   // normalized sRGB red
        const g_srgb = data[i+1] / 255;   // normalized sRGB green
        const b_srgb = data[i+2] / 255;   // normalized sRGB blue
        const alpha  = data[i+3] / 255;   // normalized alpha (1 = fully opaque)

        // Convert to linear and apply exposure scaling
        const r_lin = srgbToLinear(r_srgb) * exposure * alpha;
        const g_lin = srgbToLinear(g_srgb) * exposure * alpha;
        const b_lin = srgbToLinear(b_srgb) * exposure * alpha;

        // Accumulate linear values (note: index/4 gives pixel index)
        let pixelIndex = (i / 4) * 3;
        linearAccum[pixelIndex]     += r_lin;
        linearAccum[pixelIndex + 1] += g_lin;
        linearAccum[pixelIndex + 2] += b_lin;
      }
    });

    // Now linearAccum contains the sum of all images in linear space for each pixel.
    // Convert this accumulated linear color back to sRGB and store in outputPixels.
    const numPixels = imgWidth * imgHeight;
    for (let p = 0; p < numPixels; p++) {
      let r_lin_sum = linearAccum[p*3];      // accumulated linear red
      let g_lin_sum = linearAccum[p*3 + 1];  // accumulated linear green
      let b_lin_sum = linearAccum[p*3 + 2];  // accumulated linear blue

      // Clamp linear values to 1.0 (to avoid overflow beyond displayable range)
      if (r_lin_sum > 1) r_lin_sum = 1;
      if (g_lin_sum > 1) g_lin_sum = 1;
      if (b_lin_sum > 1) b_lin_sum = 1;

      // Convert back to sRGB space
      const r_srgb_out = linearToSrgb(r_lin_sum);
      const g_srgb_out = linearToSrgb(g_lin_sum);
      const b_srgb_out = linearToSrgb(b_lin_sum);

      // Convert to 0-255 and write to output pixel array
      const outIndex = p * 4;
      outputPixels[outIndex]     = Math.round(r_srgb_out * 255);
      outputPixels[outIndex + 1] = Math.round(g_srgb_out * 255);
      outputPixels[outIndex + 2] = Math.round(b_srgb_out * 255);
      outputPixels[outIndex + 3] = 255;  // Set alpha to fully opaque in output
    }

    // Draw the output ImageData onto the canvas
    ctx.putImageData(outputImage, 0, 0);
  }

  // ==== Event Handlers ====

  // Handle file input (when user selects images)
  fileInput.addEventListener('change', () => {
    const files = fileInput.files;
    if (!files || files.length === 0) return;
    imagesData = [];  // reset previous images
    // Load each file as an image
    let loadCount = 0;
    for (let file of files) {
      const reader = new FileReader();
      reader.onload = function(event) {
        const img = new Image();
        img.onload = function() {
          // Set canvas size based on first image (assuming all images same size)
          if (imgWidth === 0 && imgHeight === 0) {
            imgWidth = img.width;
            imgHeight = img.height;
            canvas.width = imgWidth;
            canvas.height = imgHeight;
          }
          // Draw image to an off-screen canvas to get pixel data
          const offCanvas = document.createElement('canvas');
          offCanvas.width = imgWidth;
          offCanvas.height = imgHeight;
          const offCtx = offCanvas.getContext('2d');
          offCtx.drawImage(img, 0, 0, imgWidth, imgHeight);
          // Get image data (this captures the RGBA pixel values of the image)
          const imageData = offCtx.getImageData(0, 0, imgWidth, imgHeight);
          imagesData.push(imageData);
          loadCount++;
          // When all images have been loaded and processed, perform the blending
          if (loadCount === files.length) {
            blendImages();
          }
        };
        img.src = event.target.result;  // start loading the image (data URL)
      };
      // Read the file as a Data URL (so we can use it as image source)
      reader.readAsDataURL(file);
    }
  });

  // Handle exposure slider change (update number field and re-blend)
  exposureSlider.addEventListener('input', () => {
    exposureNum.value = exposureSlider.value;
    blendImages();
  });
  // Handle exposure number input change (update slider field and re-blend)
  exposureNum.addEventListener('input', () => {
    // Ensure the number is clamped within min-max
    if (exposureNum.value === "") return; // ignore empty input
    let val = parseFloat(exposureNum.value);
    if (val < 0.1) val = 0.1;
    if (val > 5.0) val = 5.0;
    exposureNum.value = val.toFixed(1);
    exposureSlider.value = exposureNum.value;
    blendImages();
  });
  </script>
</body>
</html>

2
[Max] General Discussion / Re: Corona 12 Update 1
« on: Yesterday at 15:48:25 »
@tinikam - is your CPU by any chance Ryzen 9950X? Users are reporting similar problems with some potential solutions/workarounds here https://forum.corona-renderer.com/index.php?topic=43755.100

3
[C4D] General Discussion / Re: Randomizer issues
« on: Yesterday at 14:48:50 »
The best I could come up with was using the "mirrored tiling" option in the Corona Bitmap and then using a mix of Mapping Randomizer and Triplanar. :)

4
[C4D] General Discussion / Re: C4D's VFB responsiveness
« on: 2025-03-20, 16:57:47 »
I may be wrong, but I think your IR subsampling is set to 3 in the case of 3ds Max and 2 in the case of C4D.
In Max you can find this option in Render Setup > System > System settings
In C4D - Corona > Preferences

Also: in C4D you are rendering to 1280x720px and in Max 800x450.

5
[Max] General Discussion / Re: ForestPack Masking
« on: 2025-03-20, 16:36:34 »
As far as I know, it was always necessary to consider the original model when rendering masks for Forest Pack (not the Forest object itself). So if you specify different object IDs for different model objects, you end up with different mask colors. Also the include/exclude lists, for example in render elements, consider the model objects.

Maybe I misunderstood the question. Could you explain what exactly you are trying to achieve and what is happening?

Thanks!

6
I tried with the 3ds Max Color Correction and Corona Color Correct and the results seem pretty close. Could you please specify what exactly you mean by "don't get translated properly and have missing textures"? Could you share a sample scene, or at least screenshots showing what you are getting?

Update: I am pasting a maxscript I wroteChatGPT wrote. It removes the Corona Color Correct and Max Color nodes from material diffuse slots and instead plugs the bitmaps directly. It works for any material which is assigned to any scene object. I couldn't force it to affect all material editor materials, even unassigned.

Code: [Select]
-- Global recursive function to process materials
fn processMaterial mat =
(
    if mat == undefined then return ()  -- Skip if undefined

    if classof mat == CoronaPhysicalMtl then
    (
        if mat.baseTexmap != undefined do
        (
            -- If the diffuse map is a Color Correction or Corona Color Correct node, strip it
            while (classof mat.baseTexmap == Color_Correction or classof mat.baseTexmap == CoronaColorCorrect) do
            (
                local ccMap = mat.baseTexmap         -- current color correction node
                local originalMap = getSubTexmap ccMap 1  -- get its input (the bitmap)
                if originalMap == undefined then exit  -- if there is no submap, exit the loop
                mat.baseTexmap = originalMap          -- assign the bitmap directly to the diffuse slot
            )
        )
    )
    else if classof mat == MultiMaterial then
    (
        -- Process each sub-material recursively
        for s = 1 to mat.numsubs do
        (
            processMaterial mat[s]
        )
    )
    -- (Optional: handle other container material types as needed)
)

-- Main function to gather and process all materials
fn RemoveColorCorrectionsFromCoronaMaterials =
(
    local allMaterials = #()  -- array to store unique materials

    -- Add all materials assigned in the scene
    for m in scenematerials do
    (
        if m != undefined do append allMaterials m
    )

    -- Add materials from the Material Editor if not already included
    for i = 1 to meditMaterials.count do
    (
        local m = meditMaterials[i]
        if m != undefined and (findItem allMaterials m) == 0 do append allMaterials m
    )

    -- Process each material
    for mat in allMaterials do
    (
        processMaterial mat
    )
)

-- Execute the script
RemoveColorCorrectionsFromCoronaMaterials()

7
[Max] I need help! / Re: Clean blue normal sky
« on: 2025-03-18, 17:56:58 »
Place your sun very high up in the sky, or even at the zenith.

8
[Max] Bug Reporting / Re: Corona 12H1 Scaling issue
« on: 2025-03-17, 15:08:01 »
IF it's not related to Corona (I am not sure yet), then it's fixed in Max 2025. In any case, I have logged it as (Report ID=CMAX-1534).

9
[Max] I need help! / Re: Material Glossiness Problem
« on: 2025-03-17, 15:06:06 »
...or place a temporary Corona Light over the table top so that you can see its reflection. Once you are happy with your material setup, remove that temporary light.

10
Hardware / Re: 9950x3d in a "silent" build? Case choices
« on: 2025-03-17, 15:04:13 »
I don't want to ruin your plans, but here is a thread where multiple 9950X users reported performance issues with this CPU. Perhaps it would be better to consider a different model, or wait until this is fixed by Microsoft.

11
[Max] I need help! / Re: Interactive rendering slows down.
« on: 2025-03-17, 10:15:23 »
Thank you for checking!

12
[Max] Bug Reporting / Re: Corona 12H1 Scaling issue
« on: 2025-03-17, 09:53:32 »
Update: reproduced, but only in 3ds Max 2024, not 2025
I couldn't reproduce it with a similar setup but we will look into it some more. I was having similar issues during the pre-release stage but those ones were fixed.
Regarding VFB1/2 switch - you need to restart the session for it to work, e.g. reset scene.

13
[Max] I need help! / Re: Interactive rendering slows down.
« on: 2025-03-17, 09:16:23 »
Another wild guess, but hopefully worth trying:
Navigate to Windows Security > App & Browser Control > Exploit Protection and disable "Control Flow Guard"
You can also try disabling all the other settings which are listed there.
Afterwards, please restart your computer and check if the performance is any better. If not, then please turn all those options back on.
Thank you in advance for testing this.

14
[Max] I need help! / Re: Color accuracy
« on: 2025-03-14, 11:52:06 »
start with some theory: Pointer's gamut - real surface colours, measured.
https://tftcentral.co.uk/articles/pointers_gamut

Corona can process only the ones in the triangle (attached):

Could you please explain what exactly you mean here, and where you got that information from? Corona can, and does, "process" in wider gamut. In newest versions it's ACEScg (when using the 3ds Max OCIO mode). In older versions and when using the gamma 2.2 workflow, it used to be Adobe Wide RGB (for many, many, years). You can find the setting for this in "development/experimental stuff".
Max - https://support.chaos.com/hc/en-us/articles/4528523195537
C4D - https://support.chaos.com/hc/en-us/articles/4528469959953

15
[Max] I need help! / Re: Displace Problem
« on: 2025-03-13, 17:31:46 »
The object where it's not working most likely doesn't have proper UVW mapping. You can try applying a UVW Map modifier to it and applying one of the basic modes like planar.
You may also need to enable the "use real world scale" option there (if the texture has it enabled).

Pages: [1] 2 3 ... 892