"Blur on CubeMap " / How to acces certains mipmap level of cubemap. ?

Hi,
i would like to perform a “Blur” effect on a script generated cubemap,
i did try to do GetPixels() / PutPixels() and compute blur with a script but it’s too power consuming.
i did try the “Blurcamera filter but looks like it doesn’t work with RenderToCubemap.

the othert option is to fake a “blur” using cube mipmap level

ex: 
mipmap level 0 : Clean texture
mipmap level 5 : Blured texture (low res tex)

so i would like to acces mipmap level on demande like the “texCUBEbias()” “cg” or “hlsl” fonction. but i fail again to find a way to acces this mipmap…

any idea ?
thanks

(or if someone know a way to blur cubemap directly without using GetPixels / PutPixels…)

I think you can create 6 cameras and render a cubemap “manually” (and apply a blur posteffect to each camera).

hi, thanks,
but, by doing that, i’ll end up doing 6 times “GetPixels()/SetPixels()” to construct my cubemap…
as i’m computing large amount of cubemap it cost a lot…

isn’t there any way to acces cubemap mipmaplevel ? (without GetPixels()/SetPixels()???)

you need exactly 0 get - set pixels, the idea of using a camera to do it is that you render the camera content straight into the cubemaps texturebuffers without touching the cpu.

This is assuming that you are owning Pro, otherwise its not reasonably possible at all.

Also if you know a cg function that does it, you should be able to use it with unity, just ensure that you use the SM3 pragma in case its an SM3+ only function.

Also you can just force the texture into a lower mipmap level through mipMapBias on the texture class from which all real texture implementations extend

texCUBElod

But as i know, dynamic-generated cubemaps has no mip-map’s

hoo tanks, i had miss the “#pragma target 3.0”
now texCUBElod and texCUBEbias are working perfectly and i can access the mipmap level i want :slight_smile:

thank’s everybody !

by the way, did some one know a way to minimize “cube seams” ??

try setting wrapmode=clamp in your RTT (if it’s not already set like that)

Hi,
first of all, thank you for the help :slight_smile:

i did some really basic shader that use a auto-generated Cubemap. and I’m experiencing strange behaviors.
1/ MipMap Levels:
I use tecCUBEbias(); to acces mipmap level of the cubemap to make a “blur” like effect.
but it’s look like there is a conflict with the mipmap level i set and the one used by the camera.
When i look at the object i can see triangles that are mapped with an other mipmap level making “z-fight” like effect.
(see: fig.01.jpg)
→ how can i force the render to “ONLY” use the mipmap level i want ? (something like #pragma doNotMipTheMap in the shader)

/*-------------- THIS PART SOLVED – THE PROBLEM HAVE VANISHED
2/texCUBElod(); use:
to simulate some indirect lighting, I perform a texCUBElod() lookup into the vertex function and paste the value to the surface. It works quite well… when i render the cube in ONE PASS

For performance purpose, i decided to render On face of the Cubemap per frame. then the rendered image start flickering.It 's really strange because the rendered Cube doesn’t flicker at all when using texCUBE lookup in the pixel function. if I disable the texCUBElod() everythings is all right.
The stranger thing is even if i don’t use the color value of the texCUBElod() lookup, the Cubemap is flikering.
the only fact of accessing the Cubemap in the vertex function makes the all thing flicker.
→ How can I fix this up ? (not rendering all the face in one frame)
--------------------------------------------------------------*/
here is the shader:

Shader "Reflction" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_Cube("reflection",Cube) =  "white" {}
		
		_cubeBlurr("blur Amount", range(0,6)) = 0
		
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf BlinnPhong vertex:vert
		#pragma target 3.0
		
		
		struct Input {
			float2 uv_MainTex;
			float4 vColor;
			float3 worldRefl;	
			
			INTERNAL_DATA
		};
		
		sampler2D _MainTex;
		samplerCUBE _Cube;
		
		void vert(inout appdata_full v, out Input o){
			#if !defined(SHADER_API_OPENGL)
			o.vColor = texCUBElod (_Cube, float4(v.normal,3));
			#endif
		
		}
		
		int _cubeBlurr;
		
		void surf (Input IN, inout SurfaceOutput o) {
			o.Albedo = IN.vColor;
			//o.Emission = texCUBEbias(_Cube, float4(IN.worldRefl, _cubeBlurr)).rgb ;

		}
		ENDCG
	} 
	FallBack "Diffuse"
}

the AutoCube script:

using UnityEngine;
using System.Collections;


[ExecuteInEditMode()]  
[AddComponentMenu("Mutsu/AutoEnvMap")]
public class autoEnvMap : MonoBehaviour {

	public int _cubeMapSize = 256;
	public LayerMask _layerMask;	
	
	private GameObject _cubeCam;
	private RenderTexture _cubeMap;
	

	// --------------------------------------------------------

