Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom mipmaps not working #66

Closed
Displee opened this issue Nov 26, 2020 · 5 comments
Closed

Custom mipmaps not working #66

Displee opened this issue Nov 26, 2020 · 5 comments
Labels
bug Something isn't working

Comments

@Displee
Copy link
Contributor

Displee commented Nov 26, 2020

I try to use my own generated mipmaps, but for whatever reason my geometry always turns black when I do this. I copied the textures example and only edited the material of the plane buffer geometry:

package info.laht.threekt.examples.textures

import info.laht.threekt.*
import info.laht.threekt.cameras.PerspectiveCamera
import info.laht.threekt.controls.OrbitControls
import info.laht.threekt.geometries.BoxBufferGeometry
import info.laht.threekt.geometries.PlaneBufferGeometry
import info.laht.threekt.geometries.SphereBufferGeometry
import info.laht.threekt.loaders.TextureLoader
import info.laht.threekt.materials.MeshBasicMaterial
import info.laht.threekt.math.Color
import info.laht.threekt.math.DEG2RAD
import info.laht.threekt.objects.Mesh
import info.laht.threekt.renderers.GLRenderer
import info.laht.threekt.scenes.Scene
import info.laht.threekt.textures.Image
import info.laht.threekt.textures.Texture
import kotlinx.io.core.IoBuffer
import org.lwjgl.BufferUtils
import java.awt.image.DataBufferByte
import java.io.File
import javax.imageio.ImageIO

object TextureExample {

	@JvmStatic
	fun main(args: Array<String>) {

		Window(antialias = 4).use { canvas ->

			val scene = Scene().apply {
				setBackground(Color.aliceblue)
			}

			val camera = PerspectiveCamera(75, canvas.aspect, 0.1, 1000)
			camera.position.z = 10f

			val renderer = GLRenderer(canvas.size).apply {
				checkShaderErrors = true
			}

			Mesh(PlaneBufferGeometry(10f, 10f), MeshBasicMaterial().apply {
				color.set(Color.gray)
				val repeatS = true
				val repeatT = true
				val useMipmaps = true
				map = Texture(
					format = TextureFormat.RGBA,
					type = TextureType.UnsignedByte,
					mapping = TextureMapping.UV,
					wrapS = if (repeatS) TextureWrapping.Repeat else TextureWrapping.ClampToEdge,
					wrapT = if (repeatT) TextureWrapping.Repeat else TextureWrapping.ClampToEdge,
					minFilter = if (useMipmaps) TextureFilter.LinearMipMapLinear else TextureFilter.Linear,
					magFilter = TextureFilter.Linear
				)
				val images = arrayOf(
					loadImage("C:\\Users\\Displee\\Documents\\Projects\\Github\\rs-model-editor-kt\\texture_228_0.png"),
					loadImage("C:\\Users\\Displee\\Documents\\Projects\\Github\\rs-model-editor-kt\\texture_228_1.png"),
					loadImage("C:\\Users\\Displee\\Documents\\Projects\\Github\\rs-model-editor-kt\\texture_228_2.png"),
					loadImage("C:\\Users\\Displee\\Documents\\Projects\\Github\\rs-model-editor-kt\\texture_228_3.png"),
					loadImage("C:\\Users\\Displee\\Documents\\Projects\\Github\\rs-model-editor-kt\\texture_228_4.png"),
					loadImage("C:\\Users\\Displee\\Documents\\Projects\\Github\\rs-model-editor-kt\\texture_228_5.png"),
					loadImage("C:\\Users\\Displee\\Documents\\Projects\\Github\\rs-model-editor-kt\\texture_228_6.png"),
				)
				map?.image = images[0]
				map?.mipmaps?.addAll(images)
				map?.needsUpdate = true
			}).also {
				it.rotation.x = DEG2RAD * -90
				it.translateZ(-1f)
				scene.add(it)
			}


			Mesh(BoxBufferGeometry(1f), MeshBasicMaterial().apply {
				color.set(Color.gray)
				map = TextureLoader.load(javaClass.classLoader.getResource("textures/crate.gif")!!.file)
			}).also {
				it.translateY(2f)
				scene.add(it)
			}

			Mesh(SphereBufferGeometry(0.5f), MeshBasicMaterial().apply {
				color.set(Color.gray)
				map = TextureLoader.load(javaClass.classLoader.getResource("textures/checker.png")!!.file)
			}).also {
				it.translateY(4f)
				scene.add(it)
			}

			OrbitControls(camera, canvas)

			canvas.animate {
				renderer.render(scene, camera)
			}

		}

	}

	fun loadImage(path: String): Image {
		val bufferedImage = ImageIO.read(File(path))
		val byteArray = (bufferedImage.raster.dataBuffer as DataBufferByte).data
		val textureImageBuffer = IoBuffer(BufferUtils.createByteBuffer(byteArray.size))
		textureImageBuffer.writeFully(byteArray, 0, byteArray.size)
		return Image(bufferedImage.width, bufferedImage.height, textureImageBuffer)
	}

}

Result:
Mipmaps example

My mipmaps:
64x64:
Mipmap 64x64
32x32:
Mipmap 32x32
16x16:
Mipmap 16x16
8x8:
Mipmap 8x8
4x4:
Mipmap 4x4
2x2:
Mipmap 2x2
1x1:
Mipmap 1x1

