How was this Game Rendered?

Posted By: Dooley

How was this Game Rendered? - 08/06/20 19:30

It's not exactly related to shaders, but I wrote up an article on how I rendered this small project in a unique way.
How was this Game Rendered?
[Linked Image]
Posted By: 3run

Re: How was this Game Rendered? - 08/06/20 20:01

Hey!

Interesting article (I liked paradox visuals too). So after reading it, I wanted to try Horror in the Museum out.
It runs with around 4-7 fps on my machine, I bet that's not intentional?

My specs
CPU: Core i7 3770
RAM: 8 gb
GPU: RX580 4gb

Greets
Posted By: Emre

Re: How was this Game Rendered? - 08/07/20 08:38

Same here. GPU usage:%40 CPU usage:%12. Result:5 fps.

Specs:R5 2600 & RX 590
Posted By: Quad

Re: How was this Game Rendered? - 08/07/20 08:54

Runs fine here, but i would love to try the higher resolution version. Also the one with perpendicular lines look awesome too.
Posted By: 3run

Re: How was this Game Rendered? - 08/07/20 10:05

Maybe it's caused by use of AMD GPUs ? Quad, are you using NVIDIA?
Posted By: Dooley

Re: How was this Game Rendered? - 08/07/20 11:45

Hmmm.... Are you absolutely sure it is the FPS, or could it be the stuttering effect of the drawn vertices? They are switching directions every few frames, and that might appear to be the frame rate.

I'm not doubting the possibility of this, but I just want to eliminate this explanation before moving forward.

Thanks for trying it by the way!

I have an Nvidia GTX 770. I will put in a frame rate counter, so I can see more clearly what's happening.
Posted By: 3run

Re: How was this Game Rendered? - 08/07/20 12:00

Originally Posted by Dooley
Hmmm.... Are you absolutely sure it is the FPS, or could it be the stuttering effect of the drawn vertices? They are switching directions every few frames, and that might appear to be the frame rate.
I used RivaTuner Statistics Server to check framerate + CPU and GPU usage, and it gave me around 4-7 fps.
Posted By: Quad

Re: How was this Game Rendered? - 08/07/20 12:01

@3run,
yep i have a rtx2070 and i7-9750H on my laptop

i also thought it might be rx5xx series. Maybe they do not support hw acceleration on drawing lines.
Posted By: Dooley

Re: How was this Game Rendered? - 08/07/20 12:15

Okay, I uploaded a test version that displays the full resolution game at 1280 x 720, without the old-school pixel shader.

It also has a frame-rate counter in the upper left corner. I am getting about 29-30 fps.

https://schmidt-workshops.itch.io/the-horror-in-the-museum
Posted By: 3run

Re: How was this Game Rendered? - 08/07/20 12:25

Just tested it and it starts with around 100 fps and drops down very fast... Like in 10 seconds it's became 4 fps.
Posted By: Dooley

Re: How was this Game Rendered? - 08/07/20 12:39

Interesting. I am going to venture a guess that this might be due to the 56000 vertices in my line drawing object laugh

Maybe I can reduce that and figure out a different way to generate a similar density of lines...
Posted By: Quad

Re: How was this Game Rendered? - 08/07/20 12:55

I think this is definitely an AMD issue, it runs at about 45fps on integrated intel uhd 630 graphics, and fixed 60fps on nvidia rtx 2070
Posted By: Dooley

Re: How was this Game Rendered? - 08/07/20 13:07

Still, it would be nice to make it run for everyone.
I am wondering if maybe having two line drawing objects, with half the vertices each, might help. There may be some kind of vertex limit per object?

Also, each line is technically a particle. Perhaps there is a limit on particle within those cards...
Posted By: 3run

Re: How was this Game Rendered? - 08/07/20 14:07

I also think that this is related to AMD but I don't think there is a particle or any that kind of limitations. My guess is that this is related to the way that acknex works with latest AMD drivers, otherways this problem would be widely discussed on the web. And I personally never faced any troubles with other games (even old ones from dx8 times).
Posted By: Dooley

Re: How was this Game Rendered? - 08/07/20 14:57

UPDATE:
I am getting over 500 fps with fog instead of the vector lines. So I'm sure this is the culprit. It might just be slightly slower on the AMD cards, but that's enough to go from 30 down to 5. I will experiment a bit more before updating again. I appreciate all the feedback!

If other Acknex games run fine, then it must be something wrong with my game, no?
I am going to upload another test version. But instead of vector lines, I will use standard fog settings. If you don't mind testing that, that would be great. That would indicate it has something to do with all the line draw commands...

