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)