Am I doing something wrong?

@markaren
Copy link
Owner

No idea.. Your are kinda venturing into uncharted territory. But what if you use the supplied ImageLoader ?

@Displee
Copy link
Contributor Author

Displee commented Nov 27, 2020

Yeah I can also use the ImageLoader, but that gives me the same result.

I tried implementing this example: https://sbcode.net/threejs/custom-mipmaps/ into threekt.

But I get the same problem here (left is threejs, right is threekt):
threejs mipmaps vs threekt mipmaps

Here's the code:

package info.laht.threekt.examples.textures

import info.laht.threekt.TextureFilter
import info.laht.threekt.TextureWrapping
import info.laht.threekt.Window
import info.laht.threekt.cameras.PerspectiveCamera
import info.laht.threekt.controls.OrbitControls
import info.laht.threekt.geometries.PlaneBufferGeometry
import info.laht.threekt.helpers.AxesHelper
import info.laht.threekt.loaders.ImageLoader
import info.laht.threekt.materials.MeshBasicMaterial
import info.laht.threekt.math.Color
import info.laht.threekt.objects.Mesh
import info.laht.threekt.renderers.GLRenderer
import info.laht.threekt.scenes.Scene
import info.laht.threekt.textures.Image
import info.laht.threekt.textures.Texture
import kotlinx.io.core.IoBuffer
import org.lwjgl.BufferUtils
import java.awt.image.DataBufferByte
import java.io.File
import javax.imageio.ImageIO

object TextureExample {

	@JvmStatic
	fun main(args: Array<String>) {

		Window(antialias = 4).use { canvas ->

			val scene = Scene().apply {
				setBackground(Color.aliceblue)
			}

			val camera = PerspectiveCamera(75, canvas.aspect, 0.01, 1000)
			camera.position.z = 1f

			val renderer = GLRenderer(canvas.size).apply {
				checkShaderErrors = true
			}

			val axesHelper1 = AxesHelper(5)
			scene.add(axesHelper1)
			val axesHelper2 = AxesHelper(5)
			scene.add(axesHelper2)

			val planeGeometry1 = PlaneBufferGeometry()
			val planeGeometry2 = PlaneBufferGeometry()

			val mipmap: (Int, String) -> Image = { size, color ->
				ImageLoader.load("C:\\Users\\Displee\\Desktop\\textures\\texture_1_$size.png", false)
			}

			val texture1 = Texture()
			texture1.mipmaps.add(mipmap(128, "#ff0000"))
			texture1.mipmaps.add(mipmap(64, "#00ff00"))
			texture1.mipmaps.add(mipmap(32, "#0000ff"))
			texture1.mipmaps.add(mipmap(16, "#880000"))
			texture1.mipmaps.add(mipmap(8, "#008800"))
			texture1.mipmaps.add(mipmap(4, "#000088"))
			texture1.mipmaps.add(mipmap(2, "#008888"))
			texture1.mipmaps.add(mipmap(1, "#880088"))
			texture1.repeat.set(5f, 5f)
			texture1.wrapS = TextureWrapping.Repeat
			texture1.wrapT = TextureWrapping.Repeat

			val texture2 = Texture()
			texture2.mipmaps.add(mipmap(128, "#ff0000"))
			texture2.mipmaps.add(mipmap(64, "#00ff00"))
			texture2.mipmaps.add(mipmap(32, "#0000ff"))
			texture2.mipmaps.add(mipmap(16, "#880000"))
			texture2.mipmaps.add(mipmap(8, "#008800"))
			texture2.mipmaps.add(mipmap(4, "#000088"))
			texture2.mipmaps.add(mipmap(2, "#008888"))
			texture2.mipmaps.add(mipmap(1, "#880088"))
			texture2.repeat.set(5f, 5f)
			texture2.wrapS = TextureWrapping.Repeat
			texture2.wrapT = TextureWrapping.Repeat
			texture2.minFilter = TextureFilter.Nearest
			texture2.magFilter = TextureFilter.Nearest

			val material1 = MeshBasicMaterial().apply {
				map = texture1
			}
			val material2 = MeshBasicMaterial().apply {
				map = texture2
			}

			val plane1 = Mesh(planeGeometry1, material1)
			val plane2 = Mesh(planeGeometry2, material2)

			scene.add(plane1)
			scene.add(plane2)

			OrbitControls(camera, canvas).apply {
				screenSpacePanning = true
			}

			canvas.animate {
				renderer.render(scene, camera)
			}

		}

	}

}

This would serve as a good example tbh (to test if custom mipmaps works).

Here are the mipmaps I used:
128x128
128x128
64x64
64x64
32x32
32x32
16x16
16x16
8x8
8x8
4x4
4x4
2x2
2x2
1x1
1x1

@markaren markaren added the bug Something isn't working label Nov 27, 2020
@markaren
Copy link
Owner

I added MipMapsFailingExample to the code base. I doubt I will ever get around to fix this, as it is a feature I'm not using in my limited use of this library. Feel free to give it a go!

@Displee
Copy link
Contributor Author

Displee commented Nov 27, 2020

I tried debugging it, but everything looks alright (compared to threejs). This is a really weird bug. I guess I need to dive deeper into the issue. Thanks though.

@markaren
Copy link
Owner

Closed by #68

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants