Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Triplanar mapping #358

Merged
merged 4 commits into from Feb 19, 2023

Conversation

TaaTT4
Copy link
Contributor

@TaaTT4 TaaTT4 commented Jan 12, 2023

This was a feature that I had in my engine for a while and, rather than letting it die with him, I preferred to make it available to the community (since someone also asked for it). As the title says, it adds support for enabling/disabling triplanar mapping on HLMS Terra detail maps.

Some remarks:

  • It doesn't provide triplanar mapping to the non-detail maps (so only the diffuse map in terrain context) simply because it wasn't needed in my scenario; with some fairly simple modifications the triplanar mapping can easily be extended to non-detail maps as well.
  • User can enable triplanar mapping per texture channels (e.g. for diffuse and normal detail maps only); this allows him to find a compromise between visual quality and performance and/or to save some calculations if he uses monochromatic textures in some channels (e.g. metalness). When triplanar mapping is enabled for some channels, but not for others, the textures of the latters are sampled using world coordinates from a top view projection.

Some screenshots (left w/o triplanar mapping; right w/ triplanar mapping):

@cryham
Copy link
Contributor

cryham commented Feb 3, 2023

Works in DX11, but there is a crash in OpenGL3+ and Vulkan when pressing T (for triplanar), pixel shader has an error.

@TaaTT4
Copy link
Contributor Author

TaaTT4 commented Feb 8, 2023

It seemed I had tested It both in OpenGL and Vulkan, but I could be wrong... What's the error?

@cryham
Copy link
Contributor

cryham commented Feb 8, 2023

So this is in Ogre.log when I press T on GL3+

11:33:26: Vertex Shader: 100000003VertexShader_vs
Fragment Shader: 100000003PixelShader_ps
 GLSL validation result : 
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
11:33:26: Vertex Shader: 700000006VertexShader_vs
Fragment Shader: 700000006PixelShader_ps
 GLSL validation result : 
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
11:33:26: Vertex Shader: 700000007VertexShader_vs
Fragment Shader: 700000007PixelShader_ps
 GLSL validation result : 
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
Validation Error: Samplers of different types point to the same texture unit
11:33:29: Shader Compiler:error(high) 0: SHADER_ID_COMPILE error has been generated. GLSL compile failed for shader 29, "700000008PixelShader_ps (./700000008PixelShader_ps.glsl)": ERROR: 0:1184: 'pow' : no matching overloaded function found (using implicit conversion) 
ERROR: 0:1184: 'pow' : function is not known 
ERROR: 0:1183: '=' :  cannot convert from 'const highp float' to '3-component vector of highp float'
ERROR: 0:1269: '=' :  cannot convert from '4-component vector of highp float' to 'highp float'
ERROR: 0:1277: '=' :  cannot convert from '4-component vector of highp float' to 'highp float'
ERROR: 0:1306: '=' :  cannot convert from '4-component vector of highp float' to 'highp float'
ERROR: 0:1314: '=' :  cannot convert from '4-component vector of highp float' to 'highp float'


11:33:29: GLSL compile log: 700000008PixelShader_ps
ERROR: 0:1184: 'pow' : no matching overloaded function found (using implicit conversion) 
ERROR: 0:1184: 'pow' : function is not known 
ERROR: 0:1183: '=' :  cannot convert from 'const highp float' to '3-component vector of highp float'
ERROR: 0:1269: '=' :  cannot convert from '4-component vector of highp float' to 'highp float'
ERROR: 0:1277: '=' :  cannot convert from '4-component vector of highp float' to 'highp float'
ERROR: 0:1306: '=' :  cannot convert from '4-component vector of highp float' to 'highp float'
ERROR: 0:1314: '=' :  cannot convert from '4-component vector of highp float' to 'highp float'
11:33:29: OGRE EXCEPTION(3:RenderingAPIException): Fragment Program 700000008PixelShader_ps failed to compile. See compile log above for details. in GLSLShader::compile at D:\_\sr\og3\Ogre\ogre-next\RenderSystems\GL3Plus\src\GLSL\OgreGLSLShader.cpp (line 316)
11:33:29: WARNING: GraphicsSystem::deinitialize() not called!!!

Honestly I can't even because the line numbers given in .log point to empty lines in .glsl.

But I suspected and changed the only pow from that triplanar line for blend factors midf3 triplanarBlend =
to some const, and I got other errors next. Which IDK where are (above reason).

@cryham
Copy link
Contributor

cryham commented Feb 10, 2023

Okay found a way, have to delete the block at start from #if 0 to #endif with all parameters dump, then the lines from .log match to right lines in .glsl.

I fixed the first issue with pow by replacing
midf3 triplanarBlend = pow( pixelData.geomNormal, _h( 4.0 ) );
to this
midf3 triplanarBlend = pow( pixelData.geomNormal, midf3_c( 4.0, 4.0, 4.0 ) );
And the second issue lands into all those

midf metalness0 = SampleMetalness0Triplanar( textureMaps2,
midf roughness0 = SampleRoughness0Triplanar( textureMaps2,

saying I can't put a float3 into float.
Fixed it by adding .x in DetailTriplanar_piece_ps.any for SampleMetalness* and SampleRoughness*, in 6 places total, replacing this

arrayIdx ) * triplanarBlend.x +													   \

to this

arrayIdx ).x * triplanarBlend.x +													   \

BTW this happened for me on Windows 10 in GL3+ with integrated Intel GPU and did also on Debian 11 with AMD GPU.

@TaaTT4
Copy link
Contributor Author

TaaTT4 commented Feb 14, 2023

Well spotted, congrats and thank you! :) As you correctly identified it, the problem is that OpenGL and Vulkan don't implicitly cast from float to float3. I'm quite busy in these days, but I'll try to fix it ASAP.

@darksylinc darksylinc merged commit 019fccd into OGRECave:master Feb 19, 2023
@darksylinc
Copy link
Member

darksylinc commented Feb 19, 2023

Merged manually!

I fixed the problems.

After fixing the pow3, another problem arise which boiled down to:

float4 a,b,c;

#define Foo()  a + b + c
float value = Foo().x;

// Which translates to:
float value = a + b + c.x; // The result is a float4!!! Cannot be casted down implicitly

// Solution:
#define Foo()  (a + b + c)
float value = Foo().x; // Everything's alright now

I was surprised that this works on GL3+ as well! (because GL uses a basic macro parser, and that multi-line macro looked scary)

Thanks for your contribution!

@cryham
Copy link
Contributor

cryham commented Mar 3, 2023

Hi @darksylinc in case you missed my post, I'm also adding link here
https://forums.ogre3d.org/viewtopic.php?p=554263#p554263
Could someone confirm if you have this too? Or is this just something wrong in my code, I merged manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants