Gamestudio Links
Zorro Links
Newest Posts
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (AndrewAMD, alibaba), 1,184 guests, and 3 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Hanky27, firatv, wandaluciaia, Mega_Rod, EternallyCurious
19051 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 1 of 2 1 2
Atmospheric Scattering + Sun Shader #434195
12/16/13 15:29
12/16/13 15:29
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
This code/shader simulates atmospheric scattering and renders the sun into the sky.

Because it's a bit tricky to set up everything right, I made a test level where you can directly see the results in realtime (and play with sun angles)

Download testlevel and source files:
http://www.stonehill-games.de/downloads/atmospheric_scattering_A8.rar

If you want to get real sun positions, use this script:
http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=434181

Shader code is taken from Sean O'Neil's GPU Gems 2:
http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html




EDIT: for those who want to set up the code by themselfs. Here you go:

1. create s centered sphere "sky_sphere.mdl" in MED with radius = 1 quant with inverted normals.

2. create the "atmospheric_scattering.fx" file:
Code:
#define PI 3.14159f

#define m_hdrExposure 1.25f

// Difference between inner and ounter radius. Must be 2.5%
#define m_outerScaleFactor 1.025f	

// Wave length of sun light
#define m_waveLength float3(0.65f, 0.57f, 0.475f) 

// Sun brightness constant
#define m_ESun 20.0f 			

// Rayleigh scattering constant
#define m_kr 0.0035f 	

// Mie scattering constant		
#define m_km 0.0010f 			

// The Mie phase asymmetry factor, must be between 0.999 to -0.999
#define m_g -0.99f			

// The scale depth (i.e. the altitude at which the atmosphere's average density is found)
#define m_scaleDepth 0.25f 	

#define radius vecSkill1.x


float4x4 matWorldViewProj;
float4x4 matWorld;
float4 vecViewPos;
float4 vecSunDir;
float4 vecSkill1;

float3 v3InvWavelength;
float fOuterRadius;				// The outer (planetary) radius
float fOuterRadius2;				// fOuterRadius^2
float fInnerRadius;				// The inner (planetary) radius
float fInnerRadius2;				// fInnerRadius^2
float fKrESun;						// Kr * ESun
float fKmESun;						// Km * ESun
float fKr4PI;						// Kr * 4 * PI
float fKm4PI;						// Km * 4 * PI
float fScale;						// 1 / (fOuterRadius - fInnerRadius)
float fScaleOverScaleDepth;	// fScale / fScaleDepth
float fHdrExposure;				// HDR exposure

struct v2f 
{
	float4 pos : POSITION;
	float2 uv : TEXCOORD0;
	float3 t0 : TEXCOORD1;
	float3 c0 : COLOR0;
	float3 c1 : COLOR1;
};

float scale(float fCos)
{
	float x = 1.0 - fCos;
	return 0.25 * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
}

v2f VS (
float4 inPos : POSITION,
float2 inTexCoord : TEXCOORD0
)
{
	v2f Out;
	
	Out.pos = mul(inPos,matWorldViewProj);
	
	v3InvWavelength = float3(1.0f / pow(m_waveLength.x, 4.0f), 1.0f / pow(m_waveLength.y, 4.0f), 1.0f / pow(m_waveLength.z, 4.0f));
	fOuterRadius = radius * m_outerScaleFactor;
	fOuterRadius2 = fOuterRadius*fOuterRadius;		
	fInnerRadius = radius;			
	fInnerRadius2 = fInnerRadius*fInnerRadius;	
	fKrESun = m_kr*m_ESun;				
	fKmESun = m_km*m_ESun;				
	fKr4PI = m_kr*4.0f*PI;			
	fKm4PI = m_km*4.0f*PI;	
	fScale = (1.f / (fOuterRadius - fInnerRadius));					
	fScaleOverScaleDepth = fScale/m_scaleDepth;		

	float3 v3CameraPos = float3(0.f,radius,0.f); 								// The camera's current position
	float fCameraHeight = radius;													// The camera's current height
	//float fCameraHeight2 = fCameraHeight*fCameraHeight;		// fCameraHeight^2
	
	// Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)
	float3 v3Pos = mul(matWorld, inPos).xyz;
	float3 v3Ray = v3Pos - v3CameraPos;
	float fFar = length(v3Ray);
	v3Ray /= fFar;
	
	// Calculate the ray's starting position, then calculate its scattering offset
	float3 v3Start = v3CameraPos;
	float fHeight = length(v3Start);
	float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fCameraHeight));
	float fStartAngle = dot(v3Ray, v3Start) / fHeight;
	float fStartOffset = fDepth *scale(fStartAngle);
	
	float fSamples = 2.0;
	
	// Initialize the scattering loop variables
	float fSampleLength = fFar / fSamples;
	float fScaledLength = fSampleLength * fScale;
	float3 v3SampleRay = v3Ray * fSampleLength;
	float3 v3SamplePoint = v3Start + v3SampleRay * 0.5f;
	
	// Now loop through the sample rays
	float3 v3FrontColor = float3(0.0, 0.0, 0.0);
	for(int i=0; i<int(fSamples); i++)
	{
		float fHeight = length(v3SamplePoint);
		float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
		float fLightAngle = dot(vecSunDir.xyz*(-1.f), v3SamplePoint) / fHeight;
		float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
		float fScatter = (fStartOffset + fDepth*(scale(fLightAngle) - scale(fCameraAngle)));
		float3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
		v3FrontColor += v3Attenuate * fDepth * fScaledLength;
		v3SamplePoint += v3SampleRay;
	}
	
	Out.uv = inTexCoord.xy;
	
	// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
	Out.c0 = v3FrontColor * v3InvWavelength * fKrESun;
	Out.c1 = v3FrontColor * fKmESun;
	Out.t0 = v3CameraPos - v3Pos;

	return Out;
}