Posted By: 3run

Re: How was this Game Rendered? - 08/07/20 15:28

Sure thing, I'll be glad to help you out!
Posted By: Dooley

Re: How was this Game Rendered? - 08/07/20 15:53

I was able to double the frame rate by reducing the number of vertices in the drawing object down to 24000. I also added a little bit of dark green fog to get it to look somewhat similar to the original.

If you want to try version 0.05, you can download it here.

https://schmidt-workshops.itch.io/the-horror-in-the-museum

I'm wondering if it doubles the frame rate for you too, or maybe it will improve more than that...
Posted By: 3run

Re: How was this Game Rendered? - 08/07/20 16:33

Sadly, fps still drops down right from the start... from 51 (weird, used to be around 100) to 8 (used to be 4).
Posted By: Dooley

Re: How was this Game Rendered? - 08/07/20 16:50

Okay, but double isn't too bad laugh
Maybe further optimizations will help. I'll have to think about it.
Posted By: Emre

Re: How was this Game Rendered? - 08/07/20 17:33

Hi Dooley,

The original version of the game is drawing 56501 particles per frame, i got 5 fps. The last one (v0.05) is drawing 24369 particles per frame and i got 12 fps. Correct me if i'm wrong, you use "draw_line3d" or something similar right? So we can do a little experiment to see if the problem is caused by this. I tried this code. I'm getting 10 fps at 30000 particles. Actually i didn't find it unusual and i don't know how you guys get more fps on Nvidia cards. That's strange. confused



Code
///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////
function main()
{
	vec_set(sky_color.blue,vector(0,0,0));
	max_particles=70000;
	video_mode=9;
	video_screen=2;
	level_load("");
	def_debug();
	while(1)
	{
		int i=0;
		for(i=0;i<30000;i++)
		{
			draw_line3d(vector(random(100000),random(100000),random(100000)), COLOR_GREEN, 10); 
		}
		wait(1);
	}	
}

Posted By: 3run

Re: How was this Game Rendered? - 08/07/20 19:02

@Emre I'm also getting 8 fps.

As I know all 'draw_' functions are extremely slow (manual disagrees, but they were always slow from my experience)...
Probably the way those functions are working in on acknex side has something to do with AMD GPUs... confused

Edit: take a look at the particles ms/frame... it's around ~100ms... damn
[Linked Image]
Posted By: Quad

Re: How was this Game Rendered? - 08/07/20 19:49

@Emre that's 180-200 fps here.
Posted By: Dooley

Re: How was this Game Rendered? - 08/07/20 21:28

Wondering if using the wireframe material might be faster...
Posted By: Emre

Re: How was this Game Rendered? - 08/08/20 00:34

Originally Posted by Quad
@Emre that's 180-200 fps here.

Wow! It seems jcl has developed a "Line tracing" or" DLSL" (Deep learning super lines) technique that only works for Nvidia rtx cards.

@3run seems the manual tell the half of the truth. They forgot to add; "For the best experience, requires an Nvidia branded card supporting DLSL technology."

grin

Edit: Last verison runs fine. (300 fps)
Posted By: Dooley

Re: How was this Game Rendered? - 08/08/20 00:35

Okay, I have updated the game, and it is running a lot faster!
https://schmidt-workshops.itch.io/the-horror-in-the-museum

If you download Version 0.06 you can try it. Press TAB to switch from pixel graphics to full resolution and see the fps counter.

I think you will be surprised laugh
Posted By: Quad

Re: How was this Game Rendered? - 08/08/20 09:54

Okay, that works better. Let's see what Emre and 3run are experiencing.

The effect kind of looks a diminished a little bit. It's still a very cool effect but maybe you could bring the near cutoff range closer to camera?
Posted By: 3run

Re: How was this Game Rendered? - 08/08/20 13:27

Originally Posted by Emre
@3run seems the manual tell the half of the truth. They forgot to add; "For the best experience, requires an Nvidia branded card supporting DLSL technology."

grin
grin

Demo seems to run perfectly fine now. I get around 500 fps with normal resolution (drops down to ~200 when tentacles are near by).
In normal resolution effect reminds me somehow of the spider webs, looks nice man! When pixelated, it looks like white noise, but only green in color.
Posted By: Dooley

Re: How was this Game Rendered? - 08/08/20 14:38

What I did was create a bunch of overlapping triangle meshes, set them to passable and have them follow the player's camera. Using the wireframe material has them only draw the edges, and that seems to take far less time to draw than the draw commands I was using. Also, using the fog feels like cheating after writing that article ... but it helps fill out the color in the distance without all the extra vertices, and you can't really tell.

