Diffrent color tone from Canvas Texture

I have the original canvas on the right and my rendered webgl on the left. Once the mesh is added to the scene, the color changes. How can I get the material color to maintain the same color tone with the original canvas?

If you add mesh, this color will change.
Can you please show image and code ?

import * as THREE from 'three'
import { boardHTML } from './templates'

let models
let mesh = new Map()
let textures = new Map()

async function getUIs(_models, { width, height }) {
  models = _models
  await createTextures({ width, height })
  console.log('yyy')
  createAllMesh({ width, height })

  return mesh
}

async function createTextures({ width, height }) {
  // Create Board Texture
  const boardTexture = await createTextureFromTemplate(boardHTML, { width, height })
  console.log(boardTexture)
  textures.set('boardTexture', boardTexture)
}

function createAllMesh({ width, height }) {
  // Create Cube Mesh
  mesh.set('cube', new THREE.Mesh(models.cube, new THREE.MeshPhongMaterial({ color: 'red' })))

  // Create Board Mesh
  const plane = new THREE.PlaneGeometry(width, height)

  const material = new THREE.MeshBasicMaterial({
    map: textures.get('boardTexture'),
    side: THREE.DoubleSide
  })

  mesh.set('board', new THREE.Mesh(plane, material))
}

// Convert the HTML to an SVG data URL
async function createTextureFromTemplate(getHTML, { width, height }) {
  const HTML = getHTML({ width, height })
  const svg = `
     <svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}">
        <foreignObject width="100%" height="100%">
            <div xmlns="http://www.w3.org/1999/xhtml">
              ${HTML}
            </div>
        </foreignObject>
    </svg>
`

  const svgBlob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' })
  const url = URL.createObjectURL(svgBlob)

  return await new THREE.TextureLoader().load(url)
}

export { getUIs }
import * as THREE from 'three'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { getUIs } from './ui'

let camera
let scene = new THREE.Scene()
const renderer = new THREE.WebGLRenderer({})

let container
let models = {}
let mesh


async function createArena(screenDiv) {
  container = screenDiv.value

  await load()
  await init()
  finalize()
}

const load = async () => {
  const loader = new GLTFLoader()

  try {
    // Get Cube Geometry From Model
    const gltf = await loader.loadAsync('../assets/dice-merge/models/cube.gltf')
    models.cube = gltf.scene.children[0].children[0].children[0].geometry
  } catch (e) {
    console.log(e)
  }
}

async function init() {
  createCamera(container.offsetWidth, container.offsetHeight)
  addLights()

  mesh = await getUIs(models, { width: container.offsetWidth, height: container.offsetHeight })

  createScene()

  setRenderer()

  configControls()
}

function finalize() {
  fitCameraView(mesh.get('board'))

  // Animate Scene
  renderer.setAnimationLoop(() => renderer.render(scene, camera))
}

// Create Camera
const createCamera = (width, height) =>
  (camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000))

// Fitting Camera To Screen
function fitCameraView(object) {
  // Step 1: Compute the bounding box of the object
  const box = new THREE.Box3().setFromObject(object)
  const boxSize = box.getSize(new THREE.Vector3())
  const boxCenter = box.getCenter(new THREE.Vector3())

  // Step 2: Determine the distance required to fit the entire object within the camera view
  const maxDim = Math.max(boxSize.x, boxSize.y, boxSize.z)
  const fov = camera.fov * (Math.PI / 180) // Convert vertical FOV from degrees to radians
  let cameraZ = maxDim / (2 * Math.tan(fov / 2))

  // Adjust the camera's position to fit the object, considering the camera's aspect ratio
  if (camera.aspect > 1) cameraZ /= camera.aspect

  camera.position.set(boxCenter.x, boxCenter.y, cameraZ + boxCenter.z)

  // Step 3: Update the camera
  camera.lookAt(boxCenter)

  // Optionally, adjust near and far planes
  camera.near = cameraZ / 100
  camera.far = cameraZ * 100

  // Update camera projection matrix after modifying properties
  camera.updateProjectionMatrix()
}

function addLights() {
  // Add Lights
  const color = 0xffffff
  const intensity = 3
  const light = new THREE.DirectionalLight(color, intensity)
  light.position.set(-1, 2, 4)
  scene.add(light)
}

// Set Renderer
function setRenderer() {
  renderer.toneMapping = THREE.NoToneMapping
  renderer.outputEncoding = THREE.sRGBEncoding;
  
  renderer.setSize(container.offsetWidth, container.offsetHeight)
  renderer.domElement.style.position = 'absolute'
  container.appendChild(renderer.domElement)
  renderer.render(scene, camera)
}

// Optional
function configControls() {
  const controls = new OrbitControls(camera, container.children[0])
  controls.target.set(0, 0, 0)
  controls.update()
}

function createScene() {
  scene.add(mesh.get('board'))
  scene.add(mesh.get('cube'))

}


export { createArena }

const boardHTML = ({ width, height }) => `
<style>
#background {
  width: ${width}px;
  height: ${height}px;
  background: #175800;
}

</style>
<div id="background" class="absolute grid content-around">
  <div class="mx-auto w-full p-4" style="max-width: 500px;" ref="board">
    <div class="grid grid-cols-5 gap-1 h-full p-1 rounded-sm" style="">
      Opposite
    </div>
  </div>

  <div class="text-center my-10">Dice</div>
  <div class="flex flex-row flex-wrap gap-3 justify-center"></div>
</div>
`

export { boardHTML }

The color is not the same with the color code in my blob

Did you mean to post the before and after screenshots? there is only one image posted…

How are you setting the color for the canvas vs the renderer vs the scene.background?

Are you trying to use a transparent canvas? (you may need alpha:true in your renderer constructor)


Opps. I meant to upload this image instead.

However I found the fault and changed it. I was using the npm version of three.js. I switched to the cdn version and the output comes out fine now.

1 Like