Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | Xqua |
Alright I’ve been at this for a bit and the doc didn’t help me
Just for context, my goal is to make a RayMarching shader through a 3D volumetric dataset from microscopy recording. I’ve done it in Unity in the past and I want to continue this project. But I want to switch to Godot, out of principles, and because the Node system is just amazing.
So here I am trying to create a simple RayMarching shader through a cube, and I need to pass my 3D texture so that I can sample from the volume in the fragment shader.
So, as per the documentation, I need to use the inherited function set_layer_data
which takes an Image instance, and an layer Int. Ok all good !
Well no … the layer never gets set and pixels stay at [0.0, 0.0, 0.0, 1.0]
Here is my code sample so that one of you wizard might see what I am doing wrong …
extends MeshInstance
var mat = get_surface_material(0)
func _ready():
# Instanciate a Texture3D
var tex3D = Texture3D.new()
# Create the texture with a 64 cube with RGB8 format, we won't need Alpha
tex3D.create(64, 64, 64, Image.FORMAT_RGB8)
# Instanciate an image this will serve as our layer for now
var img = Image.new()
# Let's give it the right dimension 64x64 and the right format
img.create(64, 64, false, Image.FORMAT_RGB8)
# Gotta Lock it to set a pixel (this is confusing ... Like, Lock? Why not "Unlock" it ??? Anyhow)
img.lock()
# Define out color
var c1 = Color("#ffb2d90a")
# And set the pixel
img.set_pixel(31, 31, c1)
# Let's check that it worked ?
print(img.get_pixel(31, 31))
# This gives me a beautiful: 0.698039,0.85098,0.039216,1
# Amazing let's set the layer then !
tex3D.set_layer_data(img, 0)
# Great so then let's see if it worked ?
print(tex3D.get_layer_data(0).get_pixel(31, 31))
# 0,0,0,1
# What ? O.o
print(tex3D.data['layers'][0].get_pixel(31, 31))
# 0,0,0,1
# Yup nothing !
# Let's feed the texture to the shader
mat.set_shader_param("My3DTexture", tex3D)
Edit: I also checked that I wasn’t crazy by trying this on a 2D texture on a Sprite, and this worked just fine, so the pixel setting on an img works along with the texture shader pipeline.
extends Sprite
func _ready():
var texture = ImageTexture.new()
var img = Image.new()
# Let's give it the right dimension 64x64 and the right format
img.create(64, 64, false, Image.FORMAT_RGB8)
# Gotta Lock it to set a pixel (this is confusing ... Like, Lock? Why not "Unlock" it ??? Anyhow)
img.lock()
# Define out color
var c1 = Color("#ffb2d90a")
# And set the pixel
img.set_pixel(0, 0, c1)
img.set_pixel(1, 1, c1)
img.set_pixel(2, 2, c1)
img.set_pixel(3, 3, c1)
texture.create_from_image(img)
material.set_shader_param("tex", texture)