Generating and saving random 3D cloud animations
-
- Addict
- Posts: 1233
- Joined: Wed Feb 28, 2007 9:13 am
- Location: London
Generating and saving random 3D cloud animations
I would like to generate random 3D animations (of moving clouds against a sky) at 1920x1080 resolution and save them as image sequences - numbered PNG files. Unfortunately, I have never done any 3D stuff with PB before. I have plenty of experience with the 2D functions, but none at all with the 3D functions.
Ogre seems capable of rendering good 3D clouds, but so does OpenGL, so I don't know which of these engines to choose. A complicating factor is that I don't know whether PB allows access to enough of the functions of these engines to draw good clouds. What would experienced users say about that?
Then there is the requirement to "record" the animations. Whether I choose OpenGL or Ogre (or some other system), I will need to be able to grab the animation 25 times a second and save it to file. Would screenshotting the window be the way to do this?
I get the feeling that this is not the kind of thing that PB's 3D engine is intended for, so I want to ask: is it insane to pursue this? Are the things I want to do actually possible with the current toolset in PB?
Thank you.
Ogre seems capable of rendering good 3D clouds, but so does OpenGL, so I don't know which of these engines to choose. A complicating factor is that I don't know whether PB allows access to enough of the functions of these engines to draw good clouds. What would experienced users say about that?
Then there is the requirement to "record" the animations. Whether I choose OpenGL or Ogre (or some other system), I will need to be able to grab the animation 25 times a second and save it to file. Would screenshotting the window be the way to do this?
I get the feeling that this is not the kind of thing that PB's 3D engine is intended for, so I want to ask: is it insane to pursue this? Are the things I want to do actually possible with the current toolset in PB?
Thank you.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Generating and saving random 3D cloud animations
Hi Seymour, Another possible solution would be to take a sequence of time-lapse photos of the real thing?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Addict
- Posts: 1233
- Joined: Wed Feb 28, 2007 9:13 am
- Location: London
Re: Generating and saving random 3D cloud animations
Yes, but the point of this is to have a program set up so that I can just press F5 and get a new cloud sequence.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Generating and saving random 3D cloud animations
- take several sets of time lapse photos?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Addict
- Posts: 1233
- Joined: Wed Feb 28, 2007 9:13 am
- Location: London
Re: Generating and saving random 3D cloud animations
Ha, unfortunately not. I am going to need possibly dozens of cloud animations.
Can anyone advise on the two challenges outlined above? Saving a 3D animation to image file, and generating high-quality 3D clouds? I'd be very grateful for any pointers.
Can anyone advise on the two challenges outlined above? Saving a 3D animation to image file, and generating high-quality 3D clouds? I'd be very grateful for any pointers.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
Re: Generating and saving random 3D cloud animations
@Seymour Clufley,
I believe Open CV will do this.
JHPJHP has made a huge project of making it accessible from PureBasic, perhaps you could ask him.
http://www.purebasic.fr/english/viewtop ... 12&t=57457
Also try Googling it as it seems that Photoshop can generate clouds, I think.
I believe Open CV will do this.
JHPJHP has made a huge project of making it accessible from PureBasic, perhaps you could ask him.
http://www.purebasic.fr/english/viewtop ... 12&t=57457
Also try Googling it as it seems that Photoshop can generate clouds, I think.
DE AA EB
-
- Addict
- Posts: 1233
- Joined: Wed Feb 28, 2007 9:13 am
- Location: London
Re: Generating and saving random 3D cloud animations
Davido,
Yes, Photoshop can generate clouds, but not 3D clouds, and in any case Photoshop can't be controlled from a PB program.
What do you think OpenCV could do? Rendering of 3D models?
Yes, Photoshop can generate clouds, but not 3D clouds, and in any case Photoshop can't be controlled from a PB program.
What do you think OpenCV could do? Rendering of 3D models?
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
Re: Generating and saving random 3D cloud animations
have a google for cloud shader glsl, would this work?
https://www.shadertoy.com/view/XsjSRt
https://www.shadertoy.com/view/XsjSRt
Windows 11, Manjaro, Raspberry Pi OS
Re: Generating and saving random 3D cloud animations
Or you could do something like this:
Download this image and save it at the same location as the source.
http://s000.tinyupload.com/?file_id=204 ... 9713839147
Code:
Download this image and save it at the same location as the source.
http://s000.tinyupload.com/?file_id=204 ... 9713839147
Code:
Code: Select all
;Modify as needed
;Try different cloud formations and skycolor etc...
;It's all about gfx...
UseJPEGImageDecoder()
UsePNGImageEncoder()
InitEngine3D()
InitSprite()
InitKeyboard()
#SeqMax = 60
#SkyColor = $FF9C39 ;Blue sky
#TexSize = 512
Structure _Object
id.i
ma.i
ms.i
tx.i
bg.i
EndStructure
Structure _Scene
cloudlayer._Object
box._Object
node.i
EndStructure
Global s._Scene, cam.i, ev.i, tx.i, Sequence.i = 0, Begin.i = #False, Quit.i = #False
Global pa.s = GetPathPart(ProgramFilename())
AntialiasingMode(#PB_AntialiasingMode_x6)
OpenWindow(0, 0, 0, 1024, 768, "Clouds - Space key = create sequence ( Key up / key down for tilt)", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768)
Add3DArchive(".", #PB_3DArchive_FileSystem)
cam = CreateCamera(#PB_Any, 0, 0, 100, 100)
With s\box
\ms = CreateCube(#PB_Any, 1)
\tx = CreateTexture(#PB_Any, 10, 10, "Sky")
StartDrawing(TextureOutput(\tx))
Box(0, 0, 10, 10, #SkyColor)
StopDrawing()
\ma = CreateMaterial(#PB_Any, TextureID(\tx))
MaterialBlendingMode(\ma, #PB_Material_Add)
MaterialCullingMode(\ma, #PB_Material_NoCulling)
\id = CreateEntity(#PB_Any, MeshID(\ms), MaterialID(\ma), 0, 0, 0)
ScaleEntity(\id, 1000, 1000, 1000)
EndWith
With s\cloudlayer
\ms = CreatePlane(#PB_Any, 1, 1, 1, 1, 1, 1)
\tx = LoadTexture(#PB_Any, "cloud.jpg")
\ma = CreateMaterial(#PB_Any, TextureID(\tx))
MaterialBlendingMode(\ma, #PB_Material_Add)
AddMaterialLayer(\ma, TextureID(\tx), #PB_Material_Replace)
AddMaterialLayer(\ma, TextureID(\tx), #PB_Material_Modulate)
ScrollMaterial(\ma, 0.004, 0.003, #PB_Material_Animated,0)
ScrollMaterial(\ma, -0.002, 0.002, #PB_Material_Animated,1)
ScrollMaterial(\ma, 0.002, -0.004, #PB_Material_Animated,2)
\id = CreateEntity(#PB_Any, MeshID(\ms), MaterialID(\ma), 0, 0, -350)
RotateEntity(\id, 90, 0, 0) ; Change x to rotate
ScaleEntity(\id, 2000, 1, 2000)
EndWith
s\node = CreateNode(#PB_Any, 0, 0, 0)
AttachNodeObject(s\node, EntityID(s\cloudlayer\id))
AttachNodeObject(s\node, EntityID(s\box\id))
Repeat
Repeat
ev = WindowEvent()
If ev = #PB_Event_CloseWindow : Quit = #True : EndIf
Until ev = 0
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up)
RotateNode(s\node, 0.1, 0, 0, #PB_Relative)
ElseIf KeyboardPushed(#PB_Key_Down)
RotateNode(s\node, -0.1, 0, 0, #PB_Relative)
EndIf
If KeyboardReleased(#PB_Key_Space)
Debug "Saving sequence...."
Sequence = 0
Begin = #True
EndIf
RenderWorld()
If Begin = #True
tx = CreateRenderTexture(#PB_Any, CameraID(cam), #TexSize, #TexSize, #PB_Texture_CameraViewPort, "Texture_" + Str(Random(200000,100)))
UpdateRenderTexture(tx)
result = SaveRenderTexture(tx, pa + "Texture_Sequence_" + Str(Sequence) + ".png")
Sequence + 1
If Sequence > #SeqMax
Begin = #False
Debug "Sequence Created..."
EndIf
FreeTexture(tx)
EndIf
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = #True
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Re: Generating and saving random 3D cloud animations
Ogre is an engine whereas OpenGL is an API. There will be more work involved if you go with OpenGL, but in the end you'll have a lot more control over how everything works. If you use PB/Ogre most of the needed systems are in place, but you might not have enough control depending on your project needs. PB/Ogre might be the better starting point if you are new to 3D.Seymour Clufley wrote: Ogre seems capable of rendering good 3D clouds, but so does OpenGL, so I don't know which of these engines to choose.
You could make many unique cloudlike 2D textures and then use them in particles/billboards to display them into different or random 3D formations. This would be easier in Ogre since it already has the basic requirements in place.Seymour Clufley wrote: A complicating factor is that I don't know whether PB allows access to enough of the functions of these engines to draw good clouds. What would experienced users say about that?
You can also use a shader to generate the clouds like in the link idle posted. Although that specific shader is only for 2D clouds.
I doubt you'd be able to get 25 screenshots in a second. More likely you'd get one per second (gpu to cpu is a slow process).Seymour Clufley wrote: I will need to be able to grab the animation 25 times a second and save it to file.
What you could do is pause the rendering system between screenshots to prevent the scene from progressing too far ahead.
It might take 25 seconds or more to capture everything, but the scene will have only advanced 1 second throughout the process.
-
- Addict
- Posts: 1233
- Joined: Wed Feb 28, 2007 9:13 am
- Location: London
Re: Generating and saving random 3D cloud animations
Thanks to everyone for your answers.
Samuel, thank you for your particularly informative reply.
I googled "3d cloud shader" and found this. The demo is incredibly good and basically what I'm looking to achieve with PB. Can you tell me what would be involved in porting it? Would I have to translate the shader into a language that Ogre understands?
There's also SkyX, which is already written for Ogre. It is also very nice, but is no longer available.
(I also found Simul Truesky, but it is unbelievably expensive (something like $25,000) so it's out of the question.)
Samuel, thank you for your particularly informative reply.
I googled "3d cloud shader" and found this. The demo is incredibly good and basically what I'm looking to achieve with PB. Can you tell me what would be involved in porting it? Would I have to translate the shader into a language that Ogre understands?
There's also SkyX, which is already written for Ogre. It is also very nice, but is no longer available.
(I also found Simul Truesky, but it is unbelievably expensive (something like $25,000) so it's out of the question.)
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
Re: Generating and saving random 3D cloud animations
That's a pretty cool demo. Are you only interested in rendering clouds or will there be other objects being rendered at the same time? Those clouds aren't using an MVP (Model, View, and Projection) matrix which will cause a headache if you try to render a world underneath those clouds.Seymour Clufley wrote: I googled "3d cloud shader" and found this.
The example looks like it is using GLSL ES 2.0 which I don't have any experience with, but at first glance it appears to be similar to GLSL. If it can be converted to GLSL then you can use it in OpenGL (supports GLSL shaders) or Ogre (supports HLSL, GLSL, and CG shaders).
-
- Addict
- Posts: 1233
- Joined: Wed Feb 28, 2007 9:13 am
- Location: London
Re: Generating and saving random 3D cloud animations
Samuel, thanks again for your expertise.
Some further questions regarding this particular shader... I realise you might not know all the answers but I'd be grateful for any light you could shed on this.
The cloud field is the same every time the demo is run. Could the shader be adapted to generate a random cloud field every time, perhaps with parameters for density etc. that could be set in the PB program code? (The cloud field seems to be derived from the noise graphic shown below the shader code. Perhaps just generating a new random noise graphic, customised by the parameters, would solve this problem.)
Could the cloud field be made "infinite", so that, no matter how long the animation lasted (an arbitrary duration set in the PB program code), we never ran out of cloud? (I'm not sure if this is already the case with this code, or whether the model is "looped" at some stage, or whether the clouds would eventually just vanish.)
Could the lighting and colouring be changed so that it looked like night-time?
Could the PB code include gradual camera moves to be executed through the course of the animation?
Given all of these requirements, would you now recommend either Ogre or OpenGL?
Thanks again.
I might want to have objects moving through the cloud field, or floating around on top of it. But I doubt there would be anything beneath it. What would be nice would be to have the camera itself be underneath the cloud field, looking up at it.Are you only interested in rendering clouds or will there be other objects being rendered at the same time? Those clouds aren't using an MVP (Model, View, and Projection) matrix which will cause a headache if you try to render a world underneath those clouds.
GLSL ES 2.0 (and 3.0) seems to be the language implemented in WebGL, for 3D inside web pages. I know nothing about this but found a post outlining the differences between GLSL ES 2.0 and GLSL.The example looks like it is using GLSL ES 2.0 which I don't have any experience with, but at first glance it appears to be similar to GLSL. If it can be converted to GLSL then you can use it in OpenGL (supports GLSL shaders) or Ogre (supports HLSL, GLSL, and CG shaders).
Some further questions regarding this particular shader... I realise you might not know all the answers but I'd be grateful for any light you could shed on this.
The cloud field is the same every time the demo is run. Could the shader be adapted to generate a random cloud field every time, perhaps with parameters for density etc. that could be set in the PB program code? (The cloud field seems to be derived from the noise graphic shown below the shader code. Perhaps just generating a new random noise graphic, customised by the parameters, would solve this problem.)
Could the cloud field be made "infinite", so that, no matter how long the animation lasted (an arbitrary duration set in the PB program code), we never ran out of cloud? (I'm not sure if this is already the case with this code, or whether the model is "looped" at some stage, or whether the clouds would eventually just vanish.)
Could the lighting and colouring be changed so that it looked like night-time?
Could the PB code include gradual camera moves to be executed through the course of the animation?
Given all of these requirements, would you now recommend either Ogre or OpenGL?
Thanks again.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Generating and saving random 3D cloud animations
Seymour, re SkyX, try asking about it in the Ogre forum, you never know what might turn up.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: Generating and saving random 3D cloud animations
The problem isn't just rendering objects under the clouds. Rendering objects in the clouds and above them could prove difficult as well. Technically rendering the objects isn't the difficult part. The difficult part lies in trying to make objects match the clouds proportionally since they are not using a standard matrix.Seymour Clufley wrote: I might want to have objects moving through the cloud field, or floating around on top of it. But I doubt there would be anything beneath it.
You may be able to tweak your objects enough to give nice results though. I guess experimentation will be the best path on this.
The clouds are only being rendered on one side. If you go under them you will just have a pure sky without any clouds.Seymour Clufley wrote: What would be nice would be to have the camera itself be underneath the cloud field, looking up at it.
If you don't plan on going through to the other side. Then the clouds could probably be flipped upside down which should give you the desired effect.
The clouds may be able to be calculated for above and below, but I don't know enough about this shader to say for sure.
Yes, changing the noise image should alter how the clouds are generated. I'm not sure if it was generated in a specific way for any reason, but I believe random noise should give you random clouds.Seymour Clufley wrote: The cloud field is the same every time the demo is run. Could the shader be adapted to generate a random cloud field every time, perhaps with parameters for density etc. that could be set in the PB program code? (The cloud field seems to be derived from the noise graphic shown below the shader code. Perhaps just generating a new random noise graphic, customised by the parameters, would solve this problem.)
There are also some parameters for how far away the clouds are rendered, and while I haven't found them yet, there should also be some for the height of the clouds.
The clouds are infinite and they appear to use a seamless loop.Seymour Clufley wrote: Could the cloud field be made "infinite", so that, no matter how long the animation lasted (an arbitrary duration set in the PB program code), we never ran out of cloud? (I'm not sure if this is already the case with this code, or whether the model is "looped" at some stage, or whether the clouds would eventually just vanish.)
Yep, I'll post some code below for you to test in ShaderToy.Seymour Clufley wrote: Could the lighting and colouring be changed so that it looked like night-time?
Yep, shouldn't be a problem.Seymour Clufley wrote: Could the PB code include gradual camera moves to be executed through the course of the animation?
I'd go with OpenGL, but that's easier for me to say because I've been using it for several years now.Seymour Clufley wrote: Given all of these requirements, would you now recommend either Ogre or OpenGL?
If this is your first 3D project then I'd recommend Ogre. If this is going to be a very large project you're working on. Then Ogre might not be a good permanent solution, but it would give you a base understanding of how 3D engines work. Which would make diving into OpenGL easier.
PB/Ogre is what I originally started with and I worked with it for 2 or so years. Then I swapped to straight OpenGL and all the things I learned with Ogre really helped me in creating my own engine.
Shadertoy example nighttime with extended cloud distance. Just paste this in the block and hit the play button below it to run.
Code: Select all
// Created by inigo quilez - iq/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// Volumetric clouds. It performs level of detail (LOD) for faster rendering
float noise( in vec3 x )
{
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
#if 1
vec2 uv = (p.xy+vec2(37.0,17.0)*p.z) + f.xy;
vec2 rg = textureLod( iChannel0, (uv+ 0.5)/256.0, 0. ).yx;
#else
ivec3 q = ivec3(p);
ivec2 uv = q.xy + ivec2(37,17)*q.z;
vec2 rg = mix( mix( texelFetch( iChannel0, (uv )&255, 0 ),
texelFetch( iChannel0, (uv+ivec2(1,0))&255, 0 ), f.x ),
mix( texelFetch( iChannel0, (uv+ivec2(0,1))&255, 0 ),
texelFetch( iChannel0, (uv+ivec2(1,1))&255, 0 ), f.x ), f.y ).yx;
#endif
return -1.0+2.0*mix( rg.x, rg.y, f.z );
}
float map5( in vec3 p )
{
vec3 q = p - vec3(0.0,0.1,1.0)*iGlobalTime;
float f;
f = 0.50000*noise( q ); q = q*2.02;
f += 0.25000*noise( q ); q = q*2.03;
f += 0.12500*noise( q ); q = q*2.01;
f += 0.06250*noise( q ); q = q*2.02;
f += 0.03125*noise( q );
return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
}
float map4( in vec3 p )
{
vec3 q = p - vec3(0.0,0.1,1.0)*iGlobalTime;
float f;
f = 0.50000*noise( q ); q = q*2.02;
f += 0.25000*noise( q ); q = q*2.03;
f += 0.12500*noise( q ); q = q*2.01;
f += 0.06250*noise( q );
return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
}
float map3( in vec3 p )
{
vec3 q = p - vec3(0.0,0.1,1.0)*iGlobalTime;
float f;
f = 0.50000*noise( q ); q = q*2.02;
f += 0.25000*noise( q ); q = q*2.03;
f += 0.12500*noise( q );
return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
}
float map2( in vec3 p )
{
vec3 q = p - vec3(0.0,0.1,1.0)*iGlobalTime;
float f;
f = 0.50000*noise( q ); q = q*2.02;
f += 0.25000*noise( q );;
return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
}
vec3 sundir = normalize( vec3(-1.0,0.0,-1.0) );
vec4 integrate( in vec4 sum, in float dif, in float den, in vec3 bgcol, in float t )
{
// lighting
vec3 lin = vec3(0.65,0.7,0.75)*1.4 + vec3(1.0, 1.0, 1.0)*dif;
vec4 col = vec4( mix( vec3(1.0,0.95,0.8), vec3(0.1,0.15,0.2), den ), den );
col.xyz *= lin;
col.xyz = mix( col.xyz, bgcol, 1.0-exp(-0.003*t*t) );
// front to back blending
col.a *= 0.4;
col.rgb *= col.a;
return sum + col*(1.0-sum.a);
}
#define MARCH(STEPS,MAPLOD) for(int i=0; i<STEPS; i++) { vec3 pos = ro + t*rd; if( pos.y<-3.0 || pos.y>2.0 || sum.a > 0.99 ) break; float den = MAPLOD( pos ); if( den>0.01 ) { float dif = clamp((den - MAPLOD(pos+0.3*sundir))/0.6, 0.0, 1.0 ); sum = integrate( sum, dif, den, bgcol, t ); } t += max(0.05,0.02*t); }
vec4 raymarch( in vec3 ro, in vec3 rd, in vec3 bgcol, in ivec2 px )
{
vec4 sum = vec4(0.0);
float t = 0.0;//0.05*texelFetch( iChannel0, px&255, 0 ).x;
MARCH(60,map5);
MARCH(60,map4);
MARCH(60,map3);
MARCH(60,map2);
return clamp( sum, 0.0, 1.0 );
}
mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
{
vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) );
vec3 cv = normalize( cross(cu,cw) );
return mat3( cu, cv, cw );
}
vec4 render( in vec3 ro, in vec3 rd, in ivec2 px )
{
// background sky
float sun = clamp( dot(sundir,rd), 0.0, 1.0 );
vec3 col = vec3(0.0,0.0,0.1) - rd.y*0.2*vec3(1.0,1.0,1.0) + 0.15*0.5;
col += 0.2*vec3(1.0,1.0,1.0)*pow( sun, 64.0 );
// clouds
vec4 res = raymarch( ro, rd, col, px );
col = col*(1.0-res.w) + res.xyz;
// sun glare
col += 0.2*vec3(1.0,1.0,1.0)*pow( sun, 64.0 );
return vec4( col, 1.0 );
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 p = (-iResolution.xy + 2.0*fragCoord.xy)/ iResolution.y;
vec2 m = iMouse.xy/iResolution.xy;
// camera
vec3 ro = 4.0*normalize(vec3(sin(24.0*m.x), 0.4*m.y, cos(24.0*m.x)));
vec3 ta = vec3(0.0, -1.0, 0.0);
mat3 ca = setCamera( ro, ta, 0.0 );
// ray
vec3 rd = ca * normalize( vec3(p.xy,1.5));
fragColor = render( ro, rd, ivec2(fragCoord-0.5) );
}
void mainVR( out vec4 fragColor, in vec2 fragCoord, in vec3 fragRayOri, in vec3 fragRayDir )
{
fragColor = render( fragRayOri, fragRayDir, ivec2(fragCoord-0.5) );
}