Можешь щейдер годота пререписать на шейдер для юнити 3д


shader_type spatial;
//render_mode unshaded;

const float ROOM_SIZE = 2.;

uniform sampler2D cubemap_albedo : hint_albedo;
uniform sampler2D cubemap_normalmap : hint_normal;
uniform sampler2D cubemap_emission : hint_black_albedo;

uniform float room_depth : hint_range(0., 4.0, 0.01) = 1.;
uniform float emission_strength : hint_range(0., 10., 0.01) = 0.;

varying vec3 obj_vertex;
varying flat vec3 obj_cam;

float remap_range(float value, float min_in, float max_in, float min_out, float max_out) {
    return(value - min_in) / (max_in - min_in) * (max_out - min_out) + min_out;
}

float bool_to_sign(bool b) {
	return (b) ? 1. : -1.;
}

vec3 sample_cubemap(sampler2D cubemap, vec2 uv, vec3 face) {
	face = normalize(face);
	
	if (face.x == 1.) {
		//+X
		uv.x = remap_range(uv.x, 0., 1., 0., 1./3.);
		uv.y = remap_range(uv.y, 0., 1., 0., 1./2.);
	}
	else if (face.x == -1.) {
		//-X
		uv.x = remap_range(uv.x, 0., 1., 0., 1./3.);
		uv.y = remap_range(uv.y, 0., 1., 1./2., 1.);
	}
	else if (face.y == 1.) {
		//+Y
		uv.x = remap_range(uv.x, 0., 1., 1./3., 2./3.);
		uv.y = remap_range(uv.y, 0., 1., 0., 1./2.);
	}
	else if (face.y == -1.) {
		//-Y
		uv.x = remap_range(uv.x, 0., 1., 1./3., 2./3.);
		uv.y = remap_range(uv.y, 0., 1., 1./2., 1.);
	}
	else if (face.z == 1.) {
		//+Z
		uv.x = remap_range(uv.x, 0., 1., 2./3., 1.);
		uv.y = remap_range(uv.y, 0., 1., 0., 1./2.);
	}
	else if (face.z == -1.) {
		//-Z
		uv.x = remap_range(uv.x, 0., 1., 2./3., 1.);
		uv.y = remap_range(uv.y, 0., 1., 1./2., 1.);
	}
	
	return texture(cubemap, uv).rgb;
}

void vertex() {
	if (room_depth != 0.) {
		vec2 d = vec2(ROOM_SIZE, ROOM_SIZE)/2.;
		vec3 delta = vec3(d.x, 0., d.y);
		
		obj_vertex = VERTEX - delta;
		
		//camera pos in obj space
		obj_cam = inverse(MODELVIEW_MATRIX)[3].xyz - delta;
	}
}

void fragment() {
	vec3 cm_face = vec3(0., 0., 1.);
	vec2 cm_uv = UV;
		
	if (room_depth != 0.) {
		float depth = room_depth * 2.;
		vec3 cam2pix = obj_vertex - obj_cam;
		
		//camp2pix.y <= 0 --> show floor
		//camp2pix.y > 0 --> show ceiling
		float is_floor = step(cam2pix.y, 0.);
		float ceil_y   = ceil(obj_vertex.y / depth - is_floor) * depth;
		float ceil_t   = (ceil_y - obj_cam.y) / cam2pix.y;
		
		//camp2pix.z <= 0 --> show north
		//camp2pix.z > 0 --> show south
		float is_north = step(cam2pix.z, 0.);
		float wall_f_z = ceil(obj_vertex.z / ROOM_SIZE - is_north) * ROOM_SIZE;
		float wall_f_t = (wall_f_z - obj_cam.z) / cam2pix.z;
		
		//camp2pix.x <= 0 --> show east
		//camp2pix.x > 0 --> show west
		float is_east  = step(cam2pix.x, 0.);
		float wall_e_z = ceil(obj_vertex.x / ROOM_SIZE - is_east) * ROOM_SIZE;
		float wall_e_t = (wall_e_z - obj_cam.x) / cam2pix.x;
		
		vec2 tex_coord;
		float min_t = min(min(ceil_t, wall_e_t), wall_f_t);
		
		if (wall_e_t == min_t) {
			//East / West
			tex_coord = obj_cam.zy + wall_e_t * cam2pix.zy;
			cm_face = vec3((is_east == 0.) ? 1. : -1., 0., 0.);
		}
		else if (wall_f_t == min_t) {
			//Front / Back
			tex_coord = obj_cam.xy + wall_f_t * cam2pix.xy;
			cm_face = vec3(0., (is_north == 0.) ? -1. : 1., 0.);
		}
		else if (ceil_t == min_t) {
			//Ceiling / Floor
			tex_coord = obj_cam.xz + ceil_t * cam2pix.xz;
			cm_face = vec3(0., 0., (is_floor == 0.) ? -1. : 1.);
		}
		
		if (!(ceil_t == min_t)) {
			tex_coord.y /= room_depth;
		}
		
		cm_uv = (tex_coord*.5 + 1.);
		
		cm_uv.x = clamp(cm_uv.x, 0., 1.);
		cm_uv.y = clamp(cm_uv.y, 0., 1.);
	}	
		
	ALBEDO = sample_cubemap(cubemap_albedo, cm_uv, cm_face);
	NORMAL = sample_cubemap(cubemap_normalmap, cm_uv, cm_face);
	EMISSION = sample_cubemap(cubemap_emission, cm_uv, cm_face) * emission_strength;
}