Getting it to look right is more time consuming, just because I am using such a different way of rendering a similar effect. I have several such wireframe meshes that surround the player right now, and they each have around 1200 vertices. So I could add quite a few more to get a better looking effect. It's just a lot of tweaking now...
Posted By: Dooley

Re: How was this Game Rendered? - 11/08/20 01:27

Hey, I have a follow up question on this. My other game Paradox Vector seems to be experiencing the same issue with AMD cards. I am looking into possible ways to remedy this.

Right now i am using draw_line3d to render lines. The wireframe material also works, and is faster, but it ends up looking very bad because of some of it's limitations.

In lite-c, the wireframe shader seems to come down to these lines:

Code
MATERIAL* mtl_wireframe =
{
   effect = "technique { pass { Fillmode = Wireframe; } }";
   event = mtl_model_init;
}


This seems to be something built right into the engine itself, because I cannot find any "wireframe.fx" file that defines how it works.

Is there any way to write a shader (.fx file) that would draw the lines based on the same parameters as my script? And if so, do you think it might help resolve the problem?

I plan to try messing around with a shader script to see what I can come up with, but if anyone has any ideas, that would be great!

My existing script is as follows, and it is being called in the EVENT_FRAME for most objects:

Code
function draw_me(var my_blue, var my_green, var my_red, var my_alpha, var start_vec)
{
	VECTOR line_pos;
	var line_x = 0;// = start_vec;
	var vert_num = ent_status(my,1);
	
	for(line_x = start_vec;line_x < vert_num;line_x++)
	{
		vec_for_vertex(line_pos,my,line_x);
		
		if(line_x == start_vec)
		{
			draw_line3d(line_pos.x,NULL,my_alpha);
			draw_line3d(line_pos.x,vector(my_blue,my_green,my_red),my_alpha);
		}
		else if(line_x == vert_num)
		{
			vec_for_vertex(line_pos,my,start_vec);
			draw_line3d(line_pos.x,vector(my_blue,my_green,my_red),my_alpha);
		}
		else
		{
			draw_line3d(line_pos.x,vector(my_blue,my_green,my_red),my_alpha);
		}
	}	
}


Each model will provide its own colors, as will as starting vector when it calls this script - the script uses floating vectors (not attached to any triangle faces in the models) to draw the lines above the black surface faces of each model. Alpha is determined by the model's distance from the camera, as fog does not seem to work on 3d lines.
Posted By: 3run

Re: How was this Game Rendered? - 11/08/20 14:33

Hey!

draw_line, etc functions are using particles, and since particles are 2d they aren't affected by light or fog.
FillMode = Wireframe is something related to the HLSL, you can google that in Microsoft directx documentation.

I played around a little bit and got these results:
[Linked Image]

It supports:
Quote
- hard edges
- edge darken on angle
- no dynamic lights (can be added)
- alpha control for wireframe
- fog

To my taste, it lacks the ability to control the thickness of the wireframes...
Maybe some other more experienced users may tweak it or provide their own solution.

Code:
main.c
Code
#define PRAGMA_POINTER

MATERIAL *mtl_wireframe =
{
	effect = "wireframe.fx";
	flags = AUTORELOAD;
}

void main()
{
	warn_level = 6;
	fps_max = 60;
	
	level_load("");
	
	ENTITY *ent = ent_create("ball.mdl", vector(64, 0, 0), NULL);
	ent->material = mtl_wireframe;
	vec_set(&ent->blue, COLOR_GREY); // you can change color for each model by hand
	
	// material settings with range (0..1)
	ent->skill41 = floatv(1); // red
	ent->skill42 = floatv(1); // green
	ent->skill43 = floatv(1); // blue
	ent->skill44 = floatv(0.1); // alpha
}

wireframe.fx
Code
// set to zero to disable effect
#define ANGLE_SURFACE_DARKEN 0.25 // less number - less darken

float4x4 matWorldViewProj;
float4x4 matWorld;

float4 vecViewPos;
float4 vecFog;
float4 vecFogColor;
float4 vecLight;
float4 vecColor;

float4 vecSkill41; // used to controll wireframe color

texture entSkin1;

sampler ColorSampler = sampler_state
{
	Texture = <entSkin1>;
	Mipfilter = None;
	Minfilter = None;
	Magfilter = None;
};