	void LateUpdate () {
		
		// Get the CubemapCamera in the scene.
		_cubeCam = GameObject.Find("CubemapCamera");
		
		if (!_cubeCam) { // If there is no CubemapCamera create One
			_cubeCam = new GameObject("CubemapCamera",typeof(Camera)); 
			_cubeCam.camera.transform.rotation = Quaternion.identity;
			_cubeCam.camera.renderingPath = RenderingPath.Forward;
			_cubeCam.camera.nearClipPlane = 0.001f;
			_cubeCam.camera.farClipPlane = 100f;
			_cubeCam.camera.enabled = false;			
		}
		// set the camera position and the objects layer to be rendered
		_cubeCam.camera.transform.position = transform.position;
		_cubeCam.camera.cullingMask = _layerMask;
		
		
		if(!_cubeMap){ // check for the RenderTexture and create one if needed.
			_cubeMap = new RenderTexture(_cubeMapSize, _cubeMapSize, 16);
			// Set the RenderTexture to be a Cubemap that is PowerOfTwo and use MipMap
			_cubeMap.isCubemap = true;			_cubeMap.isPowerOfTwo = true;
			_cubeMap.useMipMap = true;			_cubeMap.anisoLevel = 9;
		}
		
		// Select the face of the cube to render and render 
		int faceToRender = 1 << (Time.frameCount % 6); // here it's "one face per frame" 
		_cubeCam.camera.RenderToCubemap (_cubeMap, faceToRender);

		// Check for the "_Cube" property in all the object's materials 
		for (int imat = 0; imat < this.renderer.sharedMaterials.Length ; imat++) {
			if (this.renderer.sharedMaterials[imat].HasProperty("_Cube")){
				this.renderer.sharedMaterials[imat].SetTexture("_Cube", _cubeMap);
			}		
		}		
	}
	
	void OnDisable () {
		DestroyImmediate (_cubeCam);
		DestroyImmediate (_cubeMap);
	}	
}

thanks…

450219--15696--$fig.01.jpg

1 Like

Ho by the way, one more question…
I also have a message in the editor that says :

Cleaning up leaked objects in scene since no game object, component or manager is referencing them
 RenderTexture has been leaked 1 times.

looks like the texture is lost in the wild… did i forgot some important destroy thing?

thank you…

You can’t really blur cubemaps with miplevels without getting seams, as each face is mipmapped separately. If your cubemaps can be prerendered,you can blur them with CubeMapGen, a free application meant for that exact purpose.

Hi,
I’d like to be able to blur the rendered image on a cubemap as well. Can’t I just attach a blur script to the generated camera just like i do with a placed camera?
I seem to be having a problem with doing this using this script from the tutorial:

// Attach this script to an object that uses a Reflective shader.
// Realtime reflective cubemaps!

@script ExecuteInEditMode

var cubemapSize = 128;
var oneFacePerFrame = false;
private var cam : Camera;
private var rtex : RenderTexture;

function Start () {
// render all six faces at startup
UpdateCubemap( 63 );
}

function LateUpdate () {
if (oneFacePerFrame) {
var faceToRender = Time.frameCount % 6;
var faceMask = 1 << faceToRender;
UpdateCubemap (faceMask);
} else {
UpdateCubemap (63); // all six faces
}
}

function UpdateCubemap (faceMask : int) {
if (!cam) {
var go = new GameObject ("CubemapCamera", Camera);
go.hideFlags = HideFlags.HideAndDontSave;
go.transform.position = transform.position;
go.transform.rotation = Quaternion.identity;
cam = go.camera;
cam.farClipPlane = 100; // don't render very far into cubemap
cam.enabled = false;
cam.gameObject.AddComponent ("Blur");
}

if (!rtex) { 
rtex = new RenderTexture (cubemapSize, cubemapSize, 16);
rtex.isPowerOfTwo = true;
rtex.isCubemap = true;
rtex.hideFlags = HideFlags.HideAndDontSave;
renderer.sharedMaterial.SetTexture ("_Cube", rtex);
}

cam.transform.position = transform.position;
cam.RenderToCubemap (rtex, faceMask);
}

function OnDisable () {
DestroyImmediate (cam);
DestroyImmediate (rtex);
}

I tried to add this line:

cam.gameObject.AddComponent ("Blur");

where “Blur” is the name of the blur script I am using.

but nothing happens. In fact, adding any type of script to this code does nothing.

Since Unity 4 there’s a new option called Cubemap.SmoothEdges .
When importing custom cubemap texture and use them with the Reflection Texture Type in the inspector that give you an option called “Fixeup Edge Seams”.

Maybe in some ways you can add it to your cubemap script code.

may be wrong but i think what tokyob means is that as the camera moves thecube map is going through the mip levels instead of just using the one that it is set to? i am also seeing this behavior. was it ever solved?

I put together this script/shader to turn a cubemap into an equirectangular map, so you can easily sample any mip level of the texture to get blurry reflections and not have the edges go strange…

so with your script we can convert a prebaked cubemap into equirectangular map?

Yeah, although if it’s pre-baked you’re probably better off doing that offline, rather than in real-time (i.e. transfer the functionality of cubemapToEquirectangular.shader into an editor script).

Not sure what the code for that would be, though - I haven’t played with sampling cubemaps via script.

You might be able to use Graphics.Blit as per normal and get it to save the resulting texture out to an image…

Ah alright, i was looking a way to convert a prebaked cubemap from unity into a reflection texture.

I’ve updated the gist to contain a Wizard that will convert a cubemap into an equirectangular texture.

Requires Pro, I think.

Oh wow, thank you so much for this.
actually i was about to post this http://wiki.unity3d.com/index.php?title=Skybox_Generator
but yeah if we want to process the cubemap with amd cubemapgen i think skybox generator is the best match.
the front and back is flipped in amd cubemapgen though

still trying to solve this bit here…

“-> how can i force the render to “ONLY” use the mipmap level i want ? (something like #pragma doNotMipTheMap in the shader)”

I cant seem to find a way to use the mip levels as blur only without it changing as the camera moves.