Jump to content

Notes on shaders in Kenshi


disi30

Recommended Posts

Kenshi shader modelling

I gathered some information and experience on how shaders work in Kenshi.
Most of it is pure Ogre, which helps looking up things in their manuals.
File structure:
MyMod/myshader.mod // the mod file we create with FCS
MyMod/materials/compositors/compositors.cfg // which compositors to load, it adds to the original config and/or the one from other mods
MyMod/materials/compositors/MYSHADE.compositor // what input is directed to the shader process
Mymod/materials/mytexture.png // our texture image file
MyMod/materials/post/MYSHADE.material // the material file
MyMod/materials/post/MYSHADE.hlsl // the shader file
--------------------
MyMod/MYSHADE.mod // the mod file to activate in the launcher
--------------------
MyMod/materials/compositors/compositors.cfg
MYSHADE // all your need to add here to get the option ingame
--------------------
MyMod/materials/compositors/MYSHADE.compositor
compositor_node MYSHADE {  // this is the name of your material
    in 0 rt_output // the output of the previous shader is captured
    in 1 rt_input // and redirected as input of our shader
    
    target rt_output { // here we define the output into our shader
        pass render_quad {
            material MYSHADE // the material file to use with this input
            input 1 global_gbuffer 2 // here it uses slot 2, the "global_gbuffer 2" holds the depth texture, "global_gbuffer 1" is the normal
            input 2 rt_input // "input" = input, "3" = the slot for the texture (starts at 0), "rt_input" is the deferred colour
        }
    }
    
    out 0 rt_output // the output of our shader is captured
    out 1 rt_input // and redirected as input for the next shader
}
--------------------
Mymod/materials/mytexture.png // drop textures just into the materials folder
--------------------
MyMod/materials/post/MYSHADE.material
fragment_program myshade_ps hlsl // "myshade_ps" = name of the shader process, "hlsl" type of shader, this creates the process or instance of the shader
{
    source MYSHADE.hlsl // the actual name of the file that contains the code
    target ps_4_0 // what you want to render (floating point4x4 matrix)
    entry_point main // which is the main function to run in the shader first
    enable_backwards_compatibility true // for those who want to code the shader in DX9, you can use DX11 and most DX9 functions
    default_params // any parameters/variables you want to pass to the process
    {
        param_named mytexturesize float 64 // name of a variable we pass to the shader
        param_named_auto width viewport_width // some automatic rendered information to pass to our shader
        param_named_auto height viewport_height 
        shared_params_ref SharedDeferredParams // these contain some default parameters which that might be useful to the shader
    }
}
material MYSHADE // the name of the material (same as in compositor)
{
    technique
    {
        pass
        {
            cull_hardware none // some function, see Ogre manual
            cull_software none // some function, see Ogre manual
            depth_check off // some function, see Ogre manual
            vertex_program_ref Posteffects/StdQuad_vp {} // the main shader process this material is connected to
            fragment_program_ref myshade_ps {} // the fragment program we initialised above (has to be the same name), which this input relates to
            texture_unit { // this sends a texture to our shader process as input 0
                texture mytexture.png // send an actual texture to the shader
                tex_address_mode clamp // some texture option, see Ogre manual
                filtering none // some texture option, see Ogre manual
            }
            texture_unit {
                content_type Deferred GBuffer 2 // this is the depth texture, we configured in the compositor as input 1
                tex_address_mode clamp
                filtering none
            }
            texture_unit // this is the deferred input from the previous shader, we configured in the compositor as input 2
            {
                tex_address_mode clamp
                filtering none 
            }
        }
    }
}
--------------------
MyMod/materials/post/MYSHADE.hlsl
// here you can pretty much do what you want, but I want to highlight some things


SamplerState g_samLinear      // uniform sampler for DX11
{
    Filter = MIN_MAG_MIP_POINT;
    AddressU = Wrap;
    AddressV = Wrap;
};


uniform Texture2D myTexture : register(t0);                     // the mytexture.png we configured in the material
uniform Texture2D depthTexture : register(t1);                  // the depth gbuffer we configured in the material
uniform Texture2D imageTexture : register(t2);                  // the colour texture we configured in the material


float4 main(                                                    // this is the entry function we set in the material
    float4 posIn : SV_Position,                                 // some minimal input of the vertex and texture coordinates
    float2 texCoord : TEXCOORD0,                                // Don't change these or it breaks the pipeline and you get weird results.

    float mytexturesize,                                        // our setting from the material
    float width,                                                // auto information from the material
    float height                                                // auto information from the material
) : SV_Target
{
    float4 myPixel = imageTexture.Sample(g_samLinear, texCoord);                            // get the original pixel
    float2 screensize = {width, height};
    myPixel += myTexture.Sample(g_samLinear, texCoord * screensize / mytexturesize);        // add your picture to it, but scale it first to screensize, watermark?
    myPixel *= depthTexture.Sample(g_samLinear, texCoord);                                  // multiply it by De[a|p]th ?!?!?!?!?!?! crazy!111oneone


    return myPixel;                                                                         // this is the return value, whatever it looks like
}