// Calculates the Mie phase function
float getMiePhase(float fCos, float fCos2, float g, float g2)
{
	return 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
}

// Calculates the Rayleigh phase function
float getRayleighPhase(float fCos2)
{
	return 0.75 + 0.75*fCos2;
}

float4 PS(v2f IN) : COLOR
{

	float fCos = dot(vecSunDir.xyz*(-1.f), IN.t0) / length(IN.t0);
	float fCos2 = pow(fCos,2);
	float3 col = getRayleighPhase(fCos2) * IN.c0 + getMiePhase(fCos, fCos2, m_g, m_g*m_g) * IN.c1;

	//Adjust color from HDR
	fHdrExposure = m_hdrExposure;	
	col = 1.0 - exp(col * -fHdrExposure);

	return float4(col,1.0f);
}

technique tMain
{
	pass 
	{
		VertexShader = compile vs_3_0 VS(); 
		PixelShader = compile ps_3_0 PS();
	}
}



3. create the "atmospheric_scattering.c" script with following code:
Code:
#include <acknex.h>
#include <default.c>

var mtl_atmospheric_scattaring_radius=50000;

//atmospheric scattering material
MATERIAL* mtl_atmospheric_scattering =
{
	effect="atmospheric_scattering.fx";	
}

void init_atmospheric_scattering(ENTITY* sky_)
{
	//scale sky sphere to defined radius multiplied by factor 1.025 (difference of inner and outer atmosphere radius
	vec_scale(sky_.scale_x,mtl_atmospheric_scattaring_radius);
	vec_scale(sky_.scale_x,1.025);
	
	//pass sky sphere radius to material
	mtl_atmospheric_scattering.skill1=floatv(mtl_atmospheric_scattaring_radius);
}

void atmospheric_scattering_startup()
{
	//wait until level is loaded
	while(!level_ent){wait(1);}
	
	//create sky sphere
	ENTITY* sky_=ent_create("sky_sphere.mdl",nullvector,NULL);
	
	//set flags
	set(sky_,PASSABLE|UNTOUCHABLE|NOFOG);
	
	//assign material
	sky_.material=mtl_atmospheric_scattering;
	
	//update scale
	init_atmospheric_scattering(sky_);
	
	while(1)
	{
		//sky sphere needs to have always same position as camera minus sky sphere radius
		vec_set(sky_.x,camera.x);
		sky_.z-=mtl_atmospheric_scattaring_radius;

		wait(1);
	}
}




void main()
{
	video_screen=2;
	video_mode=8;

	//load level
	level_load(NULL);
}


Last edited by oliver2s; 12/16/13 15:36.
Re: Atmospheric Scattering + Sun Shader [Re: oliver2s] #434197
12/16/13 15:42
12/16/13 15:42
Joined: Mar 2011
Posts: 3,150
Budapest
sivan Offline
Expert
sivan  Offline
Expert

Joined: Mar 2011
Posts: 3,150
Budapest
looks nice. is it okay only with a sphere sky model? maybe I will try it together with some other sky entities using alpha to blend them...