void VS(
in float4 inposition : POSITION,
in float3 innormal : NORMAL,
in float4 intex1 : TEXCOORD0,
in float4 intex2 : TEXCOORD1,
out float4 outposition : POSITION,
out float4 outcolor : COLOR0,
out float3 outnormal : TEXCOORD0,
out float4 outtex : TEXCOORD1,
out float4 outworldPos : TEXCOORD2)
{
	inposition.w = 1.0f;
	outposition = mul(inposition, matWorldViewProj);
	
	outnormal = normalize(mul(innormal, (float3x3)matWorld));
	outtex.xy = intex1.xy;
	outtex.zw = intex2.xy;
	outworldPos = mul(inposition, matWorld);
	
	// no lightning
	outcolor = float4(vecColor.xyz, vecLight.w);
}

float4 PS(
float4 color : COLOR0,
float3 normal : TEXCOORD0,
float4 tex : TEXCOORD1,
float4 worldPos : TEXCOORD2) : COLOR0
{
	// hard edges (if needed)
	float3 dpdx = ddx(worldPos);
	float3 dpdy = ddy(worldPos);
	normal.xyz = normalize(cross(dpdy, dpdx));
	
	float4 textureColor = tex2D(ColorSampler, tex.xy);
	
	// darken surface on angle
	if(ANGLE_SURFACE_DARKEN > 0)
	{
		float3 vPixelToViewDir = normalize(vecViewPos.xyz - worldPos.xyz); // *** direction vector from the surface to the camera
		float dot_result = dot(vPixelToViewDir, normal.xyz); // *** get the angle ( cos(angle) ) between these vectors; both vectors in the dot product have to be normalized (length = 1)
		color.rgb *= saturate(1.0 - (1.0 - dot_result) * ANGLE_SURFACE_DARKEN); // *** apply the darkening factor with adjustable intensity; saturate() to prevent negative numbers (and numbers > 1)
	}
	
	// add texture to the color
	color.rgb *= textureColor.rgb;
	
	// fog part
	// just remove this 3 lines to remove the fog
	float fDepth = distance ( vecViewPos.xyz, worldPos.xyz );
	float Fog = saturate ( ( fDepth - vecFog.x ) * vecFog.z );
	color.rgb = lerp ( color.rgb, vecFogColor, Fog );
	color.a = 1;
	
	return color;
}

void WR_VS(
in float4 inposition : POSITION,
out float4 outposition : POSITION)
{
	// dirty trick to draw wiraframes 
	// above the actual solid polygons
	inposition.w = 0.998f;
	outposition = mul(inposition, matWorldViewProj);
}

float4 WR_PS(
float4 color : COLOR0,
float4 worldPos : TEXCOORD2) : COLOR0
{
	// change wireframe color with vecSkill41...43
	color.rgb = vecSkill41.xyz;
	
	// fog for wireframes
	// just remove this 3 lines to remove the fog
	float fDepth = distance ( vecViewPos.xyz, worldPos.xyz );
	float Fog = saturate ( ( fDepth - vecFog.x ) * vecFog.z );
	color.rgb = lerp ( color.rgb, vecFogColor, Fog );
	color.a = vecSkill41.w; // alpha value of the wireframe
	
	return color;
}

technique
{
	pass pass0 // first draw the solid model with hard edges
	{
		ZWriteEnable = True;
		AlphaBlendEnable = False;
		AlphaTestEnable = False;
		AlphaFunc = ALWAYS;
		Fillmode = SOLID;
		
		VertexShader = compile vs_3_0 VS(); 
		PixelShader  = compile ps_3_0 PS(); 
	}
	
	pass pass1 // then draw wireframes
	{
		ZWriteEnable = True;
		AlphaBlendEnable = True;
		AlphaTestEnable = False;
		AlphaFunc = Greater;
		Fillmode = Wireframe;
		
		VertexShader = compile vs_2_0 WR_VS(); 
		PixelShader = compile ps_2_0 WR_PS();
	}
}

technique fallback { pass one { } }

ball.mdl is the one from "GStudio8\templates\models" folder.
Model's color is controller directly by ent->blue, green, red values. Wireframe color is controlled by ent->skill41, 42, 43 (red, green, blue)

Greets.
Posted By: Dooley

Re: How was this Game Rendered? - 11/09/20 03:31

This is awesome! I did not expect someone to write a whole shader ... I really appreciate that. I will see if I can use it, and if it resolves the issue.
Posted By: 3run

Re: How was this Game Rendered? - 11/09/20 08:33

Glad to be helpful.


Just a quick thoughts: to get specific visuals, not related to visual polygons, maybe you can use two models and two shaders. So first model is the visual shape and it's shader won't draw any wireframes, only solid model. And second model will have specific vertex placement and shader with wireframes. Gonna give it a try, maybe it will work as planned.