p.s. The auto parameter viewport_width and viewport_height do not exist, anymore?

I cannot say which of these are outdated, but it is a good start.

Link to comment
Share on other sites



Global_buffers:
global_buffer 0 -> specular texture
global_buffer 1 -> normal texture
global_buffer 2 -> depth texture

This should be passed to every pixel shader, the input depends on the vertex shader:
float4 InPos : SV_POSITION, // or VPOS or POSITION is a made up name, both should be the same but SV_POSITION
float2 texCoord : TEXCOORD0, // adjusted texel position
float3 ray : TEXCOORD1, // or NORMAL
float2 tangent : TEXCOORD2, // or TANGENT0 (lightning direction?)
float2 binormal : TEXCOORD3, // or BINORMAL0 or BINORMAL
float3 cameraDir : TEXCOORD4,
float3 worldPos : TEXCOORD5,
float4 Color : COLOR,

Interesting variables for your material from common.program:
shared_params SharedSkyParams
{
shared_param_named sunDirection float3 1 1 0
shared_param_named sunDirectionReal float3 1 1 0
shared_param_named sunColour float4 1 1 1 1
shared_param_named pFogParams float4 0 20000 38000 0
shared_param_named TIME_OF_DAY float 0.0
shared_param_named gameTime float 0.0
shared_param_named heatHaze float 0.0
shared_param_named horizonClouds float4 1 1 1 0
}

shared_params SharedWaterParams
{
shared_param_named waterHeight float 0
shared_param_named worldOffset float3 0 0 0 // relative rendering offset
shared_param_named waterHeightRel float 0
shared_param_named rainAmount float 0
shared_param_named wetness float 0
shared_param_named dustAmount float3 0 0 0
}

shared_params ShadowSharedParams
{
shared_param_named shadowViewMat matrix4x4
shared_param_named shadowParams float4
shared_param_named biasParams float4
shared_param_named csmParams float4 [9]
shared_param_named csmScale float4 [9]
shared_param_named csmTrans float4 [9]
shared_param_named csmUvBounds float4 [9]
}

shared_params ShadowMapBlurParams
{
shared_param_named blur float 2
shared_param_named blurDepthScale float 0
}

// Shared parameters for defferred quad rendering
shared_params SharedDeferredParams {
shared_param_named farClip float 1
shared_param_named view matrix4x4 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1

shared_param_named mat0 float4 1 0 0 0 // matrix here as setting shared matrices doesnt seem to work in DX9
shared_param_named mat1 float4 0 1 0 0
shared_param_named mat2 float4 0 0 1 0

shared_param_named camera float3 0 0 0
shared_param_named fogParams float4 0 0 0 0
shared_param_named fogColour float3 0 0 0
shared_param_named corner1 float3 0 0 0
shared_param_named corner2 float3 0 0 0
}

// SkyX shared parameters for atmospheric scattering
shared_params SkyXFogParams {
shared_param_named uCameraPos float3 0 1 0
shared_param_named uInvWaveLength float3 9.473284438 11.76047764 26.6802131 // 1 / wavelength^4
shared_param_named uInnerRadius float 1
shared_param_named uExposure float 2
// Scattering parameters
shared_param_named uKrESun float 0.32299994
shared_param_named uKr4PI float 0.0850
shared_param_named uKm4PI float 0.2008849557
// Atmosphere properties
shared_param_named uScale float 4
shared_param_named uScaleDepth float 0.125
shared_param_named uScaleOverScaleDepth float 32
shared_param_named uSkydomeRadius float 70000
}

// Global weather based fog parameters
shared_params SharedFogParams {
shared_param_named fogColour float4 1 1 1 0
shared_param_named fogDensity float 0
}

// Shared parameters for debug ambient lighting
shared_params AmbientParams {
shared_param_named ambientParams float4 0.89 0.66 0.16 1
shared_param_named groundLight float4 0.8 0.5 0.7 0.56
shared_param_named zenithLight float3 1 1 1
shared_param_named nadirLight float3 1 1 1
shared_param_named envColour float4 1 1 1 1
shared_param_named worldSize float4 1 1 0 0
}
-------------------------------------------------------
Some auto parameters for the material:
param_named_auto proj projection_matrix
param_named_auto viewport viewport_size
param_named_auto inverseView view_matrix
param_named_auto offset texel_offsets
param_named_auto farClip far_clip_distance
param_named_auto camPos camera_position_object_space
param_named_auto texelSize inverse_texture_size 0
param_named_auto worldMatrix3x4Array world_matrix_array_3x4
param_named_auto viewProjectionMatrix viewproj_matrix
param_named_auto worldMatrix world_matrix
param_named_auto waterLine custom 1

Link to comment
Share on other sites

  • 4 weeks later...

SunDirection is either already in View Space or you can move it there by multiplying it with the View-Matrix.

Depth Buffer is the z value in Viewspace and runs perpendicular from the screen towards the pixel. It defines which vectors (objects) or part of in Worldspace make it onto the screen.
You can control it with "Depth_check on/off" and "Depth_write on/off" in the material.
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...