ambiera logo

Ambiera Forum

Discussions, Help and Support.

folder icon Ambiera Forum > CopperCube > Help with CopperCube
forum topic indicator chromatic aberration effect
person icon
kane_kki
Registered User
Quote
2024-09-29 20:39:48

Hey!
I made a game that I almost finished,
and here I just added some effects so that the game is a little bit nicer, and I would like to add some chromatic aberration to it but I don't know how to do that.
Can someone help me?

person icon
guest_Guest
Guest
Quote
2024-09-29 20:47:42

Use shaders or screen shaders extension by JIC you need to modify it though.

person icon
okeoke
Registered User
Quote
2024-09-29 22:26:25

Do you want to achieve something like that?
embedded external image
🔎︎


I've only made it for OpenGL, since I'm not that familiar with hlsl. But the approach will be the same.

1. You need to setup a full screen "filter node" on top of your camera. Just refer to JIC's video here: https://youtu.be/mpHAUPlb71w?t=1...

Since I'm using OpenGl I also had to flip mesh normal (right click on the mesh -> modify selection -> flip direction of all faces) and set Z scale to -2.91. And change publish setting renderer to OpenGL.

2. Write an action that uses render to texture to render your camera view to the "filter node", and shader which adds CA effect to it.

2.1 Use RTT function to render to texture:
ccbRegisterOnFrameEvent(function () {
ccbRenderToTexture(ccbGetSceneNodeFromName('fullScreenPlane'), ccbGetActiveCamera(), 0, ccbGetScreenWidth(), ccbGetScreenHeight());
});


Notice that this could be optimized by storing screen height, width, filter node as variables or using JS closure to generate this function.

Also notice that RTT function only works inside onFrameEvent, it could not be added to behavior onAnimate.

2.2 Shader. I simply copied glsl vertex shader from here: https://www.ambiera.com/coppercu....
Fragment shader shifts red and blue uv texture coordinate to -0.005 and 0.005 on x axis correspondingly. I came up with the following:
version 130

precision mediump float;
uniform sampler2D myTexture;

void main() {
vec2 redOffset = vec2(-0.005, 0.0);
vec2 blueOffset = vec2(0.005, 0.0);

vec2 rCoord = vec2(gl_TexCoord[0]);

float colR = texture2D(myTexture, rCoord + redOffset).r;
float colG = texture2D(myTexture, rCoord).g;
float colB = texture2D(myTexture, rCoord + blueOffset).b;
float colA = texture2D(myTexture, rCoord).a;
vec4 col = gl_Color * vec4(colR, colG, colB, colA);
gl_FragColor = col;
}

Which is also might be not the most efficient way to do that.

Now you combine everything in one action, and add it to "before first draw" behavior of your root node.

person icon
okeoke
Registered User
Quote
2024-09-29 22:27:58

// The following embedded xml is for the editor and describes how the action can be edited:
// Supported types are: int, float, string, bool, color, vect3d, scenenode, texture, action
/*
<action jsname="action_ShaderTest" description="Shader Test">
<property name="temp" type="string" default="" />
</action>
*/

action_ShaderTest = function () {

}

action_ShaderTest.prototype.execute = function (node) {
var vertexShader =
"uniform mat4 mWorldViewProj; \n" +
"uniform mat4 mInvWorld; \n" +
"uniform mat4 mTransWorld; \n" +
" \n" +
"void main(void) \n" +
"{ \n" +
" gl_Position = mWorldViewProj * gl_Vertex; \n" +
" \n" +
" // normal would be this: \n" +
" vec4 normal = vec4(gl_Normal, 0.0); \n" +
" normal = mInvWorld * normal; \n" +
" normal = normalize(normal); \n" +
" \n" +
" // world position would be this: \n" +
" vec4 worldpos = gl_Vertex * mTransWorld; \n" +
" \n" +
" gl_FrontColor = gl_BackColor = vec4(1.0, 1.0, 1.0, 0.0); \n" +
" \n" +
" gl_TexCoord[0] = gl_MultiTexCoord0; \n" +
"}";

var fragmentShader = 'version 130\r\n' +
'precision mediump float;\r\n' +
'uniform sampler2D myTexture;\r\n' +
'void main() {\r\n' +
' vec2 redOffset = vec2(-0.005, 0.0);\r\n' +
' vec2 blueOffset = vec2(0.005, 0.0);\r\n' +
' vec2 rCoord = vec2(gl_TexCoord[0]);\r\n' +
' float colR = texture2D(myTexture, rCoord + redOffset).r;\r\n' +
' float colG = texture2D(myTexture, rCoord).g;\r\n' +
' float colB = texture2D(myTexture, rCoord + blueOffset).b;\r\n' +
' float colA = texture2D(myTexture, rCoord).a;\r\n' +
' vec4 col = gl_Color * vec4(colR, colG, colB, colA);\r\n' +
' gl_FragColor = col;\r\n' +
'}'

var newMaterial = ccbCreateMaterial(vertexShader, fragmentShader, 0, null);

var cube = ccbGetSceneNodeFromName('fullScreenPlane');
ccbSetSceneNodeMaterialProperty(cube, 0, 'Type', newMaterial);
}

ccbRegisterOnFrameEvent(function () {
ccbRenderToTexture(ccbGetSceneNodeFromName('fullScreenPlane'), ccbGetActiveCamera(), 0, ccbGetScreenWidth(), ccbGetScreenHeight());
});


You do it pretty much the same way for DX, but write shader using hlsl of course.

Demo project here:https://drive.google.com/file/d/...

person icon
okeoke
Registered User
Quote
2024-09-30 09:59:01

I revisited this today, damn it looks ugly:) It looked much better on a bigger screen.
But the approach is still correct I believe, you just need to rewrite the shader properly.

person icon
guest_writer
Guest
Quote
2024-12-18 15:01:33

Will this oke oke ever be released for exe.
And also thanks to the community that you work for the common good thanks from everyone who is grateful (google translate).


Create reply:










 

  

Possible Codes


Feature Code
Link [url] www.example.com [/url]
Bold [b]bold text[/b]
Image [img]http://www.example.com/image.jpg[/img]
Quote [quote]quoted text[/quote]
Code [code]source code[/code]

Emoticons


icon_holyicon_cryicon_devilicon_lookicon_grinicon_kissicon_monkeyicon_hmpf
icon_sadicon_happyicon_smileicon_uhicon_blink   






Copyright© Ambiera e.U. all rights reserved.
Contact | Imprint | Products | Privacy Policy | Terms and Conditions |