Skip to content
Alan Tse edited this page Sep 22, 2024 · 7 revisions

VR HLSL porting

VR porting assumes that the flat shader has been reversed already and exists in CS for flat. We typically do not RE or port for VR first due to the added complexity.

  1. Use Advanced -> Dump Shaders to dump all shaders for Flat/VR on startup. It will end up in data\ShaderDump.
  2. Use 3dmigitos decompiler on all the .bin shaders to get hlsl. We have a script Skyrim_Disassemble_Shaders that we haven't posted yet that will crawl all of the bin files. (ask on discord)
  3. Check cbuffers vs flat. Same size should be fine. Search this regex (VSCode escaped) in VR will identify eyeIndex based buffers. cb[0-9]+\[([^\]]+\+)+\w+\]. Compare against flat files for same cb (non regex). For example,
//FLAT
  r1.xyzw = float4(0,0,0,1) * cb12[8].wwww;
//VR
  r2.xyzw = cb12[r0.z+16].wwww * float4(0,0,0,1);

These are essentially the same buffer access of cb12. The addition order doesn't matter, and the additional index of r0.z is basically eyeIndex. The offset of + 16 shows that the variable at packoffset(c8) in flat is actually packoffset(c16) in VR. This is due to the fact we're in a set of arrays that use eyeIndex. Specifically, this matches what we've determined here: https://github.com/doodlum/skyrim-community-shaders/blob/dev/package/Shaders/Common/FrameBuffer.hlsl#L6.

Update the CS flat hlsl to use the right VR cbuffers. Use the define VR for VR specific code.

  1. On identifying eyeIndex based cbuffers, edit the CS flat hlsl that you are porting to now use the eyeIndex.
  2. Fix stereoUV coords. VR renders both left and right eye at the same time vs flat which is a single eye. So certain coords in flat UV space may need to be converted to stereoUV. Depthtexture is a prime example. See other examples. Keep track of the coordinate system acccessing the texture. For example UV or texcoord (in compute shaders) will need to be stereo.

Helpful VR functions can be found in https://github.com/doodlum/skyrim-community-shaders/blob/dev/package/Shaders/Common/VR.hlsli

Screen Space Reflections

VR disabled SSR. It can be forced enable at PostPostLoad with:

	if (REL::Module::IsVR()) {
		std::map<std::string, uintptr_t> hiddenVRCubeMapSettings{
			{ "bScreenSpaceReflectionEnabled:Display", 0x1ED5BC0 },
		};
		for (const auto& settingPair : hiddenVRCubeMapSettings) {
			const auto& settingName = settingPair.first;
			const auto address = REL::Offset{ settingPair.second }.address();
			bool* setting = reinterpret_cast<bool*>(address);
			if (!*setting) {
				logger::info("[PostPostLoad] Changing {} from {} to {} to support Dynamic Cubemaps", settingName, *setting, true);
				*setting = true;
			}
		}
	}

Latest work (near release)

Volumetric Lighting

ini setting doesn't seem to do anything, but enabling all these manually does turn on the compute shader, etc. (maybe some can be skipped)

		{ "bEnableVolumetricLighting:Display", { "Enable Volumetric Lighting", "Enables volumetric lighting.", 0x1ed63d8, true, false, true } },
		{ "bVolumetricLightingEnable:Display", { "Enable Volumetric Lighting (Second location))", "Enables volumetric lighting.", 0x3485360, true, false, true } },
		{ "bVolumetricLightingUpdateWeather:Display", { "Enable Volumetric Lighting (Weather)", "Enables volumetric lighting for weather.", 0x3485361, true, false, true } },
		{ "gVolumetricLightingEnabled_143232EF0", { "Enable Volumetric Lighting (Papyrus)", "Enables volumetric lighting."  "This was the Papyrus command.", 0x3485362, true, false, true } },

Requires this

Clone this wiki locally