Greets!
Posted By: Dooley

Re: How was this Game Rendered? - 11/09/20 13:32

Yes, it works, but the wireframe always seems to be limited to triangles. It ends up looking kind of clunky. It would also require that I re-create every model in my game, which I am trying to avoid.

I am looking into working with the AMD graphics card/drivers/preferences and stuff. I think there may be some settings that could help...
Posted By: 3run

Re: How was this Game Rendered? - 11/09/20 15:23

Sadly I can't really help with any AMD stuff. Let's hope more advanced users might help.
Posted By: Dooley

Re: How was this Game Rendered? - 11/10/20 15:10

Just to make sure I understand this ... a shader seems to me limited to working with models/textures etc that are already being rendered. It seems like shaders would not be used to draw new images/pixels onto the screen, but rather to modify the ones that are already there. Is that accurate?
Posted By: 3run

Re: How was this Game Rendered? - 11/10/20 15:27

I'm not sure, if I understood you correctly, but take a look at this video:
What is HLSL?

Edit: I've also made some changes in the wireframe shader, so now you can change its (wireframe) alpha via entitie's skill44.

Edit2: I've found some tips on the web, about (f.e.) removing the inner line in wireframe shader. It's pretty simple (in theory):
Quote
What you want is to only draw lines around the edge of the cube. And there are many ways you can acheive this...

Render a texture on to the cube, which has alpha everywhere but the edges.
Use a pixel shader to turn all pixels that are not at the edge of the cube to alpha. <- This is recommended by me, as you will be able to set the line length around the cube.

Sad thing is, that I don't really know, how to find pixels which aren't on the edge of the polygons...

Source:
How can I get rid of the diagonal wires in wireframe boxes?

Edit3: articles about how to create wireframe shader and remove the inner line (but it's OpenGL):
Single-Pass Wireframe Rendering
Single-Pass Wireframe Rendering Explained and Extended

Posted By: Dooley

Re: How was this Game Rendered? - 11/11/20 03:18

I just came across the "Lesson 4: Using DirectX functions" part in the manual. I'm wondering if anyone has explored any of these functions...

My guess is that draw_line3d would have to somehow utilize a directx function anyway, and that it would probably be more efficient than anything I could come up with. But maybe it's worth a try?
Posted By: 3run

Re: How was this Game Rendered? - 11/11/20 07:02

Those lessons are related to the SDK. So they aren't really useful in your case. Lesson 4 just shows how to use DirectX functions from DirectX SDK.

draw_line3d already uses DirectX, because DirectX is responsible for rendering everything in the games window (models, sprites, particles, etc).
draw_line3d uses particles (and it's pretty slow). My guess is, that (as you own A8 pro) you are using particle instancing and it probably doesn't work correctly with AMD cards.
The best way to resolve this problem will be asking jcl directly, maybe he has some thoughts, maybe he can confirm that instancing is only supported by NVIDIA.

Edit: I think it will be MUCH FASTER to use shaders for your needs, but I'm too limited with my knowledge, to write anything more than I've already shared.
Posted By: Emre

Re: How was this Game Rendered? - 11/11/20 16:22

What about pp edge detection shader, like sobel?

[Linked Image]

Code
#include <acknex.h>
#include <default.c>
#include <mtlView.c>

#define PRAGMA_PATH "%EXE_DIR%\templates\models";

action ent_act()
{
	while(1)
	{
		my.pan+=3*time_step;
		my.tilt+=3*time_step;
		wait(1);
	}
}
function main()
{
	video_mode=10;
	level_load("");
	ent_create(CUBE_MDL,vector(300,0,0),ent_act);
	ent_create("ball.mdl",vector(300,-50,0),ent_act);
	ent_create("sf_women.mdl",vector(300,50,0),ent_act);
	
	pp_set(camera,mtl_sobel);
	
}
Posted By: LoriHansen

Re: How was this Game Rendered? - 12/14/20 08:09

Exactly the Same here. GPU usage:%40 CPU usage:%12. Result:5 fps.

Specs:R5 2600 & RX 590

texttospeech.onl
Posted By: Dooley

Re: How was this Game Rendered? - 12/14/20 17:48

Originally Posted by LoriHansen
Exactly the Same here. GPU usage:%40 CPU usage:%12. Result:5 fps.

Specs:R5 2600 & RX 590

Which game are you referring to? Paradox Vector or the Horror in the Museum?
© 2024 lite-C Forums