Free world editor for 3D Gamestudio: MapBuilder Editor
Re: Atmospheric Scattering + Sun Shader [Re: sivan] #434198
12/16/13 15:44
12/16/13 15:44
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
Originally Posted By: sivan
is it okay only with a sphere sky model?

What do mean by "okay"? It's only working with a sphere sky model. But not defined as Sky Entity but as regular Entity (see code).

Re: Atmospheric Scattering + Sun Shader [Re: oliver2s] #434204
12/16/13 16:31
12/16/13 16:31
Joined: Jul 2010
Posts: 283
Germany
J
jenGs Offline
Member
jenGs  Offline
Member
J

Joined: Jul 2010
Posts: 283
Germany
Isn't it possible to set the SCENE flag, so the sky never could clip other geometry?

Re: Atmospheric Scattering + Sun Shader [Re: jenGs] #434207
12/16/13 16:42
12/16/13 16:42
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
No that doesn't work, this was already discussed in another thread I found while facing this problem.

Re: Atmospheric Scattering + Sun Shader [Re: oliver2s] #434231
12/17/13 08:10
12/17/13 08:10
Joined: Mar 2011
Posts: 3,150
Budapest
sivan Offline
Expert
sivan  Offline
Expert

Joined: Mar 2011
Posts: 3,150
Budapest
I meant that thanks laugh
there are several bad things in 3dgs sky system I rreported earlier, but no correction can be expected:
- SCENE models are clipped
- image based sky cube covers world at around sqrt(2)*clip_far distance
- sky domes have no material assigned
anyway it is another great contribution, I'm sure it can be integrated with other skies hiding model edges by fog, dof or other effects.


Free world editor for 3D Gamestudio: MapBuilder Editor
Re: Atmospheric Scattering + Sun Shader [Re: sivan] #434345
12/17/13 10:47
12/17/13 10:47
Joined: Nov 2007
Posts: 2,568
Germany, BW, Stuttgart
MasterQ32 Offline
Expert
MasterQ32  Offline
Expert

Joined: Nov 2007
Posts: 2,568
Germany, BW, Stuttgart
Wow, nice contribution! Also the other terrain stuff is awesome.
I always wanted to have such a shader in some of my projects.


Visit my site: www.masterq32.de
Re: Atmospheric Scattering + Sun Shader [Re: MasterQ32] #434428
12/18/13 13:10
12/18/13 13:10
Joined: Mar 2006
Posts: 1,993
Karlsruhe
PadMalcom Offline
Serious User
PadMalcom  Offline
Serious User

Joined: Mar 2006
Posts: 1,993
Karlsruhe
Do you plan to integrate that into IceX3?

Re: Atmospheric Scattering + Sun Shader [Re: PadMalcom] #434430
12/18/13 13:19
12/18/13 13:19
Joined: Aug 2002
Posts: 3,258
Mainz
oliver2s Offline OP
Expert
oliver2s  Offline OP
Expert

Joined: Aug 2002
Posts: 3,258
Mainz
Yes, it will be integrated in IceX3.

Re: Atmospheric Scattering + Sun Shader [Re: oliver2s] #434442
12/18/13 15:42
12/18/13 15:42
Joined: May 2005
Posts: 2,713
Lübeck
Slin Offline
Expert
Slin  Offline
Expert

Joined: May 2005
Posts: 2,713
Lübeck
Nice that you went through with it laugh
When I read the article after seeing your post I decided to delay better sky rendering for now tongue
The results seem pretty good, but the code to get there is by far not as straight forward as I would like it to be.
Also I would like to do this on a per fragment basis instead of doing most things per vertex using a sky sphere with an even polygon distribution for clean results.

From just a quick look at your code, I do recommend you to use a define for fSamples. I know that without at least the glsl compiler on my mac won´t unroll the loop and probably even take additional time for the cast to int. Especially real (as in not unrolled, dynamic) loops, have a serious performance impact.

Also about sky rendering in general: To make the sky appear behind everything you usually render the sky before everything else without depth writing and only applying the cameras rotation and projection matrix and if needed the skies rotation matrix. As a result it will appear behind everything else, won´t be clipped and won´t clip anything and just replace the clear color as it should.
As far as I know gamestudio does this by default, but since you messed with it more than I did you probably know better how you can or can´t use this shader with gamestudio sky system or replace it with your own custom sky rendering.

Page 1 of 2 1 2

Moderated by  HeelX, Lukas, rayp, Rei_Ayanami, Superku, Tobias, TWO, VeT 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1