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 “Blur” camera filter but looks like it doesn’t work with RenderToCubemap.
the othert option is to fake a “blur”using cube mipmap level…
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…)
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
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:
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);
}
}
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…
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…
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